Hooks
Hooks execute logic after a flow (login, registration, settings, ...):
- Before login: is executed when a login flow starts.
- After login: is executed after a successful identification and authentication of the user, but before the kratos session is created.
- Before registration: is executed when a registration flow starts.
- After registration: is executed when a registration was successful:
- Before persisting: runs before the identity is saved in the database.
- After persisting: runs after the identity was saved in the database.
- After recovery: is executed after a password has been successfully recovered.
- After settings: is executed when a settings was successful:
- Before persisting: runs before the identity is saved in the database.
- After persisting: runs after the identity was saved in the database.
- After verification: is executed when the verification of an account was successful.
There are hooks, which can be configured only for a particular flow (login, registration, settings, ...) method (password, oidc, profile) and hooks, which can be configured for all methods of any flow.
To configure hooks for all methods of a particular flow, following pattern must be used:
selfservice:
flows:
<login|registration|recovery|...>:
<before|after>:
hooks:
- hook: <hook 1 name>
<hook 1 specific configuration>
- hook: <hook 2 name>
<hook 2 specific configuration>
...
Following pattern must be followed to configure hooks for a particular flow method:
selfservice:
flows:
<login|registration|recovery|...>:
<before or after>:
<particular method>:
hooks:
- hook: <hook 1 name>
<hook 1 specific configuration>
- hook: <hook 2 name>
<hook 2 specific configuration>
...
Hooks configured on a particular method level always override the hooks configured on the flow level. So given the following example
selfservice:
flows:
login:
before:
hooks:
- hook: hook_1
# hook_1 specific configuration
after:
hooks:
- hook: hook_2
# hook_2 specific configuration
password:
hooks:
- hook: hook_3
# hook_3 specific configuration
# ...
hook_1
is always run when the flow is started. On the finalization of the
flow, hook_2
isn't run for the password
method, but for the oidc
method.
If the password
method is used, then hook_3
will run.
All flows
Following hooks can be configured for all flows.
Web-Hooks
Web-Hooks can be configured for every, but error and logout flow and can be configured on either the before/after level or at the level of a particular method. Support for Web-Hooks before execution of a method is supported only for registration and login methods.
note
As of today Web-Hooks can't control the execution of the flow by patching/updating particular properties of flow specific object upon Web-Hook completion. It will however cancel the execution of the flow if the call to the Web-Hook end point fails either due to a network error or if the end point responses with an HTTP code > 300.
The configuration for a web-hook goes into the hooks
property either on the
flow before/after, or the method level and has the following structure:
- hook: web_hook
config:
url: https://test.kratos.ory.sh/after_verification_hook
method: POST # GET, DELETE, etc
body: file:///path/of/my/jsonnet/file
auth:
type: <some-type>
config: <type-specific-config>
The configuration section of a web-hook consists of
url
- the url, the web-hook should call (mandatory)method
- the HTTP method (GET, POST, ...), the web-hook should use (mandatory)body
- URI of a jsonnet template, used by the web-hook to render the payload to send (optional). Use afile://path/to/body.jsonnet
URL for referring to local files. This property is ignored for HTTPmethod
s, which don't support sending of HTTP body payloads.auth
- configuration of authentication and authorization mechanisms to be used by the web-hook
Web-Hooks bind the flow
, as well as request headers (request_headers
),
request method (request_method
), and the request url (request_url
) of the
flow into the jsonnet template for all methods and execution paths (before and
after). For the after
execution path of all flows, it binds the identity
object into the jsonnet template as well. These objects are available through a
ctx
object. To create a body looking like { user_id: <some-id> }
to be sent
to the web hook endpoint, the Jsonnet template would look like this:
function(ctx) { user_id: ctx.identity.id }
Canceling Webhooks
You can cancel configured webhooks and not make the defined request.
This can come in handy in testing. For example, if you cancel the webhook, you prevent the test accounts created during testing from being added to CRM.
In such a scenario, cancel the webhook by raising an error for all accounts with
the test-
name prefix:
function(ctx)
if std.startsWith(ctx.identity.traits.email, "test-") then
error "cancel"
else
{
user_id: ctx.identity.id
}
info
Currently, JsonNet doesn't support regular expressions. Follow this issue to see if the feature has been implemented: google/go-jsonnet/409.
Non-blocking webhooks
Sometimes you need to notify a system without needing its response. For example, when a user signs up, their email address is added to the newsletter. If the system's response is not important, you can ignore the response and make the webhook execution non-blocking.
To do that, set response.ignore
to true
in the webhook config:
- hook: web_hook
config:
response:
ignore: true
Web-Hook Authentication and Authorization Mechanisms
For auth
following mechanisms are supported:
- Authentication via an Api Key. Type must be set to
api_key
. - Authentication via Basic Authentication. Type must be set to
basic_auth
.
For api_key
the config looks as follows:
name: Some-Name
value: The-Value-of-My-Key
in: header # alternatively cookie
All properties are mandatory.
For basic_auth
the config looks as follows:
user: My-User
password: My-Pass-Value
All properties are mandatory.
Login
Hooks running before or after successful user login are defined per Self-Service Registration Method in Ory Kratos' configuration file.
Before
selfservice:
flows:
login:
before:
hooks:
- hook: web_hook
# web-hook specific configuration
After
selfservice:
flows:
login:
after:
password:
hooks:
- hook: revoke_active_sessions
- hook: require_verified_address
revoke_active_sessions
The revoke_active_sessions
will delete all active sessions for that user on
successful login. This hook is available for all supported methods:
selfservice:
flows:
login:
after:
<method>:
hooks:
- hook: revoke_active_sessions
# can't be configured
require_verified_address
The require_verified_address
will ensure, the user can login only if its email
address is verified. This hook is available for the password
method only:
selfservice:
flows:
login:
after:
password:
hooks:
- hook: require_verified_address
# can't be configured
Please be aware, that since require_verified_address
hook is enforcing a
verified address before the user can login, a typo in an email address done by
the user either during the registration or as part of a self service flow (email
change) will make the login for that user impossible. So you should think about
measures to prevent such situations, like requiring two email addresses being
configured by the user, thus having a backup if something goes wrong.
Registration
Hooks running before or after successful user registration are defined per Self-Service Registration Method in Ory Kratos' configuration file.
Before
selfservice:
flows:
registration:
before:
hooks:
- hook: web_hook
# web-hook specific configuration
After
selfservice:
flows:
registration:
after:
oidc:
hooks:
- hook: session
password:
hooks:
- hook: session
session
Adding the session
hook signs the user immediately in once the account has
been created. It runs after the identity has been saved to the database.
info
Using this job as part of your post-registration workflow makes your system
vulnerable to
Account Enumeration Attacks
because a threat agent can distinguish between existing and non-existing
accounts by checking if Set-Cookie
was sent as part of the registration
response.
To use this hook, you must first define one or more (for secret rotation)
secrets. You can either choose to use the "default" secrets or the more specific
"cookie" secrets. The other required config is setting the hook in after
work
flows:
secrets:
cookie:
- something-super-secret # The first entry will be used to sign and verify session cookies
# All other entries will be used to verify session cookies that were signed before "something-super-secret" became
# the current signing secret.
- old-session-secret
- older-session-secret
- ancient-session-secret
selfservice:
flows:
registration:
after:
<method>:
hooks:
- hook: session
# can't be configured
Depending on the registration flow type the behavior changes.
Registration Flow via Browser
When performing a registration flow with a Browser, this hook sends a
Set-Cookie
HTTP header which contains the session cookie.
Therefore, the user is logged in immediately.
Registration Flow via API
When performing a registration flow with an API client (such as a mobile app), this hook creates a session and returns the session token and the session itself in the response body as application/json:
{
"session": {
"id": "..."
// ...
},
"session_token": "...",
"identity": {
"id": "..."
// ...
}
}
info
Because the HTTP reply is handled by the hook itself, no other hooks can be executed because the HTTP reply can't be modified further (for example HTTP Status Code was already sent as 200 and can't be changed to 301). You must ensure that the session hook is the last hook in your configuration!
Settings
Hooks running after successfully updating user settings and are defined per Self-Service Settings Method in Ory Kratos' configuration file.
After
selfservice:
flows:
settings:
after:
Only Web-Hooks hooks are available for this flow at the moment.