Back to Authentik

Expression Policies

website/docs/customize/policies/expression.mdx

latest7.0 KB
Original Source

Expression policies are perhaps the most flexible way to define specific implementations of flows and stages. When you create an expression policy, you provide your own custom Python code to enforce custom checks and validation.

The passing of the policy is determined by the return value of the code: True or False.

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

When the policy returns True, the MFA validation stage is enforced. When it returns False, the MFA validation stage is skipped.

Sample expression policies

Expression policies with sample Python that we have documented:

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

      :::caution When a policy is executed in the context of a flow, this will be set to the user initiating the 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. :::

    • request.http_request: The Django HTTP Request. See Django documentation.

    • request.obj: A Django Model instance. This is only set if the policy is run 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. :::

    • continent: a two-character continent code like NA (North America) or OC (Oceania).
    • country: the two-character 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. :::

    • 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, 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

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

  • 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
      }