Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ When multiple policies/groups/users are attached, you can configure the _Policy

The most common ways to control access to an application by using bindings are:

1. [Create a policy binding](../../customize/policies/working_with_policies.md#bind-a-policy-to-an-application) in which a policy is used to determine whether or not a user can access an application.
1. [Create a policy binding](../../customize/policies/bindings.md#bind-a-policy-to-an-application) in which a policy is used to determine whether or not a user can access an application.
2. [Bind a user or group to the application](#bind-a-user-or-group-to-an-application).

### Policy-driven authorization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ As covered in the [overview](./index.md), bindings interact with many other comp
For instructions to create a binding, refer to the documentation for the specific components:

- [Bind a stage to a flow](../flows-stages/stages/index.md#bind-a-stage-to-a-flow)
- [Bind a policy to a flow, stage, application, or source](../../customize/policies/working_with_policies.md#bind-a-policy-to-a-flow-stage-application-or-source)
- [Bind a policy to a flow, stage, application, or source](../../customize/policies/bindings.md#bind-a-policy-to-a-flow-stage-application-or-source)
- [Bind users or groups to a specific application](../applications/manage_apps.mdx#use-bindings-to-control-access)
- [Bind users and groups to a stage binding, to define whether or not that stage is shown](../flows-stages/stages/index.md#bind-users-and-groups-to-a-flows-stage-binding)
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ For example, in the Identification Stage (part of the default login flow), you c

Any data can be stored in the flow context, however there are some reserved keys in the context dictionary that are used by authentik stages.

To manage flow context on a more granular level, see [Setting flow context keys](../../../../customize/policies/expression/managing_flow_context_keys.md).
To manage flow context on a more granular level, see [Setting flow context keys](../../../../customize/policies/types/expression/managing_flow_context_keys.md).

## Context dictionary and reserved keys

Expand Down Expand Up @@ -227,7 +227,7 @@ This value can be set either via [Prompt data](#prompt_data-dictionary) or via p

##### `redirect_stage_target` (string)

[Set this key](../../../../customize/policies/expression/managing_flow_context_keys.md) in an Expression Policy to override [Redirect stage](../../stages/redirect/index.md) to force it to redirect to a certain URL or flow. This is useful when a flow requires that the redirection target be decided dynamically.
[Set this key](../../../../customize/policies/types/expression/managing_flow_context_keys.md) in an Expression Policy to override [Redirect stage](../../stages/redirect/index.md) to force it to redirect to a certain URL or flow. This is useful when a flow requires that the redirection target be decided dynamically.

Use the format `ak-flow://{slug}` to use the Redirect stage in Flow mode. Any other format will result in the Redirect stage running in Static mode.

Expand Down
2 changes: 1 addition & 1 deletion website/docs/add-secure-apps/flows-stages/flow/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ To create a flow, follow these steps:
2. In the Admin interface, navigate to **Flows and Stages > Flows**.
3. Click **Create**, define the flow using the [configuration settings](#flow-configuration-options) described below, and then click **Finish**.

After creating the flow, you can then [bind specific stages](../stages/index.md#bind-a-stage-to-a-flow) to the flow and [bind policies](../../../customize/policies/working_with_policies.md) to the flow to further customize the user's log in and authentication process.
After creating the flow, you can then [bind specific stages](../stages/index.md#bind-a-stage-to-a-flow) to the flow and [bind policies](../../../customize/policies/bindings.md) to the flow to further customize the user's log in and authentication process.

To determine which flow should be used, authentik will first check which default authentication flow is configured in the active [**Brand**](../../../sys-mgmt/brands/index.md). If no default is configured there, the policies in all flows with the matching designation are checked, and the first flow with matching policies sorted by `slug` will be used.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ For information about creating a stage, refer to our [documentation](../#create-

By default, the email is sent to the currently pending user. To override this, you can set `email` in the plan's context to another email address, which will override the user's email address (the user won't be changed).

For example, create this [expression policy](../../../../customize/policies/expression.mdx) and bind it to the email stage:
For example, create this [expression policy](../../../../customize/policies/types/expression/index.mdx) and bind it to the email stage:

```python
request.context["flow_plan"].context["email"] = "foo@bar.baz"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ To bind a stage to a flow (which adds the stage as a "step" in the flow), follow

### Control access to a stage

There are several ways use policy bindings to control access to a specific stage of a flow: - Bind a policy to a stage-binding. [See our policy documentation](../../../customize/policies/working_with_policies.md#bind-a-policy-to-a-stage-binding). - Bind a user or group to the stage. [See steps below](#bind-users-and-groups-to-a-flows-stage-binding).
There are several ways use policy bindings to control access to a specific stage of a flow: - Bind a policy to a stage-binding. [See our policy documentation](../../../customize/policies/bindings.md#bind-a-policy-to-a-stage-binding). - Bind a user or group to the stage. [See steps below](#bind-users-and-groups-to-a-flows-stage-binding).

### Bind users and groups to a flow's stage binding

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ A flag which decides whether or not this field is required.
A field placeholder, shown within the input field.

By default, the placeholder is interpreted as-is. If you enable _Interpret placeholder as expression_, the placeholder
will be evaluated as a Python expression. This happens in the same environment as [_Policies_](../../../../customize/policies/expression.mdx).
will be evaluated as a Python expression. This happens in the same environment as [_Policies_](../../../../customize/policies/types/expression/index.mdx).

For `Radio Button Group` and `Dropdown` prompts, this field defines the available choices. When used as a plain string, it represents a single allowed value (the placeholder). When used as an expression, it can return a list of choices. For example, `return ["first option", 42, {"label": "another option", "value": "some value"}]` defines three possible values.

Expand All @@ -80,7 +80,7 @@ The prompt's initial value. It can also be left empty, in which case the field w
With the `hidden` prompt, the initial value will also be the actual value, because the field is hidden to the user.

By default, the initial value is interpreted as-is. If you enable _Interpret initial value as expression_, the initial value
will be evaluated as a Python expression. This happens in the same environment as [_Policies_](../../../../customize/policies/expression.mdx).
will be evaluated as a Python expression. This happens in the same environment as [_Policies_](../../../../customize/policies/types/expression/index.mdx).

In the case of `Radio Button Group` and `Dropdown` prompts, this field defines the default choice. When interpreted as-is, the default choice will be the initial value string. When interpreted as expression, the default choice will be the returned value. For example, `return 42` defines `42` as the default choice. When a choice is defined as an object `{"label": "Option", "value": "internal-value"}`, the initial value needs to be set to the value string `internal-value` in this case.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Alternatively, you can set the `client_secret` parameter to `<inputJWT>`, for ap

Input JWTs are checked to verify that they are signed by any of the selected _Federated OIDC Sources_, and that their `exp` attribute is not set as now or in the past.

To dynamically limit access based on the claims of the tokens, you can use [Expression policies](../../../customize/policies/expression.mdx), for example:
To dynamically limit access based on the claims of the tokens, you can use [Expression policies](../../../customize/policies/types/expression/index.mdx), for example:

```python
return request.context["oauth_jwt"]["iss"] == "https://my.issuer"
Expand Down Expand Up @@ -138,7 +138,7 @@ Alternatively, you can set the `client_secret` parameter to `<inputJWT>`, for ap

Input JWTs must be valid access tokens issued by any of the configured _Federated OIDC Providers_, they must not have been revoked and must not have expired.

To dynamically limit access based on the claims of the tokens, you can use [Expression policies](../../../customize/policies/expression.mdx), for example:
To dynamically limit access based on the claims of the tokens, you can use [Expression policies](../../../customize/policies/types/expression/index.mdx), for example:

```python
return request.context["oauth_jwt"]["iss"] == "https://my.issuer"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ The property mapping should return a value that is expected by the provider. Sup

## Available Functions

import Functions from "../../../expressions/_functions.mdx";
import Functions from "../../../expressions/reference/_functions.mdx";

<Functions />

## Variables

import Objects from "../../../expressions/_objects.md";
import Objects from "../../../expressions/reference/_objects.md";

<Objects />

import User from "../../../expressions/_user.md";
import User from "../../../expressions/reference/_user.md";

<User />

Expand Down
198 changes: 198 additions & 0 deletions website/docs/customize/policies/bindings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
---
title: Policy Bindings and Evaluation
tags:
- policy
- bindings
- access-control
---

For a high-level overview of the available policy types, see [Policies](./index.md). This page focuses on the mechanics: where policies are attached, how bindings work, and how authentik evaluates multiple results.

## What a binding does

A policy answers a question like "should this pass?" A binding decides where authentik asks that question.

For example:

- a policy bound to a **flow** controls whether the flow can be used
- a policy bound to a **stage binding** controls whether that stage runs inside the flow
- a policy bound to an **application** controls whether the user can access that application
- a policy bound to a **source** controls whether that source can be used

In the same binding UI, you can also bind a **user** or **group** directly. Those are evaluated as simple membership checks and are useful when you want a direct allow or deny rule without creating a separate policy object.

## Create a policy

To create a policy:

1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Customization** > **Policies**.
3. Click **Create**.
4. Select the policy type.
5. Configure the policy-specific settings.
6. Click **Finish**.

If you are not sure which policy type to use, see [Choose a policy type](./index.md#choose-a-policy-type).

## Bind a policy to a flow, stage, application, or source

After creating a policy, bind it to the place where you want the check to apply:

- [flow](../../add-secure-apps/flows-stages/flow/index.md)
- [stage binding](../../add-secure-apps/flows-stages/stages/index.md)
- [application](../../add-secure-apps/applications/index.md)
- [source](../../users-sources/sources/index.md)

:::info Stage Bindings
In authentik, a stage is attached to a flow through a stage binding. When you attach a policy to a stage inside a flow, you are binding the policy to that stage binding, not directly to the stage definition itself. To learn more, see [Bindings](../../add-secure-apps/bindings-overview/index.md).
:::

### Where each binding is evaluated

| Binding target | What it controls |
| -------------- | ------------------------------------------------------ |
| Flow | Whether the user can start or continue using the flow |
| Stage binding | Whether a specific stage runs in that flow |
| Application | Whether the user can access the application |
| Source | Whether the source can be used for login or enrollment |

### Bind a policy to a flow

Flow bindings control who can use the flow at all.

1. Log in to authentik as an administrator and open the authentik Admin interface.
2. 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. Either create a new policy and bind it immediately with **Create and bind Policy**, or attach an existing policy, group, or user with **Bind existing policy/group/user**.

### Bind a policy to a stage binding

Stage-binding policies control whether a specific stage runs inside a flow.

1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Flows and Stages** > **Flows**.
3. Open the flow that contains the stage you want to control.
4. Click on the **Stage Bindings** tab at the top of the page.
5. Expand the stage binding for the stage you want to control.
6. Either create and bind a new policy, or bind an existing policy, group, or user.

This is the most common place to use policies for conditional flow behavior. For example:

- only show a CAPTCHA stage when a [Reputation policy](./types/reputation.md) passes
- only show an MFA stage for users who match a policy
- redirect users to different authentication paths with an [Expression policy](./types/expression/index.mdx)

If the policy depends on request data that is only known after the user has interacted with the flow, configure the stage binding to **Evaluate when stage is run** instead of only at planning time.

### Bind a policy to an application

Application bindings control which users, groups, or policy matches can access an application.

1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Applications** > **Applications**.
3. In the list of applications, click on the name of the application to which you want to bind a policy.
4. Click on the **Policy/Group/User Bindings** tab at the top of the page.
5. Either create and bind a new policy, or bind an existing policy, group, or user.

This is a good fit when you want application access to depend on more than static group membership. For example, you can use a policy to enforce device, network, or contextual requirements before an application appears to the user.

### Bind a policy to a source

Source bindings control who can use a source for login or enrollment.

1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Directory** > **Federation and Social login**.
3. In the list of sources, click on the name of the source to which you want to bind a policy.
4. Click on the **Policy Bindings** tab at the top of the page.
5. Either create and bind a new policy, or bind an existing policy, group, or user.

This is commonly used to limit enrollment or authentication to certain users, groups, or email domains.

## Validate prompt data with policies

Some stages also have their own policy hooks. The most common example is the [Prompt stage](../../add-secure-apps/flows-stages/stages/prompt/index.md), which supports **Validation Policies**.

Use prompt-stage validation policies when the decision depends on data the user has just entered, such as:

- password complexity
- password history
- matching two prompt fields
- validating an email domain during enrollment

Prompt-stage validation is often the right place for [Password](./types/password.md), [Password Uniqueness](./types/password-uniqueness.md), and [Expression](./types/expression/index.mdx) policies.

## How authentik evaluates policies

When a flow, stage binding, application, or source has multiple bindings, authentik evaluates them in order.

### Engine mode: `Any` vs `All`

Every policy binding target has a **Policy engine mode**:

- `Any`: the target passes when any binding passes
- `All`: the target passes only when every binding passes

The default mode is `Any`.

### Order

Bindings are evaluated in ascending order. This matters most when you inspect logs or when you are combining multiple policies that produce end-user messages.

### Enabled bindings only

Disabled bindings are skipped entirely.

### Direct user and group bindings

Bindings to users and groups are evaluated alongside policy bindings:

- a user binding passes when the current user matches
- a group binding passes when the current user is a member of that group

These are a simple way to mix static membership checks with policy-based logic.

### No bindings means pass

If a target has no applicable bindings, authentik treats the result as passing.

## Binding options

Bindings have a few important options beyond the target and order.

### Negate

**Negate** flips the pass or fail result of the binding. This is useful when you want to express "everyone except this group" or turn an allow-style policy into a deny-style rule without copying it.

Negation only changes the boolean result. Any messages returned by the policy are left unchanged.

### Timeout

**Timeout** limits how long authentik will wait for a policy execution before it is terminated. This is especially relevant for expression policies or other policy types that may call external systems.

### Failure result

If a policy errors during execution, **Failure result** decides whether authentik should treat that failure as pass or fail.

Use this carefully:

- fail closed when the policy protects access to something sensitive
- fail open only when availability is more important than enforcement for that specific check

### Execution logging

Individual policies can enable **Execution logging**. When enabled, authentik logs every execution of that policy, not only failures and exceptions. This is helpful while debugging complex access rules.

## Common patterns

### Gate an application with a group or policy

Bind a group directly when the rule is static. Bind a policy when access depends on runtime context such as network, source, prompt data, or request history.

### Run a stage only for some users

Bind a policy to the stage binding, not just to the flow. The stage will only run when that binding passes.

### Validate user input

Attach validation policies directly to the prompt stage when the decision depends on the values the user just entered.
Loading
Loading