Authority Scopes & Tenancy

Audience: Authority Core, platform security engineers, DevOps owners. Scope: The canonical OAuth scope catalogue, scope-bundle (role) definitions, tenancy enforcement, and rollout guidance — including the Aggregation-Only Contract (AOC) scopes introduced in Sprint 19.

Canonical source of truth: the scope constants live in src/Authority/StellaOps.Authority/StellaOps.Auth.Abstractions/StellaOpsScopes.cs. When this table and the code disagree, the code wins. ASP.NET policy names may differ from scope claim values (e.g. dot-form vs. colon-form) — audit against the scope constant.

Authority issues short-lived tokens bound to tenants and scopes. This document lists the canonical scope catalogue, defines the scope bundles (roles) that compose those scopes, describes tenancy propagation, and outlines operational safeguards. The AOC guardrail scopes in Concelier and Excititor (Sprint 19) are part of this catalogue.


1 · Scope catalogue

ScopeSurfacePurposeNotes
advisory:ingestConcelier ingestion APIsAppend-only writes to advisory_raw collections.Requires tenant claim; blocked for global clients.
advisory:read/aoc/verify, Concelier dashboards, CLIRead-only access to stored advisories and guard results.Must be requested with aoc:verify; Authority rejects tokens missing the pairing.
advisory-ai:viewAdvisory AI dashboards, remediation exportsRead-only access to Advisory AI artefacts (summaries, remediation bundles).Requires aoc:verify; defaults granted to advisory-ai-viewer role.
advisory-ai:operateAdvisory AI remote inference workflowsSubmit Advisory AI inference/remediation jobs and retrieve anonymized outputs.Requires aoc:verify; remote inference must be enabled and tenant-consented.
advisory-ai:adminAdvisory AI configuration APIs, Console adminManage Advisory AI profiles, remote inference toggles, and audit exports.Restricted to platform admins; requires aoc:verify; all operations audited.
vex:ingestExcititor ingestion APIsAppend-only writes to vex_raw.Mirrors advisory:ingest; tenant required.
vex:read/aoc/verify, Excititor dashboards, CLIRead-only access to stored VEX material.Must be requested with aoc:verify; Authority rejects tokens missing the pairing.
vex.adminExcititor provider control plane, CLI automationManage VEX provider configuration, review actions, and forced ingestion runs.Granted to first-party CLI automation in the standard bootstrap config; downstream Excititor mutations require this scope.
aoc:verifyCLI/CI pipelines, Console verification jobsExecute Aggregation-Only Contract guard runs.Always issued with tenant; required whenever requesting advisory:read, vex:read, or any signals:* scope.
signals:readSignals API, reachability dashboardsRead-only access to stored reachability signals.Tenant and aoc:verify required; missing pairing returns invalid_scope.
signals:writeSignals ingestion APIsAppend-only writes for reachability signals.Requires tenant and aoc:verify; Authority logs authority.aoc_scope_violation on mismatch.
signals:adminSignals administration toolingRotate credentials, manage reachability sensors, purge stale data.Reserved for automation; aoc:verify + tenant mandatory; violations are audited.
airgap:status:readAirGap Controller status API, Console status pane, CLIRead sealed state, staleness metrics, and import history.Tenant required; defaulted via airgap-viewer and Console bundles.
airgap:importAirGap Importer APIs, CLI workflowsImport offline bundles into catalog and object storage.Tenant required; issued to airgap-operator; operations are fully audited.
airgap:sealAirGap Controller sealing endpointsSeal or unseal installations and confirm sealing tickets.Tenant required; restrict to airgap-admin; pair with operator ticket policy.
obs:readObservability API, Console dashboardsRead observability dashboards, SLO digests, and incident overlays.Tenant required; typically paired with timeline:read and evidence:read.
timeline:readTimeline API, observability consoles, CLIRead incident timeline entries and annotations.Issue alongside obs:read for analyst workflows; tenant enforced.
timeline:writeTimeline ingest workers, SchedulerAppend deterministic incident timeline events and annotations.Automation only; Authority audits source client + tenant.
evidence:createEvidence Locker ingestion APIsCreate evidence items, upload artefacts, and link attestations.Append-only; emits authority.evidence.create audit trail per item.
evidence:readEvidence Locker APIs, Offline Kit exportsRead evidence items, artefacts, and linkage metadata.Analysts/legal staff; tenant enforced.
evidence:holdEvidence Locker legal hold endpointsApply or release legal holds on evidence items.Restricted to compliance/legal operators; audited.
attest:readAttestation evidence explorer, Observability UIRead attestation records, DSSE bundles, and verification proofs.Read-only counterpart to signer/attestor pipelines; tenant required.
obs:incidentIncident bridge automation, ConsoleToggle incident mode, extend retention, enable emergency telemetry.Requires fresh auth + incident_reason, no refresh; audit via /authority/audit/incident.
graph:writeCartographer pipelineEnqueue graph build/overlay jobs.Reserved for Cartographer service identity; tenant required.
graph:readGraph API, Scheduler overlays, UIRead graph projections/overlays.Tenant required; granted to Cartographer, Graph API, Scheduler.
graph:exportGraph export endpointsStream GraphML/JSONL artefacts.UI/gateway automation only; tenant required.
graph:simulatePolicy simulation overlaysTrigger what-if overlays on graphs.Restricted to automation; tenant required.
effective:writePolicy EngineCreate/update effective_finding_* collections.Only the Policy Engine service client may hold this scope; tenant required.
findings:readConsole, CLI, exportsRead derived findings materialised by Policy Engine.Shared across tenants with RBAC; tenant claim still enforced.
policy:authorPolicy Studio (Console, CLI)Author drafts, run lint, execute quick simulations.Tenant required; typically granted via role/policy-author.
policy:reviewPolicy Studio review panesReview drafts, leave comments, request changes.Tenant required; pair with policy:simulate for diff previews.
policy:approvePolicy Studio approvalsApprove or reject policy drafts.Tenant required; fresh-auth enforced by Console UI.
policy:operatePolicy Studio promotion controlsTrigger batch simulations, promotions, and canary runs.Tenant required; combine with policy:run/policy:activate.
policy:publishPolicy Studio / CLI attestation flowsPublish approved policy versions and generate signing bundles.Interactive only; tenant required; tokens must include policy_reason, policy_ticket, and policy digest (fresh-auth enforced). stella policy publish --sign injects the headers.
policy:promotePolicy Studio / CLI attestation flowsPromote policy attestations between environments (e.g., staging → prod).Interactive only; tenant required; requires policy_reason, policy_ticket, digest, and fresh-auth within 5 minutes. CLI: stella policy promote --environment <env>.
policy:auditPolicy audit exportsAccess immutable policy history, comments, and signatures.Tenant required; read-only access.
policy:simulatePolicy Studio / CLI simulationsRun simulations against tenant inventories.Tenant required; available to authors, reviewers, operators.
vuln:viewVuln Explorer API/UIRead normalized vulnerability data, issue permalinks.Tenant required; ABAC attributes (env, owner, business_tier) further constrain access.
vuln:investigateVuln Explorer triage workflowsAssign findings, add comments, attach remediation notes.Tenant + ABAC attributes required; typically paired with vuln:view.
vuln:operateVuln Explorer state transitionsChange remediation state, accept risk, trigger remediation plans.Tenant + ABAC attributes required; interactive flows should enforce fresh-auth on prod tenants.
vuln:auditVuln Explorer audit/report exportsAccess immutable ledgers, reports, and offline bundles.Tenant required; ABAC attributes restrict which assets may be exported.
export.viewerExport Center APIsList export profiles/runs, fetch manifests and bundles.Tenant required; read-only access.
export.operatorExport Center APIsTrigger export runs, manage schedules, request verifications.Tenant required; pair with export.admin for retention/encryption changes.
export.adminExport Center administrative APIsConfigure retention policies, encryption keys, and scheduling defaults.Tenant required; token requests must include export_reason + export_ticket; Authority audits denials.
notify.viewerNotifier APIs, Console, CLIRead notifier rules, channel configuration, and delivery history.Tenant required; responses are redacted for cross-tenant data; no mutation rights.
notify.operatorNotifier APIs, automation hooksManage notifier rules, trigger tests, acknowledge/resolve incidents.Tenant required; Authority enforces operator metadata (notify_reason, notify_ticket) when configured.
notify.adminNotifier administrative APIsConfigure channels, secrets, quiet hours, and escalation policies.Tenant required; Authority audits secret rotations and escalation changes.
notify.escalateNotifier ack/escalation bridgeIssue escalation-bearing ack tokens and honour escalation acknowledgements.Tenant required; Authority enforces pairing with notify.admin when escalation mutates platform state.
orch:readOrchestrator dashboards/APIRead queued jobs, worker state, and rate-limit telemetry.Tenant required; never grants mutation rights.
orch:operateOrchestrator control actionsExecute pause/resume, retry, sync-now, and backfill operations. Requires tenant assignment and operator_reason/operator_ticket parameters when requesting tokens.
replay:readReplay API, Console VerifyDeterministically verify or recompute recorded replay decisions and inspect replay state.Tenant required; does not authorize durable token, bundle, manifest, or snapshot production.
replay:writeReplay producer APIsProduce durable replay tokens, bundles, manifests, and feed snapshots.Tenant required; grant only to replay producers and operators.
orch:quotaOrchestrator quota administrationAdjust per-tenant quotas, burst ceilings, and backfill allowances. Requires tenant assignment and quota_reason (≤256 chars); optional quota_ticket (≤128 chars) is recorded for audit.
scanner:readScanner API, ConsoleRead scan results, configurations, and summaries.Tenant required; read-only access.
scanner:scanScanner control APIsTrigger scans and pipelines.Tenant required; operator workflows should enforce fresh-auth.
scanner:exportScanner export APIsExport scan artefacts and evidence bundles.Tenant required; used by reporting flows.
scanner.signed-sbom-material.writeScanner signed-SBOM export APIsWrite signed SBOM material for release evidence handoff.Tenant required; assign to producer service accounts instead of broad Scanner admin roles.
scanner:writeScanner admin APIsUpdate scanner configuration, feeds, and tenants.Tenant required; admin only.
scheduler:readScheduler API, ConsoleRead schedules, job runs, and worker status.Proposed scope; add to Authority constants and gateway enforcement.
scheduler:operateScheduler control APIsTrigger/manual run, pause/resume schedules.Proposed scope; operator flows should enforce fresh-auth.
scheduler:adminScheduler admin APIsManage schedules, queues, and retention policies.Proposed scope; admin only.
packs.readPacks Registry, Task RunnerDiscover Task Packs, download manifests, and inspect metadata.Tenant claim required; Authority rejects cross-tenant tokens and tags violations with authority.pack_scope_violation.
packs.writePacks Registry APIsPublish or update Task Packs (requires signed bundles).Tenant claim required; typically restricted to registry automation; violations surface via authority.pack_scope_violation.
packs.runTask RunnerExecute Task Packs via CLI or Task Runner APIs.Tenant claim required; Task Runner enforces tenant isolation; Authority emits authority.pack_scope_violation when missing.
packs.approveTask Runner approvalsFulfil Task Pack approval gates and resume runs.Tenant claim required; approval events audited with run ID and Pack scope violations tagged as authority.pack_scope_violation.
exceptions:readException service APIs, ConsoleEnumerate exception definitions, routing templates, and approval state.Tenant and approval routing metadata required for audit replay.
exceptions:writePolicy Engine → Authority bridgePersist exception evaluations, lifecycle events, and status changes.Tenant required; only service principals should hold this scope.
exceptions:approveConsole fresh-auth flows, delegated adminsApprove or reject exception requests routed through Authority.Tenant required; Authority enforces MFA when any bound routing template has requireMfa=true.
ui.readConsole base APIsRetrieve tenant catalog, profile metadata, and token introspection results.Tenant header required; responses are DPoP-bound and audit logged.
ui.adminConsole admin workspaceAccess admin routes and admin UI shell.Must be paired with authority:* scopes; DPoP required.
authority:tenants.readConsole admin workspaceEnumerate configured tenants, default roles, and isolation metadata.Tenant claim must match header; access audited via authority.console.tenants.read.
authority:tenants.writeConsole admin workspaceCreate and update tenant records (status, defaults, isolation).Fresh-auth enforced for suspend/resume and isolation changes.
authority:users.readConsole admin workspaceList tenant users and role assignments.Tenant claim must match header; audit logged.
authority:users.writeConsole admin workspaceUpdate user status, assignments, and local users.Fresh-auth enforced for disable/enable.
authority:roles.readConsole admin workspaceRead role bundles, scope mappings, and audiences.Audit logged.
authority:roles.writeConsole admin workspaceCreate or update role bundles.Fresh-auth enforced for role changes.
authority:clients.readConsole admin workspaceList OAuth clients, audiences, and grant settings.Audit logged.
authority:clients.writeConsole admin workspaceCreate, update, or rotate client credentials.Fresh-auth enforced for key rotation.
authority:tokens.readConsole admin workspaceRead active/revoked token inventory.Audit logged.
authority:tokens.revokeConsole admin workspaceRevoke access/refresh/device tokens.Fresh-auth enforced; revocation bundles emitted.
authority.audit.readConsole admin workspaceRead authority audit events.Audit logged.
authority:branding.readConsole admin workspaceRead branding configuration.Audit logged.
authority:branding.writeConsole admin workspaceUpdate branding configuration (logo/theme tokens).Fresh-auth enforced.
authority:idp.readConsole admin identity-provider workspaceRead global identity-provider configuration and live status.Global-admin resource; policy requires the exact read scope.
authority:idp.writeConsole admin identity-provider workspaceCreate, update, apply, enable, disable, or delete global identity-provider configuration.Global admin + fresh auth; the read scope does not satisfy this policy.
Existing scopes(e.g., policy:*, concelier.jobs.trigger)Unchanged.concelier.merge is retired — clients must request advisory:ingest/advisory:read; requests continue to fail with invalid_client. Review policy governance for policy-specific scopes.

