feat: Implement Scheduler Worker Options and Planner Loop
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Docs CI / lint-and-preview (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Docs CI / lint-and-preview (push) Has been cancelled
				
			- 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