Documentation menu

Atrium Actions overview

How to choose the right trigger, host, and template without guessing.

An Atrium Action is a JavaScript handler bound to a ZITADEL execution. Atrium stores the source, the runtime executes it, and ZITADEL calls the matching endpoint when the configured condition fires.

Start here

Pick the first statement that matches your goal:

If you need to...UseWhy
React after something happenedEventBest for onboarding, provisioning, notifications, and audit fan-out
Change claims in userinfo / ID tokenFunction: preuserinfoSynchronous claim mutation
Change claims in access tokensFunction: preaccesstokenSynchronous access-token mutation
Change SAML attributesFunction: presamlresponseSynchronous SAML response mutation
Intercept a specific ZITADEL API request/responseRequest / ResponseNarrow, advanced webhook routing

The most important trap to avoid is this:

  • Events are not claim hooks.
  • Functions are not generic lifecycle automations.

If the old v1 script used api.v1.claims.setClaim(...), its v2 replacement is almost certainly a Function, not an Event.

OMMAX patterns that are actually real

1. First-time onboarding

Use EVENT:user.human.added.

Examples:

  • create or populate an Atrium group
  • append a default app grant
  • send a welcome notification

2. Login-time catch-up for existing users

Use an observed login event such as EVENT:oidc_session.added.

Important:

  • this event usually gives you userID plus session/client context
  • it does not reliably carry custom user attributes like department
  • fetch persisted user metadata explicitly via ctx.zitadel.users.getMetadata(...)

3. flatRoles parity

Use:

  • FUNCTION:preuserinfo
  • and, if needed by consuming apps, FUNCTION:preaccesstoken

This is the right home for:

  • urn:ommax:department
  • litellm_team_ids
  • my:zitadel:grants

Trigger slots in Atrium

ZITADEL can route multiple Targets for the same condition. Atrium's runtime does not merge multiple scripts for the same exact trigger.

In practice that means:

  • many DRAFT scripts may point at FUNCTION:preuserinfo
  • only one ACTIVE script can own FUNCTION:preuserinfo
  • the same is true for exact Event names like EVENT:user.human.added

If you need two behaviours in one live slot, compose them into one script.

Event groups vs exact script triggers

ZITADEL supports Event execution conditions at three levels:

  • all
  • group
  • event

That is a routing scope in ZITADEL, not an inheritance model inside Atrium.

So:

  • an Execution on all events can still feed Atrium
  • Atrium then matches scripts by exact triggerType:triggerName
  • session.added and oidc_session.added are different slots

Do not assume:

  • a child event implies a parent event
  • oidc_session.access_token.added also matches oidc_session.added
  • session.added is a safe shorthand for "real app login"

Return values by trigger type

Trigger typeDoes ZITADEL care about the body?What to return
EventUsually no business effect from the bodyAny diagnostic object you want to inspect in test runs
FunctionYesA valid mutation payload such as { setClaims: { ... } }
RequestYesModified request or null to pass through
ResponseYesModified response or null to pass through

For Functions, the returned JSON is the point of the integration.

For Events, the important work usually happens through side effects such as:

  • ctx.atrium.groups.*
  • ctx.zitadel.users.*
  • ctx.fetch(...)

Where each class of script belongs

KindRecommended home
Atrium lifecycle automation (user.human.added, user.grant.added, oidc_session.added)Atrium Actions runtime
Load-bearing token/userinfo mutation (flatRoles)Dedicated Zitadel-adjacent function endpoint is the target architecture

Current OMMAX reality:

  • the Atrium runtime can execute Function scripts
  • that is useful for iteration and migration
  • but auth-path functions still deserve a higher bar for latency and failure isolation than normal Event scripts

Start with these first:

  1. auto-group-by-department
  2. prefill-from-entra
  3. flatten-roles
  4. flatten-roles-access-token

Use these as integration patterns, not drop-in business logic:

  • welcome-email
  • scim-fanout-on-grant
  • sentry-grant-fanout
  • dokploy-grant-fanout
  • slack-notify-on-grant

For the catalog with readiness notes and prerequisites, see Action templates.