OAuth 2.0 Bearer Token Usage

Access Tokens can be granted which can be leveraged as bearer tokens for the purpose of authorization in place of the Session Cookie Forwarded Authorization Flow. This is performed leveraging the RFC6750: OAuth 2.0 Bearer Token Usage specification.

Authorization Endpoints

A registered OAuth 2.0 client which is permitted to request the authelia.bearer.authz scope can request users grant access to a token which can be used for the forwarded authentication flow integrated into a proxy (i.e. access_control rules) in place of the standard session cookie-based authorization flow (which redirects unauthorized users) by utilizing RFC6750: OAuth 2.0 Bearer Token Usage authorization scheme norms (i.e. using the bearer scheme).

Note: these tokens are not intended for usage with the Authelia API, a separate exclusive scope (or scopes) and specific audiences will likely be implemented at a later date for this.

General Protections

The following protections have been considered:

  • There are several safeguards to ensure this Authorization Flow cannot operate accidentally. It must be explicitly configured:
  • The token must:
    • Be granted the authelia.bearer.authz scope.
    • Be presented via the bearer scheme in the header matching your server Authorization Endpoints configuration. See Authorization Endpoint Configuration.
    • Not be expired, revoked, or otherwise invalid.
    • Actually be an Access Token (tokens with the prefix authelia_at_, not tokens with the prefixes authelia_rt_ or authelia_ac_).
  • Authorizations using this method have special specific processing rules when considering the access control rules:
    • If the token was granted via the authorization_code grant then the user who granted the consent for the requested scope and audience and their effective authentication level (1FA or 2FA) will be used to match the configured access control rules.
    • If the token was granted via the client_credentials grant then the token will always be considered as having an authentication level of 1FA and when it comes to matching a subject rule a special subject type oauth2:client:<id> will match the token instead of a user or groups (where <id> is the registered client id). See Access Control Configuration.
    • The audience of the token is also considered and if the token does not have an audience which is an exact match or the prefix of the URL being requested, the authorization will automatically be denied.
  • At this time, each request using this scheme will cause a lookup to be performed on the authentication backend.
  • Specific changes to the client registration will result in the authorization being denied, such as:
    • The client is no longer registered.
    • The authelia.bearer.authz scope is removed from the registration.
    • The audience which matches the request is removed from the registration.
  • The audience of the token must explicitly be requested. Omission of the audience parameter may be denied and will not grant any audience (thus making it useless) even if the client has been whitelisted for the particular audience.

For example, if john consents to grant the token, and it includes the audience https://app1.example.com, but the user john is not normally authorized to visit https://app1.example.com the token will not grant access to this resource. In addition, if john has his access updated via the access control rules, their groups, etc., then this access is automatically applied to these tokens.

These rules effectively give both administrators and end-users fine-grained control over which endpoints can utilize this authorization scheme as administrators will be required to allow each individual URL prefix which can be requested and end users will be able to request individual audiences from the allowed list (effectively narrowing the audience of the token).

The following recommendations should be considered by users who use this authorization method:

  • Using the JWT Profile for Access Tokens effectively makes the introspection stateless and is discouraged for this purpose unless you have specific performance issues. We would rather find the cause of the performance issues and improve them in an instance where they are noticed.

Audience Request

While not explicitly part of the specifications, the audience parameter can be used during the Authorization Request phase of the Authorization Code Grant Flow or the Access Token Request phase of the Client Credentials Grant Flow. The specification leaves it up to Authorization Server policy specifically how audiences are granted, and this seems like a common practice.

Authorization Endpoint Configuration

This authorization scheme is not available by default and must be explicitly enabled. The following examples demonstrate how to enable this scheme (along with the basic scheme). See the Server Authz Endpoints configuration guide for more information.

configuration.yml
server:
  endpoints:
    authz:
      forward-auth:
        implementation: 'ForwardAuth'
        authn_strategies:
          - name: 'HeaderAuthorization'
            schemes:
              - 'Basic'
              - 'Bearer'
          - name: 'CookieSession'
      ext-authz:
        implementation: 'ExtAuthz'
        authn_strategies:
          - name: 'HeaderAuthorization'
            schemes:
              - 'Basic'
              - 'Bearer'
          - name: 'CookieSession'
      auth-request:
        implementation: 'AuthRequest'
        authn_strategies:
          - name: 'HeaderAuthRequestProxyAuthorization'
            schemes:
              - 'Basic'
              - 'Bearer'
          - name: 'CookieSession'
      legacy:
        implementation: 'Legacy'
        authn_strategies:
          - name: 'HeaderLegacy'
          - name: 'CookieSession'

