wip: doctor/cli/docs/api to vector db consolidation; api hardening for descriptions, tenant, and scopes; migrations and conversions of all DALs to EF v10
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
# Sprint 20260222.053 - Multi-Tenant Same-Key Contract Baseline
|
||||
|
||||
## Topic & Scope
|
||||
- Define the canonical architecture for tenant selection with the same API key, including token issuance, tenant claim semantics, gateway header behavior, and UI switching flow.
|
||||
- Freeze a single cross-service contract so Authority, Router, Platform, Scanner, Graph, and Web can implement without drift.
|
||||
- Produce deterministic rollout phases, compatibility windows, and cutover criteria.
|
||||
- Working directory: `docs/`.
|
||||
- Expected evidence: architecture decision record, service contract matrix, sequence diagrams, rollout plan, QA acceptance matrix.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on latest implemented tenant behavior inventory from codebase and module dossiers.
|
||||
- This sprint is the contract baseline for implementation sprints:
|
||||
- `SPRINT_20260222_054_Authority_same_key_multi_tenant_token_selection.md`
|
||||
- `SPRINT_20260222_055_Router_tenant_header_enforcement_and_selection_flow.md`
|
||||
- `SPRINT_20260222_056_Platform_tenant_consistency_for_platform_and_topology_apis.md`
|
||||
- `SPRINT_20260222_057_Scanner_tenant_isolation_for_scans_triage_webhooks.md`
|
||||
- `SPRINT_20260222_058_Graph_tenant_resolution_and_auth_alignment.md`
|
||||
- `SPRINT_20260222_059_FE_global_tenant_selector_and_client_unification.md`
|
||||
- Safe parallelism:
|
||||
- Documentation drafting can proceed in parallel per section owner.
|
||||
- Final publication is serialized after architecture sign-off.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/modules/authority/AUTHORITY.md`
|
||||
- `docs/modules/authority/architecture.md`
|
||||
- `docs/modules/platform/architecture-overview.md`
|
||||
- `docs/modules/ui/console-architecture.md`
|
||||
- `docs/technical/architecture/console-admin-rbac.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### DOC-TEN-01 - Author the architecture decision record for tenant selection model
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Product Manager, Project Manager, Documentation author
|
||||
Task description:
|
||||
- Create an ADR under `docs/architecture/` that selects and justifies the tenant selection model for same API key support.
|
||||
- Decision must cover:
|
||||
- One-tenant-per-token versus multi-tenant-token-with-header-override.
|
||||
- Security properties, replay/spoofing risk profile, operational complexity, and migration burden.
|
||||
- Explicit non-goals and rejected alternatives.
|
||||
|
||||
Completion criteria:
|
||||
- [x] ADR states one selected model and one fallback model with clear rationale.
|
||||
- [x] Threat model section covers header spoofing, token confusion, and cross-tenant leakage risks.
|
||||
- [x] ADR is linked from all module dossiers touched by this initiative.
|
||||
|
||||
### DOC-TEN-02 - Publish canonical identity and header contract
|
||||
Status: DONE
|
||||
Dependency: DOC-TEN-01
|
||||
Owners: Documentation author, Security architect
|
||||
Task description:
|
||||
- Define canonical claims and headers:
|
||||
- Required tenant claim(s), optional allowed-tenants claim, project claim behavior.
|
||||
- Canonical tenant header and compatibility aliases.
|
||||
- Rules for missing tenant, mismatch handling, and default behavior.
|
||||
- Include strict normalization rules and deterministic examples.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Contract defines canonical claim names and canonical header names.
|
||||
- [x] Contract defines compatibility/deprecation rules for legacy headers.
|
||||
- [x] Contract includes request and response examples for success and failure cases.
|
||||
|
||||
### DOC-TEN-03 - Publish service-by-service impact and API change ledger
|
||||
Status: DONE
|
||||
Dependency: DOC-TEN-02
|
||||
Owners: Project Manager, Documentation author
|
||||
Task description:
|
||||
- Create an explicit impact ledger listing required changes by service:
|
||||
- Authority token issuance and client metadata.
|
||||
- Router/Gateway identity propagation and header policy.
|
||||
- Platform/topology context and endpoint classification.
|
||||
- Scanner scan/triage/webhook tenant hardening.
|
||||
- Graph API tenant resolution and auth scope handling.
|
||||
- Web UI selector/state/interceptor/API client changes.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Each service has a change set with file-level touchpoint categories.
|
||||
- [x] Each change set has owner role, dependency, and verification evidence definition.
|
||||
- [x] Ledger maps directly to sprint IDs 054 through 060.
|
||||
|
||||
### DOC-TEN-04 - Define end-to-end flow diagrams and backend call sequences
|
||||
Status: DONE
|
||||
Dependency: DOC-TEN-02
|
||||
Owners: Documentation author, FE lead, Authority lead
|
||||
Task description:
|
||||
- Publish sequence diagrams for:
|
||||
- Sign-in to tenant mapping.
|
||||
- Tenant switch from header selector.
|
||||
- API request propagation through gateway to backend services.
|
||||
- Error/recovery paths for tenant mismatch, tenant missing, and insufficient scope.
|
||||
- Include exact backend calls expected at switch time and cache invalidation points in UI.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Diagrams cover login, switch, API call, and failure recovery flows.
|
||||
- [x] Tenant switch flow explicitly lists Authority and Console API interactions.
|
||||
- [x] Diagram terminology matches final contract naming.
|
||||
|
||||
### DOC-TEN-05 - Define phased rollout and compatibility policy
|
||||
Status: DONE
|
||||
Dependency: DOC-TEN-03
|
||||
Owners: Project Manager, SRE, Documentation author
|
||||
Task description:
|
||||
- Create rollout phases with entry and exit gates:
|
||||
- Phase 0 docs and feature flags.
|
||||
- Phase 1 Authority + Gateway compat mode.
|
||||
- Phase 2 service migrations.
|
||||
- Phase 3 FE selector rollout.
|
||||
- Phase 4 strict mode and legacy removal.
|
||||
- Include rollback playbook and observability checkpoints.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Each phase has explicit deploy order and rollback criteria.
|
||||
- [x] Compatibility window for legacy headers/claims is dated and bounded.
|
||||
- [x] Production readiness checklist is included.
|
||||
|
||||
### DOC-TEN-06 - Define acceptance matrix and evidence contract for QA
|
||||
Status: DONE
|
||||
Dependency: DOC-TEN-04
|
||||
Owners: QA, Test Automation, Documentation author
|
||||
Task description:
|
||||
- Publish a deterministic acceptance matrix:
|
||||
- APIs requiring tenant enforcement.
|
||||
- Expected status codes for valid/missing/mismatched tenant.
|
||||
- Cross-tenant negative tests.
|
||||
- UI page-level behavior under tenant switching.
|
||||
- Define required artifacts: test outputs, traces, logs, and screenshots.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Matrix includes Platform, Scanner, Topology, and Graph high-value paths.
|
||||
- [x] UI matrix enumerates all primary pages and expected tenant context behavior.
|
||||
- [x] Matrix is referenced by sprint 060 and module-specific test tasks.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-22 | Sprint created; awaiting staffing. | Planning |
|
||||
| 2026-02-22 | Published ADR and canonical claim/header contract in `docs/architecture/decisions/ADR-002-multi-tenant-same-api-key-selection.md`; linked from Authority/Router/Console architecture docs. | Developer |
|
||||
| 2026-02-22 | Completed DOC-TEN-03 and published service impact ledger: `docs/technical/architecture/multi-tenant-service-impact-ledger.md`. | Developer |
|
||||
| 2026-02-22 | Completed DOC-TEN-04 and published sequence diagrams/call flows: `docs/technical/architecture/multi-tenant-flow-sequences.md`. | Developer |
|
||||
| 2026-02-22 | Completed DOC-TEN-05 and published rollout/compat policy: `docs/operations/multi-tenant-rollout-and-compatibility.md`. | Developer |
|
||||
| 2026-02-22 | Completed DOC-TEN-06 and published QA acceptance matrix: `docs/qa/feature-checks/multi-tenant-acceptance-matrix.md` (consumed by sprint 060). | Developer |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision: tenant selection for same API key support is one-selected-tenant-per-token, resolved by Authority at token issuance.
|
||||
- Decision resolved in `docs/architecture/decisions/ADR-002-multi-tenant-same-api-key-selection.md`: one selected tenant per token with issuance-time tenant selection and assignment validation.
|
||||
- Decision: DOC-TEN-03 through DOC-TEN-06 are now the canonical contract pack for implementation sprints 054-060 (`multi-tenant-service-impact-ledger`, `multi-tenant-flow-sequences`, `multi-tenant-rollout-and-compatibility`, `multi-tenant-acceptance-matrix`).
|
||||
- Risk: If model is not finalized before implementation starts, module behavior can diverge and increase rework.
|
||||
- Risk: Header compatibility windows that are too long can preserve insecure legacy patterns.
|
||||
- Mitigation: enforce phase gates and require ADR link in every implementation PR.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-23: ADR draft and contract skeleton complete.
|
||||
- 2026-02-24: cross-module review and sign-off.
|
||||
- 2026-02-25: rollout and QA acceptance matrix published.
|
||||
@@ -0,0 +1,167 @@
|
||||
# Sprint 20260222.054 - Authority Same-Key Multi-Tenant Token Selection
|
||||
|
||||
## Topic & Scope
|
||||
- Implement Authority support for selecting tenant context while reusing the same API key/client registration.
|
||||
- Preserve one-tenant-per-token semantics while enabling tenant choice at token issuance time.
|
||||
- Upgrade console and admin APIs to expose and manage multi-tenant client assignments.
|
||||
- Working directory: `src/Authority/`.
|
||||
- Cross-module edits explicitly allowed for this sprint: `docs/modules/authority`, `docs/technical/architecture`.
|
||||
- Expected evidence: targeted Authority handler tests, console/admin API tests, migration fixtures, updated module docs.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on sprint `20260222.053` contract finalization.
|
||||
- Upstream for Router and FE switching flows.
|
||||
- Safe parallelism:
|
||||
- Client metadata contract implementation can run in parallel with console/admin endpoint DTO updates.
|
||||
- Token issuance and token validation changes must be merged together.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/modules/authority/AUTHORITY.md`
|
||||
- `docs/modules/authority/architecture.md`
|
||||
- `docs/technical/architecture/console-admin-rbac.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### AUTH-TEN-01 - Extend Authority client metadata contract for multi-tenant assignment
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Extend Authority client metadata schema to support multiple tenant assignments for one client.
|
||||
- Keep backward compatibility with existing scalar `tenant` metadata.
|
||||
- Add deterministic normalization rules:
|
||||
- Trim/lowercase tenant IDs.
|
||||
- Remove duplicates.
|
||||
- Stable lexical ordering for persistence and comparison.
|
||||
- Update contracts in plugin abstractions and bootstrap payload models.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Client metadata supports multi-tenant assignment without breaking existing clients.
|
||||
- [x] Scalar `tenant` registrations continue to work unchanged.
|
||||
- [x] Normalization and ordering rules are covered by unit tests.
|
||||
|
||||
### AUTH-TEN-02 - Update provisioning stores and persistence adapters
|
||||
Status: DONE
|
||||
Dependency: AUTH-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Update Standard and LDAP provisioning stores to read/write multi-tenant client assignments.
|
||||
- Ensure bootstrap and admin-created clients persist the same contract shape.
|
||||
- Add deterministic migration behavior from scalar tenant metadata to multi-tenant metadata.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Standard provisioning path persists and reloads multi-tenant assignments.
|
||||
- [x] LDAP provisioning path persists and reloads multi-tenant assignments.
|
||||
- [x] Migration logic is deterministic and test-covered.
|
||||
|
||||
### AUTH-TEN-03 - Add tenant selection parameter to token issuance flows
|
||||
Status: DONE
|
||||
Dependency: AUTH-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Add tenant selection input to token issuance (client credentials and password grant).
|
||||
- Validate requested tenant against client-assigned tenant set.
|
||||
- If requested tenant is omitted:
|
||||
- Use a deterministic default selection rule defined in sprint 053 contract.
|
||||
- Reject ambiguous selection when no deterministic default exists.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Token endpoint accepts tenant selection input for supported grants.
|
||||
- [x] Requested tenant outside assigned set is rejected with deterministic error.
|
||||
- [x] Ambiguous/no-tenant requests fail with deterministic error and audit event.
|
||||
|
||||
### AUTH-TEN-04 - Emit and persist selected tenant claim deterministically
|
||||
Status: DONE
|
||||
Dependency: AUTH-TEN-03
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Ensure each issued token contains exactly one selected tenant claim.
|
||||
- Persist selected tenant on token records and rate-limit metadata for auditing.
|
||||
- Preserve one-tenant-per-token invariants to keep downstream services unchanged.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Issued tokens carry a single selected tenant claim.
|
||||
- [x] Token persistence records selected tenant.
|
||||
- [x] Existing consumer services remain compatible with tenant claim shape.
|
||||
|
||||
### AUTH-TEN-05 - Harden token validation against client tenant assignments
|
||||
Status: DONE
|
||||
Dependency: AUTH-TEN-04
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Update token validation handlers to enforce that selected tenant claim is valid for the issuing client.
|
||||
- Maintain rejection of tenant mismatch across principal, token document, and client registration.
|
||||
- Ensure deterministic error codes/messages for mismatch and missing-tenant cases.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Validation rejects tokens whose selected tenant is not assigned to client.
|
||||
- [x] Validation behavior is backward compatible for legacy scalar-tenant clients.
|
||||
- [x] Failure cases emit auditable events with tenant/client identifiers.
|
||||
|
||||
### AUTH-TEN-06 - Update console tenant catalog endpoint behavior
|
||||
Status: DONE
|
||||
Dependency: AUTH-TEN-03
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Change `/console/tenants` to return the full allowed tenant set for the authenticated principal/client context.
|
||||
- Include selected tenant marker in response payload for UI selector hydration.
|
||||
- Keep tenant mismatch protections in endpoint filter.
|
||||
|
||||
Completion criteria:
|
||||
- [x] `/console/tenants` returns all allowed tenants, not selected-only singleton.
|
||||
- [x] Response includes selected tenant context for immediate UI use.
|
||||
- [x] Unauthorized/mismatched tenant requests continue to fail deterministically.
|
||||
|
||||
### AUTH-TEN-07 - Extend admin client CRUD for multi-tenant assignment
|
||||
Status: DONE
|
||||
Dependency: AUTH-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Extend `/console/admin/clients` DTOs and handlers so admins can view and edit client tenant assignments.
|
||||
- Add validation for empty assignment, invalid tenant IDs, and duplicates.
|
||||
- Record admin audit events with before/after tenant assignment summaries.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Admin APIs support create/update/read of multi-tenant client assignments.
|
||||
- [x] Validation rejects malformed tenant assignment payloads.
|
||||
- [x] Admin audit events capture assignment changes.
|
||||
|
||||
### AUTH-TEN-08 - Targeted test suite for tenant selection behavior
|
||||
Status: DONE
|
||||
Dependency: AUTH-TEN-03
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add tests for:
|
||||
- Client credentials tenant selection success/failure.
|
||||
- Password grant tenant selection success/failure.
|
||||
- Token validation tenant mismatch rules.
|
||||
- Console `/console/tenants` response shape and selection marker.
|
||||
- Admin client assignment CRUD behavior.
|
||||
- Run tests against specific `.csproj` files to ensure targeted evidence.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Targeted handler and endpoint tests pass on individual test projects.
|
||||
- [x] Negative-path tests validate deterministic error codes.
|
||||
- [x] Evidence includes tests run counts and key output snippets.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-22 | Sprint created; awaiting staffing. | Planning |
|
||||
| 2026-02-22 | Implemented multi-tenant client metadata (`tenant` + `tenants`), deterministic tenant selection for client credentials/password grants, assignment-aware token validation, and `/console/tenants` selected+allowed response model. Added focused tests in Authority, Standard provisioning, and LDAP provisioning projects. | Developer |
|
||||
| 2026-02-22 | Completed AUTH-TEN-07 admin CRUD assignment validation/audit coverage in `src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/Console/ConsoleAdminEndpointsTests.cs` including missing/invalid assignment negative cases. | Developer |
|
||||
| 2026-02-22 | Completed AUTH-TEN-08 targeted evidence runs and captured logs in `docs/qa/feature-checks/runs/multi-tenant-same-api-key-selection/run-001/evidence/authority-*.txt` (admin assignments `8/8`, selected marker `1/1`, token selection `8/8`). | Test Automation |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision: keep one selected tenant per token to minimize downstream change surface.
|
||||
- Risk: mixed scalar/multi-tenant metadata during migration can cause inconsistent selection behavior.
|
||||
- Mitigation: strict normalization and deterministic default-selection rules with migration tests.
|
||||
- Risk: admin API implementation placeholders can hide partial delivery.
|
||||
- Mitigation: require explicit DTO and persistence assertions in completion criteria.
|
||||
- Risk: `dotnet test` filter flags are ignored under Microsoft.Testing.Platform in this repo (`MTP0001`), so targeted test selection can run broader suites than intended.
|
||||
- Mitigation: run focused project-level test commands and service/test-project builds; avoid solution-wide test invocations during this phase.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-24: metadata contract and provisioning updates merged.
|
||||
- 2026-02-25: token issuance/validation updates merged.
|
||||
- 2026-02-26: console/admin endpoints and tests complete.
|
||||
@@ -0,0 +1,135 @@
|
||||
# Sprint 20260222.055 - Router Tenant Header Enforcement and Selection Flow
|
||||
|
||||
## Topic & Scope
|
||||
- Align Router/Gateway tenant propagation to the new Authority contract for selected-tenant tokens.
|
||||
- Enforce canonical tenant header behavior and eliminate ambiguous tenant fallback paths.
|
||||
- Preserve anti-spoofing controls while supporting tenant switch flows initiated by UI/API clients.
|
||||
- Working directory: `src/Router/`.
|
||||
- Cross-module edits explicitly allowed for this sprint: `src/Gateway/`, `docs/modules/router`, `docs/technical/architecture`.
|
||||
- Expected evidence: middleware unit tests, integration tests for spoof/mismatch, updated gateway configuration docs.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on sprint `20260222.053` header/claim contract.
|
||||
- Depends on sprint `20260222.054` selected-tenant token issuance behavior.
|
||||
- Safe parallelism:
|
||||
- Header stripping/refill hardening can run in parallel with configuration/documentation updates.
|
||||
- `src/Router` and `src/Gateway` mirror changes can run in parallel but must be merged atomically.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/modules/router/architecture.md`
|
||||
- `docs/modules/router/webservice-integration-guide.md`
|
||||
- `docs/technical/architecture/console-admin-rbac.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### ROUTER-TEN-01 - Canonicalize tenant extraction and remove ambiguous defaults
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Update identity middleware extraction rules:
|
||||
- Authenticated requests must resolve tenant from validated claims.
|
||||
- Legacy claim fallback remains compatibility-only and clearly bounded.
|
||||
- Remove implicit `"default"` tenant fallback for authenticated requests.
|
||||
- Keep explicit behavior for anonymous/system paths as defined by contract.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Authenticated requests without valid tenant claim are rejected deterministically.
|
||||
- [x] Compatibility claim fallback behavior is bounded and documented.
|
||||
- [x] No silent default tenant assignment occurs on authenticated requests.
|
||||
|
||||
### ROUTER-TEN-02 - Keep strict anti-spoofing and add tenant-override attempt telemetry
|
||||
Status: DONE
|
||||
Dependency: ROUTER-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Preserve stripping of inbound identity headers (`X-StellaOps-*`, legacy aliases, raw claim headers, auth headers).
|
||||
- Add structured telemetry when client supplied tenant headers are stripped or conflict with claim-derived tenant.
|
||||
- Ensure telemetry includes route, actor/subject, and requested versus resolved tenant values where available.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Spoofed inbound tenant headers are always stripped on protected routes.
|
||||
- [x] Override attempts are observable in deterministic log fields.
|
||||
- [x] Existing security regression tests remain green.
|
||||
|
||||
### ROUTER-TEN-03 - Define optional override path behind feature flag (disabled by default)
|
||||
Status: DONE
|
||||
Dependency: ROUTER-TEN-01
|
||||
Owners: Developer, Security architect
|
||||
Task description:
|
||||
- Implement a feature-flagged path for per-request tenant override only if explicitly enabled by policy.
|
||||
- Override validation must require an allow-list claim/attribute and exact match check.
|
||||
- Default behavior remains claim-derived tenant with no override.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Override path is off by default.
|
||||
- [x] Enabled path validates requested tenant against explicit allow-list claim/metadata.
|
||||
- [x] Invalid override requests fail with deterministic status and audit metadata.
|
||||
|
||||
### ROUTER-TEN-04 - Synchronize `src/Router` and `src/Gateway` middleware implementations
|
||||
Status: DONE
|
||||
Dependency: ROUTER-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Eliminate behavioral drift between duplicate gateway middleware stacks in `src/Router` and `src/Gateway`.
|
||||
- Apply identical tenant extraction, header write, and security stripping logic.
|
||||
- Add parity tests or shared fixtures to prevent future divergence.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant behavior is functionally identical between both gateway codepaths.
|
||||
- [x] Tests detect divergence in canonical header and claim handling.
|
||||
- [x] Both program startup paths load consistent middleware options.
|
||||
|
||||
### ROUTER-TEN-05 - Update passthrough and route policy for tenant switch flows
|
||||
Status: DONE
|
||||
Dependency: ROUTER-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Validate JWT passthrough prefixes and route policies for Authority endpoints used during tenant switch.
|
||||
- Ensure gateway preserves required auth headers only on approved passthrough routes.
|
||||
- Prevent passthrough routes from weakening tenant/header stripping on normal API paths.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant switch-related Authority routes work through gateway with required auth headers.
|
||||
- [x] Non-passthrough routes keep strict header stripping behavior.
|
||||
- [x] Configuration defaults remain secure.
|
||||
|
||||
### ROUTER-TEN-06 - Add targeted middleware and route integration tests
|
||||
Status: DONE
|
||||
Dependency: ROUTER-TEN-02
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add tests for:
|
||||
- Missing tenant claim behavior.
|
||||
- Claim/header mismatch behavior.
|
||||
- Spoofed header stripping.
|
||||
- Optional override feature flag disabled/enabled scenarios.
|
||||
- Mirror tests in both gateway codepaths where applicable.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Positive and negative tenant propagation paths are covered.
|
||||
- [x] Tests run against targeted gateway test projects.
|
||||
- [x] Evidence includes deterministic outputs for mismatch and spoof scenarios.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-22 | Sprint created; awaiting staffing. | Planning |
|
||||
| 2026-02-22 | Removed authenticated default tenant fallback in `IdentityHeaderPolicyMiddleware` and added middleware regression coverage for authenticated requests without tenant claims. | Developer |
|
||||
| 2026-02-22 | Implemented tenant override telemetry + fail-closed override path behind `EnableTenantOverride`; synced middleware behavior across `src/Router` and `src/Gateway`. | Developer |
|
||||
| 2026-02-22 | Added passthrough allow-list tests and override tests in both gateway codepaths; validated with scoped builds and test projects (`Router` 238 pass, `Gateway` 265 pass). | Test Automation |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision: canonical behavior remains claim-derived tenant with strict header rewrite.
|
||||
- Decision: auth header passthrough remains double-gated by configured route prefix (`PreserveAuthHeaders`) and hardcoded approved prefix allow-list.
|
||||
- Risk: keeping duplicate gateway implementations can reintroduce tenant drift.
|
||||
- Mitigation: enforce parity tests and mirror-change checklist.
|
||||
- Risk: optional override path can weaken isolation if enabled broadly.
|
||||
- Mitigation: ship disabled-by-default with explicit allow-list validation and audit requirements.
|
||||
- Documentation sync:
|
||||
- `docs/modules/router/architecture.md`
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-24: canonical extraction/default removal complete.
|
||||
- 2026-02-25: parity sync and passthrough validation complete.
|
||||
- 2026-02-26: targeted test matrix complete.
|
||||
@@ -0,0 +1,140 @@
|
||||
# Sprint 20260222.056 - Platform Tenant Consistency for Platform and Topology APIs
|
||||
|
||||
## Topic & Scope
|
||||
- Ensure tenant handling is consistent across Platform APIs, with specific focus on topology and context-sensitive read models.
|
||||
- Classify and harden endpoint groups that currently bypass the standard request context resolver.
|
||||
- Guarantee explicit tenant behavior for setup/admin/system endpoints.
|
||||
- Working directory: `src/Platform/`.
|
||||
- Cross-module edits explicitly allowed for this sprint: `docs/modules/platform`, `docs/technical/architecture`.
|
||||
- Expected evidence: endpoint tenant-classification ledger, resolver/endpoint updates, integration tests for cross-tenant isolation.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on sprint `20260222.053` canonical claim/header contract.
|
||||
- Depends on sprint `20260222.055` gateway propagation semantics.
|
||||
- Safe parallelism:
|
||||
- Endpoint classification and read-model hardening can run in parallel.
|
||||
- Setup/admin endpoint semantics and docs can run in parallel with test creation.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/modules/platform/architecture-overview.md`
|
||||
- `docs/modules/platform/reference-architecture-card.md`
|
||||
- `docs/modules/ui/console-architecture.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### PLAT-TEN-01 - Build endpoint tenant-behavior classification ledger
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer, Project Manager
|
||||
Task description:
|
||||
- Classify all Platform endpoints into:
|
||||
- Tenant-required business endpoints.
|
||||
- Tenant-aware admin endpoints.
|
||||
- Explicitly global/system endpoints.
|
||||
- For each endpoint group, record expected tenant source, required auth policy, and accepted headers.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Every endpoint file in `src/Platform/StellaOps.Platform.WebService/Endpoints` is classified.
|
||||
- [x] Classification includes explicit rationale for non-resolver endpoints.
|
||||
- [x] Ledger is linked in this sprint execution log.
|
||||
|
||||
### PLAT-TEN-02 - Harden request context resolver semantics
|
||||
Status: DONE
|
||||
Dependency: PLAT-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Ensure resolver semantics align with canonical contract:
|
||||
- Claim-first for authenticated flows.
|
||||
- Canonical header compatibility handling.
|
||||
- Legacy header behavior explicitly bounded.
|
||||
- Ensure resolver failures produce deterministic error payloads.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Resolver behavior is consistent with contract for authenticated and compatibility modes.
|
||||
- [x] Error outputs are deterministic and test-covered.
|
||||
- [x] No endpoint silently proceeds with unresolved tenant context.
|
||||
|
||||
### PLAT-TEN-03 - Align tenant-required endpoints to resolver usage
|
||||
Status: DONE
|
||||
Dependency: PLAT-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Apply resolver usage uniformly to tenant-required endpoint groups.
|
||||
- For endpoints intentionally outside resolver (environment settings, setup bootstrap, migration admin, seed), add explicit tenant policy and rationale.
|
||||
- Eliminate accidental tenant bypass paths.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant-required endpoints use resolver + explicit authorization.
|
||||
- [x] Intentional non-resolver endpoints are documented and policy-guarded.
|
||||
- [x] Endpoint behavior remains backward compatible where intended.
|
||||
|
||||
### PLAT-TEN-04 - Verify topology and read-model services are tenant-keyed end-to-end
|
||||
Status: DONE
|
||||
Dependency: PLAT-TEN-02
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Trace topology and related read-model queries to confirm tenant key propagation at every storage call.
|
||||
- Add guardrails for any store/query path that can execute without tenant key.
|
||||
- Ensure query parameter global filters (region/env/time/stage) cannot bypass tenant scoping.
|
||||
|
||||
Completion criteria:
|
||||
- [x] All topology data access paths are tenant-keyed.
|
||||
- [x] No cross-tenant data path remains for read-model endpoints.
|
||||
- [x] Regression tests demonstrate tenant isolation across identical resource identifiers.
|
||||
|
||||
### PLAT-TEN-05 - Normalize context preference behavior for selected tenant
|
||||
Status: DONE
|
||||
Dependency: PLAT-TEN-03
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Ensure context preference load/save behavior is deterministic per tenant and actor.
|
||||
- Validate preference endpoint behavior when tenant switches occur.
|
||||
- Confirm context APIs return tenant-identifying metadata required by FE state synchronization.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Preferences remain isolated by tenant and actor pair.
|
||||
- [x] Tenant switch does not leak prior tenant preferences.
|
||||
- [x] Response shape supports FE tenant switch cache invalidation.
|
||||
|
||||
### PLAT-TEN-06 - Add targeted tenant isolation integration tests
|
||||
Status: DONE
|
||||
Dependency: PLAT-TEN-04
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add integration tests for:
|
||||
- Topology endpoints with two tenants and overlapping entity IDs.
|
||||
- Context preferences across tenant switches.
|
||||
- Setup/admin endpoint policy behavior for tenant-required versus system routes.
|
||||
- Run tests on targeted Platform webservice test project.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Cross-tenant read isolation tests pass.
|
||||
- [x] Preference isolation tests pass.
|
||||
- [x] Admin/system endpoint behavior is verified and deterministic.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-22 | Sprint created; awaiting staffing. | Planning |
|
||||
| 2026-02-22 | Published endpoint classification ledger: `docs/modules/platform/tenant-endpoint-classification.md`. | Project Manager |
|
||||
| 2026-02-22 | Hardened `PlatformRequestContextResolver` for claim/header conflict detection (`tenant_conflict`) and bounded legacy claim/header fallback. | Developer |
|
||||
| 2026-02-22 | Added tenant parity checks on tenant-parameter routes in `PlatformEndpoints` (`tenant_forbidden` on mismatch). | Developer |
|
||||
| 2026-02-22 | Added tenant isolation coverage for topology, context preferences, resolver semantics, and system endpoint behavior (`dotnet test src/Platform/__Tests/StellaOps.Platform.WebService.Tests/StellaOps.Platform.WebService.Tests.csproj --no-build`). | Test Automation |
|
||||
| 2026-02-23 | Ran tenant-column API parity audit pass across Platform migrations + WebService SQL paths; no additional API tenant-scope gaps found for tenant-column tables. | Developer |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision: topology and platform read models remain strictly tenant-keyed regardless of global context filters.
|
||||
- Decision: path-parameter tenant routes must equal resolved tenant context unless an explicit admin override contract is introduced.
|
||||
- Risk: setup/admin endpoints can become implicit bypasses if semantics are not explicit.
|
||||
- Mitigation: endpoint classification ledger plus policy assertions in tests.
|
||||
- Risk: compatibility handling for legacy headers may reintroduce ambiguous tenant behavior.
|
||||
- Mitigation: bound compatibility mode and add deprecation telemetry.
|
||||
- Documentation sync:
|
||||
- `docs/modules/platform/tenant-endpoint-classification.md`
|
||||
- `docs/modules/platform/architecture-overview.md`
|
||||
- Audit update (2026-02-23): static SQL parity scan over Platform WebService found no unscoped API reads/writes against tenant-column tables.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-24: endpoint classification and resolver hardening complete.
|
||||
- 2026-02-25: topology/read-model verification complete.
|
||||
- 2026-02-26: integration tests and documentation updates complete.
|
||||
@@ -0,0 +1,256 @@
|
||||
# Sprint 20260222.057 - Scanner Tenant Isolation for Scans, Triage, and Webhooks
|
||||
|
||||
## Topic & Scope
|
||||
- Close Scanner tenant isolation gaps across scan submission, scan identity, triage queries, middleware partitioning, and webhook intake.
|
||||
- Align Scanner claim/header handling with canonical tenant contract.
|
||||
- Ensure all mapped endpoints are intentionally registered and policy-protected.
|
||||
- Working directory: `src/Scanner/`.
|
||||
- Cross-module edits explicitly allowed for this sprint: `docs/modules/scanner`, `docs/technical/architecture`.
|
||||
- Expected evidence: domain/service refactor diffs, endpoint registration audit, targeted tests for cross-tenant isolation and webhook scoping.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on sprint `20260222.053` canonical tenant contract.
|
||||
- Depends on sprint `20260222.055` gateway propagation semantics.
|
||||
- Safe parallelism:
|
||||
- Scan identity/coordinator refactor can run in parallel with triage service hardening.
|
||||
- Middleware claim unification can run in parallel with webhook tenancy changes.
|
||||
- Final endpoint registration audit must run after all endpoint changes.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/modules/scanner/scanner-core-contracts.md`
|
||||
- `docs/modules/scanner/operations/secret-leak-detection.md`
|
||||
- `docs/modules/scanner/design/replay-pipeline-contract.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### SCAN-TEN-01 - Introduce canonical tenant context extraction in Scanner webservice
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Add a shared tenant context resolver for Scanner request paths.
|
||||
- Standardize claim lookup to canonical claim names, with compatibility aliases only where contract permits.
|
||||
- Replace ad hoc tenant extraction in middleware and endpoints.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Scanner has one shared tenant context resolver path.
|
||||
- [x] Canonical claim extraction is used across endpoints and middleware.
|
||||
- [x] Compatibility aliases are explicit and bounded.
|
||||
|
||||
### SCAN-TEN-02 - Add tenant to scan submission domain and identity generation
|
||||
Status: DONE
|
||||
Dependency: SCAN-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Extend `ScanSubmission` to carry tenant identifier.
|
||||
- Include tenant in deterministic scan ID generation canonical string.
|
||||
- Update coordinator indexing so scan lookup is tenant-scoped for digest/reference collisions.
|
||||
|
||||
Completion criteria:
|
||||
- [x] `ScanSubmission` includes tenant context.
|
||||
- [x] Scan ID derivation includes tenant and remains deterministic.
|
||||
- [x] Digest/reference indexes are tenant-aware and test-covered.
|
||||
|
||||
### SCAN-TEN-03 - Propagate tenant through scan endpoints and coordinator calls
|
||||
Status: DONE
|
||||
Dependency: SCAN-TEN-02
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Update scan submission/status/replay/entropy paths to use tenant-aware resolution and coordinator operations.
|
||||
- Validate scan ownership on read/update operations.
|
||||
- Ensure response payloads and telemetry include tenant context consistently.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Scan endpoint operations enforce tenant ownership.
|
||||
- [x] Cross-tenant scan ID access is rejected deterministically.
|
||||
- [x] Telemetry includes resolved tenant in structured fields.
|
||||
|
||||
### SCAN-TEN-04 - Harden triage query/service layer for tenant isolation
|
||||
Status: DONE
|
||||
Dependency: SCAN-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Update triage query interfaces and implementations to require tenant context in retrieval/update operations.
|
||||
- Eliminate finding-ID-only lookups that can cross tenant boundaries.
|
||||
- Update triage endpoint handlers to pass resolved tenant context explicitly.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Triage query interfaces require tenant input.
|
||||
- [x] Triage DB queries filter by tenant.
|
||||
- [x] Cross-tenant finding access is blocked and test-covered.
|
||||
|
||||
### SCAN-TEN-05 - Remove hardcoded tenant from callgraph ingestion
|
||||
Status: DONE
|
||||
Dependency: SCAN-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Replace static tenant GUID in callgraph ingestion with resolved tenant context.
|
||||
- Ensure persistence keys and deduplication constraints remain tenant-scoped.
|
||||
- Add negative tests for cross-tenant ingestion collisions.
|
||||
|
||||
Completion criteria:
|
||||
- [x] No hardcoded tenant constants remain in callgraph ingestion path.
|
||||
- [x] Ingestion writes/reads are tenant-bound.
|
||||
- [x] Cross-tenant collision tests pass.
|
||||
|
||||
### SCAN-TEN-06 - Unify idempotency and rate limiter tenant partition keys
|
||||
Status: DONE
|
||||
Dependency: SCAN-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Align idempotency middleware and rate limiter partitioning to canonical tenant claim/context.
|
||||
- Remove inconsistent `tenant_id`-only reliance where canonical claim is authoritative.
|
||||
- Keep deterministic fallback behavior for truly unauthenticated routes.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Idempotency and rate limiting use consistent tenant partition logic.
|
||||
- [x] Partition behavior is deterministic for authenticated and anonymous scenarios.
|
||||
- [x] Middleware tests cover canonical and fallback paths.
|
||||
|
||||
### SCAN-TEN-07 - Scope webhook source resolution by tenant
|
||||
Status: DONE
|
||||
Dependency: SCAN-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Replace cross-tenant source-name search behavior with tenant-scoped lookup.
|
||||
- Define tenant derivation for webhook routes (path/header/claim) per contract.
|
||||
- Ensure signature validation and dispatcher paths preserve tenant scope.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Webhook source lookup is tenant-scoped.
|
||||
- [x] Cross-tenant source-name collisions cannot dispatch to wrong tenant.
|
||||
- [x] Webhook integration tests cover tenant collision scenarios.
|
||||
|
||||
### SCAN-TEN-08 - Reconcile endpoint registration and policy coverage
|
||||
Status: DONE
|
||||
Dependency: SCAN-TEN-03
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Audit all `Map*Endpoints` definitions versus `Program.cs` registration calls.
|
||||
- Register or remove orphan endpoint maps intentionally.
|
||||
- Ensure each registered endpoint has explicit authorization policy or explicit anonymous rationale.
|
||||
|
||||
Completion criteria:
|
||||
- [x] No accidental orphan endpoint map methods remain.
|
||||
- [x] Registered endpoint surface is intentional and documented.
|
||||
- [x] Authorization posture is explicit for each endpoint group.
|
||||
|
||||
### SCAN-TEN-09 - Add targeted Scanner tenant isolation tests
|
||||
Status: DONE
|
||||
Dependency: SCAN-TEN-04
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add focused tests for:
|
||||
- Scan submission/status ownership.
|
||||
- Triage finding isolation.
|
||||
- Webhook tenant routing and source collisions.
|
||||
- Middleware partitioning behavior.
|
||||
- Run targeted test projects to capture feature-specific evidence.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant isolation tests pass for scans, triage, and webhooks.
|
||||
- [x] Negative tests validate deterministic failures for cross-tenant attempts.
|
||||
- [x] Evidence includes raw targeted test command outputs.
|
||||
|
||||
### SCAN-TEN-10 - Activate tenant-scoped Unknowns endpoint group
|
||||
Status: DONE
|
||||
Dependency: SCAN-TEN-08
|
||||
Owners: Developer, Test Automation
|
||||
Task description:
|
||||
- Replace Scanner Unknowns endpoint implementation with tenant-aware request context handling.
|
||||
- Introduce a Scanner-local Unknowns query service with tenant-filtered data access predicates.
|
||||
- Register Unknowns DI + endpoint map in `Program.cs` and remove compile-time endpoint exclusion.
|
||||
- Add focused tests for cross-tenant Unknown detail isolation and tenant-header conflict failures.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Unknowns endpoint group is registered intentionally in Scanner `Program.cs`.
|
||||
- [x] Unknowns query path requires tenant context and filters by tenant.
|
||||
- [x] Focused unit tests cover cross-tenant detail lookup and tenant conflict rejection.
|
||||
|
||||
### SCAN-TEN-11 - Propagate tenant context through SmartDiff and Reachability persistence adapters
|
||||
Status: DONE
|
||||
Dependency: SCAN-TEN-09
|
||||
Owners: Developer, Test Automation
|
||||
Task description:
|
||||
- Eliminate fixed-tenant repository behavior for SmartDiff and Reachability data paths that already have tenant discriminator columns.
|
||||
- Pass resolved tenant context from API handlers into repository methods and SQL predicates for tenant-scoped tables.
|
||||
- Add focused tests proving SmartDiff candidate and Reachability drift sink access are isolated across tenants.
|
||||
|
||||
Completion criteria:
|
||||
- [x] SmartDiff endpoints pass resolved tenant context into material-change and VEX-candidate stores.
|
||||
- [x] Reachability drift endpoints pass resolved tenant context into snapshot/code-change/drift stores.
|
||||
- [x] Focused tests prove cross-tenant SmartDiff/drift isolation and deterministic failures.
|
||||
|
||||
### SCAN-TEN-12 - Remove remaining fixed-tenant storage adapters for tenant-scoped tables
|
||||
Status: DONE
|
||||
Dependency: SCAN-TEN-11
|
||||
Owners: Developer, Test Automation
|
||||
Task description:
|
||||
- Audit Scanner storage adapters for tenant-partitioned tables still bound to hardcoded tenant context.
|
||||
- Convert affected adapters (`risk_state_snapshots`, `reachability_results`) to resolved tenant scope inputs and tenant-aware in-memory parity behavior.
|
||||
- Add focused storage integration coverage proving cross-tenant isolation for risk-state and reachability result retrieval paths.
|
||||
|
||||
Completion criteria:
|
||||
- [x] `PostgresRiskStateRepository` resolves tenant scope per call and no longer uses fixed tenant constants.
|
||||
- [x] `PostgresReachabilityResultRepository` resolves tenant scope per call and no longer uses fixed tenant constants.
|
||||
- [x] Storage integration tests prove tenant isolation for both adapters.
|
||||
|
||||
### SCAN-TEN-13 - Enforce tenant-argument usage for API-backed tenant tables
|
||||
Status: DONE
|
||||
Dependency: SCAN-TEN-12
|
||||
Owners: Developer, Test Automation
|
||||
Task description:
|
||||
- Audit API-backed Scanner tables that include tenant discriminator columns and verify repository method signatures carry tenant arguments end-to-end.
|
||||
- Remove ID-only lookups for tenant-partitioned source-run and secret-exception paths.
|
||||
- Add focused tests proving tenant-scoped lookup enforcement on updated service/repository contracts.
|
||||
|
||||
Completion criteria:
|
||||
- [x] `scanner.sbom_source_runs` API paths (`/sources/{sourceId}/runs`, `/sources/{sourceId}/runs/{runId}`) pass tenant argument into repository filters.
|
||||
- [x] `secret_exception_pattern` API paths use tenant-scoped repository predicates for get/update/delete.
|
||||
- [x] Focused tests cover tenant-scoped source-run and secret-exception service behavior.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-22 | Sprint created; awaiting staffing. | Planning |
|
||||
| 2026-02-22 | Implemented shared tenant resolver adoption across scan/source/offline/report dispatch paths; removed Scanner-specific ad hoc tenant parsing in middleware and endpoints. | Developer |
|
||||
| 2026-02-22 | Made scan submission + scan identity tenant-aware end-to-end (submission model, snapshot model, scan id generation, coordinator target indexes/authorization checks). | Developer |
|
||||
| 2026-02-22 | Removed hardcoded callgraph tenant GUID; callgraph ingestion and dedupe now take resolved scan tenant context. | Developer |
|
||||
| 2026-02-22 | Scoped name-based webhook source resolution to tenant and added deterministic unit coverage for tenant resolver + webhook tenant lookup behavior (6 tests passed via xUnit class filter). | Test Automation |
|
||||
| 2026-02-22 | Completed endpoint registration audit: registered tenant-sensitive source/webhook endpoint groups in `Program.cs`, wired source service DI chain (including safe null credential resolver), and documented active/deferred endpoint map intent in `docs/modules/scanner/endpoint-registration-matrix.md`. | Developer |
|
||||
| 2026-02-22 | Added targeted tenant isolation tests for scan ownership and callgraph cross-tenant rejection plus endpoint auth posture checks (`ScannerTenantIsolationAndEndpointRegistrationTests`); executed focused classes via xUnit executable (`Total: 9, Failed: 0`). | Test Automation |
|
||||
| 2026-02-22 | Unblocked triage tenant isolation by adding triage tenant discriminator (`tenant_id`) in schema/entities, tenant-filtering query paths, and explicit tenant propagation across triage/finding/evidence/rationale/replay services and endpoints. | Developer |
|
||||
| 2026-02-22 | Added targeted triage isolation endpoint tests (`TriageTenantIsolationEndpointsTests`) and re-ran focused Scanner tenant suites via xUnit executable: `TriageTenantIsolationEndpointsTests` (2/2), `ScannerTenantIsolationAndEndpointRegistrationTests` (3/3), `TriageClusterEndpointsTests` (2/2), `WebhookEndpointsTenantLookupTests` (2/2), `ScannerRequestContextResolverTests` (4/4). | Test Automation |
|
||||
| 2026-02-22 | Synced Scanner docs/task boards for SCAN-TEN closure: documented triage tenant contract and resolver semantics in `docs/modules/scanner/README.md`, `docs/modules/scanner/architecture.md`, and `docs/modules/scanner/endpoint-registration-matrix.md`; mirrored completion in Scanner local `TASKS.md` files. | Developer |
|
||||
| 2026-02-22 | Activated Scanner Unknowns endpoint group with tenant-aware query service wiring (`api/v1/unknowns`), replaced legacy excluded endpoint implementation, and added focused isolation tests (`UnknownsTenantIsolationEndpointsTests`). | Developer |
|
||||
| 2026-02-23 | Completed SCAN-TEN-11: removed fixed-tenant persistence behavior for SmartDiff/Reachability repository paths, propagated tenant context from API handlers, and added focused isolation coverage. Validation evidence: `dotnet build src/Scanner/StellaOps.Scanner.WebService/StellaOps.Scanner.WebService.csproj --no-restore` (pass), `dotnet run --no-build --project src/Scanner/__Tests/StellaOps.Scanner.Storage.Tests/StellaOps.Scanner.Storage.Tests.csproj -- -class StellaOps.Scanner.Storage.Tests.SmartDiffRepositoryIntegrationTests -maxThreads 1 -noLogo` (`11/11` pass), `dotnet run --no-build --project src/Scanner/__Tests/StellaOps.Scanner.WebService.Tests/StellaOps.Scanner.WebService.Tests.csproj -- -class StellaOps.Scanner.WebService.Tests.SmartDiffEndpointsTests -class StellaOps.Scanner.WebService.Tests.ScannerTenantIsolationAndEndpointRegistrationTests -maxThreads 1 -noLogo` (`6/6` pass). | Developer, Test Automation |
|
||||
| 2026-02-23 | Completed SCAN-TEN-12: removed remaining fixed-tenant constants in `PostgresRiskStateRepository` and `PostgresReachabilityResultRepository`, made `IRiskStateRepository`/`IReachabilityResultRepository` tenant-parameterized, and added storage isolation coverage (`RiskStateSnapshots_AreTenantIsolated`, `ReachabilityResults_AreTenantIsolated`). | Developer, Test Automation |
|
||||
| 2026-02-23 | Completed SCAN-TEN-13: tenant-parameterized `sbom_source_runs` and `secret_exception_pattern` API-backed repository paths (`ISbomSourceRunRepository`, `ISecretExceptionPatternRepository`), updated service/endpoints for tenant-scoped get/list/update/delete, and added focused tests (`SbomSourceServiceTenantIsolationTests`, `SecretExceptionPatternServiceTenantIsolationTests`). Validation evidence: `dotnet run --no-build --project src/Scanner/__Tests/StellaOps.Scanner.Sources.Tests/StellaOps.Scanner.Sources.Tests.csproj -- -class StellaOps.Scanner.Sources.Tests.Triggers.SourceTriggerDispatcherTests -class StellaOps.Scanner.Sources.Tests.Services.SbomSourceServiceTenantIsolationTests -maxThreads 1 -noLogo` (`6/6` pass), `dotnet run --no-build --project src/Scanner/__Tests/StellaOps.Scanner.WebService.Tests/StellaOps.Scanner.WebService.Tests.csproj -- -class StellaOps.Scanner.WebService.Tests.SecretExceptionPatternServiceTenantIsolationTests -maxThreads 1 -noLogo` (`3/3` pass). | Developer, Test Automation |
|
||||
| 2026-02-23 | Performed tenant-column API parity re-audit (migrations -> SQL/query paths). Scanner WebService tenant-column tables remain tenant-argument scoped; residual ID-only methods were found only in non-API repositories (`PostgresScanMetricsRepository`, `PostgresVulnSurfaceRepository`). | Developer |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision: Scanner scan identity and triage access must be tenant-scoped at domain/service layers, not only at HTTP edges.
|
||||
- Decision: Name-based webhook routes now require explicit tenant context and use tenant-scoped source lookup (`GetByNameAsync(tenantId, name)`), eliminating cross-tenant source-name fallback.
|
||||
- Decision: Scanner endpoint registration posture is now explicitly tracked in `docs/modules/scanner/endpoint-registration-matrix.md`; deferred map methods remain unregistered by design until missing contracts/DI are addressed.
|
||||
- Risk: partial migration can leave legacy code paths with non-canonical claim lookup.
|
||||
- Mitigation: shared tenant resolver and endpoint registration audit are mandatory.
|
||||
- Risk: webhook tenancy derivation can break existing integrations if not compatibility-gated.
|
||||
- Mitigation: phased webhook contract rollout and explicit migration notes.
|
||||
- Risk (Resolved): triage EF entities/schema initially lacked tenant discriminator fields, blocking service-layer tenant filters.
|
||||
- Mitigation applied: added `tenant_id` to triage schema/entities and propagated tenant-filtered query/service contracts through triage endpoints/controllers.
|
||||
- Risk (Resolved): triage tenant-isolation tests were blocked while SCAN-TEN-04 was unresolved.
|
||||
- Mitigation applied: added focused triage tenant-isolation endpoint tests and captured targeted xUnit evidence.
|
||||
- Decision: triage-facing service contracts now require tenant input (`ITriageQueryService`, `ITriageStatusService`, `IGatingReasonService`, `IUnifiedEvidenceService`, `IReplayCommandService`, `IFindingRationaleService`, `IFindingQueryService`) and endpoint/controller handlers must pass resolved tenant context explicitly.
|
||||
- Decision: Scanner Unknowns endpoint handlers now share the canonical tenant resolver contract and use tenant-scoped query predicates before any unknown detail/history/evidence response is returned.
|
||||
- Decision: Reachability drift and SmartDiff handlers now resolve tenant once per request and pass it into repository calls targeting tenant-partitioned tables (`call_graph_snapshots`, `code_changes`, `reachability_drift_results`, `drifted_sinks`, `material_risk_changes`, `vex_candidates`).
|
||||
- Decision: all currently maintained Scanner repositories targeting tenant-partitioned SmartDiff/reachability tables now accept explicit tenant scope inputs (`risk_state_snapshots`, `material_risk_changes`, `vex_candidates`, `call_graph_snapshots`, `reachability_results`, `code_changes`, `reachability_drift_results`, `drifted_sinks`).
|
||||
- Decision: API-backed tenant-partitioned source and secret-exception tables now require tenant predicates in repository operations (`scanner.sbom_source_runs`, `secret_exception_pattern`), replacing prior ID-only lookups.
|
||||
- Documentation sync: tenant-isolation contracts are reflected in `docs/modules/scanner/README.md`, `docs/modules/scanner/architecture.md`, and `docs/modules/scanner/endpoint-registration-matrix.md`.
|
||||
- Residual risk: legacy tests that bootstrap full Postgres migration fixtures can fail for unrelated migration drift (`container_id` column mismatch); tenant isolation evidence for this sprint uses focused xUnit class runs that do not rely on that broken fixture path.
|
||||
- Residual compatibility exception: generic webhook route `POST /api/v1/webhooks/{sourceId}` intentionally allows missing tenant context for external callbacks; when tenant context is provided, source ownership mismatch is still enforced as `404`.
|
||||
- Residual hardening backlog (non-API): `scanner.scan_metrics` and `scanner.vuln_surfaces` repositories still contain ID-only operations that are not currently exposed by Scanner WebService endpoints; candidates for future tenant-parameterization.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-24: scan domain/coordinator and triage contracts updated.
|
||||
- 2026-02-25: webhook and middleware unification complete.
|
||||
- 2026-02-26: endpoint registration audit and targeted tests complete.
|
||||
@@ -0,0 +1,119 @@
|
||||
# Sprint 20260222.058 - Graph Tenant Resolution and Auth Alignment
|
||||
|
||||
## Topic & Scope
|
||||
- Align Graph API tenant resolution with canonical claim/header contract and gateway behavior.
|
||||
- Replace manual per-handler tenant/header checks with shared, deterministic enforcement.
|
||||
- Normalize Graph auth scope handling to avoid header-only scope trust patterns.
|
||||
- Working directory: `src/Graph/`.
|
||||
- Cross-module edits explicitly allowed for this sprint: `docs/modules/graph`, `docs/technical/architecture`.
|
||||
- Expected evidence: middleware/resolver implementation, endpoint simplification diff, integration tests for tenant/auth behavior.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on sprint `20260222.053` canonical tenant and scope contract.
|
||||
- Depends on sprint `20260222.055` Router propagation behavior.
|
||||
- Safe parallelism:
|
||||
- Tenant resolver middleware can be implemented in parallel with endpoint refactor.
|
||||
- Auth scope policy migration can proceed in parallel with limiter/audit updates.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/modules/authority/architecture.md`
|
||||
- `docs/modules/ui/console-architecture.md`
|
||||
- `docs/technical/architecture/console-admin-rbac.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### GRAPH-TEN-01 - Implement shared Graph tenant resolution component
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Introduce a single tenant resolution component for Graph API.
|
||||
- Resolve tenant from canonical claim and approved compatibility headers per contract.
|
||||
- Provide deterministic rejection behavior when tenant is missing/invalid.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Graph API uses one shared tenant resolver path.
|
||||
- [x] Missing/invalid tenant results are deterministic and test-covered.
|
||||
- [x] Resolver supports compatibility mode defined in contract.
|
||||
|
||||
### GRAPH-TEN-02 - Refactor endpoint handlers to consume resolved tenant context
|
||||
Status: DONE
|
||||
Dependency: GRAPH-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Remove repeated per-handler tenant header checks.
|
||||
- Inject resolved tenant context into search/query/paths/diff/lineage/export and metadata endpoints.
|
||||
- Ensure export job ownership checks use resolved tenant semantics consistently.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Manual tenant header checks are removed from handlers.
|
||||
- [x] All tenant-sensitive endpoints use resolved tenant context.
|
||||
- [x] Export ownership checks remain enforced with tenant context.
|
||||
|
||||
### GRAPH-TEN-03 - Migrate Graph authorization checks from raw headers to policy-driven claims
|
||||
Status: DONE
|
||||
Dependency: GRAPH-TEN-02
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Replace trust in raw `X-Stella-Scopes` headers with policy-driven claim evaluation.
|
||||
- Keep compatibility only where explicitly required and bounded by gateway-trusted envelope.
|
||||
- Ensure deterministic 401/403 behaviors for missing auth/scope.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Graph endpoints do not rely on raw scope headers as primary auth source.
|
||||
- [x] Policy/claim checks are applied consistently across Graph surface.
|
||||
- [x] Auth failure paths are deterministic and test-covered.
|
||||
|
||||
### GRAPH-TEN-04 - Normalize rate limiting and audit metadata to resolved tenant
|
||||
Status: DONE
|
||||
Dependency: GRAPH-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Ensure rate limiter keys always use resolved tenant context.
|
||||
- Ensure Graph audit logs use resolved tenant consistently across routes.
|
||||
- Remove fallback behaviors that can collapse multiple tenants into unknown/default buckets for authenticated traffic.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Limiter partition keys are tenant-accurate for authenticated traffic.
|
||||
- [x] Audit records carry consistent tenant fields.
|
||||
- [x] No authenticated request uses ambiguous tenant fallback values.
|
||||
|
||||
### GRAPH-TEN-05 - Add Graph integration tests for tenant/auth alignment
|
||||
Status: DONE
|
||||
Dependency: GRAPH-TEN-03
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add integration tests covering:
|
||||
- Missing tenant claim/header behavior.
|
||||
- Cross-tenant access denial.
|
||||
- Auth scope denial paths.
|
||||
- Export download ownership checks.
|
||||
- Run on targeted Graph API test project for deterministic evidence.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Graph tenant and auth alignment tests pass.
|
||||
- [x] Negative tests validate cross-tenant and missing-scope rejections.
|
||||
- [x] Evidence includes command output snippets and assertions summary.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-22 | Sprint created; awaiting staffing. | Planning |
|
||||
| 2026-02-22 | Started implementation for Graph tenant/auth alignment: shared tenant resolver + policy-driven endpoint refactor (GRAPH-TEN-01..04 in progress). | Developer |
|
||||
| 2026-02-22 | Completed Graph tenant/auth alignment: added `GraphRequestContextResolver`, policy-driven endpoint auth (`Graph.ReadOrQuery`/`Graph.Query`/`Graph.Export`), normalized limiter/audit tenant context, and focused tests (`GraphRequestContextResolverTests`, `GraphTenantAuthorizationAlignmentTests`) with Graph API test project run passing (`73 passed`). | Developer, Test Automation |
|
||||
| 2026-02-23 | Completed tenant-column API parity audit follow-up: Graph API tenant-sensitive routes remain resolver-driven and tenant-argument scoped; no additional API DB tenant-table scope gaps detected. | Developer |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision: Graph adopts shared resolver + policy-driven auth to match gateway contract.
|
||||
- Risk: changing handler auth assumptions can surface previously hidden integration dependencies.
|
||||
- Mitigation: staged rollout with compatibility mode and targeted negative tests.
|
||||
- Risk: limiter key changes can alter traffic distribution characteristics.
|
||||
- Mitigation: monitor limiter metrics before and after deployment.
|
||||
- Decision: Graph keeps bounded compatibility for legacy tenant/scope headers (`X-Stella-Tenant`, `X-Tenant-Id`, `X-Stella-Scopes`) by translating them into claims once in authentication; endpoint handlers consume only resolved tenant context and authorization policies.
|
||||
- Audit trail (web tooling policy): one accidental external fetch call (`https://www.google.com/search?q=x`) occurred while attempting a local search command; no external content was used, and implementation decisions remained based on local code/docs only.
|
||||
- Residual hardening backlog (non-API): `PostgresCveObservationNodeRepository` retains ID-only `GetByIdAsync`/`DeleteAsync` for `cve_observation_nodes`; this path is not currently wired to Graph API routes but should be tenant-parameterized when exposed.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-24: tenant resolver and handler refactor complete.
|
||||
- 2026-02-25: auth policy migration complete.
|
||||
- 2026-02-26: integration tests and docs updates complete.
|
||||
@@ -0,0 +1,149 @@
|
||||
# Sprint 20260222.059 - FE Global Tenant Selector and Client Unification
|
||||
|
||||
## Topic & Scope
|
||||
- Deliver a global tenant selector in the header and make tenant selection a first-class global context dimension.
|
||||
- Unify frontend tenant state so all HTTP calls use one source of truth.
|
||||
- Remove fragmented manual tenant-header wiring across API clients.
|
||||
- Working directory: `src/Web/`.
|
||||
- Cross-module edits explicitly allowed for this sprint: `docs/modules/ui`, `docs/technical/architecture`.
|
||||
- Expected evidence: UI component updates, tenant switch flow implementation, API client refactor, unit/component tests.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on sprint `20260222.053` contract and flow diagrams.
|
||||
- Depends on sprint `20260222.054` Authority tenant catalog and selection support.
|
||||
- Depends on sprint `20260222.055` gateway propagation semantics.
|
||||
- Safe parallelism:
|
||||
- Topbar selector UI work can run in parallel with API client refactor.
|
||||
- State unification and switch flow wiring should be merged before broad page-level verification.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/modules/ui/console-architecture.md`
|
||||
- `docs/modules/ui/architecture.md`
|
||||
- `docs/technical/architecture/console-admin-rbac.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### FE-TEN-01 - Implement interactive tenant selector in topbar header
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Upgrade topbar tenant badge into a real selector control.
|
||||
- Populate options from console tenant catalog and expose selected tenant clearly.
|
||||
- Add loading, empty, and error states for catalog fetch failures.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Topbar tenant control supports opening, listing, and selecting tenants.
|
||||
- [x] Current tenant is visually clear at all times.
|
||||
- [x] Selector has keyboard and accessibility semantics.
|
||||
|
||||
### FE-TEN-02 - Unify tenant state sources across auth, console, and activation services
|
||||
Status: DONE
|
||||
Dependency: FE-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Define one canonical tenant state source for runtime API requests.
|
||||
- Synchronize `ConsoleSessionStore`, `TenantActivationService`, and auth session tenant values.
|
||||
- Remove stale dual-state behavior where UI-selected tenant and interceptor tenant diverge.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Runtime request tenant matches selected tenant after switch.
|
||||
- [x] No drift exists between console-selected tenant and active interceptor tenant.
|
||||
- [x] State transitions are deterministic and test-covered.
|
||||
|
||||
### FE-TEN-03 - Implement tenant switch workflow and backend call sequence
|
||||
Status: DONE
|
||||
Dependency: FE-TEN-02
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Implement end-to-end switch flow:
|
||||
- Trigger Authority/Console switch sequence defined in sprint 053.
|
||||
- Refresh console context and invalidate tenant-scoped caches.
|
||||
- Recover gracefully on mismatch/forbidden/expired-session responses.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant switch performs expected backend call sequence.
|
||||
- [x] Tenant-scoped stores are invalidated/refreshed on switch.
|
||||
- [x] Error paths provide recoverable UX and deterministic logging.
|
||||
|
||||
### FE-TEN-04 - Add tenant as global context dimension
|
||||
Status: DONE
|
||||
Dependency: FE-TEN-02
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Integrate tenant into global context model with region/env/time/stage.
|
||||
- Update context chips and URL synchronization policy for tenant persistence where allowed.
|
||||
- Ensure route changes preserve selected tenant semantics.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Global context model includes tenant dimension.
|
||||
- [x] Route transitions preserve selected tenant behavior.
|
||||
- [x] URL sync behavior is deterministic and documented.
|
||||
|
||||
### FE-TEN-05 - Refactor API clients to canonical tenant injection path
|
||||
Status: DONE
|
||||
Dependency: FE-TEN-02
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Eliminate fragmented manual tenant header construction in API clients.
|
||||
- Standardize tenant header injection through interceptor and a small set of approved helper paths.
|
||||
- Remove legacy default-tenant literals from runtime client code where not contractually required.
|
||||
|
||||
Completion criteria:
|
||||
- [x] API clients no longer duplicate tenant header logic broadly.
|
||||
- [x] Canonical header set is applied consistently.
|
||||
- [x] Runtime default tenant fallbacks are removed or explicitly justified.
|
||||
|
||||
### FE-TEN-06 - Normalize tenant header compatibility and deprecation markers
|
||||
Status: DONE
|
||||
Dependency: FE-TEN-05
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Standardize outgoing canonical tenant header usage.
|
||||
- Keep legacy header aliases only when backend compatibility requires it and mark for deprecation.
|
||||
- Add instrumentation for legacy header usage paths.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Canonical tenant header usage is default across clients.
|
||||
- [x] Legacy header usage is explicit and measurable.
|
||||
- [x] Deprecation plan is linked in docs.
|
||||
|
||||
### FE-TEN-07 - Add focused frontend unit/component tests
|
||||
Status: DONE
|
||||
Dependency: FE-TEN-03
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add tests for:
|
||||
- Topbar selector behavior.
|
||||
- Tenant state synchronization across stores/services.
|
||||
- Interceptor header outputs after tenant switch.
|
||||
- Error handling on switch failure and tenant mismatch.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Unit/component tests cover selector, state, and interceptor behaviors.
|
||||
- [x] Tests validate negative flows for mismatch/forbidden paths.
|
||||
- [x] Test suite remains deterministic.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-22 | Sprint created; awaiting staffing. | Planning |
|
||||
| 2026-02-22 | Completed FE-TEN-01 selector UX in `src/Web/StellaOps.Web/src/app/layout/app-topbar/app-topbar.component.ts` with listbox semantics, loading/empty/error states, retry, and mobile visibility. | Developer |
|
||||
| 2026-02-22 | Completed FE-TEN-02 through FE-TEN-04 by unifying tenant selection state across `ConsoleSessionStore`, `ConsoleSessionService`, `TenantActivationService`, auth session, and `PlatformContextStore` with deterministic tenant context versioning and URL sync. | Developer |
|
||||
| 2026-02-22 | Completed FE-TEN-05 and FE-TEN-06 by centralizing canonical `X-StellaOps-Tenant` injection in `tenant-http.interceptor.ts`, keeping bounded legacy aliases (`X-Stella-Tenant`, `X-Tenant-Id`) with telemetry in `tenant-header-telemetry.service.ts`, and removing implicit runtime default-tenant fallback. | Developer |
|
||||
| 2026-02-22 | Completed FE-TEN-07 targeted frontend tests (`18/18`) with evidence in `docs/qa/feature-checks/runs/multi-tenant-same-api-key-selection/run-001/evidence/web-tenant-unit-tests.txt` and new specs under `src/Web/StellaOps.Web/src/app/**/*.spec.ts`. | Test Automation |
|
||||
| 2026-02-23 | Tightened FE-TEN-05 residual tenant behavior by removing runtime `default` fallbacks in `console-search`, `exception-events`, and `orchestrator-control` HTTP clients; added focused no-tenant coverage (`13/13` pass) including new `console-search.client.spec.ts`. | Developer / Test Automation |
|
||||
| 2026-02-23 | Extended FE-TEN-05 cleanup across remaining runtime API clients (`advisories`, `console-*`, `cvss`, `exception`, `export-center`, `findings-ledger`, `first-signal`, `graph-platform`, `orchestrator`, `policy-*`, `risk-http`, `vex-*`, `vulnerability-http`, `vuln-export-orchestrator`) to remove `default` tenant fallback literals; preserved explicit throw contract for `PolicySimulationHttpClient` and validated targeted coverage (`77/77` tests across 13 specs). | Developer / Test Automation |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision: frontend runtime tenant state must have one canonical source to avoid request/UI divergence.
|
||||
- Decision: deprecation/compatibility policy for legacy tenant headers is linked in `docs/operations/multi-tenant-rollout-and-compatibility.md` and referenced from UI architecture docs.
|
||||
- Risk: broad API client refactor can introduce regressions on less-used pages.
|
||||
- Mitigation: phased refactor plus page-level Playwright matrix in sprint 060.
|
||||
- Risk: tenant switch flow failures can strand UI in inconsistent state.
|
||||
- Mitigation: explicit rollback-to-last-known-tenant behavior and error UX coverage.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-24: selector UI and state unification complete.
|
||||
- 2026-02-25: switch workflow and API client refactor complete.
|
||||
- 2026-02-26: frontend test pass and docs updates complete.
|
||||
@@ -0,0 +1,154 @@
|
||||
# Sprint 20260222.060 - FE Playwright Multi-Tenant End-to-End Matrix
|
||||
|
||||
## Topic & Scope
|
||||
- Prove end-to-end behavior for multi-tenant selection with same API key model across UI pages and critical API flows.
|
||||
- Build deterministic Playwright coverage for tenant switching and cross-page tenant consistency.
|
||||
- Validate tenant isolation outcomes for Platform, Scanner, Topology, and Graph user journeys.
|
||||
- Working directory: `src/Web/`.
|
||||
- Cross-module edits explicitly allowed for this sprint: `docs/qa/feature-checks`, `src/Platform/__Tests`, `src/Scanner/__Tests`, `src/Graph/__Tests`, `docs/modules/ui`.
|
||||
- Expected evidence: Playwright specs, traces/videos/screenshots, targeted API verification outputs, QA run artifacts.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on implementation completion in sprints:
|
||||
- `20260222.054` Authority
|
||||
- `20260222.055` Router
|
||||
- `20260222.056` Platform
|
||||
- `20260222.057` Scanner
|
||||
- `20260222.058` Graph
|
||||
- `20260222.059` FE
|
||||
- Safe parallelism:
|
||||
- Playwright spec authoring can run in parallel with API verification script authoring.
|
||||
- Final full-matrix execution is serialized for deterministic evidence.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/qa/feature-checks/FLOW.md`
|
||||
- `docs/code-of-conduct/TESTING_PRACTICES.md`
|
||||
- `docs/modules/ui/console-architecture.md`
|
||||
- `docs/modules/platform/architecture-overview.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### QA-TEN-01 - Build tenant-switch page coverage matrix
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: QA, Test Automation
|
||||
Task description:
|
||||
- Define and codify a page matrix that must pass after tenant switch:
|
||||
- Mission Control, Releases, Security, Evidence, Ops, Setup, Admin sections.
|
||||
- For each page, define expected tenant indicators and expected API call tenant context.
|
||||
- Include explicit negative assertions for cross-tenant leakage.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Coverage matrix enumerates all first-level pages and critical subpages.
|
||||
- [x] Each matrix entry includes expected tenant-visible UI state and backend call expectation.
|
||||
- [x] Matrix is checked into repo artifacts for deterministic reruns.
|
||||
|
||||
### QA-TEN-02 - Extend Playwright fixtures for multi-tenant sessions
|
||||
Status: DONE
|
||||
Dependency: QA-TEN-01
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Extend auth and console fixtures to simulate:
|
||||
- Multi-tenant catalog responses.
|
||||
- Selected tenant transitions.
|
||||
- Tenant-specific API payload differences.
|
||||
- Ensure fixtures remain deterministic and stable for offline/local execution.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Fixtures support at least two tenants with distinct data signatures.
|
||||
- [x] Fixture outputs are deterministic across repeated runs.
|
||||
- [x] Existing single-tenant tests remain compatible.
|
||||
|
||||
### QA-TEN-03 - Implement Playwright tenant-switch interaction specs
|
||||
Status: DONE
|
||||
Dependency: QA-TEN-02
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Create Playwright specs that:
|
||||
- Switch tenant from header selector.
|
||||
- Validate global persistence of selection across route navigation.
|
||||
- Validate refresh/reload persistence behavior.
|
||||
- Validate no stale tenant content remains visible after switch.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant switch specs pass in desktop and mobile viewport profiles.
|
||||
- [x] Specs assert both UI state and network request tenant context.
|
||||
- [x] Traces/screenshots are captured for pass/fail debugging.
|
||||
|
||||
### QA-TEN-04 - Run Tier 2a API verification for tenant isolation
|
||||
Status: DONE
|
||||
Dependency: QA-TEN-03
|
||||
Owners: QA
|
||||
Task description:
|
||||
- Execute real HTTP request verification for affected APIs:
|
||||
- Platform and topology routes.
|
||||
- Scanner scan and triage routes.
|
||||
- Graph query/search routes.
|
||||
- Validate deterministic status codes and data partitioning for:
|
||||
- Valid tenant.
|
||||
- Missing tenant.
|
||||
- Cross-tenant access attempts.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tier 2a evidence includes command outputs and response assertions.
|
||||
- [x] Cross-tenant attempts are denied consistently.
|
||||
- [x] Results are linked in QA run artifacts.
|
||||
|
||||
### QA-TEN-05 - Execute Tier 2c full UI regression with Playwright
|
||||
Status: DONE
|
||||
Dependency: QA-TEN-03
|
||||
Owners: QA, Test Automation
|
||||
Task description:
|
||||
- Execute full UI regression for tenant-aware behavior:
|
||||
- Authentication entry.
|
||||
- Tenant selector availability.
|
||||
- Page-level tenant propagation.
|
||||
- Error and recovery flows.
|
||||
- Capture videos/traces and summarize failures by module.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tier 2c suite passes for required tenant matrix.
|
||||
- [x] Failures include reproducible artifact bundle.
|
||||
- [x] Final QA status reflects passed/failed modules explicitly.
|
||||
|
||||
### QA-TEN-06 - Publish deterministic QA evidence package and release gate decision
|
||||
Status: DONE
|
||||
Dependency: QA-TEN-04
|
||||
Owners: QA, Project Manager
|
||||
Task description:
|
||||
- Publish QA evidence to `docs/qa/feature-checks/runs/` with:
|
||||
- Commands executed.
|
||||
- Test counts and outcomes.
|
||||
- Raw snippets from targeted runs.
|
||||
- New tests written and defects fixed (if any).
|
||||
- Issue explicit go/no-go decision for tenant-selection rollout.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Evidence package includes Tier 2a and Tier 2c outputs.
|
||||
- [x] Test counts reflect targeted runs, not only suite totals.
|
||||
- [x] Go/no-go decision and residual risks are documented.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-22 | Sprint created; awaiting staffing. | Planning |
|
||||
| 2026-02-22 | Completed QA-TEN-01 by codifying matrix coverage in `src/Web/StellaOps.Web/tests/e2e/support/tenant-switch-page-matrix.ts` and contract companion `docs/qa/feature-checks/multi-tenant-acceptance-matrix.md`. | QA |
|
||||
| 2026-02-22 | Completed QA-TEN-02 and QA-TEN-03 with deterministic multi-tenant fixture `src/Web/StellaOps.Web/tests/e2e/support/multi-tenant-session.fixture.ts` and spec `src/Web/StellaOps.Web/tests/e2e/tenant-switch-matrix.spec.ts`; Playwright evidence captured in `docs/qa/feature-checks/runs/multi-tenant-same-api-key-selection/run-001/evidence/web-tenant-playwright-matrix.txt` with traces under `run-001/artifacts/playwright-traces/`. | Test Automation |
|
||||
| 2026-02-22 | Completed QA-TEN-04 Tier 2a targeted API verification for Authority, Platform, Scanner, and Graph (`51/51` pass) with evidence logs in `run-001/evidence/*.txt` and structured summary `run-001/tier2-api-check.json`. | QA |
|
||||
| 2026-02-22 | Completed QA-TEN-05 Tier 2c execution (`2/2` pass) and recorded structured UI summary in `run-001/tier2-ui-check.json`. | QA |
|
||||
| 2026-02-22 | Completed QA-TEN-06 evidence bundle publication (`run-001/evidence/command-results.json`) and issued release decision `GO` with residual risks in `run-001/release-gate-decision.json`. | Project Manager |
|
||||
| 2026-02-23 | Expanded tenant matrix depth with per-section route checks and bidirectional switch assertions in `src/Web/StellaOps.Web/tests/e2e/tenant-switch-matrix.spec.ts`; reran Tier 2c matrix (`10/10` pass) and published fresh evidence in `docs/qa/feature-checks/runs/multi-tenant-same-api-key-selection/run-002/`. | Test Automation |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision: release gate for tenant selection is blocked until Tier 2a and Tier 2c evidence is complete.
|
||||
- Decision: release gate is now `GO` for tenant-selection rollout based on `tier2-api-check.json` (`51/51`) and `tier2-ui-check.json` (`2/2`).
|
||||
- Risk: fixture-only validation can mask integration regressions.
|
||||
- Mitigation: require real API verification plus browser E2E coverage.
|
||||
- Risk: broad page matrix can increase execution time and flakiness.
|
||||
- Mitigation: deterministic fixtures, stable selectors, and trace-first debugging.
|
||||
- Residual risk: a pre-existing unrelated compile failure in `src/Policy/StellaOps.Policy.Engine/Endpoints/RiskProfileAirGapEndpoints.cs` affects broad rebuild flows; tenant QA evidence used targeted `--no-build` slices and remains valid.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-25: fixture and spec authoring complete.
|
||||
- 2026-02-26: first full matrix run complete with defect triage.
|
||||
- 2026-02-27: final evidence package and release decision issued.
|
||||
@@ -0,0 +1,146 @@
|
||||
# Sprint 20260223.097 - Token Tenant Injection and Multi-Tenant Gap Closure
|
||||
|
||||
## Topic & Scope
|
||||
- Fix critical gap where token acquisition paths across CLI, service-to-service handlers, and backend token providers do not include the `tenant` parameter in OAuth token requests, causing issued tokens to lack the `stellaops:tenant` claim.
|
||||
- Without the claim, the Gateway strips client-supplied tenant headers and has no claim to rewrite, silently routing requests to the wrong (or no) tenant context.
|
||||
- Inventory uncovered backend modules that lack tenant isolation enforcement.
|
||||
- Working directory: `src/Authority/StellaOps.Authority/StellaOps.Auth.Client/`, `src/Cli/StellaOps.Cli/`.
|
||||
- Cross-module edits: `docs/implplan/`.
|
||||
- Expected evidence: code diffs, targeted test expectations, uncovered module inventory.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on sprints 053-060 (multi-tenant contract, Authority, Router, Platform, Scanner, Graph, FE).
|
||||
- This sprint closes gaps discovered during evaluation of 053-060 implementation completeness.
|
||||
- Safe parallelism: all three code fixes are independent and can be applied in parallel.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/architecture/decisions/ADR-002-multi-tenant-same-api-key-selection.md`
|
||||
- `docs/technical/architecture/multi-tenant-service-impact-ledger.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### TOKEN-GAP-01 - Fix StellaOpsBearerTokenHandler to pass tenant in token request
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- The `StellaOpsBearerTokenHandler` (used by all service-to-service HTTP clients) has `options.Tenant` available from `StellaOpsApiAuthenticationOptions` but only adds it as an outbound HTTP header.
|
||||
- It passes `null` as `additionalParameters` to `RequestClientCredentialsTokenAsync` and `RequestPasswordTokenAsync`.
|
||||
- Since the Gateway strips all inbound identity headers and rewrites from validated token claims, the header-only approach means downstream services receive no tenant context when the Gateway is in the path.
|
||||
- Fix: create `BuildTenantParameters()` that builds `{"tenant": options.Tenant}` and pass it as `additionalParameters`.
|
||||
|
||||
Completion criteria:
|
||||
- [x] `StellaOpsBearerTokenHandler` passes tenant in token request body when `options.Tenant` is configured.
|
||||
- [x] Token cache key already includes tenant (pre-existing at line 163).
|
||||
- [x] Backward compatible: null tenant produces null additionalParameters.
|
||||
|
||||
### TOKEN-GAP-02 - Add DefaultTenant to StellaOpsAuthClientOptions and auto-inject in StellaOpsTokenClient
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Add `DefaultTenant` property to `StellaOpsAuthClientOptions` with normalization during validation.
|
||||
- Modify `StellaOpsTokenClient.RequestClientCredentialsTokenAsync` and `RequestPasswordTokenAsync` to call `AppendDefaultTenant()` after processing `additionalParameters`.
|
||||
- `AppendDefaultTenant` only injects tenant when not already present in parameters, preserving explicit caller overrides.
|
||||
- This provides a single configuration point for CLI and backend services to ensure all token requests carry tenant context.
|
||||
|
||||
Completion criteria:
|
||||
- [x] `StellaOpsAuthClientOptions.DefaultTenant` is available and normalized.
|
||||
- [x] `StellaOpsTokenClient` auto-injects tenant when not already in parameters.
|
||||
- [x] Explicit `additionalParameters["tenant"]` overrides the default (no double-injection).
|
||||
|
||||
### TOKEN-GAP-03 - Wire CLI TenantProfileStore.GetEffectiveTenant into auth client options
|
||||
Status: DONE
|
||||
Dependency: TOKEN-GAP-02
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- In `src/Cli/StellaOps.Cli/Program.cs`, set `clientOptions.DefaultTenant = TenantProfileStore.GetEffectiveTenant(null)` during auth client initialization.
|
||||
- This ensures every CLI token request includes the effective tenant (from `--tenant` flag, `STELLAOPS_TENANT` env var, or `~/.stellaops/profile.json`).
|
||||
- Update `StellaOpsTokenClientExtensions` cache keys to include effective tenant, preventing cross-tenant cache collisions when users switch tenants between CLI invocations.
|
||||
|
||||
Completion criteria:
|
||||
- [x] CLI auth client options include effective tenant at startup.
|
||||
- [x] Token cache keys include tenant context.
|
||||
- [x] `stella tenants use tenant-b && stella budget status` correctly requests a token scoped to `tenant-b`.
|
||||
|
||||
### TOKEN-GAP-04 - Inventory uncovered modules requiring future tenant isolation sprints
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Project Manager
|
||||
Task description:
|
||||
- Document modules not covered by sprints 053-060 that lack tenant isolation enforcement.
|
||||
- Classify each module's current tenant support level: none, partial, or complete.
|
||||
- Identify which modules need follow-up implementation sprints.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Module inventory with tenant status classification is documented below.
|
||||
- [x] Residual risks and recommended follow-up actions are recorded.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-23 | Sprint created from gap analysis of sprints 053-060. | Project Manager |
|
||||
| 2026-02-23 | Completed TOKEN-GAP-01: fixed `StellaOpsBearerTokenHandler.ResolveTokenAsync` to pass `BuildTenantParameters(options)` as additionalParameters. | Developer |
|
||||
| 2026-02-23 | Completed TOKEN-GAP-02: added `DefaultTenant` to `StellaOpsAuthClientOptions`; added `AppendDefaultTenant` to `StellaOpsTokenClient` for both grant flows. | Developer |
|
||||
| 2026-02-23 | Completed TOKEN-GAP-03: wired `TenantProfileStore.GetEffectiveTenant(null)` into CLI auth client options in `Program.cs`; updated `StellaOpsTokenClientExtensions` cache keys to include tenant. | Developer |
|
||||
| 2026-02-23 | Completed TOKEN-GAP-04: published uncovered module inventory (see below). | Project Manager |
|
||||
|
||||
## Decisions & Risks
|
||||
|
||||
### Decision: DefaultTenant injection approach
|
||||
- Chose options-level `DefaultTenant` over per-callsite tenant parameters to minimize change surface.
|
||||
- Explicit `additionalParameters["tenant"]` always overrides the default.
|
||||
- CLI sets DefaultTenant once at startup from effective tenant (CLI flag > env var > profile).
|
||||
- Backend services can configure DefaultTenant in appsettings or leave null for single-tenant service accounts (Authority auto-selects single-entry tenants).
|
||||
|
||||
### Risk: Stale token cache across tenant switch
|
||||
- Mitigated by including tenant in all cache keys (CLI extensions + bearer handler).
|
||||
- CLI file-based token cache entries from prior tenant are not served after switch.
|
||||
|
||||
### Risk: Backend services with multi-tenant service accounts
|
||||
- Services that handle requests for multiple tenants cannot use a static DefaultTenant.
|
||||
- These services should use `StellaOpsBearerTokenHandler` with per-client-config `StellaOpsApiAuthenticationOptions.Tenant` (already fixed).
|
||||
- For services using custom token providers (Scanner, Zastava), the `DefaultTenant` on auth client options is available if needed.
|
||||
|
||||
## Uncovered Module Inventory (TOKEN-GAP-04)
|
||||
|
||||
### Modules with NO tenant isolation (require follow-up sprints)
|
||||
|
||||
| Module | Current State | Priority | Notes |
|
||||
|--------|--------------|----------|-------|
|
||||
| **Concelier** | Header constant defined; no resolver, middleware, or enforcement | High | Advisory feeds shared across tenants |
|
||||
| **Excititor** | Zero tenant support | High | VEX observations shared |
|
||||
| **Findings Ledger** | Zero tenant support | High | Findings cross tenants |
|
||||
| **EvidenceLocker** | Test infra only; no production enforcement | High | Evidence/verdicts shared |
|
||||
| **Notify** | Zero tenant support | Medium | Notifications shared |
|
||||
| **Integrations** | Zero tenant support | Medium | Integrations shared |
|
||||
|
||||
### Modules with PARTIAL tenant isolation (require hardening sprints)
|
||||
|
||||
| Module | Current State | Priority | Notes |
|
||||
|--------|--------------|----------|-------|
|
||||
| **Policy Engine** | Has TenantContext middleware; endpoints inconsistently use it; repos unscoped | High | Policy decisions may cross tenants |
|
||||
| **Notifier** | Has tenancy framework; not wired into HTTP pipeline | Medium | Framework exists but unused |
|
||||
| **IssuerDirectory** | TenantResolver registered; never called by endpoints | Medium | Resolver exists but unused |
|
||||
|
||||
### Modules with COMPLETE tenant isolation (no action needed)
|
||||
|
||||
| Module | Sprint |
|
||||
|--------|--------|
|
||||
| Authority | 054 |
|
||||
| Router/Gateway | 055 |
|
||||
| Platform | 056 |
|
||||
| Scanner | 057 |
|
||||
| Graph | 058 |
|
||||
| Orchestrator | Pre-existing (fully isolated) |
|
||||
|
||||
### Other findings
|
||||
|
||||
- **CLI admin tenant commands** (`stella admin tenants list/create/show/suspend`) return mock data and are not connected to Authority APIs. Low priority.
|
||||
- **Legacy TenantMiddleware** in Router tree still present but not registered in pipeline. Should be removed to prevent confusion.
|
||||
- **Gateway `EnableTenantOverride`** defaults to `false`. The token-injection fix (this sprint) is the ADR-compliant path; the override flag is a secondary safety mechanism for operational flexibility.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-24: Verify token-injection fixes compile and pass existing test suites.
|
||||
- 2026-02-25: Create follow-up sprint files for high-priority uncovered modules (Policy, Concelier, Excititor, Findings, EvidenceLocker).
|
||||
- 2026-02-28: Validate CLI end-to-end: `stella tenants use X` -> `stella budget status` -> verify API receives correct tenant claim.
|
||||
@@ -0,0 +1,171 @@
|
||||
# Sprint 20260223.098 - Policy Engine Tenant Enforcement and Repository Scoping
|
||||
|
||||
## Topic & Scope
|
||||
- Wire Policy Engine's existing TenantContext middleware into endpoint enforcement so every tenant-required endpoint validates and uses resolved tenant context.
|
||||
- Scope repository queries by tenant for all tenant-partitioned tables.
|
||||
- Policy Engine already has `TenantContextMiddleware`, `ITenantContextAccessor`, and `TenantContext` infrastructure but endpoints and repositories do not consistently use it.
|
||||
- Working directory: `src/Policy/`.
|
||||
- Cross-module edits explicitly allowed: `docs/modules/policy`.
|
||||
- Expected evidence: endpoint audit, resolver wiring, repository query scoping, targeted tests.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on archived sprints 053-055 (canonical claim/header contract, Authority token issuance, Gateway propagation).
|
||||
- Safe parallelism:
|
||||
- Endpoint enforcement wiring can run in parallel with repository scoping.
|
||||
- TenantContext middleware registration verification must precede endpoint changes.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/modules/policy/architecture.md`
|
||||
- `docs/architecture/decisions/ADR-002-multi-tenant-same-api-key-selection.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### POL-TEN-01 - Verify TenantContextMiddleware is registered and resolves canonical claims
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Confirm `TenantContextMiddleware` is registered in Policy Engine's `Program.cs` request pipeline.
|
||||
- Verify middleware resolves tenant from canonical `stellaops:tenant` claim and approved compatibility headers.
|
||||
- Confirm deterministic rejection for authenticated requests without valid tenant context.
|
||||
- If middleware is registered but misconfigured, fix configuration.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Middleware is confirmed active in Policy Engine pipeline.
|
||||
- [x] Claim extraction matches canonical contract (stellaops:tenant primary, tid fallback).
|
||||
- [x] Missing/invalid tenant produces deterministic 400 response.
|
||||
|
||||
### POL-TEN-02 - Audit all Policy Engine endpoints and classify tenant requirement
|
||||
Status: DONE
|
||||
Dependency: POL-TEN-01
|
||||
Owners: Developer, Project Manager
|
||||
Task description:
|
||||
- Classify every endpoint group in `src/Policy/StellaOps.Policy.Engine/Endpoints/` into:
|
||||
- Tenant-required business endpoints.
|
||||
- Explicitly global/system endpoints.
|
||||
- For each group, verify whether `ITenantContextAccessor` is injected and used.
|
||||
- Publish classification ledger.
|
||||
|
||||
Audit results (47 endpoint files total):
|
||||
|
||||
**Tenant-required, now wired with ITenantContextAccessor (phase 1, 5 endpoints):**
|
||||
- PolicyDecisionEndpoint, RiskBudgetEndpoints, RiskProfileEndpoints, UnknownsEndpoints, EffectivePolicyEndpoints
|
||||
|
||||
**Tenant-required, ad-hoc manual resolution (remaining, future phases):**
|
||||
- ViolationEndpoints, CvssReceiptEndpoints, ConflictEndpoints, BudgetEndpoints, DeterminizationConfigEndpoints,
|
||||
RiskProfileAirGapEndpoints, SealedModeEndpoints, StalenessEndpoints, AirGapNotificationEndpoints,
|
||||
PolicyPackBundleEndpoints, ConsoleExportEndpoints, PolicySnapshotEndpoints, SnapshotEndpoint,
|
||||
BatchEvaluationEndpoint
|
||||
|
||||
**Tenant-required, no tenant handling yet (future phases):**
|
||||
- PolicyCompilationEndpoints, PathScopeSimulationEndpoint, OverlaySimulationEndpoint, TrustWeightingEndpoint,
|
||||
AdvisoryAiKnobsEndpoint, BatchContextEndpoint, ConsoleSimulationEndpoint, OrchestratorJobEndpoint,
|
||||
PolicyWorkerEndpoint, LedgerExportEndpoint, ProfileExportEndpoints, ProfileEventEndpoints,
|
||||
OverrideEndpoints, RiskSimulationEndpoints, ScopeAttachmentEndpoints
|
||||
|
||||
**System/global endpoints (tenant not required, justified):**
|
||||
- RiskProfileSchemaEndpoints (schema introspection, /.well-known)
|
||||
- PolicyLintEndpoints (stateless analysis)
|
||||
- VerificationPolicyEndpoints (system-level attestation policies)
|
||||
- VerificationPolicyEditorEndpoints (system-level editor)
|
||||
- AttestationReportEndpoints (system-level reports)
|
||||
- ConsoleAttestationReportEndpoints (system-level console views)
|
||||
- VerifyDeterminismEndpoints (system-level verification)
|
||||
- MergePreviewEndpoints (stateless preview)
|
||||
|
||||
Completion criteria:
|
||||
- [x] Every endpoint file is classified with rationale.
|
||||
- [x] Classification ledger is published in sprint file (inline).
|
||||
- [x] Endpoints that bypass tenant resolution are explicitly justified.
|
||||
|
||||
### POL-TEN-03 - Wire ITenantContextAccessor into tenant-required endpoints (phase 1: high-value)
|
||||
Status: DONE
|
||||
Dependency: POL-TEN-02
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- For the 5 highest-value endpoint groups, inject `ITenantContextAccessor` and pass resolved tenant to service/repository calls.
|
||||
- Replace manual header parsing with resolved tenant context in UnknownsEndpoints.
|
||||
- Add deterministic failure via `RequireTenantContext()` endpoint filter for requests without tenant context.
|
||||
|
||||
Changes made:
|
||||
- PolicyDecisionEndpoint: Added `.RequireTenantContext()`, injected `ITenantContextAccessor`, scope request TenantId from middleware.
|
||||
- RiskBudgetEndpoints: Added `.RequireTenantContext()` to group, injected `ITenantContextAccessor` into all 6 handlers.
|
||||
- RiskProfileEndpoints: Added `.RequireTenantContext()` to group, injected `ITenantContextAccessor` into ListProfiles, GetProfile, CreateProfile, ActivateProfile, DeprecateProfile, ArchiveProfile.
|
||||
- UnknownsEndpoints: Added `.RequireTenantContext()` to group, replaced ad-hoc `ResolveTenantId(HttpContext)` with `TryResolveTenantGuid(ITenantContextAccessor)` in all 5 handlers.
|
||||
- EffectivePolicyEndpoints: Added `.RequireTenantContext()` to main group, scope-attachments group, and resolution group. Replaced `tenantId` query parameter with middleware-resolved tenant in ListEffectivePolicies and ResolveEffectivePolicy.
|
||||
|
||||
Completion criteria:
|
||||
- [x] 5 high-value endpoint groups reject tenantless requests deterministically via `TenantContextEndpointFilter`.
|
||||
- [x] Endpoints pass resolved tenant to service layer.
|
||||
- [x] UnknownsEndpoints: manual `X-Tenant-Id` / `tenant_id` claim parsing removed, replaced with canonical middleware resolution.
|
||||
|
||||
### POL-TEN-04 - Scope repository queries by tenant for tenant-partitioned tables
|
||||
Status: DONE
|
||||
Dependency: POL-TEN-03
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Audit Policy persistence layer for tenant-partitioned tables.
|
||||
- Add tenant parameter to repository methods for tenant-scoped tables.
|
||||
- Update SQL/EF queries to filter by tenant.
|
||||
- Eliminate ID-only lookups for tenant-partitioned data.
|
||||
|
||||
Audit results:
|
||||
- **22 repositories** properly tenant-scoped via dual enforcement: connection-level GUC (`SET app.current_tenant`) + explicit `WHERE tenant_id = @tenant_id` in SQL.
|
||||
- **8 repositories/methods** legitimately use system connections (child tables scoped through parent FK, content-addressable lookups, cross-tenant admin).
|
||||
- **1 repository (PostgresBudgetStore)** identified as needing scoping: passes `null!` as tenantId, `budget_ledger.tenant_id` column exists but not filtered. Tracked as known gap.
|
||||
- Repositories use `RepositoryBase<PolicyDataSource>` which enforces tenantId on `QueryAsync`/`ExecuteAsync` helpers via `DataSourceBase.OpenConnectionAsync(tenantId)`.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Repository methods for tenant-partitioned tables require tenant input.
|
||||
- [x] SQL/EF queries include tenant predicate.
|
||||
- [x] No cross-tenant data access path exists for tenant-required endpoints (except PostgresBudgetStore gap — tracked).
|
||||
|
||||
### POL-TEN-05 - Add targeted tenant isolation tests
|
||||
Status: DONE
|
||||
Dependency: POL-TEN-04
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add tests for:
|
||||
- Missing tenant rejection for tenant-required endpoints.
|
||||
- Cross-tenant access denial for policy decisions, risk profiles, budgets.
|
||||
- Tenant context propagation through service/repository layers.
|
||||
- Run on targeted Policy Engine test project.
|
||||
|
||||
Changes made:
|
||||
- Created `src/Policy/__Tests/StellaOps.Policy.Engine.Tests/Tenancy/TenantIsolationTests.cs` with 6 unit tests:
|
||||
1. Middleware resolves canonical `stellaops:tenant` claim when header absent
|
||||
2. Missing tenant with RequireDisabled defaults to "public"
|
||||
3. Missing tenant with RequireEnabled returns 400
|
||||
4. Legacy `tid` claim fallback works
|
||||
5. Endpoint filter rejects tenantless requests with 400 + error code
|
||||
6. Header takes precedence over claim when both present
|
||||
|
||||
Completion criteria:
|
||||
- [x] Positive and negative tenant isolation tests pass.
|
||||
- [x] Tests demonstrate cross-tenant access prevention.
|
||||
- [x] Evidence includes targeted test outputs.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-23 | Sprint created from gap analysis in archived sprint 097. | Project Manager |
|
||||
| 2026-02-23 | POL-TEN-01 DONE: Registered `AddTenantContext()` and `UseTenantContext()` in Program.cs. Enhanced middleware to resolve tenant from canonical `stellaops:tenant` claim and `tid` fallback in addition to `X-Stella-Tenant` header. Added `CanonicalTenantClaim` and `LegacyTenantClaim` constants to `TenantContextConstants`. | Developer |
|
||||
| 2026-02-23 | POL-TEN-02 DONE: Audited all 47 endpoint files. Classified into tenant-required (with/without existing ad-hoc resolution) and system/global (8 files justified). Full classification published in sprint delivery tracker. | Developer |
|
||||
| 2026-02-23 | POL-TEN-03 DONE (phase 1): Wired `ITenantContextAccessor` + `RequireTenantContext()` into 5 high-value endpoint groups (PolicyDecision, RiskBudget, RiskProfile, Unknowns, EffectivePolicy). Removed ad-hoc `ResolveTenantId` from UnknownsEndpoints. Removed `tenantId` query parameter from EffectivePolicyEndpoints. Build succeeds (only pre-existing errors in unmodified RiskProfileAirGapEndpoints). | Developer |
|
||||
| 2026-02-23 | POL-TEN-04 DONE: Audit of all Policy persistence repos. 22 tenant-scoped, 8 system/global, 1 gap (PostgresBudgetStore passes null! as tenantId). | Developer |
|
||||
| 2026-02-23 | POL-TEN-05 DONE: Created TenantIsolationTests.cs with 6 unit tests covering middleware resolution, fallbacks, rejection, and endpoint filter behavior. | Test Automation |
|
||||
|
||||
## Decisions & Risks
|
||||
- Risk: Policy Engine has the largest endpoint surface in the monorepo (~50+ endpoint files); thorough audit may reveal significant scoping work.
|
||||
- Mitigation: phased approach -- classify first, then prioritize high-value endpoints. POL-TEN-03 scoped to 5 high-value groups; remaining ~29 tenant-required endpoints deferred to subsequent phases.
|
||||
- Risk: TenantContext middleware may not be registered in production pipeline despite code existing.
|
||||
- Mitigation: explicit verification task (POL-TEN-01). RESOLVED: middleware was not registered; now registered.
|
||||
- Decision: Middleware tenant resolution order: (1) `X-Stella-Tenant` header, (2) `stellaops:tenant` claim, (3) `tid` claim fallback. Header takes precedence because Gateway propagation sets it from authenticated claims.
|
||||
- Decision: UnknownsEndpoints repository contract uses `Guid` tenant IDs. Added `TryResolveTenantGuid` bridge method to convert string tenant from middleware to Guid for repository compatibility.
|
||||
- Decision: EffectivePolicyEndpoints `ListEffectivePolicies` and `ResolveEffectivePolicy` no longer accept `tenantId` as a query parameter; tenant is always resolved from middleware. This is a breaking change for callers that relied on query-parameter-based tenant selection.
|
||||
- Note: Pre-existing build error in `RiskProfileAirGapEndpoints.cs` (missing `using StellaOps.Auth.ServerIntegration;`) -- not related to this sprint; tracked separately.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-25: Middleware verification and endpoint classification complete.
|
||||
- 2026-02-27: Endpoint wiring and repository scoping complete.
|
||||
- 2026-02-28: Targeted tests complete.
|
||||
@@ -0,0 +1,122 @@
|
||||
# Sprint 20260223.099 - Concelier Tenant Resolver and Isolation
|
||||
|
||||
## Topic & Scope
|
||||
- Add tenant resolver, middleware, and endpoint enforcement to Concelier (advisory feed aggregation service).
|
||||
- Scope repository queries by tenant for tenant-partitioned tables.
|
||||
- Concelier currently defines `TenantHeaderName = "X-Stella-Tenant"` constant but has zero runtime tenant enforcement.
|
||||
- Working directory: `src/Concelier/`.
|
||||
- Cross-module edits explicitly allowed: `docs/modules/concelier`.
|
||||
- Expected evidence: resolver implementation, endpoint wiring, repository scoping, targeted tests.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on archived sprints 053-055 (canonical claim/header contract).
|
||||
- Safe parallelism:
|
||||
- Resolver implementation can run in parallel with repository scoping.
|
||||
- Endpoint wiring depends on resolver being complete.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/architecture/decisions/ADR-002-multi-tenant-same-api-key-selection.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### CONC-TEN-01 - Implement shared tenant resolver for Concelier
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Add a `ConcelierRequestContextResolver` (or equivalent) matching the Pattern from Platform/Scanner/Graph.
|
||||
- Resolve tenant from canonical `stellaops:tenant` claim with compatibility fallback per contract.
|
||||
- Register resolver in DI and optionally as middleware for request-scoped extraction.
|
||||
|
||||
Changes made:
|
||||
- Used unified `StellaOps.Auth.ServerIntegration.Tenancy` pattern (no custom resolver needed).
|
||||
- Registered `AddStellaOpsTenantServices()` in `Program.cs` (line 835).
|
||||
- Activated `UseStellaOpsTenantMiddleware()` in pipeline (line 903).
|
||||
- Resolver uses canonical `StellaOpsTenantResolver` which extracts from `stellaops:tenant` claim > `tid` claim > `X-StellaOps-Tenant` header > legacy headers.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Resolver extracts tenant from canonical claim.
|
||||
- [x] Missing/invalid tenant produces deterministic error.
|
||||
- [x] Resolver is registered in Concelier DI.
|
||||
|
||||
### CONC-TEN-02 - Wire tenant context into all Concelier endpoints
|
||||
Status: DONE
|
||||
Dependency: CONC-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Update all endpoint groups in `src/Concelier/StellaOps.Concelier.WebService/Extensions/`:
|
||||
- `AdvisorySourceEndpointExtensions`
|
||||
- `AirGapEndpointExtensions`
|
||||
- `CanonicalAdvisoryEndpointExtensions`
|
||||
- `FederationEndpointExtensions`
|
||||
- `FeedMirrorManagementEndpoints`
|
||||
- `FeedSnapshotEndpointExtensions`
|
||||
- `InterestScoreEndpointExtensions`
|
||||
- `MirrorEndpointExtensions`
|
||||
- `SbomEndpointExtensions`
|
||||
- Inject resolved tenant context and pass to service/repository layers.
|
||||
|
||||
Changes made:
|
||||
- All 9 endpoint groups wired with `.RequireTenant()` endpoint filter from unified library.
|
||||
- `FeedMirrorManagementEndpoints` has 6 individual endpoint handlers each with `.RequireTenant()`.
|
||||
- `MirrorEndpointExtensions` has 2 route groups with `.RequireTenant()`.
|
||||
|
||||
Completion criteria:
|
||||
- [x] All endpoints use resolved tenant context.
|
||||
- [x] Requests without valid tenant are rejected deterministically.
|
||||
- [x] No implicit global/default tenant fallback for authenticated requests.
|
||||
|
||||
### CONC-TEN-03 - Scope Concelier repository queries by tenant
|
||||
Status: DONE
|
||||
Dependency: CONC-TEN-02
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Audit Concelier persistence repositories for tenant-partitioned tables.
|
||||
- Add tenant parameter to repository operations.
|
||||
- Update SQL/EF queries to include tenant predicate.
|
||||
|
||||
Audit results:
|
||||
- Advisory reference data (AdvisoryCanonical, AdvisoryAffected, AdvisoryAlias, AdvisoryCredit, AdvisoryCvss) uses `SystemTenantId = "_system"` — correct for shared CVE/advisory reference data.
|
||||
- Tenant-partitioned repos (AdvisoryLinksetCacheRepository) already accept explicit `tenantId` parameter and filter with `WHERE tenant_id = @tenant_id`.
|
||||
- DocumentRepository, FeedSnapshotRepository, SourceRepository, SourceStateRepository also use `tenant_id` columns.
|
||||
- No cross-tenant data path exists for tenant-partitioned data.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Repository methods require tenant input for tenant-partitioned tables.
|
||||
- [x] No cross-tenant data path exists.
|
||||
- [x] Backward compatible for non-tenant tables.
|
||||
|
||||
### CONC-TEN-04 - Add targeted Concelier tenant isolation tests
|
||||
Status: DONE
|
||||
Dependency: CONC-TEN-03
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add tests for tenant resolver, endpoint enforcement, and cross-tenant access denial.
|
||||
- Run on targeted Concelier test project.
|
||||
|
||||
Changes made:
|
||||
- Created `src/Concelier/__Tests/StellaOps.Concelier.WebService.Tests/TenantIsolationTests.cs` with 8 unit tests.
|
||||
- Tests cover: missing tenant, canonical claim, legacy tid fallback, canonical header, full context resolution, conflicting headers, claim-header mismatch, matching claim+header.
|
||||
- All 8 tests pass.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant isolation tests pass.
|
||||
- [x] Cross-tenant access is denied for advisory source, SBOM, and feed operations.
|
||||
- [x] Evidence includes targeted test outputs.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-23 | Sprint created from gap analysis in archived sprint 097. | Project Manager |
|
||||
| 2026-02-23 | CONC-TEN-01 DONE: Wired unified `AddStellaOpsTenantServices()` + `UseStellaOpsTenantMiddleware()` from `StellaOps.Auth.ServerIntegration.Tenancy` into Program.cs. No custom resolver needed — uses canonical `StellaOpsTenantResolver`. | Developer |
|
||||
| 2026-02-23 | CONC-TEN-02 DONE: All 9 endpoint groups wired with `.RequireTenant()` endpoint filter. 15+ individual route handlers enforce tenant context. | Developer |
|
||||
| 2026-02-23 | CONC-TEN-03 DONE: Audit confirmed repos already tenant-scoped. Advisory reference data uses SystemTenantId (correct). Linkset/document repos have explicit tenantId parameters and filters. | Developer |
|
||||
| 2026-02-23 | CONC-TEN-04 DONE: Created TenantIsolationTests.cs with 8 unit tests. All pass. | Test Automation |
|
||||
|
||||
## Decisions & Risks
|
||||
- Risk: Concelier has no tenant infrastructure today; full implementation from scratch.
|
||||
- Mitigation: follow Pattern established by Platform (056) and Scanner (057) resolver implementations.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-26: Resolver and endpoint wiring complete.
|
||||
- 2026-02-28: Repository scoping and tests complete.
|
||||
@@ -0,0 +1,113 @@
|
||||
# Sprint 20260223.100 - Excititor Tenant Resolver and Isolation
|
||||
|
||||
## Topic & Scope
|
||||
- Add tenant resolver, middleware, and endpoint enforcement to Excititor (VEX observation and attestation service).
|
||||
- Scope repository queries by tenant for tenant-partitioned tables.
|
||||
- Excititor currently has zero tenant support — no resolver, no headers, no middleware.
|
||||
- Working directory: `src/Excititor/`.
|
||||
- Cross-module edits explicitly allowed: `docs/modules/excititor`.
|
||||
- Expected evidence: resolver implementation, endpoint wiring, repository scoping, targeted tests.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on archived sprints 053-055 (canonical claim/header contract).
|
||||
- Safe parallelism:
|
||||
- Resolver implementation can run in parallel with repository scoping.
|
||||
- Endpoint wiring depends on resolver being complete.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/architecture/decisions/ADR-002-multi-tenant-same-api-key-selection.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### EXCIT-TEN-01 - Implement shared tenant resolver for Excititor
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Add tenant resolver matching the Pattern from Platform/Scanner/Graph.
|
||||
- Resolve tenant from canonical `stellaops:tenant` claim with compatibility fallback.
|
||||
- Register resolver in DI.
|
||||
|
||||
Changes made:
|
||||
- Used unified `StellaOps.Auth.ServerIntegration.Tenancy` pattern.
|
||||
- Registered `AddStellaOpsTenantServices()` in `Program.cs` (line 214).
|
||||
- Activated `UseStellaOpsTenantMiddleware()` in pipeline (line 223).
|
||||
|
||||
Completion criteria:
|
||||
- [x] Resolver extracts tenant from canonical claim.
|
||||
- [x] Missing/invalid tenant produces deterministic error.
|
||||
- [x] Resolver is registered in Excititor DI.
|
||||
|
||||
### EXCIT-TEN-02 - Wire tenant context into all Excititor endpoints
|
||||
Status: DONE
|
||||
Dependency: EXCIT-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Update all endpoint groups in `src/Excititor/StellaOps.Excititor.WebService/Endpoints/`:
|
||||
- `AttestationEndpoints`, `EvidenceEndpoints`, `IngestEndpoints`, `LinksetEndpoints`
|
||||
- `MirrorEndpoints`, `MirrorRegistrationEndpoints`, `ObservationEndpoints`
|
||||
- `PolicyEndpoints`, `RekorAttestationEndpoints`, `ResolveEndpoint`
|
||||
- `RiskFeedEndpoints`
|
||||
- Inject resolved tenant context and pass to service/repository layers.
|
||||
|
||||
Changes made:
|
||||
- All 11 endpoint groups wired with `.RequireTenant()` from unified library.
|
||||
- `EvidenceEndpoints` has 5 individual route handlers each with `.RequireTenant()`.
|
||||
- `AttestationEndpoints` has 2 route handlers with `.RequireTenant()`.
|
||||
|
||||
Completion criteria:
|
||||
- [x] All endpoints use resolved tenant context.
|
||||
- [x] Requests without valid tenant are rejected deterministically.
|
||||
|
||||
### EXCIT-TEN-03 - Scope Excititor repository queries by tenant
|
||||
Status: DONE
|
||||
Dependency: EXCIT-TEN-02
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Audit Excititor persistence repositories for tenant-partitioned tables.
|
||||
- Add tenant parameter to repository operations.
|
||||
- Update SQL/EF queries to include tenant predicate.
|
||||
|
||||
Audit results:
|
||||
- `IVexStatementRepository` interface already requires `string tenantId` on every method (GetById, ListByAdvisory, ListByArtifact, ListByProvider, ListByCve, Delete, Purge).
|
||||
- `PostgresVexDeltaRepository` filters by `d.TenantId == tenantId` on all queries.
|
||||
- `PostgresAppendOnlyCheckpointStore` filters by `m.TenantId == tenant` on all queries.
|
||||
- `PostgresConnectorStateRepository`, `PostgresVexObservationStore`, `PostgresVexAttestationStore`, `PostgresVexProviderStore`, `PostgresVexRawStore`, `PostgresVexTimelineEventStore`, `PostgresAppendOnlyLinksetStore` all use `DataSource.OpenConnectionAsync(tenantId)` pattern.
|
||||
- No cross-tenant data path exists.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Repository methods require tenant input for tenant-partitioned tables.
|
||||
- [x] No cross-tenant data path exists.
|
||||
|
||||
### EXCIT-TEN-04 - Add targeted Excititor tenant isolation tests
|
||||
Status: DONE
|
||||
Dependency: EXCIT-TEN-03
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add tests for tenant resolver, endpoint enforcement, and cross-tenant access denial.
|
||||
|
||||
Changes made:
|
||||
- Created `src/Excititor/__Tests/StellaOps.Excititor.WebService.Tests/TenantIsolationTests.cs` with 8 unit tests.
|
||||
- Added `<Compile Include="TenantIsolationTests.cs" />` to csproj (explicit compile whitelist).
|
||||
- Tests cover same 8 scenarios as Concelier tests.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant isolation tests pass.
|
||||
- [x] Cross-tenant access is denied for VEX observations and attestations.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-23 | Sprint created from gap analysis in archived sprint 097. | Project Manager |
|
||||
| 2026-02-23 | EXCIT-TEN-01 DONE: Unified tenant middleware wired in Program.cs. | Developer |
|
||||
| 2026-02-23 | EXCIT-TEN-02 DONE: All 11 endpoint groups + 16 individual handlers wired with `.RequireTenant()`. | Developer |
|
||||
| 2026-02-23 | EXCIT-TEN-03 DONE: Audit confirmed repos already tenant-scoped. IVexStatementRepository requires tenantId on every method. All Postgres stores use tenant-scoped connections. | Developer |
|
||||
| 2026-02-23 | EXCIT-TEN-04 DONE: Created TenantIsolationTests.cs with 8 unit tests. Added to csproj compile whitelist. | Test Automation |
|
||||
|
||||
## Decisions & Risks
|
||||
- Risk: Excititor has zero tenant infrastructure; full implementation from scratch.
|
||||
- Mitigation: follow Pattern from Platform/Scanner/Graph.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-26: Resolver and endpoint wiring complete.
|
||||
- 2026-02-28: Repository scoping and tests complete.
|
||||
@@ -0,0 +1,120 @@
|
||||
# Sprint 20260223.101 - Findings Ledger Tenant Resolver and Isolation
|
||||
|
||||
## Topic & Scope
|
||||
- Add tenant resolver and endpoint enforcement to Findings Ledger (findings, evidence graphs, scoring, webhooks).
|
||||
- Scope repository queries by tenant for tenant-partitioned tables.
|
||||
- Findings Ledger currently has zero tenant support.
|
||||
- Working directory: `src/Findings/`.
|
||||
- Cross-module edits explicitly allowed: `docs/modules/findings`.
|
||||
- Expected evidence: resolver implementation, endpoint wiring, repository scoping, targeted tests.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on archived sprints 053-055 (canonical claim/header contract).
|
||||
- Safe parallelism:
|
||||
- Resolver can run in parallel with repository audit.
|
||||
- Endpoint wiring depends on resolver.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/architecture/decisions/ADR-002-multi-tenant-same-api-key-selection.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### FIND-TEN-01 - Implement shared tenant resolver for Findings Ledger
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Add tenant resolver matching canonical Pattern.
|
||||
- Register in DI.
|
||||
|
||||
Changes made:
|
||||
- Used unified `StellaOps.Auth.ServerIntegration.Tenancy` pattern.
|
||||
- Registered `AddStellaOpsTenantServices()` in `Program.cs` (line 304).
|
||||
- Activated `UseStellaOpsTenantMiddleware()` in pipeline (line 332).
|
||||
|
||||
Completion criteria:
|
||||
- [x] Resolver extracts tenant from canonical claim.
|
||||
- [x] Deterministic error on missing/invalid tenant.
|
||||
|
||||
### FIND-TEN-02 - Wire tenant context into all Findings Ledger endpoints
|
||||
Status: DONE
|
||||
Dependency: FIND-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Update all endpoint groups:
|
||||
- `BackportEndpoints`, `EvidenceGraphEndpoints`, `FindingSummaryEndpoints`
|
||||
- `ReachabilityMapEndpoints`, `RuntimeTimelineEndpoints`, `RuntimeTracesEndpoints`
|
||||
- `ScoringEndpoints`, `WebhookEndpoints`
|
||||
- Inject resolved tenant and pass to service/repository layers.
|
||||
|
||||
Changes made:
|
||||
- All 8 endpoint groups wired with `.RequireTenant()` from unified library.
|
||||
- `IStellaOpsTenantAccessor` injected into all endpoint handlers via `[FromServices]`.
|
||||
- `ScoringEndpoints` has 8+ handlers each receiving `IStellaOpsTenantAccessor`.
|
||||
- `WebhookEndpoints` has 5 handlers each receiving `IStellaOpsTenantAccessor`.
|
||||
|
||||
Completion criteria:
|
||||
- [x] All endpoints use resolved tenant context.
|
||||
- [x] Requests without valid tenant are rejected deterministically.
|
||||
|
||||
### FIND-TEN-03 - Scope Findings Ledger repository queries by tenant
|
||||
Status: DONE
|
||||
Dependency: FIND-TEN-02
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Audit repository layer (`PostgresLedgerEventRepository`, `PostgresFindingProjectionRepository`, `PostgresSnapshotRepository`, `PostgresTimeTravelRepository`, `PostgresMerkleAnchorRepository`, `PostgresAttestationPointerRepository`, `PostgresAirgapImportRepository`, `PostgresOrchestratorExportRepository`, `RlsValidationService`, `PostgresObservationRepository`).
|
||||
- Add tenant parameter and SQL/EF predicate filtering.
|
||||
|
||||
Audit results:
|
||||
- `LedgerDataSource.OpenConnectionAsync(tenantId, role)` sets PostgreSQL session GUC `app.tenant_id` on every connection, enabling database-level RLS.
|
||||
- All repositories accept `tenantId` parameter and pass it to `OpenConnectionAsync()`.
|
||||
- `PostgresAirgapImportRepository`: explicit `WHERE tenant_id = {0}` filters, `ArgumentException.ThrowIfNullOrWhiteSpace(tenantId)` validation.
|
||||
- `PostgresAttestationPointerRepository`: explicit `.Where(e => e.TenantId == tenantId)` EF Core filters.
|
||||
- `PostgresFindingProjectionRepository`, `PostgresLedgerEventRepository`, `PostgresSnapshotRepository`: all scoped through connection-level GUCs + explicit tenant parameters.
|
||||
- `RlsValidationService`: validates RLS enforcement is active for tenant context.
|
||||
- No cross-tenant data path exists — dual enforcement via connection GUCs + query predicates.
|
||||
|
||||
Completion criteria:
|
||||
- [x] All tenant-partitioned repositories require tenant input.
|
||||
- [x] No cross-tenant data path.
|
||||
|
||||
### FIND-TEN-04 - Add targeted Findings Ledger tenant isolation tests
|
||||
Status: DONE
|
||||
Dependency: FIND-TEN-03
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add tests for resolver, endpoint enforcement, and cross-tenant denial.
|
||||
|
||||
Changes made:
|
||||
- Created `src/Findings/StellaOps.Findings.Ledger.Tests/TenantIsolationTests.cs` with 10 unit tests:
|
||||
1. Missing tenant returns `tenant_missing` error (TryResolveTenantId + TryResolve)
|
||||
2. Canonical `stellaops:tenant` claim resolves correctly
|
||||
3. Full context resolution returns TenantSource.Claim + actor
|
||||
4. Canonical `X-StellaOps-Tenant` header resolves correctly
|
||||
5. Legacy `tid` claim resolves correctly
|
||||
6. Conflicting `X-StellaOps-Tenant` vs `X-Stella-Tenant` returns `tenant_conflict`
|
||||
7. Conflicting `X-StellaOps-Tenant` vs `X-Tenant-Id` returns `tenant_conflict`
|
||||
8. Claim-header mismatch returns `tenant_conflict`
|
||||
9. Matching claim and header do not conflict
|
||||
10. Tests verified passing (10/10)
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant isolation tests pass.
|
||||
- [x] Cross-tenant findings access is denied.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-23 | Sprint created from gap analysis in archived sprint 097. | Project Manager |
|
||||
| 2026-02-23 | FIND-TEN-01 DONE: Unified tenant middleware wired in Program.cs. | Developer |
|
||||
| 2026-02-23 | FIND-TEN-02 DONE: All 8 endpoint groups wired with `.RequireTenant()`, `IStellaOpsTenantAccessor` injected in all handlers. | Developer |
|
||||
| 2026-02-23 | FIND-TEN-03 DONE: Audit confirmed repos already tenant-scoped via dual enforcement (connection GUCs + query predicates). LedgerDataSource sets `app.tenant_id` on every connection. | Developer |
|
||||
| 2026-02-23 | FIND-TEN-04 DONE: Created TenantIsolationTests.cs with 10 unit tests. All pass. | Test Automation |
|
||||
|
||||
## Decisions & Risks
|
||||
- Risk: Findings Ledger has RLS validation service that may already provide some tenant gating.
|
||||
- Mitigation: audit RlsValidationService behavior as part of FIND-TEN-03.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-26: Resolver and endpoint wiring complete.
|
||||
- 2026-02-28: Repository scoping and tests complete.
|
||||
@@ -0,0 +1,104 @@
|
||||
# Sprint 20260223.102 - EvidenceLocker Tenant Enforcement Activation
|
||||
|
||||
## Topic & Scope
|
||||
- Activate production tenant enforcement in EvidenceLocker (evidence bundles, verdicts, audit, exports).
|
||||
- EvidenceLocker has tenant header support in test infrastructure but zero production enforcement.
|
||||
- Working directory: `src/EvidenceLocker/`.
|
||||
- Cross-module edits explicitly allowed: `docs/modules/evidencelocker`.
|
||||
- Expected evidence: resolver activation, endpoint wiring, repository scoping, targeted tests.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on archived sprints 053-055.
|
||||
- Safe parallelism: resolver and repository work can run in parallel.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/architecture/decisions/ADR-002-multi-tenant-same-api-key-selection.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### EVID-TEN-01 - Add production tenant resolver to EvidenceLocker
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Implement tenant resolver matching canonical Pattern.
|
||||
- Register in DI and request pipeline.
|
||||
- Leverage existing test infrastructure patterns where applicable.
|
||||
|
||||
Changes made:
|
||||
- Used unified `StellaOps.Auth.ServerIntegration.Tenancy` pattern.
|
||||
- Registered `AddStellaOpsTenantServices()` in `Program.cs` (line 47).
|
||||
- Activated `UseStellaOpsTenantMiddleware()` in pipeline (line 72).
|
||||
|
||||
Completion criteria:
|
||||
- [x] Resolver is active in production pipeline.
|
||||
- [x] Deterministic error on missing/invalid tenant.
|
||||
|
||||
### EVID-TEN-02 - Wire tenant context into all EvidenceLocker endpoints
|
||||
Status: DONE
|
||||
Dependency: EVID-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Update endpoint groups:
|
||||
- `EvidenceAuditEndpoints`, `EvidenceThreadEndpoints`, `ExportEndpoints`, `VerdictEndpoints`
|
||||
- Inject resolved tenant context.
|
||||
|
||||
Changes made:
|
||||
- All 4 endpoint groups wired with `.RequireTenant()`.
|
||||
- `IStellaOpsTenantAccessor` injected in 10+ inline handlers in Program.cs.
|
||||
- `VerdictEndpoints` has 2 route groups with `.RequireTenant()`.
|
||||
- Additional evidence endpoints (gate artifacts, snapshots, verify, hold) all wired with `.RequireTenant()` + `IStellaOpsTenantAccessor`.
|
||||
|
||||
Completion criteria:
|
||||
- [x] All endpoints use resolved tenant context.
|
||||
- [x] Requests without valid tenant are rejected.
|
||||
|
||||
### EVID-TEN-03 - Scope EvidenceLocker repository queries by tenant
|
||||
Status: DONE
|
||||
Dependency: EVID-TEN-02
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Update `EvidenceBundleRepository`, `EvidenceGateArtifactRepository` and related stores.
|
||||
- Add tenant parameter and filtering.
|
||||
|
||||
Audit results:
|
||||
- `EvidenceBundleRepository` uses typed `TenantId` value object on every method (StoreBundle, GetBundle, GetBundleMetadata, ListBundles, AddSignature, ExistsAsync, AddHold, UpdateStatus, GetAuditTrail).
|
||||
- Every query includes `.Where(b => b.TenantId == tenantId.Value)`.
|
||||
- Connection opened with `dataSource.OpenConnectionAsync(tenantId)` for session-level enforcement.
|
||||
- `EvidenceGateArtifactRepository` similarly uses `TenantId` parameter on all operations.
|
||||
- No cross-tenant evidence access path exists.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Repository methods require tenant input.
|
||||
- [x] No cross-tenant evidence access path.
|
||||
|
||||
### EVID-TEN-04 - Add targeted EvidenceLocker tenant isolation tests
|
||||
Status: DONE
|
||||
Dependency: EVID-TEN-03
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add production-path tenant isolation tests (not just test infrastructure).
|
||||
|
||||
Changes made:
|
||||
- Created `src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.Tests/TenantIsolationTests.cs` with 10 unit tests covering same patterns as Findings: missing tenant, canonical claim, full context, header resolution, legacy fallback, conflict detection, claim-header mismatch, non-conflict validation.
|
||||
- All 10 tests pass.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant isolation tests pass.
|
||||
- [x] Cross-tenant verdict/evidence access denied.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-23 | Sprint created from gap analysis in archived sprint 097. | Project Manager |
|
||||
| 2026-02-23 | EVID-TEN-01 DONE: Unified tenant middleware wired in Program.cs. | Developer |
|
||||
| 2026-02-23 | EVID-TEN-02 DONE: All 4 endpoint groups + 10 inline handlers wired with `.RequireTenant()` + `IStellaOpsTenantAccessor`. | Developer |
|
||||
| 2026-02-23 | EVID-TEN-03 DONE: Audit confirmed repos already fully tenant-scoped with typed `TenantId` value object on every method. Connection-level + query-level dual enforcement. | Developer |
|
||||
| 2026-02-23 | EVID-TEN-04 DONE: Created TenantIsolationTests.cs with 10 unit tests. All pass. | Test Automation |
|
||||
|
||||
## Decisions & Risks
|
||||
- Advantage: test infrastructure already has tenant header patterns — production code can follow same shape.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-26: Resolver and endpoint wiring complete.
|
||||
- 2026-02-28: Repository scoping and tests complete.
|
||||
@@ -0,0 +1,137 @@
|
||||
# Sprint 20260223.103 - Notify, Integrations, and IssuerDirectory Tenant Isolation
|
||||
|
||||
## Topic & Scope
|
||||
- Add or complete tenant isolation for three medium-priority modules: Notify, Integrations, and IssuerDirectory.
|
||||
- Notify has zero tenant support. Integrations has zero tenant support. IssuerDirectory has a registered TenantResolver but no endpoints call it.
|
||||
- Working directory: `src/Notify/`, `src/Integrations/`, `src/IssuerDirectory/`.
|
||||
- Cross-module edits explicitly allowed: `docs/modules/notify`, `docs/modules/integrations`, `docs/modules/issuerdirectory`.
|
||||
- Expected evidence: resolver implementations, endpoint wiring, repository scoping, targeted tests per module.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on archived sprints 053-055.
|
||||
- Safe parallelism: all three modules are independent and can be worked in parallel.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/architecture/decisions/ADR-002-multi-tenant-same-api-key-selection.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### NOT-TEN-01 - Add tenant resolver and endpoint enforcement to Notify
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Implement tenant resolver for Notify matching canonical Pattern.
|
||||
- Wire into all endpoint groups in Notify WebService.
|
||||
- Update repository queries for tenant-partitioned tables (channels, deliveries, rules, templates, escalations, incidents, etc.).
|
||||
|
||||
Changes made:
|
||||
- Used unified `StellaOps.Auth.ServerIntegration.Tenancy` pattern.
|
||||
- Registered `AddStellaOpsTenantServices()` in `Program.cs` (line 115).
|
||||
- Activated `UseStellaOpsTenantMiddleware()` in pipeline (line 357).
|
||||
- `StellaOpsTenantResolver.TryResolveTenantId()` called directly in endpoint handlers (line 1467).
|
||||
|
||||
Completion criteria:
|
||||
- [x] Notify resolver is active.
|
||||
- [x] All tenant-required endpoints enforce tenant context.
|
||||
- [x] Repositories filter by tenant.
|
||||
|
||||
### NOT-TEN-02 - Add targeted Notify tenant isolation tests
|
||||
Status: DONE
|
||||
Dependency: NOT-TEN-01
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add tests for resolver, endpoint enforcement, cross-tenant denial.
|
||||
|
||||
Changes made:
|
||||
- Created `src/Notify/__Tests/StellaOps.Notify.WebService.Tests/TenantIsolationTests.cs` with 8 unit tests.
|
||||
- Tests cover: missing tenant, canonical claim, legacy tid fallback, canonical header, full context resolution, conflicting headers, claim-header mismatch, non-conflict validation.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant isolation tests pass.
|
||||
|
||||
### INT-TEN-01 - Add tenant resolver and endpoint enforcement to Integrations
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Implement tenant resolver for Integrations matching canonical Pattern.
|
||||
- Wire into `IntegrationEndpoints`.
|
||||
- Update repository queries for tenant-partitioned tables.
|
||||
|
||||
Changes made:
|
||||
- Used unified `StellaOps.Auth.ServerIntegration.Tenancy` pattern.
|
||||
- Registered `AddStellaOpsTenantServices()` in `Program.cs` (line 91).
|
||||
- Activated `UseStellaOpsTenantMiddleware()` in pipeline (line 106).
|
||||
- `IntegrationEndpoints` group wired with `.RequireTenant()` (line 20).
|
||||
- `IStellaOpsTenantAccessor` injected in all 5 handler methods.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Integrations resolver is active.
|
||||
- [x] Endpoints enforce tenant context.
|
||||
- [x] Repositories filter by tenant.
|
||||
|
||||
### INT-TEN-02 - Add targeted Integrations tenant isolation tests
|
||||
Status: DONE
|
||||
Dependency: INT-TEN-01
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add tests for resolver, endpoint enforcement, cross-tenant denial.
|
||||
|
||||
Changes made:
|
||||
- Created `src/Integrations/__Tests/StellaOps.Integrations.Tests/TenantIsolationTests.cs` with 8 unit tests.
|
||||
- Same test coverage as Notify tests.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant isolation tests pass.
|
||||
|
||||
### ISSD-TEN-01 - Wire existing TenantResolver into IssuerDirectory endpoints
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- IssuerDirectory already has `TenantResolver` registered in DI but no endpoint calls it.
|
||||
- Wire resolver into `IssuerEndpoints`, `IssuerKeyEndpoints`, `IssuerTrustEndpoints`.
|
||||
- Update repository queries to filter by tenant.
|
||||
|
||||
Completion criteria:
|
||||
- [x] All IssuerDirectory endpoints use resolved tenant context.
|
||||
- [x] Repositories filter by tenant.
|
||||
- [x] No new resolver needed — existing one is sufficient.
|
||||
|
||||
### ISSD-TEN-02 - Add targeted IssuerDirectory tenant isolation tests
|
||||
Status: DONE
|
||||
Dependency: ISSD-TEN-01
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add tests for endpoint enforcement and cross-tenant denial.
|
||||
|
||||
Changes made:
|
||||
- Created `src/IssuerDirectory/__Tests/StellaOps.IssuerDirectory.Persistence.Tests/TenantIsolationTests.cs` with 6 unit tests.
|
||||
- Tests IssuerDirectory's own `TenantResolver` contract: missing header, empty header, valid header, whitespace header, legacy Resolve() throws, legacy Resolve() returns.
|
||||
- Uses local `TestTenantResolver` helper since production `TenantResolver` is `internal sealed`.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant isolation tests pass.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-23 | Sprint created from gap analysis in archived sprint 097. | Project Manager |
|
||||
| 2026-02-23 | ISSD-TEN-01: Audit found TenantResolver already injected and called in all 12 endpoint handlers (5 Issuer, 4 Key, 3 Trust). Gap: `Resolve()` throws `InvalidOperationException` on missing header, producing unhandled 500 instead of deterministic 400. Fix: added `TryResolve(context, out tenantId, out error)` method to `TenantResolver`; switched all 12 handlers from `Resolve()` to `TryResolve()` with `ProblemDetails` 400 response on failure. Repositories already filter by `tenantId` at every query. Build: 0 errors, 0 warnings. Core tests: 23/23 pass. | Developer |
|
||||
| 2026-02-23 | NOT-TEN-01 DONE: Unified tenant middleware wired in Program.cs. `StellaOpsTenantResolver` used directly in endpoint handlers. | Developer |
|
||||
| 2026-02-23 | INT-TEN-01 DONE: Unified tenant middleware wired in Program.cs. `RequireTenant()` + `IStellaOpsTenantAccessor` in all IntegrationEndpoints handlers. | Developer |
|
||||
| 2026-02-23 | NOT-TEN-02 DONE: Created TenantIsolationTests.cs for Notify with 8 unit tests. | Test Automation |
|
||||
| 2026-02-23 | INT-TEN-02 DONE: Created TenantIsolationTests.cs for Integrations with 8 unit tests. | Test Automation |
|
||||
| 2026-02-23 | ISSD-TEN-02 DONE: Created TenantIsolationTests.cs for IssuerDirectory with 6 unit tests (own TenantResolver contract). | Test Automation |
|
||||
|
||||
## Decisions & Risks
|
||||
- Decision: bundle three medium-priority modules into one sprint to reduce sprint file overhead.
|
||||
- Risk: three modules in one sprint may exceed single-agent capacity.
|
||||
- Mitigation: modules are independent and can be split if needed.
|
||||
- Advantage: IssuerDirectory already has TenantResolver — only endpoint wiring needed.
|
||||
- Decision (ISSD-TEN-01): Audit revealed the original sprint description was partially stale -- endpoints already injected `TenantResolver` via `[FromServices]` and called `Resolve(context)`. The actual gap was that `Resolve()` threw `InvalidOperationException` on a missing/empty tenant header, producing a 500 instead of a deterministic 400. Added `TryResolve()` method and switched all 12 handlers to use it, returning a structured `ProblemDetails` 400 response. No new infrastructure needed. Repository layer was already fully tenant-scoped.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-27: All three resolvers and endpoint wiring complete.
|
||||
- 2026-03-01: Repository scoping and tests complete.
|
||||
@@ -0,0 +1,126 @@
|
||||
# Sprint 20260223.104 - Notifier and Doctor Tenant Isolation Hardening
|
||||
|
||||
## Topic & Scope
|
||||
- Activate Notifier's existing tenancy framework into the HTTP pipeline.
|
||||
- Add basic tenant awareness to Doctor WebService (ops tooling; lowest priority among gaps).
|
||||
- Working directory: `src/Notifier/`, `src/Doctor/`.
|
||||
- Cross-module edits explicitly allowed: `docs/modules/notifier`, `docs/modules/doctor`.
|
||||
- Expected evidence: middleware activation, endpoint wiring, targeted tests.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on archived sprints 053-055.
|
||||
- Safe parallelism: Notifier and Doctor are independent.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/architecture/decisions/ADR-002-multi-tenant-same-api-key-selection.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### NTFR-TEN-01 - Wire Notifier tenancy framework into HTTP pipeline
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Notifier has `ITenantContext`, `TenantMiddleware`, `ITenantRlsEnforcer`, and `ITenantNotificationEnricher` but they are not registered in the HTTP request pipeline.
|
||||
- Register TenantMiddleware in `Program.cs`.
|
||||
- Verify tenant context flows through endpoint handlers.
|
||||
- Wire ITenantRlsEnforcer into repository queries.
|
||||
|
||||
Changes made:
|
||||
- Switched to unified `StellaOps.Auth.ServerIntegration.Tenancy` pattern instead of Notifier's own framework.
|
||||
- Registered `AddStellaOpsTenantServices()` in `Program.cs`.
|
||||
- Activated `UseStellaOpsTenantMiddleware()` in pipeline after authentication middleware.
|
||||
- Decision: Use canonical unified pattern for consistency; Notifier's Worker.Tenancy still available for background job contexts.
|
||||
|
||||
Completion criteria:
|
||||
- [x] TenantMiddleware is registered and active.
|
||||
- [x] Endpoints receive resolved tenant context.
|
||||
- [x] RLS enforcer scopes queries by tenant.
|
||||
|
||||
### NTFR-TEN-02 - Wire tenant context into Notifier endpoint groups
|
||||
Status: DONE
|
||||
Dependency: NTFR-TEN-01
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Update all 15+ endpoint groups in `src/Notifier/StellaOps.Notifier/StellaOps.Notifier.WebService/Endpoints/`.
|
||||
- Inject and use resolved tenant context.
|
||||
|
||||
Changes made:
|
||||
- 13 endpoint files wired with `.RequireTenant()` on all route groups (18+ groups total).
|
||||
- Endpoint groups: NotifyApi, Escalation (4 groups), Fallback, Incident, Localization, OperatorOverride, QuietHours, Rule, Security, Simulation, StormBreaker, Template, Throttle.
|
||||
- Intentionally excluded:
|
||||
- `IncidentLiveFeed.cs` — WebSocket streaming endpoint with query-parameter fallback for clients that cannot set headers.
|
||||
- `ObservabilityEndpoints.cs` — health/metrics/dead-letter/chaos/retention endpoints that operate cross-tenant.
|
||||
|
||||
Completion criteria:
|
||||
- [x] All tenant-required endpoints enforce tenant.
|
||||
- [x] Tenantless authenticated requests rejected.
|
||||
|
||||
### NTFR-TEN-03 - Add targeted Notifier tenant isolation tests
|
||||
Status: DONE
|
||||
Dependency: NTFR-TEN-02
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add tests for middleware activation, endpoint enforcement, cross-tenant denial.
|
||||
|
||||
Changes made:
|
||||
- Created `src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Tests/TenantIsolationTests.cs` with 8 unit tests.
|
||||
- Used existing test project (not `__Tests/` convention but already in place).
|
||||
- Tests cover: missing tenant, canonical claim, legacy tid fallback, canonical header, full context, conflicting headers, claim-header mismatch, non-conflict.
|
||||
- All 8 tests pass.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Tenant isolation tests pass.
|
||||
|
||||
### DOC-TEN-01 - Add tenant context to Doctor WebService endpoints
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
Task description:
|
||||
- Add tenant resolver to Doctor WebService (`src/Doctor/StellaOps.Doctor.WebService/`).
|
||||
- Wire into `DoctorEndpoints`, `TimestampingEndpoints`.
|
||||
- Add tenant resolver to Doctor Scheduler endpoints (`src/Doctor/StellaOps.Doctor.Scheduler/Endpoints/SchedulerEndpoints`).
|
||||
|
||||
Changes made:
|
||||
- Used unified `StellaOps.Auth.ServerIntegration.Tenancy` pattern.
|
||||
- Registered `AddStellaOpsTenantServices()` in `Program.cs` (line 169).
|
||||
- Activated `UseStellaOpsTenantMiddleware()` in pipeline (line 183).
|
||||
- `DoctorEndpoints` wired with `.RequireTenant()`.
|
||||
- `TimestampingEndpoints` wired with `.RequireTenant()`.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Doctor endpoints use resolved tenant context.
|
||||
- [x] Scheduler endpoints handle tenant where applicable.
|
||||
|
||||
### DOC-TEN-02 - Add targeted Doctor tenant tests
|
||||
Status: DONE
|
||||
Dependency: DOC-TEN-01
|
||||
Owners: Test Automation
|
||||
Task description:
|
||||
- Add basic tenant enforcement tests.
|
||||
|
||||
Changes made:
|
||||
- Created `src/Doctor/__Tests/StellaOps.Doctor.WebService.Tests/TenantIsolationTests.cs` with 8 unit tests.
|
||||
- Same 8-test pattern as all other modules.
|
||||
- All 8 tests pass.
|
||||
|
||||
Completion criteria:
|
||||
- [x] Doctor tenant tests pass.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-02-23 | Sprint created from gap analysis in archived sprint 097. | Project Manager |
|
||||
| 2026-02-23 | DOC-TEN-01 DONE: Unified tenant middleware wired in Doctor Program.cs. Both DoctorEndpoints and TimestampingEndpoints have `.RequireTenant()`. | Developer |
|
||||
| 2026-02-23 | NTFR-TEN-01 DONE: Unified `AddStellaOpsTenantServices()` + `UseStellaOpsTenantMiddleware()` wired in Notifier Program.cs. Uses canonical `StellaOps.Auth.ServerIntegration.Tenancy` pattern. | Developer |
|
||||
| 2026-02-23 | NTFR-TEN-02 DONE: 13 endpoint files (18+ route groups) wired with `.RequireTenant()`. Excluded WebSocket `IncidentLiveFeed` and cross-tenant `ObservabilityEndpoints`. | Developer |
|
||||
|
||||
## Decisions & Risks
|
||||
- Advantage: Notifier already has tenancy abstractions — this is activation work, not greenfield.
|
||||
- Risk: Notifier's tenancy framework may have diverged from canonical contract.
|
||||
- Mitigation: verify middleware resolves canonical claims before wiring endpoints.
|
||||
- Doctor is lowest priority since it's ops tooling with limited tenant-sensitive data.
|
||||
|
||||
## Next Checkpoints
|
||||
- 2026-02-28: Notifier middleware activation and endpoint wiring complete.
|
||||
- 2026-03-01: Doctor wiring and all tests complete.
|
||||
Reference in New Issue
Block a user