All of the above said mechanisms must be configured in the mechanisms
section of heimdall’s rules
configuration property. Only those mechanisms, which have been configured, can then be (re-)used by rules.
rules:
mechanisms:
authenticators:
<list of authenticators>
authorizers:
<list of authorizers>
contextualizers:
<list of contextualizers>
unifiers:
<list of unifiers>
error_handlers:
<list of error handlers>
Each mechanism configuration entry must contain at least the following properties:
id
- The unique identifier of the mechanism. Identifiers are used to reference the required mechanism within a rule. You can choose whatever identifier, you want. It is just a name. It must however be unique across all defined mechanisms of a particular mechanism category (like authenticator, authorizer, etc.).
type
- The specific type of the mechanism.
Depending on the mechanism type, there can be an additional config
property, which then holds the mechanism’s specific configuration.
Every mechanism type can be configured as many times as needed. However, for those, which don’t have a configuration, it doesn’t really make sense, as all of them would behave the same way.
For example, your authenticator definitions could look like this:
rules:
mechanisms:
authenticators:
- id: foo
type: bar
- id: baz
type: bla
config:
bla: bar
- id: zab
type: bar
- id: oof
type: bla
config:
bar: bla
The above snippet configures two instances of an imaginary authenticator of a type bar
, made available for usage in rules via ids foo
and zab
, as well as two instances of an imaginary authenticator of a type bla
, made available for usage in rule via ids baz
and oof
. The baz
and oof
authenticators are different, as they are configured differently, but foo
and zab
authenticators do not have any configuration. So, they behave the same way and there is actually no need to define two instances of them.
In simplest case a rule will just reuse mechanisms in its pipeline. In more complex cases a rule can reconfigure parts of it (More about rules configuration can be found here). Which parts can be reconfigured are mechanism specific and described in the mechanism specific documentation. Reconfiguration is always limited to the particular rule pipeline and does not affect other rules.
Here is an example which configures a couple of mechanisms:
rules:
mechanisms:
authenticators:
- id: anon_authn
type: anonymous
- id: opaque_auth_token_authn
type: oauth2_introspection
config:
introspection_endpoint:
url: http://hydra:4445/oauth2/introspect
assertions:
issuers:
- http://127.0.0.1:4444/
authorizers:
- id: deny_all_authz
type: deny
- id: local_authz
type: cel
config:
expressions:
- expression:
"manager" in Subject.Attributes.groups
message: user is not in the expected group
contextualizers:
- id: group_manager
type: generic
config:
endpoint:
url: http://group-manager.local/groups
method: GET
forward_headers:
- Authorization
cache_ttl: 1m
unifiers:
- id: jwt_unifier
type: jwt
config:
ttl: 5m
claims: |
{
{{ $user_name := .Subject.Attributes.identity.user_name -}}
"email": {{ quote .Subject.Attributes.identity.email }},
"email_verified": {{ .Subject.Attributes.identity.email_verified }},
{{ if $user_name -}}
"name": {{ quote $user_name }}
{{ else -}}
"name": {{ quote $email }}
{{ end -}}
}
error_handlers:
- id: default
type: default
- id: authenticate_with_kratos
type: redirect
config:
to: http://127.0.0.1:4433/self-service/login/browser?return_to={{ .Request.URL | urlenc }}
when:
- error:
- type: authentication_error
- type: authorization_error
request_headers:
Accept:
- text/html