feat: Implement console session management with tenant and profile handling
- Add ConsoleSessionStore for managing console session state including tenants, profile, and token information. - Create OperatorContextService to manage operator context for orchestrator actions. - Implement OperatorMetadataInterceptor to enrich HTTP requests with operator context metadata. - Develop ConsoleProfileComponent to display user profile and session details, including tenant information and access tokens. - Add corresponding HTML and SCSS for ConsoleProfileComponent to enhance UI presentation. - Write unit tests for ConsoleProfileComponent to ensure correct rendering and functionality.
This commit is contained in:
@@ -12,28 +12,61 @@ Authority issues short-lived tokens bound to tenants and scopes. Sprint 19 int
|
||||
| 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. | Needed alongside `aoc:verify` for CLI/console verification. |
|
||||
| `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. |
|
||||
| `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. | Pair with `aoc:verify` for guard checks. |
|
||||
| `aoc:verify` | CLI/CI pipelines, Console verification jobs | Execute Aggregation-Only Contract guard runs. | Always issued with tenant; read-only combined with `advisory:read`/`vex:read`. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| Existing scopes | (e.g., `policy:*`, `concelier.jobs.trigger`) | Unchanged. | Review `/docs/security/policy-governance.md` for policy-specific scopes. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
| `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.1 Scope bundles (roles)
|
||||
|
||||
- **`role/concelier-ingest`** → `advisory:ingest`, `advisory:read`.
|
||||
- **`role/excititor-ingest`** → `vex:ingest`, `vex:read`.
|
||||
- **`role/signals-uploader`** → `signals:write`, `signals:read`, `aoc:verify`.
|
||||
- **`role/aoc-operator`** → `aoc:verify`, `advisory:read`, `vex:read`.
|
||||
- **`role/policy-engine`** → `effective:write`, `findings:read`.
|
||||
- **`role/cartographer-service`** → `graph:write`, `graph:read`.
|
||||
- **`role/graph-gateway`** → `graph:read`, `graph:export`, `graph:simulate`.
|
||||
- **`role/console`** → `advisory:read`, `vex:read`, `aoc:verify`, `findings:read`, `vuln:read`.
|
||||
- **`role/console`** → `ui.read`, `advisory:read`, `vex:read`, `exceptions:read`, `aoc:verify`, `findings:read`, `orch:read`, `vuln:read`.
|
||||
- **`role/ui-console-admin`** → `ui.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/policy-author`** → `policy:author`, `policy:read`, `policy:simulate`, `findings:read`.
|
||||
- **`role/policy-reviewer`** → `policy:review`, `policy:read`, `policy:simulate`, `findings:read`.
|
||||
- **`role/policy-approver`** → `policy:approve`, `policy:review`, `policy:read`, `policy:simulate`, `findings:read`.
|
||||
- **`role/policy-operator`** → `policy:operate`, `policy:run`, `policy:activate`, `policy:read`, `policy:simulate`, `findings:read`.
|
||||
- **`role/policy-auditor`** → `policy: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/exceptions-service`** → `exceptions:read`, `exceptions:write`.
|
||||
- **`role/exceptions-approver`** → `exceptions:read`, `exceptions:approve`.
|
||||
|
||||
Roles are declared per tenant in `authority.yaml`:
|
||||
|
||||
@@ -43,12 +76,34 @@ tenants:
|
||||
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]
|
||||
policy-engine:
|
||||
scopes: [effective:write, findings:read]
|
||||
exceptions-service:
|
||||
scopes: [exceptions:read, exceptions:write]
|
||||
exceptions-approver:
|
||||
scopes: [exceptions:read, exceptions:approve]
|
||||
```
|
||||
|
||||
> **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
|
||||
@@ -64,15 +119,18 @@ Tokens now include:
|
||||
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.2 Propagation
|
||||
|
||||
- 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.3 Cross-tenant scenarios
|
||||
|
||||
|
||||
Reference in New Issue
Block a user