Scope notes.

  • Observability scope bundle (added 2 Nov 2025). obs:read, timeline:read, timeline:write, evidence:create, evidence:read, evidence:hold, attest:read, and obs:incident always require a tenant claim. Gateways must forward X-StellaOps-TenantId (or the configured tenant header) or resource servers will reject the request with tenant_header_missing. The sample authority.yaml assigns these scopes via the observability-* roles; reuse those roles when onboarding new tenants to keep bundles consistent.
  • Fresh-auth enforcement (Sprint 55). Authority-issued obs:incident tokens must carry both incident_reason and auth_time. Resource servers enforce a five-minute freshness window and log incident.reason, incident.auth_time, and incident.fresh_auth_satisfied in authority.resource.authorize audit events, enabling /authority/audit/incident to verify activation reason and freshness.
  • Legacy vuln:read. It remains available for backwards compatibility and is still emitted on Vuln Explorer permalinks. New clients should request the granular vuln:* scopes above.
  • Vuln Explorer attachment tokens reuse the same scopes: issuance requires vuln:investigate, verification honours the caller’s ABAC attributes, and Authority records vuln.attachment.token.* audit events for every issue/verify flow.

1.1 Scope bundles (roles)

Developer self-service ABAC attributes:

AttributePurposeEnforced by
serviceIdsExact owned service identifiers the developer can update or request updates for.Console filtering, Release Orchestrator direct deployment/request checks
repositoryIdsRepository or release slug aliases that map a service to CI/SCM ownership.Console filtering, Release Orchestrator service match
imageNamespacesRegistry namespace boundary for owned image references when image names include a namespace.Console filtering, Release Orchestrator service match
environmentIdsExact target environment ids/names the developer can touch.Console filtering, Release Orchestrator environment match
maxEnvironmentTypeCeiling for environment tier (development, nonprod, or production) when exact environment ids are not enough.Console filtering, Release Orchestrator environment match
directUpdateAllowedAllows direct deploy creation when the service/env/digest/policy checks pass. If absent or false, the developer can still create an approval request when the other ABAC checks pass.Console action state, Release Orchestrator direct deployment check

