Actions
Actions are short pieces of JavaScript that run at set moments during sign-in and sign-up. Use them to turn away certain sign-ins, require a second factor, or add your own data to tokens.
When actions run
| Trigger | Runs | Function to export | What it can do |
|---|---|---|---|
| Pre-authentication | Before the password is checked | onExecutePreAuthentication | Deny |
| MFA step-up | After the password and risk checks | onExecuteMfaStepUp | Deny, require a second factor |
| Post-login | Just before tokens are issued | onExecutePostLogin | Deny, add claims to tokens |
| User provisioning | Before any new user is created | onExecuteUserProvisioning | Deny, set user attributes |
Pre-authentication and post-login actions run for social sign-ins too. User-provisioning actions run for users created in the dashboard, through the API and through social sign-up.
Create an action
- Name it and pick a trigger
Use a name that says what it does, like “Block contractor domains”.
- Write the code
Export the function for your trigger. It receives the
eventand anapiobject. - Test it
Choose Test to run it against a sample event. You'll see whether it denied, any claims it set, and its console output.
- Deploy it
Actions only run once deployed. Undeploy to switch one off without deleting it. Several actions on one trigger run in order.
Examples
exports.onExecutePreAuthentication = async (event, api) => {
if (!event.user.email.endsWith('@acme.com')) {
api.access.deny('Use your Acme email address to sign in.')
}
}const OFFICE = ['203.0.113.10', '203.0.113.11']
exports.onExecuteMfaStepUp = async (event, api) => {
if (!OFFICE.includes(event.request.ip)) {
api.authentication.requireMfa()
}
}exports.onExecutePostLogin = async (event, api) => {
const tier = event.user.email.endsWith('@bigco.com') ? 'enterprise' : 'standard'
api.accessToken.setCustomClaim('https://example.com/tier', tier)
}exports.onExecuteUserProvisioning = async (event, api) => {
if (event.user.email.endsWith('@finance.acme.com')) {
api.user.setAttribute('department', 'finance')
}
}Reference
The event object
event.triggerstring- Which trigger is running.
event.user.emailstring- The email being signed in or created.
event.user.idstring- The user’s ID. Not present before the user is identified or created.
event.user.rolesstring[]- The user’s roles (sign-in triggers, once the user is known).
event.user.username / first_name / last_namestring- The new user’s details (user provisioning only).
event.tenant.idstring- Your workspace ID (sign-in triggers).
event.request.ip / user_agentstring- Where the sign-in came from (password sign-in).
The api object
api.access.deny(reason)all triggers- Stops the sign-in or user creation. The reason is shown to the person and recorded in the audit log.
api.authentication.requireMfa()MFA step-up- Requires a second factor for this sign-in.
api.accessToken.setCustomClaim(key, value)post-login- Adds a claim to the access token.
api.idToken.setCustomClaim(key, value)post-login- Adds an identity claim. Today it is also placed in the access token.
api.user.setAttribute(key, value)user provisioning- Stores a value on the new user.
console.log(…)all triggers- Output appears when you test the action.
Limits and safety
- Actions run in a sandbox with no network, file system or modules. Keep the data they need in the code itself.
- Each run has 250 milliseconds.
- Up to 20 custom claims or attributes, each under 2 KB as JSON. Standard claims such as
subandrolescan't be overwritten.
api.access.deny() blocks anyone. Test your action before deploying, and watch the audit log for LoginBlocked events afterwards.