Authenticators

Authenticators inspect HTTP requests, like the presence of a specific cookie, which represents the authentication object of the subject with the service and execute logic required to verify the authentication status and obtain information about that subject. A subject, could be a user who tries to use particular functionality of the upstream service, a machine (if you have machine-2-machine interaction), or something different. Authenticators ensure the subject has already been authenticated and the information available about it is valid.

The following section describes the available authenticator types in more detail.

Authenticator Types

Noop

As the name implies, this authenticator does nothing. It tells Heimdall to bypass the authentication. This is the only one authenticator type, which does not create a subject object on a successful execution, which is required by the most others pipeline handlers. This authenticator type also doesn’t have any configuration options.

To enable the usage of this authenticator, you have to set the type property to noop.

Example 1. Configure Noop authenticator
id: foo
type: noop

Unauthorized

This authenticator rejects all requests as unauthenticated (on HTTP response code level this is then mapped to 401 Unauthorized, hence the type name). It basically stops the successful execution of the pipeline resulting in the execution of the error handlers. This authenticator type doesn’t have any configuration options.

To enable the usage of this authenticator, you have to set the type property to unauthorized.

Example 2. Configure Unauthorized authenticator
id: foo
type: unauthorized

Anonymous

This authenticator just creates a subject object and sets its id to anonymous without doing anything else. You can overwrite the value of subject’s id by using the optional config property.

To enable the usage of this authenticator, you have to set the type property to anonymous.

Configuration using the config property is optional. Following properties are available:

  • subject: string (optional, overridable)

    Enables setting the id of the created subject object to a custom value.

Example 3. Configuration of Anonymous authenticator
id: foo
type: anonymous
config:
  subject: anon

Basic Auth

This authenticator verifies the provided credentials according to the HTTP "Basic" authentication scheme, described in RFC 7617. This authenticator does not challenge the authentication, it only verifies the provided credentials and sets the subject id to the configured value if the authentications succeeds. Otherwise, it raises an error, which results in the execution of the configured error handlers. The "WWW Authenticate" error handler can then for example be used if the corresponding challenge is required.

To enable the usage of this authenticator, you have to set the type property to basic_auth.

Configuration using the config property is mandatory. Following properties are available:

  • user_id: string (mandatory, overridable)

    The identifier of the subject to be verified.

  • password: string (mandatory, overridable)

    The password of the subject to be verified.

  • allow_fallback_on_error: boolean (optional, overridable)

    If set to true, allows the pipeline to fall back to the next authenticator in the pipeline if this one fails to verify the credentials. Defaults to false.

Example 4. Configuration of Basic Auth authenticator
id: foo
type: basic_auth
config:
  user_id: bar
  password: baz

Generic

This authenticator is kind of a swiss knife and can do a lot depending on the given configuration. It verifies the authentication status of the subject by making use of values available in the cookies, headers, or query parameters of the HTTP request and communicating with the actual authentication system to perform the actual verification on the one hand and to get the information about subject on the other hand. There is however one limitation: it can only deal with JSON responses.

To enable the usage of this authenticator, you have to set the type property to generic.

Configuration using the config property is mandatory. Following properties are available:

  • identity_info_endpoint: Endpoint (mandatory, not overridable)

    The endpoint to communicate to for the actual subject authentication status verification purpose. At least the url must be configured. If you don’t configure method, HTTP POST will be used. The Accept header is set to application/json by default. You can overwrite these setting however if required. Don’t forget - this authenticator supports only JSON responses.

  • authentication_data_source: Authentication Data Source (mandatory, not overridable)

    Where to extract the authentication data from the request. This authenticator will use the matched authentication data source as is while sending it to the identity_info_endpoint.

  • subject: Subject (mandatory, not overridable)

    Where to extract the subject id from the identity info endpoint response, as well as which attributes to use.

  • cache_ttl: Duration (optional, overridable)

    How long to cache the response. If not set, response caching if disabled. The cache key is calculated from the identity_info_endpoint configuration and the actual authentication data value.

  • allow_fallback_on_error: boolean (optional, overridable)

    If set to true, allows the pipeline to fall back to the next authenticator in the pipeline if this one fails to verify the credentials. Defaults to false.

  • session_lifespan: Session Lifespan (optional, not overridable)

    Where to extract the session validity information form the identity info endpoint response. If the not_after property is specified, the corresponding value from the response is also used for cache ttl calculation to prevent usage of not anymore valid session objects and overwrites the value configured for cache_ttl if the usage of that value would exceed the lifespan of the session object.

    If you’re configuring the cache_ttl property it is highly recommended to configure session_lifespan as well to ensure outdated session objects are not used for subsequent requests to heimdall. Usage of session_lifespan is recommended anyway to enable time based validation of the response from the identity info endpoint.
