7.3 Tokens, automation principals and the review export
Included from Basic tier
After this you can: inventory your tokens, mint an API key for automation, give a trigger or schedule a service account to run as, offboard a leaver without stranding their automations, and export the access review.
Before you start — tick each one:
- Lesson 7.2 — Users, groups, rules, policies (
opschain learn 7.2)
In the GUI: your own API keys live under the profile menu's Preferences → Api keys (create — the value shown once — list, revoke); Users & Groups in the Operations area mints a service account (Create service account…), disables a leaver (every token goes with them, and the dialog warns which automations and agents they ran) and repoints what they ran onto a service account (Reassign automations… on the disabled row); the Audit history screen under Governance shows the token, session and sign-in events.
Lesson 7.2 was about people. This lesson is about everything that acts when no person is at the keyboard: the API keys scripts carry, the sessions a browser holds, the identity a trigger fires as — and the one export an access reviewer needs.
1. Your token inventory
Every principal can read their own token inventory — metadata only, values are never returned:
opschain tokens list
TYPE DESCRIPTION EXPIRES CREATED ID
api_key admin automation 2027-01-01T00:00:00Z 2026-10-15T14:05:40Z 01a14d…
session password 2026-11-14T14:02:11Z 2026-10-15T14:02:11Z 01a14c…
opschain tokens revoke <id> ends either kind immediately — a session
revoked server-side is dead the moment you leave, not at its TTL.
2. Mint an API key for automation
API keys are the standing credentials for scripts and pipelines: explicit expiry and description required, authority identical to their owner's. The value is shown once:
opschain tokens create --description "admin automation" --expiry 8760h
ocak_…
api key 01a14d… (admin automation) expires 2027-10-15T14:05:40Z
Store it now — the value is shown exactly once and cannot be retrieved again.
The first line is the key value. Automation presents it as the bearer; for the admin verbs the CLI can store it:
opschain admin login --auth-token <the api-key token>
admin token stored for https://opschain.example.com
Two lifecycle facts to rely on: disabling a user
(opschain admin users disable) revokes all of their live tokens
immediately — a leaver never waits out a TTL — and a password reset
revokes their refresh tokens. Sessions rotate their refresh token on
every use, a replayed one revokes the whole session, and
token.session_absolute_expiry (default 30 days) bounds how long
rotation can extend one (opschain docs identity).
3. Sessions: see and end anyone's
Administrators see and end any user's sessions without waiting for a leaver process:
opschain admin sessions list dana
ID METHOD STRENGTH SOURCE LAST ADDRESS AGENT CREATED LAST SEEN
019a0d7e-2b61-7c3e-9f00-3c1f6a1be001 password - 203.0.113.7 203.0.113.7 opschain-cli/5.6.1 2026-10-15T14:02:11Z 2026-10-15T14:40:03Z
SOURCE is where the session was established from, LAST ADDRESS where it
last refreshed, and AGENT what it was established with — enough to tell
dana's laptop from a session she does not recognise. Behind a load balancer
or Cloudflare these are the real client addresses only once the proxy is
listed under server.trusted_proxies in config.yaml (opschain docs config); otherwise every session shows the proxy's address. Every audited
action a session performs names it back in the audit trail (actor.session_id
on the event, opschain docs events).
opschain admin sessions revoke <session-id> ends one immediately —
dana's other sessions stay live, so a stolen laptop costs one session,
not a workday. Without the admin determination another user's sessions
simply read as absent.
4. Automation principals: who a trigger acts as
A trigger (lesson 5.2), a scheduled activity (lesson 5.3) and an inbound webhook connection all execute as an identity, and every firing is authorisation-checked as that identity. The default is the author — fine for a personal automation, a landmine for anything a team depends on, because the day the author leaves, the firings refuse. The durable answer is a service account: a principal with no login lane at all (no password, no session, no API key — the mints refuse by name), never an approver, taking its authority exactly like any identity through policy assignments and group membership:
opschain admin service-accounts create deploy-bot
opschain admin groups add-member app-operators deploy-bot
Created service account deploy-bot (id 019a…)
Grant it authority via policy assignments or group membership, then point automations at it with run_as.
Point an automation at it — run_as on the trigger definition (your
own act_as trust grant for that identity on the project authorises
the delegation), the run-as field on a scheduled activity, or the
--service-account an inbound webhook connection is created with:
opschain triggers update acme/promote_on_success --run-as deploy-bot
updated trigger acme/promote_on_success
The firing's audit carries both principals — author and
executed_as — so delegation never hides who wrote the automation.
Groups never act: --owned-by on the same verbs names the team that
owns the automation for notification and maintenance routing, while
the firing authority is always the executing principal.
5. Offboarding without stranding
Disabling an identity warns you what it was running:
opschain admin users disable carol
Disabled carol (provider ldap:corp)
Warning: carol's standing automations will refuse firing until reassigned ...:
triggers (2): bot-run, nightly-deploy
scheduled activities (1): deploy (/projects/demo)
The disable always proceeds; the firings refuse (warn:triggers:identity)
until repointed. One verb moves everything carol executed onto a service
account — authorship stays historical, only the executing identity
moves:
opschain admin users reassign-automations carol --to deploy-bot
Reassigned carol's automations to service account deploy-bot:
triggers (2): bot-run, nightly-deploy
scheduled activities (1): deploy (/projects/demo)
It is idempotent, it refuses a human or a disabled account as the
target, and deploy-bot needs its own authority on those projects for
the firings to pass. Disable and enable work for any identity — local,
directory, federated — and take --bulk for a leaver batch; to cut a
whole provider's population at once, disable the provider connection
itself (lesson 7.5).
6. The audit answer
"Who can do what, where?" is one command, not a spreadsheet exercise:
opschain admin authz review-export --store postgres://opschain@db/opschain --format csv --out ./review
wrote grants, users, system_assignments, api_tokens and runner_registration_tokens CSVs to ./review
The export captures every rule × policy × principal grant with its four
action booleans, the user accounts with provider and standing (service
accounts included), the system policy assignments, and both token
inventories (owners, descriptions, use counts and expiries; never
values). It reads the database directly (PostgreSQL stores only), so it
needs a DSN and no login — which is exactly what an access reviewer
wants. --format json writes one document instead.
Check yourself
- Which identity does a trigger fire as by default, what should a team's trigger run as instead, and which verb moves a leaver's automations?
- What does the review export list, and what does it never contain?
What you learned
- Tokens are listed as metadata and revoked by id; disabling a user revokes every token they hold.
- An API key is minted once with an expiry and a description, and carries its owner's authority.
- A session is ended on its own; the user's other sessions survive.
- Automations execute as a principal; service accounts are the durable one, with no login lane and no approver role.
reassign-automationsis the offboarding repair; the review export is the access reviewer's one answer.
Next: lesson 7.4 — Security roles and step-up (opschain learn 7.4), or back to your track (opschain learn).