Skip to main content
Reference
DraftLast reviewed 2026-06-23

Scopes & entitlements

OpenTRMS authorizes every controller method with a single @RequireScope("resource:action") annotation, enforced by ScopeGuardAspect in trms-auth. A request without the required scope fails with HTTP 403. Humans and AI agents (via MCP and the CLI) go through the same scope check — there is no separate AI permission model.

Scopes are not stored in a database table; they are system-defined strings. ScopeCatalog in trms-auth holds the full set of known identifiers, used to validate admin grants. The table below lists every scope that is actually enforced by a @RequireScope annotation somewhere in the codebase today.

Enforced scopes, by resource

AUTO-GENERATED from @RequireScope literals in trms-api/src/main/java. Do not edit by hand; run npm run sync.

101 distinct scope strings are enforced via 225 @RequireScope annotations across the REST controllers in trms-api.

ResourceScopes
aiai:chat
approvalsapprovals:approve, approvals:escalate, approvals:read, approvals:reject
artifactsartifacts:activate, artifacts:read, artifacts:review, artifacts:submit, artifacts:upload
auditaudit:read, audit:verify
bank_accountsbank_accounts:read, bank_accounts:write
booksbooks:read, books:write
calendarscalendars:manage, calendars:read
cashcash:read
cashflowscashflows:fix
closeoutcloseout:execute, closeout:read
compliancecompliance:read
configconfig:admin, config:manage, config:read
creditcredit:read, credit:write
curvescurves:calibrate, curves:manage, curves:read
dealsdeals:amend, deals:cancel, deals:capture, deals:close_repo, deals:pre-check, deals:read, deals:substitute_collateral, deals:terminate, deals:transition
devdev:auth
entitlementsentitlements:admin
fixingsfixings:capture, fixings:read
indexesindexes:manage, indexes:read
instructionsinstructions:claim, instructions:create, instructions:execute, instructions:read
instrumentsinstruments:create, instruments:deactivate, instruments:events, instruments:read, instruments:supersede, instruments:update
journalsjournals:period_close, journals:post, journals:read, journals:reverse
market-datamarket-data:publish, market-data:read
market-quotesmarket-quotes:publish, market-quotes:read
nettingnetting:execute, netting:read
parties:internalparties:internal:read, parties:internal:write
paymentspayments:acknowledge, payments:cancel, payments:generate, payments:read, payments:send
pluginsplugins:admin
positionspositions:read
pretradepretrade:read
refref:read
reportsreports:admin, reports:read
riskrisk:manage, risk:read
settlementssettlements:cancel, settlements:instruct, settlements:read, settlements:send
simulationssimulations:manage, simulations:read, simulations:run
stpstp:manage, stp:read
systemsystem:admin, system:batch, system:read
user:preferencesuser:preferences:read, user:preferences:write
usersusers:admin
valuationsvaluations:execute, valuations:read
workbenchworkbench:read
workbench:templatesworkbench:templates:read, workbench:templates:write

Scope shape

ConventionDetail
Formatresource:action, occasionally resource:sub-resource:action (e.g. parties:internal:read, workbench:templates:write)
GranularityPer-endpoint, not per-role — a role is just a named bundle of scopes
Enforcement pointScopeGuardAspect (AOP, wraps @RequireScope-annotated methods)
Failure modeInsufficientScopeException → HTTP 403
Source of truthCode (@RequireScope literals) — no scopes table in the database

Scope catalog vs. enforced scopes

ScopeCatalog.SCOPES in trms-auth is intentionally a superset of the scopes enforced above — it also reserves identifiers for capabilities that are defined but not yet wired to a controller (or are wired but the catalog has not been pruned), such as approvals:decide, compliance:check, compliance:rules, curves:build, curves:publish, the journal:* series (distinct from the enforced journals:* series), margin:calculate, margin:collateral, margin:read, extensions:manage, extensions:read, portfolio:read, portfolio:scenarios, portfolio:valuate, settlements:generate, settlements:netting, and valuations:detail. The catalog exists so that EntitlementAdminService can reject grants of unknown scope strings (HTTP 400) when an admin assigns scopes to a FUNCTIONAL group — treat it as the forward-looking namespace, and the table above as what is actually checked today.

Granting scopes

Scopes are granted to users via group membership, administered under /api/v1/admin/entitlements (gated by entitlements:admin) and /api/v1/admin/users (gated by users:admin). See Approval chains for how requiredScope on an approval request determines who can approve a pending action.