Example 5. Configuration of Generic authenticator to work with session cookies

This example shows how to configure this authenticator to work with an authentication system, which issues a cookie upon successful user authentication to maintain the authentication state. To reduce the communication overhead, it also makes use of cache_ttl to cache the response for 5 minutes if that time frame does not exceed the actual validity of the session represented by the cookie.

id: session_cookie
type: generic
config:
  identity_info_endpoint:
    url: http://my-auth.system/sessions/whoami
  authentication_data_source:
    - cookie: my_session
  subject:
    id: "identity.id"
  cache_ttl: 5m
  session_lifespan:
    active: active
    issued_at: issued_at
    not_before: authenticated_at
    not_after: expires_at
    time_format: "2006-01-02T15:04:05.999999Z07"
    validity_leeway: 10s
Example 6. Configuration of Generic authenticator to work with a Bearer token

This example shows how to configure this authenticator to work with an authentication system, which issues a Bearer token upon successful user authentication to maintain the authentication state. To reduce the communication overhead, it also makes use of cache_ttl to cache the response for 5 minutes if it does not exceed the validity of the information present in the response from the used endpoint. In this example we configure the handler to use the GET method instead of the default POST for sending the bearer token to the authentication system for verification purposes and also to authenticate using HTTP basic auth schema. According to the below configuration, the Bearer token is located in the X-Custom-Bearer-Token header, which as also used as is while calling the http://my-auth.system/introspect endpoint.

id: bearer_token
type: generic
config:
  identity_info_endpoint:
    url: http://my-auth.system/introspect
    method: GET
    auth:
      type: basic_auth
      config:
        user: Heimdall
        password: super-secure
  authentication_data_source:
    - header: X-Custom-Bearer-Token
      schema: Bearer
  subject:
    id: "sub"
  cache_ttl: 5m
  session_lifespan:
    active: active
    issued_at: iat
    not_before: nbf
    not_after: exp
    validity_leeway: 10s

Usually, Bearer tokens are issued by an OAuth2 auth provider and there is a need to verify not only the validity of such, but also a couple of claims. This can be achieved by a Local Authorizer, but there is also a special purpose OAuth2 Introspection authenticator type, which supports asserting all security relevant claims in just one place.

OAuth2 Introspection

This authenticator handles requests that have Bearer token in the HTTP Authorization header (Authorization: Bearer <token>), in the access_token query parameter or the access_token body parameter (latter, if the body is of application/x-www-form-urlencoded MIME type). It then uses OAuth 2.0 Token Introspection endpoint to check if the token is valid. The validation includes at least the verification of the status and the time validity. That is if the token is still active and whether it has been issued in an acceptable time frame. Latter can be adjusted by specifying a leeway. All other validation options can and should be configured.

To enable the usage of this authenticator, you have to set the type property to oauth2_introspection.

