Files
git.stella-ops.org/docs/security/authority-scopes.md
master 1d962ee6fc
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Add OpenSslLegacyShim to ensure OpenSSL 1.1 libraries are accessible on Linux
This commit introduces the OpenSslLegacyShim class, which sets the LD_LIBRARY_PATH environment variable to include the directory containing OpenSSL 1.1 native libraries. This is necessary for Mongo2Go to function correctly on Linux platforms that do not ship these libraries by default. The shim checks if the current operating system is Linux and whether the required directory exists before modifying the environment variable.
2025-11-02 21:41:03 +02:00

25 KiB
Raw Blame History

Authority Scopes & Tenancy — AOC Update

Audience: Authority Core, platform security engineers, DevOps owners.
Scope: Scope taxonomy, tenancy enforcement, rollout guidance for the Aggregation-Only Contract (Sprint19).

Authority issues short-lived tokens bound to tenants and scopes. Sprint19 introduces new scopes to support the AOC guardrails in Concelier and Excititor. This document lists the canonical scope catalogue, describes tenancy propagation, and outlines operational safeguards.


1·Scope catalogue (post AOC)

Scope Surface Purpose Notes
advisory:ingest Concelier ingestion APIs Append-only writes to advisory_raw collections. Requires tenant claim; blocked for global clients.
advisory:read /aoc/verify, Concelier dashboards, CLI Read-only access to stored advisories and guard results. Must be requested with aoc:verify; Authority rejects tokens missing the pairing.
advisory-ai:view Advisory AI dashboards, remediation exports Read-only access to Advisory AI artefacts (summaries, remediation bundles). Requires aoc:verify; defaults granted to advisory-ai-viewer role.
advisory-ai:operate Advisory AI remote inference workflows Submit Advisory AI inference/remediation jobs and retrieve anonymized outputs. Requires aoc:verify; remote inference must be enabled and tenant-consented.
advisory-ai:admin Advisory AI configuration APIs, Console admin Manage Advisory AI profiles, remote inference toggles, and audit exports. Restricted to platform admins; requires aoc:verify; all operations audited.
vex:ingest Excititor ingestion APIs Append-only writes to vex_raw. Mirrors advisory:ingest; tenant required.
vex:read /aoc/verify, Excititor dashboards, CLI Read-only access to stored VEX material. Must be requested with aoc:verify; Authority rejects tokens missing the pairing.
aoc:verify CLI/CI pipelines, Console verification jobs Execute Aggregation-Only Contract guard runs. Always issued with tenant; required whenever requesting advisory:read, vex:read, or any signals:* scope.
signals:read Signals API, reachability dashboards Read-only access to stored reachability signals. Tenant and aoc:verify required; missing pairing returns invalid_scope.
signals:write Signals ingestion APIs Append-only writes for reachability signals. Requires tenant and aoc:verify; Authority logs authority.aoc_scope_violation on mismatch.
signals:admin Signals administration tooling Rotate credentials, manage reachability sensors, purge stale data. Reserved for automation; aoc:verify + tenant mandatory; violations are audited.
airgap:status:read AirGap Controller status API, Console status pane, CLI Read sealed state, staleness metrics, and import history. Tenant required; defaulted via airgap-viewer and Console bundles.
airgap:import AirGap Importer APIs, CLI workflows Import offline bundles into catalog and object storage. Tenant required; issued to airgap-operator; operations are fully audited.
airgap:seal AirGap Controller sealing endpoints Seal or unseal installations and confirm sealing tickets. Tenant required; restrict to airgap-admin; pair with operator ticket policy.
obs:read Observability API, Console dashboards Read observability dashboards, SLO digests, and incident overlays. Tenant required; typically paired with timeline:read and evidence:read.
timeline:read Timeline API, observability consoles, CLI Read incident timeline entries and annotations. Issue alongside obs:read for analyst workflows; tenant enforced.
timeline:write Timeline ingest workers, Scheduler Append deterministic incident timeline events and annotations. Automation only; Authority audits source client + tenant.
evidence:create Evidence Locker ingestion APIs Create evidence items, upload artefacts, and link attestations. Append-only; emits authority.evidence.create audit trail per item.
evidence:read Evidence Locker APIs, Offline Kit exports Read evidence items, artefacts, and linkage metadata. Analysts/legal staff; tenant enforced.
evidence:hold Evidence Locker legal hold endpoints Apply or release legal holds on evidence items. Restricted to compliance/legal operators; audited.
attest:read Attestation evidence explorer, Observability UI Read attestation records, DSSE bundles, and verification proofs. Read-only counterpart to signer/attestor pipelines; tenant required.
obs:incident Incident bridge automation, Console Toggle incident mode, extend retention, enable emergency telemetry. Requires fresh auth + incident_reason, no refresh; audit via /authority/audit/incident.

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-Tenant (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 (Sprint55). 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. | graph:write | Cartographer pipeline | Enqueue graph build/overlay jobs. | Reserved for Cartographer service identity; tenant required. | | graph:read | Graph API, Scheduler overlays, UI | Read graph projections/overlays. | Tenant required; granted to Cartographer, Graph API, Scheduler. | | graph:export | Graph export endpoints | Stream GraphML/JSONL artefacts. | UI/gateway automation only; tenant required. | | graph:simulate | Policy simulation overlays | Trigger what-if overlays on graphs. | Restricted to automation; tenant required. | | effective:write | Policy Engine | Create/update effective_finding_* collections. | Only the Policy Engine service client may hold this scope; tenant required. | | findings:read | Console, CLI, exports | Read derived findings materialised by Policy Engine. | Shared across tenants with RBAC; tenant claim still enforced. | | policy:author | Policy Studio (Console, CLI) | Author drafts, run lint, execute quick simulations. | Tenant required; typically granted via role/policy-author. | | policy:review | Policy Studio review panes | Review drafts, leave comments, request changes. | Tenant required; pair with policy:simulate for diff previews. | | policy:approve | Policy Studio approvals | Approve or reject policy drafts. | Tenant required; fresh-auth enforced by Console UI. | | policy:operate | Policy Studio promotion controls | Trigger batch simulations, promotions, and canary runs. | Tenant required; combine with policy:run/policy:activate. | | policy:audit | Policy audit exports | Access immutable policy history, comments, and signatures. | Tenant required; read-only access. | | policy:simulate | Policy Studio / CLI simulations | Run simulations against tenant inventories. | Tenant required; available to authors, reviewers, operators. | | vuln:read | Vuln Explorer API/UI | Read normalized vulnerability data. | Tenant required. | | export.viewer | Export Center APIs | List export profiles/runs, fetch manifests and bundles. | Tenant required; read-only access. | | export.operator | Export Center APIs | Trigger export runs, manage schedules, request verifications. | Tenant required; pair with export.admin for retention/encryption changes. | | export.admin | Export Center administrative APIs | Configure retention policies, encryption keys, and scheduling defaults. | Tenant required; token requests must include export_reason + export_ticket; Authority audits denials. | | notify.viewer | Notifier APIs, Console, CLI | Read notifier rules, channel configuration, and delivery history. | Tenant required; responses are redacted for cross-tenant data; no mutation rights. | | notify.operator | Notifier APIs, automation hooks | Manage notifier rules, trigger tests, acknowledge/resolve incidents. | Tenant required; Authority enforces operator metadata (notify_reason, notify_ticket) when configured. | | notify.admin | Notifier administrative APIs | Configure channels, secrets, quiet hours, and escalation policies. | Tenant required; Authority audits secret rotations and escalation changes. | | notify.escalate | Notifier ack/escalation bridge | Issue escalation-bearing ack tokens and honour escalation acknowledgements. | Tenant required; Authority enforces pairing with notify.admin when escalation mutates platform state. | | orch:read | Orchestrator dashboards/API | Read queued jobs, worker state, and rate-limit telemetry. | Tenant required; never grants mutation rights. | | orch:operate | Orchestrator control actions | Execute pause/resume, retry, sync-now, and backfill operations. Requires tenant assignment and operator_reason/operator_ticket parameters when requesting tokens. | | orch:quota | Orchestrator quota administration | Adjust 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. | | packs.read | Packs Registry, Task Runner | Discover Task Packs, download manifests, and inspect metadata. | Tenant claim required; Authority rejects cross-tenant tokens and tags violations with authority.pack_scope_violation. | | packs.write | Packs Registry APIs | Publish or update Task Packs (requires signed bundles). | Tenant claim required; typically restricted to registry automation; violations surface via authority.pack_scope_violation. | | packs.run | Task Runner | Execute 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.approve | Task Runner approvals | Fulfil 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:read | Exception service APIs, Console | Enumerate exception definitions, routing templates, and approval state. | Tenant and approval routing metadata required for audit replay. | | exceptions:write | Policy Engine → Authority bridge | Persist exception evaluations, lifecycle events, and status changes. | Tenant required; only service principals should hold this scope. | | exceptions:approve | Console fresh-auth flows, delegated admins | Approve or reject exception requests routed through Authority. | Tenant required; Authority enforces MFA when any bound routing template has requireMfa=true. | | ui.read | Console base APIs | Retrieve tenant catalog, profile metadata, and token introspection results. | Tenant header required; responses are DPoP-bound and audit logged. | | authority:tenants.read | Console admin workspace | Enumerate configured tenants, default roles, and isolation metadata. | Tenant claim must match header; access audited via authority.console.tenants.read. | | 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 /docs/security/policy-governance.md for policy-specific scopes. |

1.1Scope bundles (roles)

  • role/concelier-ingestadvisory:ingest, advisory:read.
  • role/excititor-ingestvex:ingest, vex:read.
  • role/signals-uploadersignals:write, signals:read, aoc:verify.
  • role/aoc-operatoraoc:verify, advisory:read, vex:read.
  • role/policy-engineeffective:write, findings:read.
  • role/cartographer-servicegraph:write, graph:read.
  • role/graph-gatewaygraph:read, graph:export, graph:simulate.
  • role/consoleui.read, advisory:read, vex:read, exceptions:read, aoc:verify, findings:read, airgap:status:read, orch:read, vuln:read.
  • role/ui-console-adminui.read, authority:tenants.read, authority:roles.read, authority:tokens.read, authority:clients.read (paired with write scopes where required).
  • role/orch-viewer (Authority role: Orch.Viewer)orch:read.
  • role/orch-operator (Authority role: Orch.Operator)orch:read, orch:operate.
  • role/orch-admin (Authority role: Orch.Admin)orch:read, orch:operate, orch:quota, orch:backfill.
  • role/packs-runnerpacks.read, packs.run.
  • role/packs-publisherpacks.read, packs.write.
  • role/packs-approverpacks.read, packs.approve.
  • role/policy-authorpolicy:author, policy:read, policy:simulate, findings:read.
  • role/policy-reviewerpolicy:review, policy:read, policy:simulate, findings:read.
  • role/policy-approverpolicy:approve, policy:review, policy:read, policy:simulate, findings:read.
  • role/policy-operatorpolicy:operate, policy:run, policy:activate, policy:read, policy:simulate, findings:read.
  • role/policy-auditorpolicy:audit, policy:read, policy:simulate, findings:read.
  • role/export-viewer (Authority role: Export.Viewer)export.viewer.
  • role/export-operator (Authority role: Export.Operator)export.viewer, export.operator.
  • role/export-admin (Authority role: Export.Admin)export.viewer, export.operator, export.admin.
  • role/notify-viewer (Authority role: Notify.Viewer)notify.viewer.
  • role/notify-operator (Authority role: Notify.Operator)notify.viewer, notify.operator.
  • role/notify-admin (Authority role: Notify.Admin)notify.viewer, notify.operator, notify.admin.
  • role/observability-viewer (Authority role: Observability.Viewer)obs:read, timeline:read, evidence:read, attest:read.
  • role/observability-investigator (Authority role: Observability.Investigator)obs:read, timeline:read, timeline:write, evidence:read, evidence:create, attest:read.
  • role/observability-legal (Authority role: Observability.Legal)evidence:read, evidence:hold.
  • role/observability-incident-commander (Authority role: Observability.IncidentCommander)obs:read, obs:incident, timeline:read, timeline:write, evidence:create, evidence:read, attest:read.
  • role/airgap-viewerairgap:status:read.
  • role/airgap-operatorairgap:status:read, airgap:import.
  • role/airgap-adminairgap:status:read, airgap:import, airgap:seal.
  • role/exceptions-serviceexceptions:read, exceptions:write.
  • role/exceptions-approverexceptions:read, exceptions:approve.

Roles are declared per tenant in authority.yaml:

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:read, policy:simulate, findings:read]
      policy-auditor:
        scopes: [policy:audit, policy:read, policy:simulate, findings:read]
      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.1Token claims