Full module role bundle catalog (Console, Scanner, Scheduler, Policy, Graph, Observability, etc.) is maintained in docs/technical/architecture/console-admin-rbac.md and is the reference for Console admin UI and Authority seeding.

Roles are declared per tenant in authority.yaml:

Runtime note (verified 2026-07-18): YAML role entries document/operator-configure intended bundles, but the current tenant catalog does not seed these definitions into the durable RoleRepository or token-issuance role catalog. In particular, the five pack-* bundles below are not yet a canonical runtime RBAC feature. The four packs.* scope constants and tenant checks are implemented independently.

tenants:
  - name: default
    roles:
      concelier-ingest:
        scopes: [advisory:ingest, advisory:read]
      signals-uploader:
        scopes: [signals:write, signals:read, aoc:verify]
      aoc-operator:
        scopes: [aoc:verify, advisory:read, vex:read]
      orch-viewer:
        scopes: [orch:read]
      orch-operator:
        scopes: [orch:read, orch:operate]
      policy-author:
        scopes: [policy:author, policy:read, policy:simulate, findings:read]
      policy-reviewer:
        scopes: [policy:review, policy:read, policy:simulate, findings:read]
      policy-approver:
        scopes: [policy:approve, policy:review, policy:read, policy:simulate, findings:read]
      policy-operator:
        scopes: [policy:operate, policy:run, policy:activate, policy:publish, policy:promote, policy:read, policy:simulate, findings:read]
      policy-auditor:
        scopes: [policy:audit, policy:read, policy:simulate, findings:read]
      release-developer:
        scopes: [release:read, release:write, orch:read, scanner:read, scanner:scan, sbom:read, policy:read, findings:read, evidence:read]
        claims:
          serviceIds: ["payments-api", "billing-worker"]
          environmentIds: ["dev", "qa"]
          maxEnvironmentType: "nonprod"
          directUpdateAllowed: true
      pack-viewer:
        scopes: [packs.read]
      pack-operator:
        scopes: [packs.read, packs.run]
      pack-publisher:
        scopes: [packs.read, packs.write]
      pack-approver:
        scopes: [packs.read, packs.approve]
      pack-admin:
        scopes: [packs.read, packs.write, packs.run, packs.approve]
      policy-engine:
        scopes: [effective:write, findings:read]
      exceptions-service:
        scopes: [exceptions:read, exceptions:write]
      exceptions-approver:
        scopes: [exceptions:read, exceptions:approve]
      notify-viewer:
        scopes: [notify.viewer]
      notify-operator:
        scopes: [notify.viewer, notify.operator]
      notify-admin:
        scopes: [notify.viewer, notify.operator, notify.admin]
      observability-viewer:
        scopes: [obs:read, timeline:read, evidence:read, attest:read]
      observability-investigator:
        scopes: [obs:read, timeline:read, timeline:write, evidence:read, evidence:create, attest:read]
      observability-legal:
        scopes: [evidence:read, evidence:hold]
      observability-incident-commander:
        scopes: [obs:read, obs:incident, timeline:read, timeline:write, evidence:create, evidence:read, attest:read]

