id: allow_any_request
type: allow
Heimdall
Authorizers ensure that the Subject
obtained via an authenticator has the required permissions to submit the given HTTP request and thus to execute the corresponding logic in the upstream service. E.g. a specific endpoint of the upstream service might only be accessible to a "user" from the "admin" group, or to an HTTP request if a specific HTTP header is set.
The following sections describe the available authorizer types in more detail.
As the name implies, this authorizer allows any request passing through. This authorizer type also doesn’t have any configuration options.
To enable the usage of this authorizer, you have to set the type
property to allow
.
id: allow_any_request
type: allow
As the name implies, this authorizer denies any request (on HTTP response code level this is then mapped to 403 Forbidden
). It basically stops the successful execution of the pipeline resulting in the execution of the error handler mechanisms. This authorizer type doesn’t have any configuration options.
To enable the usage of this authorizer, you have to set the type
property to deny
.
id: deny_any_request
type: deny
This authorizer allows definition of authorization requirements based on information available about the authenticated subject, as well as the actual request by using CEL based authorization expressions. Each expression is expected to return true
to signal success. Otherwise, the authorization fails, resulting in the execution of the error handler mechanisms.
To enable the usage of this authorizer, you have to set the type
property to cel
.
Configuration using the config
property is mandatory. Following properties are available:
expressions
: Authorization Expression array (mandatory, overridable)
In this example the subject is checked to be member of the "admin" group.
id: user_is_admin
type: cel
config:
expressions:
- expression: |
has(Subject.Attributes.groups) &&
Subject.Attributes.groups.exists(g, g == "admin")
message: User is not admin
The first line of the expressions verifies that the property group exists. The second line checks, whether groups
contains an entry named admin
.
This example specifies also a message, which is logged, if the expression fails.
In this example the authorizer is configured to ensure anonymous access to a resource is possible for read requests only.
id: no_modification_allowed_by_anonymous
type: cel
config:
expressions:
- expression: |
Request.Method in ["GET", "HEAD", "OPTIONS"] || Subject.ID != "anonymous"
message: Anonymous non-read access is forbidden
The usage of this type of configuration makes sense in a pipeline, which combines multiple Authenticators, allowing anonymous and authenticated access.
This authorizer allows communication with other systems, like Open Policy Agent, Ory Keto, etc. for the actual authorization purpose. If the used endpoint answers with a not 2xx HTTP response code, this authorizer assumes, the authorization has failed, resulting in the execution of the error handler mechanisms. Otherwise, if no expressions for the verification of the response are defined, the authorizer assumes, the request has been authorized. If expressions are defined and do not fail, the authorization succeeds.
If your authorization system provides a payload in the response, heimdall inspects the Content-Type
header to prepare the payload for further usage, e.g. for payload verification expressions, or for a Local (CEL) authorizer. If the content type does either end with json
or is application/x-www-form-urlencoded
, the payload is decoded, so key based access to the corresponding attributes is possible, otherwise it is made available as well, but as a simple string. In all cases this value is available for the authorization expressions as well as in the Subject’s Attributes
property under a key named by the id
of the authorizer (See also the example below).
To enable the usage of this authorizer, you have to set the type
property to remote
.
Configuration using the config
property is mandatory. Following properties are available:
endpoint
: Endpoint (mandatory, not overridable)
The API endpoint of your authorization system. At least the url
must be configured. This mechanism allows templating of the url and makes the Subject
object available to it. By default, this authorizer will use HTTP POST
to send the rendered payload to this endpoint. You can override this behavior by configuring method
as well. Depending on the API requirements of your authorization system, you might need to configure further properties, like headers, etc.
payload
: string (optional, overridable)
expressions
: Authorization Expression array (optional, overridable)
List of CEL expressions which define the logic to be applied to the response returned by the endpoint. All expressions are expected to evaluate to true
if the authorization was successful. If any of the expressions evaluates to false
, the authorization fails and the message defined by the failed expression will be logged.
Each expression has access to the Payload
object.
forward_response_headers_to_upstream
: string array (optional, overridable)
Enables forwarding of any headers from the authorization endpoint response to the upstream service.
cache_ttl
: Duration (optional, overridable)
Allows caching of the authorization endpoint responses. Defaults to 0s, which means no caching. The cache key is calculated from the entire configuration of the authorizer instance and the available information about the current subject.
Here the remote authorizer is configured to communicate with OPA. Since OPA expects the query to be formatted as JSON, the corresponding Content-Type
header is set. Since the responses are JSON objects as well, the Accept
header is also provided. In addition, this examples uses the basic_auth
auth type to authenticate against the endpoint.
id: user_can_write
type: remote
config:
endpoint:
url: https://opa.local/v1/data/myapi/policy/allow
headers:
Content-Type: json
Accept: json
auth:
type: basic_auth
config:
user: MyOpaUser
password: SuperSecretPassword
payload: |
{ "input": { "user": {{ quote .Subject.ID }}, "access": "write" } }
expressions:
- expression: |
Payload.result == true
message: User does not have write access
In this case, since an OPA response could look like { "result": true }
or { "result": false }
, heimdall makes the response also available under Subject.Attributes["user_can_write"]
as a map, with "user_can_write"
being the id of the authorizer in this example.
Last updated on Dec 24, 2022