Tokens now include:

  • tenant claim (string) — required for all ingestion and verification scopes.
  • service_identity (optional) — e.g., policy-engine, cartographer. Required when requesting effective:write or graph:write.
  • delegation_allowed (boolean) — defaults false. Prevents console tokens from delegating ingest scopes.

Authority rejects requests when:

  • tenant is missing while requesting advisory:ingest, advisory:read, vex:ingest, vex:read, or aoc:verify scopes.
  • aoc:verify is absent while tokens request advisory:read, vex:read, or any signals:* scope (invalid_scope with deterministic message).
  • service_identity != policy-engine but effective:write is present (ERR_AOC_006 enforcement).
  • service_identity != cartographer but graph:write is present (graph pipeline enforcement).
  • Tokens attempt to combine advisory:ingest with effective:write (separation of duties).
  • exceptions:approve is requested by a client without a tenant assignment or via an identity provider lacking MFA when RequireMfaForApprovals=true.

2.2Propagation

  • API Gateway forwards tenant claim as header (X-Stella-Tenant). Services refuse requests lacking the header.
  • Concelier/Excititor stamp tenant into raw documents and structured logs.
  • Policy Engine copies tenant from tokens into effective_finding_* collections.
  • Exception lifecycle services persist tenant and the selected routing template identifier alongside approval decisions. Authority audit events (authority.password.grant, authority.client_credentials.grant) surface audit.scopes and, on denials, a scope.invalid metadata entry so operators can trace exception approval attempts without inspecting downstream services.