MFA requirement: When any exceptions.routingTemplates entry sets requireMfa: true, Authority refuses to mint tokens containing exceptions:approve unless the authenticating identity provider advertises MFA support. Password/OIDC flows produce authority.password.grant audit events with reason="Exception approval scope requires an MFA-capable identity provider." when the requirement is violated.


2 · Tenancy enforcement

2.1 Token claims

Tokens now include:

Authority rejects requests when:

2.2 Propagation

2.3 Cross-tenant scenarios


3 · Configuration changes

3.1 Authority configuration (authority.yaml)

Add new scopes and optional claims transformations:

security:
  scopes:
    - name: advisory:ingest
      description: Concelier raw ingestion (append-only)
    - name: advisory:read
      description: Read Concelier advisories and guard verdicts
    - name: vex:ingest
      description: Excititor raw ingestion
    - name: vex:read
      description: Read Excititor VEX records
    - name: vex.admin
      description: Administer Excititor VEX providers
    - name: aoc:verify
      description: Run AOC verification
    - name: airgap:status:read
      description: Read air-gap sealing status and staleness indicators
    - name: airgap:import
      description: Import offline bundles into the air-gapped catalog
    - name: airgap:seal
      description: Seal or unseal the installation during change control
    - name: effective:write
      description: Policy Engine materialisation
    - name: findings:read
      description: Read derived findings
    - name: graph:write
      description: Cartographer build submissions
    - name: graph:read
      description: Read graph overlays
    - name: graph:export
      description: Export graph artefacts
    - name: graph:simulate
      description: Run graph what-if simulations
    - name: vuln:view
      description: Read Vuln Explorer data, list findings, issue permalinks
    - name: vuln:investigate
      description: Perform triage actions (assign, comment, remediation notes)
    - name: vuln:operate
      description: Execute state changes and remediation workflows
    - name: vuln:audit
      description: Access Vuln Explorer audit ledgers and offline exports
  claimTransforms:
    - match: { scope: "effective:write" }
      require:
        serviceIdentity: policy-engine
    - match: { scope: "graph:write" }
      require:
        serviceIdentity: cartographer

3.2 Client registration

Update service clients:

Client definition snippet:

clients:
  - clientId: concelier-web
    grantTypes: [client_credentials]
    scopes: [advisory:ingest, advisory:read]
    tenants: [default]
  - clientId: policy-engine
    grantTypes: [client_credentials]
    scopes: [effective:write, findings:read]
    properties:
      serviceIdentity: policy-engine
  - clientId: cartographer-service
    grantTypes: [client_credentials]
    scopes: [graph:write, graph:read]
    properties:
      serviceIdentity: cartographer

3.3 Delegated service accounts

Add delegated service accounts when automation needs scoped tokens with shorter lifetimes:

delegation:
  quotas:
    maxActiveTokens: 50
  serviceAccounts:
    - accountId: "svc-observer"
      tenant: "tenant-default"
      allowedScopes: [ "jobs:read", "findings:read" ]
      authorizedClients: [ "export-center-worker" ]

tenants:
  - name: "tenant-default"
    delegation:
      maxActiveTokens: 25

4 · Operational safeguards


5 · Offline & air-gap notes


6 · References


7 · Compliance checklist


Last updated: 2025-11-02 (Sprint 19).