Session Configuration

This feature is only intended to be supported while using the new session configuration syntax. See the example below.

configuration.yml
session:
  secret: 'insecure_session_secret'
  cookies:
    - domain: 'example.com'
      authelia_url: 'https://auth.example.com'
      default_redirection_url: 'https://www.example.com'

Access Control Configuration

In addition to the restriction of the token audience having to match the target location you must also grant access in the Access Control section of the configuration either to the user or in the instance of the client_credentials grant the client itself.

It is important to note that the client_credentials grant is always treated as 1FA, thus only the one_factor policy is useful for this grant type.

configuration.yml
access_control:
  rules:
    ## The 'app1.example.com' domain for the user 'john' regardless if they're using OAuth 2.0 or session based flows.
    - domain: app1.example.com
      policy: one_factor
      subject: 'user:john'

    ## The 'app2.example.com' domain for the 'example-three' client when using the 'client_credentials' grant.
    - domain: app2.example.com
      policy: one_factor
      subject: 'oauth2:client:example-three'

Client Restrictions

In addition to the above protections, this scope MUST only be configured on clients with strict security rules which must be explicitly set:

  1. Are not configured with any additional scope with the following exceptions:
    • The offline_access scope.
  2. Have both PAR and PKCE with the S256 challenge enforced.
  3. Have a list of audiences which represent the resources permitted to be allowed by generated tokens.
  4. Have the explicit consent mode.
  5. Only allows the client_credentials, or the authorization_code and refresh_token grant types.
  6. Only allows the code response type.
    • This is not relevant for the client_credentials grant type.
  7. Only allows the form_post or form_post.jwt response modes.
    • This is not relevant for the client_credentials grant type.
  8. Must either:
  • Be a public client with the Token Endpoint authentication method none. See configuration option token_endpoint_auth_method.
  • Be a confidential client with the Token Endpoint authentication method client_secret_basic, client_secret_jwt, or private_key_jwt configured. See configuration option token_endpoint_auth_method.

Examples

The following examples illustrate how the Client Restrictions should be applied to a client.

Public Client Example
configuration.yml
identity_providers:
  oidc:
    clients:
      - client_id: 'example-one'
        public: true
        require_pkce: true
        pkce_challenge_method: 'S256'
        redirect_uris:
          - 'http://localhost/callback'
        scopes:
          - 'offline_access'
          - 'authelia.bearer.authz'
        audience:
          - 'https://app1.example.com'
          - 'https://app2.example.com'
        grant_types:
          - 'authorization_code'
          - 'refresh_token'
        response_types:
          - 'code'
        response_modes:
          - 'form_post'
        consent_mode: 'explicit'
        require_pushed_authorization_requests: true
        token_endpoint_auth_method: 'none'
Confidential Client Example: Authorization Code Flow

This is likely the most common configuration for most users.

configuration.yml
identity_providers:
  oidc:
    clients:
      - client_id: 'example-two'
        client_secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng'  # The digest of 'insecure_secret'.
        public: false
        require_pkce: true
        pkce_challenge_method: 'S256'
        redirect_uris:
          - 'http://localhost/callback'
        scopes:
          - 'offline_access'
          - 'authelia.bearer.authz'
        audience:
          - 'https://app1.example.com'
          - 'https://app2.example.com'
        grant_types:
          - 'authorization_code'
          - 'refresh_token'
        response_types:
          - 'code'
        response_modes:
          - 'form_post'
        consent_mode: 'explicit'
        require_pushed_authorization_requests: true
        token_endpoint_auth_method: 'client_secret_basic'
Confidential Client Example: Client Credentials Flow

This example illustrates a method to configure a Client Credential flow for this purpose. This flow is useful for automations. It’s important to note that for access control evaluation purposes this token will match a subject of oauth2:client:example-three i.e. the oauth2:client: prefix followed by the client id.

configuration.yml
identity_providers:
  oidc:
    clients:
      - client_id: 'example-three'
        client_secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng'  # The digest of 'insecure_secret'.
        public: false
        scopes:
          - 'authelia.bearer.authz'
        audience:
          - 'https://app1.example.com'
          - 'https://app2.example.com'
        grant_types:
          - 'client_credentials'
        token_endpoint_auth_method: 'client_secret_basic'