Actions Engine
The Actions Engine allows you to extend Auris authentication flows with custom JavaScript code. Actions are hooks that run at specific points in the authentication pipeline — before login, after login, before signup, and so on — enabling you to implement custom business logic without modifying the Auris platform itself.
Common uses for Actions include:
- Adding custom data to JWT tokens (department, subscription tier, feature flags)
- Blocking logins based on business conditions (email domain, account status in an external system)
- Logging authentication events to an external SIEM or analytics platform
- Enforcing additional validation before user registration
- Integrating with identity governance systems
Triggers
Actions are associated with a trigger, which defines when the action runs in the authentication pipeline. A single trigger can have multiple actions, which execute in configured order.
| Trigger | When It Runs |
|---|---|
| Pre-Login | Before authentication credentials are verified. Runs for all login attempts, including those that will ultimately fail. |
| Post-Login | After successful authentication. Runs after MFA (if required) is completed. Token has not yet been issued. |
| Pre-Signup | Before a new user account is created. Allows blocking registrations based on email, domain, or other conditions. |
| Post-Signup | After a new user account has been created successfully. |
| Post-Change-Password | After a user successfully changes their password. |
| Pre-M2M-Token | Before an M2M client credentials token is issued. Allows blocking or modifying M2M token issuance. |
Note: Post-Login is the most commonly used trigger and the best starting point for most use cases (adding claims, logging). Use Pre-Login sparingly, as it runs for every login attempt including failed ones, which can affect performance under high load.
The Actions List
Go to Console → Actions to view all actions in your tenant.
The list shows:
| Column | Description |
|---|---|
| Name | Action name |
| Trigger | Which trigger point this action is attached to |
| Status | Active or Inactive |
| Last Run | Timestamp of the most recent execution |
| Execution Count | Total times this action has run |
| Error Count | Total execution errors |
Actions are sorted by trigger and execution order. Within the same trigger, the number in the Order column determines execution sequence.
Creating an Action
Click Create
From the Actions list, click Create Action.
Enter a name and select a trigger
| Field | Required | Description |
|---|---|---|
| Name | Yes | A descriptive name (for example, “Add Department Claim”, “Block Competitor Domains”) |
| Trigger | Yes | The authentication flow event this action responds to |
| Timeout | No | Maximum execution time in milliseconds. Default: 5000 (5 seconds). |
Write the action code
The code editor opens immediately. Write your action logic in JavaScript. See Writing Action Code for the full API reference.
Save
Click Save. The action is saved but is not yet active.
Activate
Toggle the Active switch to enable the action. Inactive actions are saved but do not run.
Writing Action Code
The Context Object
Every action receives a single context argument. Its structure depends on the trigger:
// context structure for Post-Login trigger
{
user: {
id: 'usr_abc123',
email: '[email protected]',
emailVerified: true,
firstName: 'Alice',
lastName: 'Smith',
username: 'alice',
roles: ['editor', 'viewer'],
metadata: {
department: 'engineering',
subscription_tier: 'pro',
},
createdAt: '2024-01-15T10:30:00Z',
lastLoginAt: '2025-02-10T08:15:00Z',
},
application: {
id: 'app_xyz789',
name: 'Main Web App',
clientId: 'your-client-id',
type: 'WEB',
},
connection: {
strategy: 'email-password', // or 'google', 'github', 'saml', etc.
name: 'Username-Password-Authentication',
},
request: {
ip: '203.0.113.42',
userAgent: 'Mozilla/5.0 ...',
geoip: {
country: 'IT',
region: 'Lombardy',
city: 'Milan',
},
},
tenant: {
id: 'your-tenant-id',
name: 'Acme Corp',
},
}For Pre-M2M-Token, the user field is absent and instead the context contains application and scopes (the requested M2M scopes).
The Return Value
Every action must return an ActionResult object:
type ActionResult = {
allow: boolean // Whether to continue the authentication flow
message?: string // Error message shown to the user if allow: false
claims?: Record<string, unknown> // Claims to add to the JWT
metadata?: Record<string, unknown> // User metadata updates (persisted)
}If your action throws an unhandled exception, the authentication flow is blocked by default to fail secure. Always wrap logic that might throw in try/catch if you want failures to be non-blocking.
Example Actions
Block login by email domain
// Block logins from emails at a competitor's domain
const blockedDomains = ['competitor.com', 'blockeddomain.org']
const emailDomain = context.user.email.split('@')[1]
if (blockedDomains.includes(emailDomain)) {
return {
allow: false,
message: 'Your organization does not have access to this application.',
}
}
return { allow: true }Add custom claims to the JWT
// Embed department and subscription tier in every token
return {
allow: true,
claims: {
department: context.user.metadata?.department || 'general',
tier: context.user.metadata?.subscription_tier || 'free',
org_region: context.user.metadata?.region || 'eu',
},
}Role-based claim
// Set a 'plan' claim based on what role the user has
const roles = context.user.roles || []
let plan = 'free'
if (roles.includes('enterprise')) plan = 'enterprise'
else if (roles.includes('pro')) plan = 'pro'
else if (roles.includes('starter')) plan = 'starter'
return {
allow: true,
claims: { plan },
}Log to an external webhook (fire-and-forget)
// Non-blocking log to an external system
// Use try/catch so a webhook failure doesn't block login
try {
const payload = JSON.stringify({
event: 'user.login',
userId: context.user.id,
email: context.user.email,
ip: context.request.ip,
timestamp: new Date().toISOString(),
})
// Note: fetch is available in the action sandbox
fetch('https://your-siem.example.com/events', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer your-key' },
body: payload,
})
} catch (e) {
// Silently ignore webhook failures — do not block login
}
return { allow: true }Block M2M token if scope is not allowed for this application
// Pre-M2M-Token: only allow the 'read:reports' scope for specific applications
const allowedApps = ['app_reporting_service', 'app_analytics']
if (context.scopes.includes('read:reports') && !allowedApps.includes(context.application.id)) {
return {
allow: false,
message: 'This application is not authorized to request the read:reports scope.',
}
}
return { allow: true }Sandboxed Execution Environment
Actions run in a restricted JavaScript sandbox. The following are available:
| Available | Description |
|---|---|
fetch | Make outbound HTTP requests |
JSON | Parse and stringify JSON |
Date | Date and time operations |
Math | Mathematical operations |
String, Array, Object | Standard JavaScript built-ins |
console.log | Writes to the action execution log (visible in Action Logs) |
The following are blocked and will throw an error if used:
| Blocked | Reason |
|---|---|
require, import | No module loading — sandbox is isolated |
process | No Node.js process access |
eval, Function constructor | No dynamic code execution |
global, globalThis | No global state access |
child_process | No subprocess execution |
fs | No filesystem access |
Timeout
Actions have a configurable timeout (default: 5000 ms). If execution exceeds the timeout, the action is terminated and the authentication flow is blocked as if allow: false was returned. Set a short timeout for actions that make external HTTP calls to avoid delaying the user’s login experience.
Execution Order
When multiple actions are associated with the same trigger, they execute sequentially in the order shown in the Actions list. If any action returns { allow: false }, execution stops and subsequent actions do not run.
Reordering Actions
On the Actions list page, filter by trigger. Drag the order handle (the six-dot icon) on any action row to change its position. The new order is saved automatically.
Blueprint Editor
For users who prefer a visual approach to defining action logic, Auris provides the Blueprint Editor — an Unreal Engine-style node-based editor for building action rules without writing code.
Access the Blueprint Editor on any action’s detail page by clicking the Blueprint tab.
Node Types
| Node | Category | Description |
|---|---|---|
| Trigger | Orange | Entry point — the trigger event that starts the flow |
| Condition | Cyan | A single field comparison (field, operator, value) |
| Logic Gate | Violet | AND or OR combinator for multiple conditions |
| Deny Action | Pink | Returns { allow: false } with a configurable message |
| Set Claims | Blue | Adds key-value pairs to the JWT claims |
| Set Metadata | Emerald | Updates user metadata fields (persisted to the user record) |
| Log | Green | Writes a message to the action execution log |
Using the Blueprint Editor
- The Trigger node is placed automatically at the left
- Click Add Condition in the toolbar to place a condition node. Connect it to the trigger or a logic gate.
- Click Add Logic Gate to combine multiple conditions with AND/OR logic
- Connect condition outputs to action nodes (Deny, Set Claims, etc.)
- Click Auto-Layout to reorganize nodes automatically
- Click Save — the blueprint is serialized to JavaScript and saved as the action’s code
The Blueprint Editor and code editor are synchronized. Switching between them shows the code representation of the current blueprint. Code written manually may not always be representable in the Blueprint Editor — complex expressions are preserved as code but not visually editable.
Action Logs
The Logs tab on any action’s detail page shows the execution history for that action.
| Column | Description |
|---|---|
| Timestamp | When the action ran |
| Trigger | The event that caused execution |
| Duration | Execution time in milliseconds |
| Status | Success, Error, or Timeout |
| Error | Error message if status is Error or Timeout |
Click any log entry to expand it and see:
- Full context data passed to the action (with sensitive fields redacted)
- Return value from the action
- Console output (
console.logcalls from within the action code) - Error stack trace (if an error occurred)
Filtering Logs
Use the date range picker and status filter at the top of the Logs tab to narrow the view. Logs are retained for 30 days by default.
Related Guides
- Hosted Login Flow — Where Actions fit in the OAuth 2.0 authorization code flow
- Custom Claims — Alternative claim configuration without code (for static/attribute-based claims)
- Actions API — Manage actions programmatically
- Webhook Integration — Outbound webhooks as an alternative for event-driven integrations without code in the auth path