feat: Implement Scheduler Worker Options and Planner Loop
- Added `SchedulerWorkerOptions` class to encapsulate configuration for the scheduler worker. - Introduced `PlannerBackgroundService` to manage the planner loop, fetching and processing planning runs. - Created `PlannerExecutionService` to handle the execution logic for planning runs, including impact targeting and run persistence. - Developed `PlannerExecutionResult` and `PlannerExecutionStatus` to standardize execution outcomes. - Implemented validation logic within `SchedulerWorkerOptions` to ensure proper configuration. - Added documentation for the planner loop and impact targeting features. - Established health check endpoints and authentication mechanisms for the Signals service. - Created unit tests for the Signals API to ensure proper functionality and response handling. - Configured options for authority integration and fallback authentication methods.
This commit is contained in:
@@ -11,28 +11,29 @@ Authority issues short-lived tokens bound to tenants and scopes. Sprint 19 int
|
||||
|
||||
| Scope | Surface | Purpose | Notes |
|
||||
|-------|---------|---------|-------|
|
||||
| `advisory:write` | Concelier ingestion APIs | Allows append-only writes to `advisory_raw`. | Granted to Concelier WebService and trusted connectors. Requires tenant claim. |
|
||||
| `advisory:verify` | Concelier `/aoc/verify`, CLI, UI dashboard | Permits guard verification and access to violation summaries. | Read-only; used by `stella aoc verify` and console dashboard. |
|
||||
| `vex:write` | Excititor ingestion APIs | Append-only writes to `vex_raw`. | Mirrors `advisory:write`. |
|
||||
| `vex:verify` | Excititor `/aoc/verify`, CLI | Read-only verification of VEX ingestion. | Optional for environments without VEX feeds. |
|
||||
| `graph:write` | Cartographer build pipeline | Enqueue graph build/overlay jobs. | Reserved for the Cartographer service identity; requires tenant claim. |
|
||||
| `graph:read` | Graph API, Scheduler overlays, UI | Read graph projections/overlays. | Requires tenant claim; granted to Cartographer, Graph API, Scheduler. |
|
||||
| `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. |
|
||||
| `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`. |
|
||||
| `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 | Allows creation/update of `effective_finding_*` collections. | **Only** the Policy Engine service client may hold this scope. |
|
||||
| `effective:read` | Console, CLI, exports | Read derived findings. | Shared across tenants with role-based restrictions. |
|
||||
| `aoc:dashboard` | Console UI | Access AOC dashboard resources. | Bundles `advisory:verify`/`vex:verify` by default; keep for UI RBAC group mapping. |
|
||||
| `aoc:verify` | Automation service accounts | Execute verification via API without the full dashboard role. | For CI pipelines, offline kit validators. |
|
||||
| Existing scopes | (e.g., `policy:*`, `sbom:*`) | Unchanged. | Review `/docs/security/policy-governance.md` for policy-specific scopes. |
|
||||
| `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. |
|
||||
| `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. |
|
||||
|
||||
### 1.1 Scope bundles (roles)
|
||||
|
||||
- **`role/concelier-ingest`** → `advisory:write`, `advisory:verify`.
|
||||
- **`role/excititor-ingest`** → `vex:write`, `vex:verify`.
|
||||
- **`role/aoc-operator`** → `aoc:dashboard`, `aoc:verify`, `advisory:verify`, `vex:verify`.
|
||||
- **`role/policy-engine`** → `effective:write`, `effective:read`.
|
||||
- **`role/concelier-ingest`** → `advisory:ingest`, `advisory:read`.
|
||||
- **`role/excititor-ingest`** → `vex:ingest`, `vex:read`.
|
||||
- **`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`.
|
||||
|
||||
Roles are declared per tenant in `authority.yaml`:
|
||||
|
||||
@@ -41,11 +42,11 @@ tenants:
|
||||
- name: default
|
||||
roles:
|
||||
concelier-ingest:
|
||||
scopes: [advisory:write, advisory:verify]
|
||||
scopes: [advisory:ingest, advisory:read]
|
||||
aoc-operator:
|
||||
scopes: [aoc:dashboard, aoc:verify, advisory:verify, vex:verify]
|
||||
scopes: [aoc:verify, advisory:read, vex:read]
|
||||
policy-engine:
|
||||
scopes: [effective:write, effective:read]
|
||||
scopes: [effective:write, findings:read]
|
||||
```
|
||||
|
||||
---
|
||||
@@ -62,10 +63,10 @@ Tokens now include:
|
||||
|
||||
Authority rejects requests when:
|
||||
|
||||
- `tenant` is missing while requesting `advisory:*`, `vex:*`, or `aoc:*` scopes.
|
||||
- `tenant` is missing while requesting `advisory:ingest`, `advisory:read`, `vex:ingest`, `vex:read`, or `aoc:verify` scopes.
|
||||
- `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:write` with `effective:write` (separation of duties).
|
||||
- Tokens attempt to combine `advisory:ingest` with `effective:write` (separation of duties).
|
||||
|
||||
### 2.2 Propagation
|
||||
|
||||
@@ -90,22 +91,30 @@ Add new scopes and optional claims transformations:
|
||||
```yaml
|
||||
security:
|
||||
scopes:
|
||||
- name: advisory:write
|
||||
description: Concelier raw ingestion
|
||||
- name: advisory:verify
|
||||
description: Verify Concelier ingestion
|
||||
- name: vex:write
|
||||
- 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:verify
|
||||
description: Verify Excititor ingestion
|
||||
- name: aoc:dashboard
|
||||
description: Access AOC UI dashboards
|
||||
- name: vex:read
|
||||
description: Read Excititor VEX records
|
||||
- name: aoc:verify
|
||||
description: Run AOC verification
|
||||
- name: effective:write
|
||||
description: Policy Engine materialisation
|
||||
- name: effective:read
|
||||
- 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:
|
||||
@@ -119,13 +128,13 @@ security:
|
||||
|
||||
Update service clients:
|
||||
|
||||
- `Concelier.WebService` → request `advisory:write`, `advisory:verify`.
|
||||
- `Excititor.WebService` → request `vex:write`, `vex:verify`.
|
||||
- `Policy.Engine` → request `effective:write`, `effective:read`; set `properties.serviceIdentity=policy-engine`.
|
||||
- `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 `aoc:dashboard`, `effective:read` plus existing UI scopes.
|
||||
- `CLI automation` → request `aoc:verify`, `advisory:verify`, `vex:verify` as needed.
|
||||
- `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:
|
||||
|
||||
@@ -133,11 +142,11 @@ Client definition snippet:
|
||||
clients:
|
||||
- clientId: concelier-web
|
||||
grantTypes: [client_credentials]
|
||||
scopes: [advisory:write, advisory:verify]
|
||||
scopes: [advisory:ingest, advisory:read]
|
||||
tenants: [default]
|
||||
- clientId: policy-engine
|
||||
grantTypes: [client_credentials]
|
||||
scopes: [effective:write, effective:read]
|
||||
scopes: [effective:write, findings:read]
|
||||
properties:
|
||||
serviceIdentity: policy-engine
|
||||
- clientId: cartographer-service
|
||||
@@ -152,7 +161,7 @@ clients:
|
||||
## 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:write` or `vex:write` to mitigate brute-force ingestion attempts.
|
||||
- **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`).
|
||||
@@ -161,7 +170,7 @@ clients:
|
||||
|
||||
## 5 · Offline & air-gap notes
|
||||
|
||||
- Offline Kit bundles include tenant-scoped service credentials. Ensure ingest bundles ship without `advisory:write` scopes unless strictly required.
|
||||
- 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.
|
||||
|
||||
@@ -191,4 +200,4 @@ clients:
|
||||
|
||||
---
|
||||
|
||||
*Last updated: 2025-10-26 (Sprint 19).*
|
||||
*Last updated: 2025-10-27 (Sprint 19).*
|
||||
|
||||
Reference in New Issue
Block a user