2.3Cross-tenant scenarios

  • Platform operators with tenant:admin can assume other tenants via /authority/tenant/switch if explicitly permitted.
  • CLI commands accept --tenant <id> to override environment default; Authority logs tenant switch events (authority.tenant.switch).
  • Console tenant picker uses delegated token exchange (/token/exchange) to obtain scoped tenant tokens without exposing raw credentials.

3·Configuration changes

3.1Authority 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: 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:read
      description: Read Vuln Explorer data
  claimTransforms:
    - match: { scope: "effective:write" }
      require:
        serviceIdentity: policy-engine
    - match: { scope: "graph:write" }
      require:
        serviceIdentity: cartographer

3.2Client registration

Update service clients:

  • Concelier.WebService → request advisory:ingest, advisory:read.
  • Excititor.WebService → request vex:ingest, vex:read.
  • Policy.Engine → request effective:write, findings:read; set properties.serviceIdentity=policy-engine.
  • Cartographer.Service → request graph:write, graph:read; set properties.serviceIdentity=cartographer.
  • Graph API Gateway → request graph:read, graph:export, graph:simulate; tenant hint required.
  • Console → request advisory:read, vex:read, aoc:verify, findings:read, vuln:read plus existing UI scopes.
  • CLI automation → request aoc:verify, advisory:read, vex:read as needed.

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

