website: Flesh out docs split.

website: Copy files during build.

website: Allow for mixed env builds.

website: Reduce build size.

website: Expose build.

website: Add build memory debugging.

WIP: Disable broken links check to compare memory usage.

website: Update deps.

website: Clean up API paths.

website: Flesh out 3.8 fixes.

Format.

website: Update ignore paths.

Website: Clean up integrations build.

website: Fix paths.

website: Optimize remark.

website: Update deps.

website: Format.

website: Remove linking.

website: Fix paths.

wip: Attempt API only build.

Prep.

Migrate render to runtime. Tidy sidebar.

Clean up templates.

docs: Move directory. WIP

docs: Flesh out split.

website: Fix issue where routes have collisions.
This commit is contained in:
Teffen Ellis
2025-06-17 21:02:38 +02:00
parent b10c795a26
commit 582812b3ec
704 changed files with 5179 additions and 4670 deletions

View File

@ -0,0 +1,168 @@
---
title: Expression Policies
---
Expression policies are perhaps the most flexible way to define specific implementations of flows and stages. With Expression polices, you can provide Python code to enforce custom checks and validation.
The passing of the policy is determined by the return value of the code.
To pass a policy, use:
```python
return True
```
To fail a policy use:
```python
return False
```
**Example**:
Here's a simple policy that you could bind to a MFA validation stage if you want to specify that only certain users should be prompted for MFA validation:
```
if request.context["pending_user"].username == "marie":
return True
return False
```
If the return is `True` that means Yes, use this stage (i.e. the user will get the MFA prompt). A return of `False` means remove this stage from the plan.
## Available Functions
### `ak_message(message: str)`
Add a message, visible by the end user. This can be used to show the reason why they were denied.
Example:
```python
ak_message("Access denied")
return False
```
import Functions from "../../expressions/_functions.mdx";
<Functions />
## Variables
import Objects from "../../expressions/_objects.md";
<Objects />
- `request`: A PolicyRequest object, which has the following properties:
- `request.user`: The current user, against which the policy is applied. See [User](../../users-sources/user/index.mdx)
:::caution
When a policy is executed in the context of a flow, this will be set to the user initiaing request, and will only be changed by a `user_login` stage. For that reason, using this value in authentication flow policies may not return the expected user. Use `context['pending_user']` instead; User Identification and other stages update this value during flow execution.
If the user is not authenticated, this will be set to a user called _AnonymousUser_, which is an instance of [authentik.core.models.User](https://docs.djangoproject.com/en/4.1/ref/contrib/auth/#django.contrib.auth.models.User) (authentik uses django-guardian for per-object permissions, [see](https://django-guardian.readthedocs.io/en/stable/)).
:::
- `request.http_request`: The Django HTTP Request. See [Django documentation](https://docs.djangoproject.com/en/4.1/ref/request-response/#httprequest-objects).
- `request.obj`: A Django Model instance. This is only set if the policy is ran against an object.
- `request.context`: A dictionary with dynamic data. This depends on the origin of the execution.
- `geoip`: GeoIP dictionary. The following fields are available:
:::info
For basic country matching, consider using a [GeoIP policy](./index.md#geoip-policy).
:::
- `continent`: a two character continent code like `NA` (North America) or `OC` (Oceania).
- `country`: the two character [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1) alpha code for the country.
- `lat`: the approximate latitude of the location associated with the IP address.
- `long`: the approximate longitude of the location associated with the IP address.
- `city`: the name of the city. May be empty.
```python
return context["geoip"]["continent"] == "EU"
```
- `asn`: ASN dictionary. The following fields are available:
:::info
For basic ASN matching, consider using a [GeoIP policy](./index.md#geoip-policy).
:::
- `asn`: the autonomous system number associated with the IP address.
- `as_org`: the organization associated with the registered autonomous system number for the IP address.
- `network`: the network associated with the record. In particular, this is the largest network where all of the fields except `ip_address` have the same value.
```python
return context["asn"]["asn"] == 64496
```
- `ak_is_sso_flow`: Boolean which is true if request was initiated by authenticating through an external provider.
- `ak_client_ip`: Client's IP Address or 255.255.255.255 if no IP Address could be extracted. Can be [compared](#comparing-ip-addresses), for example
```python
return ak_client_ip in ip_network('10.0.0.0/24')
# or
return ak_client_ip.is_private
```
See also [Python documentation](https://docs.python.org/3/library/ipaddress.html#ipaddress.ip_address)
Additionally, when the policy is executed from a flow, every variable from the flow's current context is accessible under the `context` object.
This includes the following:
- `context['flow_plan']`: The actual flow plan itself, can be used to inject stages.
- `context['flow_plan'].context`: The context of the currently active flow, which differs from the policy context. Some fields of flow plan context are passed to the root context, and updated from it, like 'prompt_data', but not every variable
- `context['flow_plan'].context['redirect']`: The URL the user should be redirected to after the flow execution succeeds. (Optional)
- `context['prompt_data']`: Data which has been saved from a prompt stage or an external source. (Optional)
- `context['application']`: The application the user is in the process of authorizing. (Optional)
- `context['source']`: The source the user is authenticating/enrolling with. (Optional)
- `context['pending_user']`: The currently pending user, see [User](../../users-sources/user/user_ref.mdx)
- `context['is_restored']`: Contains the flow token when the flow plan was restored from a link, for example the user clicked a link to a flow which was sent by an email stage. (Optional)
- `context['auth_method']`: Authentication method (this value is set by password stages) (Optional)
Depending on method, `context['auth_method_args']` is also set.
Can be any of:
- `password`: Standard password login
- `auth_mfa`: MFA login (this method is only set if no password was used)
Sets `context['auth_method_args']` to
```json
{
"mfa_devices": [
{
"pk": 1,
"app": "otp_static",
"name": "Static Token",
"model_name": "staticdevice"
}
]
}
```
- `auth_webauthn_pwl`: Password-less WebAuthn with Passkeys login
- `jwt`: OAuth Machine-to-machine login via external JWT
- `app_password`: App password (token)
Sets `context['auth_method_args']` to
```json
{
"token": {
"pk": "f6d639aac81940f38dcfdc6e0fe2a786",
"app": "authentik_core",
"name": "test (expires=2021-08-23 15:45:54.725880+00:00)",
"model_name": "token"
}
}
```
- `ldap`: LDAP bind authentication
Sets `context['auth_method_args']` to
```json
{
"source": {} // Information about the source used
}
```

View File

@ -0,0 +1,17 @@
---
title: Managing flow context keys
---
[Flow context](../../../add-secure-apps/flows-stages/flow/context/index.mdx) can be managed in [Expression policies](../expression.mdx) via the `context['flow_plan'].context` variable.
Here's an example of setting a key in an Expression policy:
```python
context['flow_plan'].context['redirect_stage_target'] = 'ak-flow://redirected-authentication-flow'
```
And here's an example of removing that key:
```python
context['flow_plan'].context.pop('redirect_stage_target', None)
```

View File

@ -0,0 +1,19 @@
---
title: Ensure unique email addresses
---
Due to the database design of authentik, email addresses are by default not required to be unique. This behavior can however be changed by policies.
The snippet below can be used as the expression in policies both with enrollment flows, where the policy should be bound to any stage before the [User write](../../../add-secure-apps/flows-stages/stages/user_write.md) stage, or with the [Prompt stage](../../../add-secure-apps/flows-stages/stages/prompt/index.md).
```python
from authentik.core.models import User
# Ensure this matches the *Field Key* value of the prompt
field_name = "email"
email = request.context["prompt_data"][field_name]
if User.objects.filter(email=email).exists():
ak_message("Email address in use")
return False
return True
```

View File

@ -0,0 +1,35 @@
---
title: Whitelist email domains
---
To add specific email addresses to an allow list for signing in through SSO or directly with default policy customization, follow these steps:
1. In the authentik Admin interface, navigate to **Customization > Policies** and modify the default policy named `default-source-enrollment-if-sso`.
2. Add the following code snippet in the policy-specific settings under **Expression** and then click **Update**.
```python
allowed_domains = ["example.org", "example.net", "example.com"]
current_domain = request.context["prompt_data"]["email"].split("@")[1] if request.context.get("prompt_data", {}).get("email") else None
if current_domain in allowed_domains:
email = request.context["prompt_data"]["email"]
request.context["prompt_data"]["username"] = email
return ak_is_sso_flow
else:
return ak_message("Enrollment denied for this email domain")
```
This configuration specifies the `allowed_domains` list of domains for logging in through SSO, such as Google OAuth2. If your email is not in the available domains, you will receive a 'Permission Denied' message on the login screen.
You can also enforce your allowed domains policy for authentication by modifying the policy `default-source-authentication-if-sso` with the following expression:
```python
allowed_domains = ["example.org", "example.net", "example.com"]
current_domain = request.user.email.split("@")[1] if hasattr(request.user, 'email') and request.user.email else None
if current_domain in allowed_domains:
return ak_is_sso_flow
else:
return ak_message("Authentication denied for this email domain")
```

View File

@ -0,0 +1,87 @@
---
title: Policies
---
Policies provide customization and flexibility when defining your users' login and authentication experience.
In effect, policies determine whether or not a specific stage is applied to a flow, or whether certain users can even access the flow.
For example, you can create a policy that, for certain users, skips over a stage that prompts for MFA input. Or, you can define a policy that allows users to access a login flow only if the policy criteria are met. See below for other policies, including the reputation policy and an events-driven policy to manage notifications.
For instructions about creating and binding policies to flows and stages, refer to ["Working with policies](./working_with_policies.md)".
## Standard policies
The following policies are our standard, out-of-the box policies.
### Event-matcher policy
This policy is used by the events subsystem. You can use this policy to match events by multiple different criteria, to choose when you get notified.
### Expression Policy
See [Expression Policy](./expression.mdx).
### GeoIP policy
Use this policy for simple GeoIP lookups, such as country or ASN matching. (For a more advanced GeoIP lookup, use an [Expression policy](./expression.mdx).)
With the GeoIP policy, you can use the **Distance Settings** options to set travel "expectations" and control login attempts based on GeoIP location. The GeoIP policy calculates the values defined for travel distances (in kilometers), and then either passes or fails based on the results. If the GeoIP policy failed, the current login attempt is not allowed.
- **Maximum distance**: define the allowed maximum distance between a login's initial GeoIP location and the GeoIP location of a subsequent login attempt.
- **Distance tolerance**: optionally, add an additional "tolerance" distance. This value is added to the **Maximum distance** value, then the total is used in the calculations that determine if the policy fails or passes.
- **Historical Login Count**: define the number of login events that you want to use for the distance calculations. For example, with the default value of 5, the policy will check the distance between each of the past 5 login attempts, and if any of those distances exceed the **Maximum distance** PLUS the **Distance tolerance**, then the policy will fail and the current login attempt will not be allowed.
- **Check impossible travel**: this option, when enabled, provides an additional layer of calculations to the policy. With Impossible travel, a built-in value of 1,000 kilometers is used as the base distance. This distance, PLUS the value defined for **Impossible travel tolerance**, is the maximum allowed distance for the policy to pass. Note that the value defined in **Historical Login Count** (the number of login events to check) is also used for Impossible travel calculations.
- **Impossible travel tolerance**: optionally, you can add an additional "tolerance" distance. This value is added to the built-in allowance of 1000 kilometers per hour, then the total is used in the calculations that run against each of the login events (to determine if the travel would have been possible in the amount of time since the previous login event) to determine if the policy fails or passes.
:::info
GeoIP is included in every release of authentik and does not require any additional setup for creating GeoIP policies. For information about advanced uses (configuring your own database, etc.) and system management of GeoIP data, refer to our [GeoIP documentation](../../sys-mgmt/ops/geoip.mdx).
:::
### Password-Expiry Policy
This policy can enforce regular password rotation by expiring set passwords after a finite amount of time. This forces users to set a new password.
### Password Policy
:::warning
By default, authentik's Password policy is compliant with [NIST's recommendations](https://pages.nist.gov/800-63-4/sp800-63b.html#password) for passwords. To remain compliant with NIST, be cautious when editing the default values. For additional hardening configuration settings, refer to [Hardening authentik](../../security/security-hardening.md#password-policy).
:::
This policy allows you to specify password rules, such as length and required characters.
The following rules can be set:
- Minimum amount of uppercase characters.
- Minimum amount of lowercase characters.
- Minimum amount of symbols characters.
- Minimum length.
- Symbol charset (define which characters are counted as symbols).
Starting with authentik 2022.11.0, the following checks can also be done with this policy:
- Check the password hash against the database of [Have I Been Pwned](https://haveibeenpwned.com/). Only the first 5 characters of the hashed password are transmitted, the rest is compared in authentik
- Check the password against the password complexity checker [zxcvbn](https://github.com/dropbox/zxcvbn), which detects weak password on various metrics.
### Password Uniqueness Policy
This policy prevents users from reusing their previous passwords when setting a new password. For detailed information, see [Password Uniqueness Policy](./unique_password.md).
### Reputation Policy
authentik keeps track of failed login attempts by source IP and attempted username. These values are saved as scores. Each failed login decreases the score for the client IP as well as the targeted username by 1 (one).
This policy can be used, for example, to prompt clients with a low score to pass a CAPTCHA test before they can continue.
To make sure this policy is executed correctly, set _Evaluate when stage is run_ when using it with a flow.
### Have I Been Pwned Policy
:::info
This policy is deprecated since authentik 2022.11.0, as this can be done with the password policy now.
:::
This policy checks the hashed password against the [Have I Been Pwned](https://haveibeenpwned.com/) API. This only sends the first 5 characters of the hashed password. The remaining comparison is done within authentik.

View File

@ -0,0 +1,45 @@
---
title: Password Uniqueness Policy
sidebar_label: Password Uniqueness Policy
tags:
- policy
- password
- security
- enterprise
authentik_version: "2025.4.0"
authentik_enterprise: true
---
The Password Uniqueness policy prevents users from reusing their previous passwords when setting a new password. To use this feature, you will need to create a Password Uniqueness policy, using the instructions below.
## How it works
This policy maintains a record of previously used passwords for each user. When a new password is created, it is compared against this historical log. If a match is found with any previous password, the policy is not met, and the user is required to choose a different password.
The password history is maintained automatically when this policy is in use. Old password hashes are stored securely in authentik's database.
:::info
This policy takes effect after the first password change following policy activation. Before that first change, there's no password history data to compare against.
:::
## Integration with other policies
For comprehensive password security, consider using this policy alongside:
- [Password Policy](./index.md#password-policy) - To enforce password complexity rules
- [Password-Expiry Policy](./index.md#password-expiry-policy) - To enforce regular password rotation
## Implement a Password Uniqueness policy
To implement a policy that prevents users from reusing their previous passwords, follow these steps:
1. In the Admin interface, navigate to **Customization** > **Policies**.
2. Click **Create** to define a new Password Uniqueness Policy.
- **Name**: provide a descriptive name for the policy.
- **Password field**: enter the name of the input field to check for the new password. By default, if no custom flows are used, the field name is `password`. This field name must match the field name used in your Prompt stage.
- **Number of previous passwords to check**: enter the number of past passwords that you want to set as the number of previous passwords that are checked and stored for each user, with a default of 1. For instance, if set to 3, users will not be able to reuse any of their last 3 passwords.
3. Bind the policy to your **password prompt stage**: For example, if you're using the `default-password-change` flow, edit the `default-password-change-prompt` stage and add the policy in the **Validation Policies** section.
:::info
Password history records are stored securely and cannot be used to reconstruct original passwords.
:::

View File

@ -0,0 +1,50 @@
---
title: Working with policies
---
For an overview of policies, refer to our documentation on [Policies](./index.md).
authentik provides several [standard policy types](./index.md#standard-policies), which can be configured for your specific needs.
We also document how to use a policy to [whitelist email domains](./expression/whitelist_email.md) and to [ensure unique email addresses](./expression/unique_email.md).
To learn more see also [bindings](../../add-secure-apps/flows-stages/bindings/index.md) and how to [bind policy bindings to a new application when the application is created](../../add-secure-apps/applications/manage_apps.mdx#instructions) (for example, to configure application-specific access).
## Create a policy
To create a new policy, follow these steps:
1. Log in as an admin to authentik, and go to the Admin interface.
2. In the Admin interface, navigate to **Customization -> Policies**.
3. Click **Create**, and select the type of policy.
4. Define the policy and click **Finish**.
## Bind a policy to a flow or stage
After creating the policy, you can bind it to either a [flow](../../add-secure-apps/flows-stages/flow/index.md) or to a [stage](../../add-secure-apps/flows-stages/stages/index.md).
:::info
Bindings are instantiated objects themselves, and conceptually can be considered as the "connector" between the policy and the stage or flow. This is why you might read about "binding a binding", because technically, a binding is "spliced" into another binding, in order to intercept and enforce the criteria defined in the policy. To learn more refer to our [Bindings documentation](../../add-secure-apps/flows-stages/bindings/index.md).
:::
### Bind a policy to a flow
These bindings control which users can access a flow.
1. Log in as an admin to authentik, and open the Admin interface.
2. In the Admin interface, navigate to **Flows and Stages -> Flows**.
3. In the list of flows, click on the name of the flow to which you want to bind a policy.
4. Click on the **Policy/Group/User Bindings** tab at the top of the page.
5. Here, you can decide if you want to create a new policy and bind it to the flow (**Create and bind Policy**), or if you want to select an existing policy and bind it to the flow (**Bind existing policy/group/user**).
### Bind a policy to a stage
These bindings control which stages are applied to a flow.
1. Log in as an admin to authentik, and open the Admin interface.
2. In the Admin interface, navigate to **Flows and Stages -> Flows**.
3. In the list of flows, click on the name of the flow to which you want to bind a policy.
4. Click on the **Stage Bindings** tab at the top of the page.
5. Click the arrow (**>**) beside the name of the stage to which you want to bind a policy.
The details for that stage displays.
6. Here, you can decide if you want to create a new policy and bind it to the stage (**Create and bind Policy**), or if you want to select an existing policy and bind it to the stage (**Bind existing policy/group/user**).