Configuration using the config property is mandatory. Following properties are available:

  • introspection_endpoint: Endpoint (mandatory, not overridable)

    The introspection endpoint of the OAuth2 authorization provider. At least the url must be configured. There is no need to define the method property or setting the Content-Type or the Accept header. These are set by default to the values required by the OAuth 2.0 Token Introspection RFC. You can however override these while configuring the authenticator.

  • token_source: Authentication Data Source (optional, not overridable)

    Where to get the access token from. Defaults to retrieve it from the Authorization header, the access_token query parameter or the access_token body parameter (latter, if the body is of application/x-www-form-urlencoded MIME type).

  • assertions: Assertions (mandatory, overridable)

    Configures the required claim assertions. Overriding on rule level is possible even partially. Those parts of the assertion, which have not been overridden are taken from the prototype configuration.

  • subject: Subject (optional, not overridable)

    Where to extract the subject id from the introspection endpoint response, as well as which attributes to use. If not configured sub is used to extract the subject id and all attributes from the introspection endpoint response are made available as attributes of the subject.

  • cache_ttl: Duration (optional, overridable)

    How long to cache the response. If not set, caching of the introspection response is based on the available token expiration information. To disable caching, set it to 0s. If you set the ttl to a custom value > 0, the expiration time (if available) of the token will be considered. The cache key is calculated from the introspection_endpoint configuration and the value of the access token.

  • allow_fallback_on_error: boolean (optional, overridable)

    If set to true, allows the pipeline to fall back to the next authenticator in the pipeline if this one fails to verify the credentials. Defaults to false.

Example 7. Minimal possible configuration
id: at_opaque
type: oauth2_introspection
config:
  introspection_endpoint:
    url: http://hydra:4445/oauth2/introspect
  assertions:
    issuers:
      - http://127.0.0.1:4444/

JWT

As the OAuth2 Introspection authenticator, this authenticator handles requests that have a Bearer token in the Authorization header, in a different header, a query parameter or a body parameter as well. Unlike the OAuth2 Introspection authenticator it expects the token to be a JSON Web Token (JWT) and verifies it according RFC 7519, Section 7.2. It does however not support encrypted payloads and nested JWTs. In addition to this, validation includes the verification of the time validity. Latter can be adjusted by specifying a leeway. All other validation options can and should be configured.

To enable the usage of this authenticator, you have to set the type property to jwt.

Configuration using the config property is mandatory. Following properties are available:

  • jwks_endpoint: Endpoint (mandatory, not overridable)

    The JWKS endpoint, this authenticator retrieves the key material in a format specified in RFC 7519 from for JWT signature verification purposes. The url must be configured. By default method is set to GET and the HTTP Accept header to application/json

  • jwt_source: Authentication Data Source (optional, not overridable)

    Where to get the access token from. Defaults to retrieve it from the Authorization header, the access_token query parameter or the access_token body parameter (latter, if the body is of application/x-www-form-urlencoded MIME type).

  • assertions: Assertions (mandatory, overridable)

    Configures the required claim assertions. Overriding on rule level is possible even partially. Those parts of the assertion, which have not been overridden are taken from the prototype configuration.

  • subject: Subject (optional, not overridable)

    Where to extract the subject id from the JWT, as well as which attributes to use. If not configured sub is used to extract the subject id and all attributes from the JWT payload are made available as attributes of the subject.

  • cache_ttl: Duration (optional, overridable)

    How long to cache the key from the JWKS response, which was used for signature verification purposes. If not set, Heimdall will cache this key for 10 minutes and not call JWKS endpoint again if the same kid is referenced in an JWT and same JWKS endpoint is used. The cache key is calculated from the jwks_endpoint configuration and the kid referenced in the JWT.

  • allow_fallback_on_error: boolean (optional, overridable)

    If set to true, allows the pipeline to fall back to the next authenticator in the pipeline if this one fails to verify the credentials. Defaults to false.

  • validate_jwk: boolean (optional, not overridable)

    Enables or disables the verification of the JWK certificate used for JWT signature verification purposes. Effective only if the JWK contains a certificate. The verification happens according to RFC 5280, section 6.1 and also includes the check, that the certificate is allowed to be used for signature verification purposes. Revokation check is not supported. Defaults to true.

  • trust_store: string (optional, not overridable)

    The path to a PEM file containing the trust anchors, to be used for the JWK certificate validation. Defaults to system trust store.

If a JWT does not reference a kid, heimdall always fetches a JWKS from the configured endpoint (so no caching is done) and iterates over the received keys until one matches. If none matches, the authenticator fails.
Example 8. Minimal possible configuration
id: at_jwt
type: jwt
config:
  jwks_endpoint:
    url: http://hydra:4444/.well-known/jwks.json
  assertions:
    issuers:
      - http://127.0.0.1:4444/

Last updated on Oct 21, 2022