4·Operational safeguards

  • Audit events: Authority emits authority.scope.granted and authority.scope.revoked events with scope and tenant. Monitor for unexpected grants.
  • Rate limiting: Apply stricter limits on /token endpoints for clients requesting advisory:ingest or vex:ingest to mitigate brute-force ingestion attempts.
  • Incident response: Link AOC alerts to Authority audit logs to confirm whether violations come from expected identities.
  • Rotation: Rotate ingest client secrets alongside guard deployments; add rotation steps to ops/authority-key-rotation.md.
  • Testing: Integration tests must fail if tokens lacking tenant attempt ingestion; add coverage in Concelier/Excititor smoke suites (see CONCELIER-CORE-AOC-19-013).

5·Offline & air-gap notes

  • Offline Kit bundles include tenant-scoped service credentials. Ensure ingest bundles ship without advisory:ingest scopes unless strictly required.
  • CLI verification in offline environments uses pre-issued aoc:verify tokens; document expiration and renewal processes.
  • Authority replicas in air-gapped environments should restrict scope issuance to known tenants and log all /token interactions for later replay.

6·References


7·Compliance checklist

  • Scope catalogue updated in Authority configuration templates.
  • Role mappings documented for each tenant profile.
  • Claim transforms enforce serviceIdentity for effective:write.
  • Claim transforms enforce serviceIdentity for graph:write.
  • Concelier/Excititor smoke tests cover missing tenant rejection.
  • Offline kit credentials reviewed for least privilege.
  • Audit/monitoring guidance validated with Observability Guild.
  • Authority Core sign-off recorded (owner: @authority-core, due 2025-10-28).

Last updated: 2025-10-27 (Sprint19).