Restructure solution layout by module
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
Deliver the Advisory AI assistant service that synthesizes advisory/VEX evidence, policy context, and SBOM data into summaries, conflict explanations, and remediation hints—always with citations and guardrails.
|
||||
|
||||
## Scope
|
||||
- Service under `src/StellaOps.AdvisoryAI` (retrievers, deterministics, orchestrator, guardrails, inference adapters, REST APIs).
|
||||
- Service under `src/AdvisoryAI/StellaOps.AdvisoryAI` (retrievers, deterministics, orchestrator, guardrails, inference adapters, REST APIs).
|
||||
- Batch processing for CLI/automation, caching, observability, and integration with Console, CLI, and downstream systems.
|
||||
- Coordination across Conseiller, Excitator, VEX Lens, SBOM Service, Policy Engine, Findings Ledger, Web Gateway, Authority, DevOps, and Docs.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Advisory AI Task Board — Epic 8
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIAI-31-001 | TODO | Advisory AI Guild | CONCELIER-VULN-29-001, EXCITITOR-VULN-29-001 | Implement structured and vector retrievers for advisories/VEX with paragraph anchors and citation metadata. | Retrievers return deterministic chunks with source IDs/sections; unit tests cover CSAF/OSV/vendor formats. |
|
||||
| AIAI-31-002 | TODO | Advisory AI Guild, SBOM Service Guild | SBOM-VULN-29-001 | Build SBOM context retriever (purl version timelines, dependency paths, env flags, blast radius estimator). | Retriever returns paths/metrics under SLA; tests cover ecosystems. |
|
||||
| AIAI-31-003 | TODO | Advisory AI Guild | AIAI-31-001..002 | Implement deterministic toolset (version comparators, range checks, dependency analysis, policy lookup) exposed via orchestrator. | Tools validated with property tests; outputs cached; docs updated. |
|
||||
| AIAI-31-004 | TODO | Advisory AI Guild | AIAI-31-001..003, AUTH-VULN-29-001 | Build orchestration pipeline for Summary/Conflict/Remediation tasks (prompt templates, tool calls, token budgets, caching). | Pipeline executes tasks deterministically; caches keyed by tuple+policy; integration tests cover tasks. |
|
||||
| AIAI-31-005 | TODO | Advisory AI Guild, Security Guild | AIAI-31-004 | Implement guardrails (redaction, injection defense, output validation, citation enforcement) and fail-safe handling. | Guardrails block adversarial inputs; output validator enforces schemas; security tests pass. |
|
||||
| AIAI-31-006 | TODO | Advisory AI Guild | AIAI-31-004..005 | Expose REST API endpoints (`/advisory/ai/*`) with RBAC, rate limits, OpenAPI schemas, and batching support. | Endpoints deployed with schema validation; rate limits enforced; integration tests cover error codes. |
|
||||
| AIAI-31-007 | TODO | Advisory AI Guild, Observability Guild | AIAI-31-004..006 | Instrument metrics (`advisory_ai_latency`, `guardrail_blocks`, `validation_failures`, `citation_coverage`), logs, and traces; publish dashboards/alerts. | Telemetry live; dashboards approved; alerts configured. |
|
||||
| AIAI-31-008 | TODO | Advisory AI Guild, DevOps Guild | AIAI-31-006..007 | Package inference on-prem container, remote inference toggle, Helm/Compose manifests, scaling guidance, offline kit instructions. | Deployment docs merged; smoke deploy executed; offline kit updated; feature flags documented. |
|
||||
| AIAI-31-009 | TODO | Advisory AI Guild, QA Guild | AIAI-31-001..006 | Develop unit/golden/property/perf tests, injection harness, and regression suite; ensure determinism with seeded caches. | Test suite green; golden outputs stored; injection tests pass; perf targets documented. |
|
||||
# Advisory AI Task Board — Epic 8
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIAI-31-001 | TODO | Advisory AI Guild | CONCELIER-VULN-29-001, EXCITITOR-VULN-29-001 | Implement structured and vector retrievers for advisories/VEX with paragraph anchors and citation metadata. | Retrievers return deterministic chunks with source IDs/sections; unit tests cover CSAF/OSV/vendor formats. |
|
||||
| AIAI-31-002 | TODO | Advisory AI Guild, SBOM Service Guild | SBOM-VULN-29-001 | Build SBOM context retriever (purl version timelines, dependency paths, env flags, blast radius estimator). | Retriever returns paths/metrics under SLA; tests cover ecosystems. |
|
||||
| AIAI-31-003 | TODO | Advisory AI Guild | AIAI-31-001..002 | Implement deterministic toolset (version comparators, range checks, dependency analysis, policy lookup) exposed via orchestrator. | Tools validated with property tests; outputs cached; docs updated. |
|
||||
| AIAI-31-004 | TODO | Advisory AI Guild | AIAI-31-001..003, AUTH-VULN-29-001 | Build orchestration pipeline for Summary/Conflict/Remediation tasks (prompt templates, tool calls, token budgets, caching). | Pipeline executes tasks deterministically; caches keyed by tuple+policy; integration tests cover tasks. |
|
||||
| AIAI-31-005 | TODO | Advisory AI Guild, Security Guild | AIAI-31-004 | Implement guardrails (redaction, injection defense, output validation, citation enforcement) and fail-safe handling. | Guardrails block adversarial inputs; output validator enforces schemas; security tests pass. |
|
||||
| AIAI-31-006 | TODO | Advisory AI Guild | AIAI-31-004..005 | Expose REST API endpoints (`/advisory/ai/*`) with RBAC, rate limits, OpenAPI schemas, and batching support. | Endpoints deployed with schema validation; rate limits enforced; integration tests cover error codes. |
|
||||
| AIAI-31-007 | TODO | Advisory AI Guild, Observability Guild | AIAI-31-004..006 | Instrument metrics (`advisory_ai_latency`, `guardrail_blocks`, `validation_failures`, `citation_coverage`), logs, and traces; publish dashboards/alerts. | Telemetry live; dashboards approved; alerts configured. |
|
||||
| AIAI-31-008 | TODO | Advisory AI Guild, DevOps Guild | AIAI-31-006..007 | Package inference on-prem container, remote inference toggle, Helm/Compose manifests, scaling guidance, offline kit instructions. | Deployment docs merged; smoke deploy executed; offline kit updated; feature flags documented. |
|
||||
| AIAI-31-009 | TODO | Advisory AI Guild, QA Guild | AIAI-31-001..006 | Develop unit/golden/property/perf tests, injection harness, and regression suite; ensure determinism with seeded caches. | Test suite green; golden outputs stored; injection tests pass; perf targets documented. |
|
||||
@@ -1,16 +1,16 @@
|
||||
# StellaOps AirGap Controller Guild Charter
|
||||
|
||||
## Mission
|
||||
Own the sealing state machine, status APIs, and enforcement hooks that keep StellaOps compliant in sealed air-gapped environments while respecting the imposed rule.
|
||||
|
||||
## Scope
|
||||
- Persisted air-gap state (`sealed`, policy hash, time anchor metadata) and RBAC enforcement.
|
||||
- HTTP endpoints for seal/unseal/status and integration with Authority scopes.
|
||||
- Startup diagnostics that refuse to run when sealing requirements are unmet.
|
||||
- Coordination with DevOps for Kubernetes/Compose egress policies.
|
||||
- Telemetry and audit events reflecting sealing actions and violations.
|
||||
|
||||
## Definition of Done
|
||||
- Deterministic tests for seal/unseal transitions and audit logging.
|
||||
- Integration tests covering RBAC, sealed-mode refusal, and policy hash validation.
|
||||
- Documentation hooks updated in `/docs/airgap/` for each shipped feature.
|
||||
# StellaOps AirGap Controller Guild Charter
|
||||
|
||||
## Mission
|
||||
Own the sealing state machine, status APIs, and enforcement hooks that keep StellaOps compliant in sealed air-gapped environments while respecting the imposed rule.
|
||||
|
||||
## Scope
|
||||
- Persisted air-gap state (`sealed`, policy hash, time anchor metadata) and RBAC enforcement.
|
||||
- HTTP endpoints for seal/unseal/status and integration with Authority scopes.
|
||||
- Startup diagnostics that refuse to run when sealing requirements are unmet.
|
||||
- Coordination with DevOps for Kubernetes/Compose egress policies.
|
||||
- Telemetry and audit events reflecting sealing actions and violations.
|
||||
|
||||
## Definition of Done
|
||||
- Deterministic tests for seal/unseal transitions and audit logging.
|
||||
- Integration tests covering RBAC, sealed-mode refusal, and policy hash validation.
|
||||
- Documentation hooks updated in `/docs/airgap/` for each shipped feature.
|
||||
@@ -1,18 +1,18 @@
|
||||
# AirGap Controller Task Board — Epic 16: Air-Gapped Mode
|
||||
|
||||
## Sprint 56 – Sealing Foundations
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-CTL-56-001 | TODO | AirGap Controller Guild | AUTH-OBS-50-001 | Implement `airgap_state` persistence, seal/unseal state machine, and Authority scope checks (`airgap:seal`, `airgap:status:read`). | State table created with migrations; seal/unseal transitions audited; unit tests cover happy/error paths. |
|
||||
| AIRGAP-CTL-56-002 | TODO | AirGap Controller Guild, DevOps Guild | AIRGAP-CTL-56-001, DEVOPS-AIRGAP-56-001 | Expose `GET /system/airgap/status`, `POST /system/airgap/seal`, integrate policy hash validation, and return staleness/time anchor placeholders. | APIs documented with OpenAPI; RBAC enforced; integration tests cover unauthorized/sealed states. |
|
||||
|
||||
## Sprint 57 – Enforcement & Diagnostics
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-CTL-57-001 | TODO | AirGap Controller Guild | AIRGAP-CTL-56-002 | Add startup diagnostics that block application run when sealed flag set but egress policies missing; emit audit + telemetry. | Startup guard tested with simulated failure; telemetry includes `airgap_sealed=true`; docs updated. |
|
||||
| AIRGAP-CTL-57-002 | TODO | AirGap Controller Guild, Observability Guild | AIRGAP-CTL-56-002, TELEMETRY-OBS-50-001 | Instrument seal/unseal events with trace/log fields and timeline emission (`airgap.sealed`, `airgap.unsealed`). | Timeline events validated; logs include actor/tenant/policy hash; integration test covers duplication suppression. |
|
||||
|
||||
## Sprint 58 – Time Anchor & Drift
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-CTL-58-001 | TODO | AirGap Controller Guild, AirGap Time Guild | AIRGAP-CTL-56-002, AIRGAP-TIME-57-001 | Persist time anchor metadata, compute drift seconds, and surface staleness budgets in status API. | Time anchor stored with bundle ID; drift calculation validated in tests; status API returns staleness metrics. |
|
||||
# AirGap Controller Task Board — Epic 16: Air-Gapped Mode
|
||||
|
||||
## Sprint 56 – Sealing Foundations
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-CTL-56-001 | TODO | AirGap Controller Guild | AUTH-OBS-50-001 | Implement `airgap_state` persistence, seal/unseal state machine, and Authority scope checks (`airgap:seal`, `airgap:status:read`). | State table created with migrations; seal/unseal transitions audited; unit tests cover happy/error paths. |
|
||||
| AIRGAP-CTL-56-002 | TODO | AirGap Controller Guild, DevOps Guild | AIRGAP-CTL-56-001, DEVOPS-AIRGAP-56-001 | Expose `GET /system/airgap/status`, `POST /system/airgap/seal`, integrate policy hash validation, and return staleness/time anchor placeholders. | APIs documented with OpenAPI; RBAC enforced; integration tests cover unauthorized/sealed states. |
|
||||
|
||||
## Sprint 57 – Enforcement & Diagnostics
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-CTL-57-001 | TODO | AirGap Controller Guild | AIRGAP-CTL-56-002 | Add startup diagnostics that block application run when sealed flag set but egress policies missing; emit audit + telemetry. | Startup guard tested with simulated failure; telemetry includes `airgap_sealed=true`; docs updated. |
|
||||
| AIRGAP-CTL-57-002 | TODO | AirGap Controller Guild, Observability Guild | AIRGAP-CTL-56-002, TELEMETRY-OBS-50-001 | Instrument seal/unseal events with trace/log fields and timeline emission (`airgap.sealed`, `airgap.unsealed`). | Timeline events validated; logs include actor/tenant/policy hash; integration test covers duplication suppression. |
|
||||
|
||||
## Sprint 58 – Time Anchor & Drift
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-CTL-58-001 | TODO | AirGap Controller Guild, AirGap Time Guild | AIRGAP-CTL-56-002, AIRGAP-TIME-57-001 | Persist time anchor metadata, compute drift seconds, and surface staleness budgets in status API. | Time anchor stored with bundle ID; drift calculation validated in tests; status API returns staleness metrics. |
|
||||
@@ -1,16 +1,16 @@
|
||||
# StellaOps AirGap Importer Guild Charter
|
||||
|
||||
## Mission
|
||||
Deliver offline bundle verification and ingestion tooling for sealed environments, covering DSSE/TUF validation, catalog updates, and audit logging under the imposed rule.
|
||||
|
||||
## Scope
|
||||
- TUF metadata verification, DSSE signature checks, Merkle root validation.
|
||||
- Import pipelines writing bundle catalogs, object-store layouts, and audit entries.
|
||||
- CLI + API surfaces for dry-run verification, import, and status queries.
|
||||
- Integration hooks for Conseiller, Excitator, Policy Engine, and Export Center.
|
||||
- Negative-case handling (tampering, expired signatures, root rotation) with operator guidance.
|
||||
|
||||
## Definition of Done
|
||||
- Deterministic fixtures for valid/invalid bundles committed.
|
||||
- Integration tests prove catalog + object-store updates are idempotent.
|
||||
- Import audit trail viewable via API and timeline events.
|
||||
# StellaOps AirGap Importer Guild Charter
|
||||
|
||||
## Mission
|
||||
Deliver offline bundle verification and ingestion tooling for sealed environments, covering DSSE/TUF validation, catalog updates, and audit logging under the imposed rule.
|
||||
|
||||
## Scope
|
||||
- TUF metadata verification, DSSE signature checks, Merkle root validation.
|
||||
- Import pipelines writing bundle catalogs, object-store layouts, and audit entries.
|
||||
- CLI + API surfaces for dry-run verification, import, and status queries.
|
||||
- Integration hooks for Conseiller, Excitator, Policy Engine, and Export Center.
|
||||
- Negative-case handling (tampering, expired signatures, root rotation) with operator guidance.
|
||||
|
||||
## Definition of Done
|
||||
- Deterministic fixtures for valid/invalid bundles committed.
|
||||
- Integration tests prove catalog + object-store updates are idempotent.
|
||||
- Import audit trail viewable via API and timeline events.
|
||||
@@ -1,19 +1,19 @@
|
||||
# AirGap Importer Task Board — Epic 16: Air-Gapped Mode
|
||||
|
||||
## Sprint 56 – Verification Primitives
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-IMP-56-001 | TODO | AirGap Importer Guild | PROV-OBS-53-001 | Implement DSSE verification helpers, TUF metadata parser (`root.json`, `snapshot.json`, `timestamp.json`), and Merkle root calculator. | Verifier returns structured results; unit tests cover valid/invalid signatures and tampering scenarios. |
|
||||
| AIRGAP-IMP-56-002 | TODO | AirGap Importer Guild, Security Guild | AIRGAP-IMP-56-001 | Introduce root rotation policy validation (dual approval) and signer trust store management. | Rotation policy enforced; tests cover valid rotation and rollback; docs stub updated. |
|
||||
|
||||
## Sprint 57 – Catalog & Storage Writes
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-IMP-57-001 | TODO | AirGap Importer Guild | AIRGAP-IMP-56-001, DEVOPS-AIRGAP-56-002 | Write `bundle_catalog` and `bundle_items` repositories with RLS + deterministic migrations. | Catalog tables created; integration tests ensure tenant/global scoping; determinism check passes. |
|
||||
| AIRGAP-IMP-57-002 | TODO | AirGap Importer Guild, DevOps Guild | AIRGAP-IMP-57-001 | Implement object-store loader storing artifacts under tenant/global mirror paths with Zstandard decompression and checksum validation. | Import writes deduplicated objects; checksum mismatches raise errors; storage layout documented. |
|
||||
|
||||
## Sprint 58 – Import Workflows
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-IMP-58-001 | TODO | AirGap Importer Guild, CLI Guild | AIRGAP-IMP-57-002, CLI-AIRGAP-56-001 | Implement API (`POST /airgap/import`, `/airgap/verify`) and CLI commands wiring verification + catalog updates, including diff preview. | CLI/API share validation engine; diff preview surfaces metadata changes; audit entries recorded with trace IDs. |
|
||||
| AIRGAP-IMP-58-002 | TODO | AirGap Importer Guild, Observability Guild | AIRGAP-IMP-58-001, TELEMETRY-OBS-50-001 | Emit timeline events (`airgap.import.started|completed|failed`) and telemetry metrics (bundle bytes, duration, warnings). | Events/metrics validated in integration tests; docs cross-link to observability dashboards. |
|
||||
# AirGap Importer Task Board — Epic 16: Air-Gapped Mode
|
||||
|
||||
## Sprint 56 – Verification Primitives
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-IMP-56-001 | TODO | AirGap Importer Guild | PROV-OBS-53-001 | Implement DSSE verification helpers, TUF metadata parser (`root.json`, `snapshot.json`, `timestamp.json`), and Merkle root calculator. | Verifier returns structured results; unit tests cover valid/invalid signatures and tampering scenarios. |
|
||||
| AIRGAP-IMP-56-002 | TODO | AirGap Importer Guild, Security Guild | AIRGAP-IMP-56-001 | Introduce root rotation policy validation (dual approval) and signer trust store management. | Rotation policy enforced; tests cover valid rotation and rollback; docs stub updated. |
|
||||
|
||||
## Sprint 57 – Catalog & Storage Writes
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-IMP-57-001 | TODO | AirGap Importer Guild | AIRGAP-IMP-56-001, DEVOPS-AIRGAP-56-002 | Write `bundle_catalog` and `bundle_items` repositories with RLS + deterministic migrations. | Catalog tables created; integration tests ensure tenant/global scoping; determinism check passes. |
|
||||
| AIRGAP-IMP-57-002 | TODO | AirGap Importer Guild, DevOps Guild | AIRGAP-IMP-57-001 | Implement object-store loader storing artifacts under tenant/global mirror paths with Zstandard decompression and checksum validation. | Import writes deduplicated objects; checksum mismatches raise errors; storage layout documented. |
|
||||
|
||||
## Sprint 58 – Import Workflows
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-IMP-58-001 | TODO | AirGap Importer Guild, CLI Guild | AIRGAP-IMP-57-002, CLI-AIRGAP-56-001 | Implement API (`POST /airgap/import`, `/airgap/verify`) and CLI commands wiring verification + catalog updates, including diff preview. | CLI/API share validation engine; diff preview surfaces metadata changes; audit entries recorded with trace IDs. |
|
||||
| AIRGAP-IMP-58-002 | TODO | AirGap Importer Guild, Observability Guild | AIRGAP-IMP-58-001, TELEMETRY-OBS-50-001 | Emit timeline events (`airgap.import.started|completed|failed`) and telemetry metrics (bundle bytes, duration, warnings). | Events/metrics validated in integration tests; docs cross-link to observability dashboards. |
|
||||
@@ -1,16 +1,16 @@
|
||||
# StellaOps AirGap Policy Guild Charter
|
||||
|
||||
## Mission
|
||||
Provide the shared enforcement layer (`EgressPolicy`, job plan validators, sealed-mode gates) that keeps all services compliant with Air-Gapped Mode requirements.
|
||||
|
||||
## Scope
|
||||
- `EgressPolicy` facade replacing raw HTTP client usage.
|
||||
- Static analysis/linting to detect unauthorized network calls.
|
||||
- Task Runner and orchestrator validators flagging disallowed destinations.
|
||||
- Shared error contract (`AIRGAP_EGRESS_BLOCKED`) and remediation messages.
|
||||
- Test harnesses simulating sealed/unsealed execution paths.
|
||||
|
||||
## Definition of Done
|
||||
- Every service imports the facade; CI fails on direct HTTP client usage.
|
||||
- Sealed-mode unit tests cover panic/remediation behavior across host types.
|
||||
- Documentation updated in `/docs/dev/airgap-contracts.md` for adoption patterns.
|
||||
# StellaOps AirGap Policy Guild Charter
|
||||
|
||||
## Mission
|
||||
Provide the shared enforcement layer (`EgressPolicy`, job plan validators, sealed-mode gates) that keeps all services compliant with Air-Gapped Mode requirements.
|
||||
|
||||
## Scope
|
||||
- `EgressPolicy` facade replacing raw HTTP client usage.
|
||||
- Static analysis/linting to detect unauthorized network calls.
|
||||
- Task Runner and orchestrator validators flagging disallowed destinations.
|
||||
- Shared error contract (`AIRGAP_EGRESS_BLOCKED`) and remediation messages.
|
||||
- Test harnesses simulating sealed/unsealed execution paths.
|
||||
|
||||
## Definition of Done
|
||||
- Every service imports the facade; CI fails on direct HTTP client usage.
|
||||
- Sealed-mode unit tests cover panic/remediation behavior across host types.
|
||||
- Documentation updated in `/docs/dev/airgap-contracts.md` for adoption patterns.
|
||||
@@ -1,19 +1,19 @@
|
||||
# AirGap Policy Task Board — Epic 16: Air-Gapped Mode
|
||||
|
||||
## Sprint 56 – Facade & Contracts
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-POL-56-001 | TODO | AirGap Policy Guild | TELEMETRY-OBS-50-001 | Implement `StellaOps.AirGap.Policy` package exposing `EgressPolicy` facade with sealed/unsealed branches and remediation-friendly errors. | Facade package builds/tests; integration tests simulate sealed/unsealed; error contract documented. |
|
||||
| AIRGAP-POL-56-002 | TODO | AirGap Policy Guild, DevEx Guild | AIRGAP-POL-56-001 | Create Roslyn analyzer/code fix warning on raw `HttpClient` usage outside approved wrappers; add CI integration. | Analyzer packaged; CI fails on intentional violation; docs updated for opt-in. |
|
||||
|
||||
## Sprint 57 – Service Adoption Wave 1
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-POL-57-001 | TODO | AirGap Policy Guild, BE-Base Platform Guild | AIRGAP-POL-56-001 | Update core web services (Web, Exporter, Policy, Findings, Authority) to use `EgressPolicy`; ensure configuration wiring for sealed mode. | Services compile with facade; sealed-mode tests run in CI; configuration docs updated. |
|
||||
| AIRGAP-POL-57-002 | TODO | AirGap Policy Guild, Task Runner Guild | AIRGAP-POL-56-001, TASKRUN-OBS-50-001 | Implement Task Runner job plan validator rejecting network steps unless marked internal allow-list. | Validator blocks forbidden steps; tests cover allow/deny; error surfaces remediation text. |
|
||||
|
||||
## Sprint 58 – Service Adoption Wave 2
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-POL-58-001 | TODO | AirGap Policy Guild, Observability Guild | AIRGAP-POL-57-001 | Ensure Observability exporters only target local endpoints in sealed mode; disable remote sinks with warning. | Exporters respect sealed flag; timeline/log message emitted; docs updated. |
|
||||
| AIRGAP-POL-58-002 | TODO | AirGap Policy Guild, CLI Guild | AIRGAP-POL-56-001, CLI-OBS-50-001 | Add CLI sealed-mode guard that refuses commands needing egress and surfaces remediation. | CLI returns `AIRGAP_EGRESS_BLOCKED`; tests cover sealed/unsealed flows; help text updated. |
|
||||
# AirGap Policy Task Board — Epic 16: Air-Gapped Mode
|
||||
|
||||
## Sprint 56 – Facade & Contracts
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-POL-56-001 | TODO | AirGap Policy Guild | TELEMETRY-OBS-50-001 | Implement `StellaOps.AirGap.Policy` package exposing `EgressPolicy` facade with sealed/unsealed branches and remediation-friendly errors. | Facade package builds/tests; integration tests simulate sealed/unsealed; error contract documented. |
|
||||
| AIRGAP-POL-56-002 | TODO | AirGap Policy Guild, DevEx Guild | AIRGAP-POL-56-001 | Create Roslyn analyzer/code fix warning on raw `HttpClient` usage outside approved wrappers; add CI integration. | Analyzer packaged; CI fails on intentional violation; docs updated for opt-in. |
|
||||
|
||||
## Sprint 57 – Service Adoption Wave 1
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-POL-57-001 | TODO | AirGap Policy Guild, BE-Base Platform Guild | AIRGAP-POL-56-001 | Update core web services (Web, Exporter, Policy, Findings, Authority) to use `EgressPolicy`; ensure configuration wiring for sealed mode. | Services compile with facade; sealed-mode tests run in CI; configuration docs updated. |
|
||||
| AIRGAP-POL-57-002 | TODO | AirGap Policy Guild, Task Runner Guild | AIRGAP-POL-56-001, TASKRUN-OBS-50-001 | Implement Task Runner job plan validator rejecting network steps unless marked internal allow-list. | Validator blocks forbidden steps; tests cover allow/deny; error surfaces remediation text. |
|
||||
|
||||
## Sprint 58 – Service Adoption Wave 2
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-POL-58-001 | TODO | AirGap Policy Guild, Observability Guild | AIRGAP-POL-57-001 | Ensure Observability exporters only target local endpoints in sealed mode; disable remote sinks with warning. | Exporters respect sealed flag; timeline/log message emitted; docs updated. |
|
||||
| AIRGAP-POL-58-002 | TODO | AirGap Policy Guild, CLI Guild | AIRGAP-POL-56-001, CLI-OBS-50-001 | Add CLI sealed-mode guard that refuses commands needing egress and surfaces remediation. | CLI returns `AIRGAP_EGRESS_BLOCKED`; tests cover sealed/unsealed flows; help text updated. |
|
||||
@@ -1,15 +1,15 @@
|
||||
# StellaOps AirGap Time Guild Charter
|
||||
|
||||
## Mission
|
||||
Manage trusted time anchors and staleness budgets for sealed environments, ensuring deterministic behavior when external time sources are unavailable.
|
||||
|
||||
## Scope
|
||||
- Parse signed time tokens from Mirror Bundles and validate signatures.
|
||||
- Persist `time_anchor` metadata and compute drift/staleness metrics.
|
||||
- Provide helpers for UI/API staleness badges and job gating.
|
||||
- Integrate with Notifications to alert on approaching drift thresholds.
|
||||
|
||||
## Definition of Done
|
||||
- Test vectors for time tokens committed alongside verification code.
|
||||
- Drift calculations deterministic and configurable per tenant.
|
||||
- Documentation updates for `/docs/airgap/staleness-and-time.md` with examples.
|
||||
# StellaOps AirGap Time Guild Charter
|
||||
|
||||
## Mission
|
||||
Manage trusted time anchors and staleness budgets for sealed environments, ensuring deterministic behavior when external time sources are unavailable.
|
||||
|
||||
## Scope
|
||||
- Parse signed time tokens from Mirror Bundles and validate signatures.
|
||||
- Persist `time_anchor` metadata and compute drift/staleness metrics.
|
||||
- Provide helpers for UI/API staleness badges and job gating.
|
||||
- Integrate with Notifications to alert on approaching drift thresholds.
|
||||
|
||||
## Definition of Done
|
||||
- Test vectors for time tokens committed alongside verification code.
|
||||
- Drift calculations deterministic and configurable per tenant.
|
||||
- Documentation updates for `/docs/airgap/staleness-and-time.md` with examples.
|
||||
@@ -1,13 +1,13 @@
|
||||
# AirGap Time Task Board — Epic 16: Air-Gapped Mode
|
||||
|
||||
## Sprint 57 – Time Anchor Validation
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-TIME-57-001 | TODO | AirGap Time Guild | PROV-OBS-54-001, AIRGAP-IMP-56-001 | Implement signed time token parser (Roughtime/RFC3161), verify signatures against bundle trust roots, and expose normalized anchor representation. | Parser handles both token formats; tests cover valid/expired/tampered tokens; documentation stubbed. |
|
||||
| AIRGAP-TIME-57-002 | TODO | AirGap Time Guild, Observability Guild | AIRGAP-TIME-57-001 | Add telemetry counters for time anchors (`airgap_time_anchor_age_seconds`) and alerts for approaching thresholds. | Metrics registered; alert templates created; integration test ensures emission on stale anchor. |
|
||||
|
||||
## Sprint 58 – Drift & Staleness Enforcement
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-TIME-58-001 | TODO | AirGap Time Guild | AIRGAP-TIME-57-001, AIRGAP-CTL-56-002 | Persist drift baseline, compute per-content staleness (advisories, VEX, policy) based on bundle metadata, and surface through controller status API. | Drift/staleness values exposed via API; unit tests cover threshold calculations; docs updated. |
|
||||
| AIRGAP-TIME-58-002 | TODO | AirGap Time Guild, Notifications Guild | AIRGAP-TIME-58-001, NOTIFY-OBS-51-001 | Emit notifications and timeline events when staleness budgets breached or approaching. | Notifications dispatched with remediation; timeline events recorded; CLI shows warning banner. |
|
||||
# AirGap Time Task Board — Epic 16: Air-Gapped Mode
|
||||
|
||||
## Sprint 57 – Time Anchor Validation
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-TIME-57-001 | TODO | AirGap Time Guild | PROV-OBS-54-001, AIRGAP-IMP-56-001 | Implement signed time token parser (Roughtime/RFC3161), verify signatures against bundle trust roots, and expose normalized anchor representation. | Parser handles both token formats; tests cover valid/expired/tampered tokens; documentation stubbed. |
|
||||
| AIRGAP-TIME-57-002 | TODO | AirGap Time Guild, Observability Guild | AIRGAP-TIME-57-001 | Add telemetry counters for time anchors (`airgap_time_anchor_age_seconds`) and alerts for approaching thresholds. | Metrics registered; alert templates created; integration test ensures emission on stale anchor. |
|
||||
|
||||
## Sprint 58 – Drift & Staleness Enforcement
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| AIRGAP-TIME-58-001 | TODO | AirGap Time Guild | AIRGAP-TIME-57-001, AIRGAP-CTL-56-002 | Persist drift baseline, compute per-content staleness (advisories, VEX, policy) based on bundle metadata, and surface through controller status API. | Drift/staleness values exposed via API; unit tests cover threshold calculations; docs updated. |
|
||||
| AIRGAP-TIME-58-002 | TODO | AirGap Time Guild, Notifications Guild | AIRGAP-TIME-58-001, NOTIFY-OBS-51-001 | Emit notifications and timeline events when staleness budgets breached or approaching. | Notifications dispatched with remediation; timeline events recorded; CLI shows warning banner. |
|
||||
56
src/Aoc/StellaOps.Aoc.sln
Normal file
56
src/Aoc/StellaOps.Aoc.sln
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{41F15E67-7190-CF23-3BC4-77E87134CADD}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Aoc", "__Libraries\StellaOps.Aoc\StellaOps.Aoc.csproj", "{54CD9E36-B119-4970-B652-826363055F7D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Tests", "__Tests", "{56BCE1BF-7CBA-7CE8-203D-A88051F1D642}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Aoc.Tests", "__Tests\StellaOps.Aoc.Tests\StellaOps.Aoc.Tests.csproj", "{5CF1158D-64F6-4981-85CB-B43453A37329}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{54CD9E36-B119-4970-B652-826363055F7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{54CD9E36-B119-4970-B652-826363055F7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{54CD9E36-B119-4970-B652-826363055F7D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{54CD9E36-B119-4970-B652-826363055F7D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{54CD9E36-B119-4970-B652-826363055F7D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{54CD9E36-B119-4970-B652-826363055F7D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{54CD9E36-B119-4970-B652-826363055F7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{54CD9E36-B119-4970-B652-826363055F7D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{54CD9E36-B119-4970-B652-826363055F7D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{54CD9E36-B119-4970-B652-826363055F7D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{54CD9E36-B119-4970-B652-826363055F7D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{54CD9E36-B119-4970-B652-826363055F7D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329}.Release|x64.Build.0 = Release|Any CPU
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{54CD9E36-B119-4970-B652-826363055F7D} = {41F15E67-7190-CF23-3BC4-77E87134CADD}
|
||||
{5CF1158D-64F6-4981-85CB-B43453A37329} = {56BCE1BF-7CBA-7CE8-203D-A88051F1D642}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,25 +1,25 @@
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public static class AocForbiddenKeys
|
||||
{
|
||||
private static readonly ImmutableHashSet<string> ForbiddenTopLevel = new[]
|
||||
{
|
||||
"severity",
|
||||
"cvss",
|
||||
"cvss_vector",
|
||||
"effective_status",
|
||||
"effective_range",
|
||||
"merged_from",
|
||||
"consensus_provider",
|
||||
"reachability",
|
||||
"asset_criticality",
|
||||
"risk_score",
|
||||
}.ToImmutableHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public static bool IsForbiddenTopLevel(string propertyName) => ForbiddenTopLevel.Contains(propertyName);
|
||||
|
||||
public static bool IsDerivedField(string propertyName)
|
||||
=> propertyName.StartsWith("effective_", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public static class AocForbiddenKeys
|
||||
{
|
||||
private static readonly ImmutableHashSet<string> ForbiddenTopLevel = new[]
|
||||
{
|
||||
"severity",
|
||||
"cvss",
|
||||
"cvss_vector",
|
||||
"effective_status",
|
||||
"effective_range",
|
||||
"merged_from",
|
||||
"consensus_provider",
|
||||
"reachability",
|
||||
"asset_criticality",
|
||||
"risk_score",
|
||||
}.ToImmutableHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public static bool IsForbiddenTopLevel(string propertyName) => ForbiddenTopLevel.Contains(propertyName);
|
||||
|
||||
public static bool IsDerivedField(string propertyName)
|
||||
=> propertyName.StartsWith("effective_", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public sealed class AocGuardException : Exception
|
||||
{
|
||||
public AocGuardException(AocGuardResult result)
|
||||
: base("AOC guard validation failed.")
|
||||
{
|
||||
Result = result ?? throw new ArgumentNullException(nameof(result));
|
||||
}
|
||||
|
||||
public AocGuardResult Result { get; }
|
||||
|
||||
public ImmutableArray<AocViolation> Violations => Result.Violations;
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public sealed class AocGuardException : Exception
|
||||
{
|
||||
public AocGuardException(AocGuardResult result)
|
||||
: base("AOC guard validation failed.")
|
||||
{
|
||||
Result = result ?? throw new ArgumentNullException(nameof(result));
|
||||
}
|
||||
|
||||
public AocGuardResult Result { get; }
|
||||
|
||||
public ImmutableArray<AocViolation> Violations => Result.Violations;
|
||||
}
|
||||
@@ -1,22 +1,22 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public static class AocGuardExtensions
|
||||
{
|
||||
public static AocGuardResult ValidateOrThrow(this IAocGuard guard, JsonElement document, AocGuardOptions? options = null)
|
||||
{
|
||||
if (guard is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(guard));
|
||||
}
|
||||
|
||||
var result = guard.Validate(document, options);
|
||||
if (!result.IsValid)
|
||||
{
|
||||
throw new AocGuardException(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
using System.Text.Json;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public static class AocGuardExtensions
|
||||
{
|
||||
public static AocGuardResult ValidateOrThrow(this IAocGuard guard, JsonElement document, AocGuardOptions? options = null)
|
||||
{
|
||||
if (guard is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(guard));
|
||||
}
|
||||
|
||||
var result = guard.Validate(document, options);
|
||||
if (!result.IsValid)
|
||||
{
|
||||
throw new AocGuardException(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,29 @@
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public sealed record AocGuardOptions
|
||||
{
|
||||
private static readonly ImmutableHashSet<string> DefaultRequiredTopLevel = new[]
|
||||
{
|
||||
"tenant",
|
||||
"source",
|
||||
"upstream",
|
||||
"content",
|
||||
"linkset",
|
||||
}.ToImmutableHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public static AocGuardOptions Default { get; } = new();
|
||||
|
||||
public ImmutableHashSet<string> RequiredTopLevelFields { get; init; } = DefaultRequiredTopLevel;
|
||||
|
||||
/// <summary>
|
||||
/// When true, signature metadata is required under upstream.signature.
|
||||
/// </summary>
|
||||
public bool RequireSignatureMetadata { get; init; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// When true, tenant must be a non-empty string.
|
||||
/// </summary>
|
||||
public bool RequireTenant { get; init; } = true;
|
||||
}
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public sealed record AocGuardOptions
|
||||
{
|
||||
private static readonly ImmutableHashSet<string> DefaultRequiredTopLevel = new[]
|
||||
{
|
||||
"tenant",
|
||||
"source",
|
||||
"upstream",
|
||||
"content",
|
||||
"linkset",
|
||||
}.ToImmutableHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public static AocGuardOptions Default { get; } = new();
|
||||
|
||||
public ImmutableHashSet<string> RequiredTopLevelFields { get; init; } = DefaultRequiredTopLevel;
|
||||
|
||||
/// <summary>
|
||||
/// When true, signature metadata is required under upstream.signature.
|
||||
/// </summary>
|
||||
public bool RequireSignatureMetadata { get; init; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// When true, tenant must be a non-empty string.
|
||||
/// </summary>
|
||||
public bool RequireTenant { get; init; } = true;
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public sealed record AocGuardResult(bool IsValid, ImmutableArray<AocViolation> Violations)
|
||||
{
|
||||
public static AocGuardResult Success { get; } = new(true, ImmutableArray<AocViolation>.Empty);
|
||||
|
||||
public static AocGuardResult FromViolations(IEnumerable<AocViolation> violations)
|
||||
{
|
||||
var array = violations.ToImmutableArray();
|
||||
return array.IsDefaultOrEmpty ? Success : new(false, array);
|
||||
}
|
||||
}
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public sealed record AocGuardResult(bool IsValid, ImmutableArray<AocViolation> Violations)
|
||||
{
|
||||
public static AocGuardResult Success { get; } = new(true, ImmutableArray<AocViolation>.Empty);
|
||||
|
||||
public static AocGuardResult FromViolations(IEnumerable<AocViolation> violations)
|
||||
{
|
||||
var array = violations.ToImmutableArray();
|
||||
return array.IsDefaultOrEmpty ? Success : new(false, array);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public sealed record AocViolation(
|
||||
[property: JsonPropertyName("code")] AocViolationCode Code,
|
||||
[property: JsonPropertyName("errorCode")] string ErrorCode,
|
||||
[property: JsonPropertyName("path")] string Path,
|
||||
[property: JsonPropertyName("message")] string Message)
|
||||
{
|
||||
public static AocViolation Create(AocViolationCode code, string path, string message)
|
||||
=> new(code, code.ToErrorCode(), path, message);
|
||||
}
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public sealed record AocViolation(
|
||||
[property: JsonPropertyName("code")] AocViolationCode Code,
|
||||
[property: JsonPropertyName("errorCode")] string ErrorCode,
|
||||
[property: JsonPropertyName("path")] string Path,
|
||||
[property: JsonPropertyName("message")] string Message)
|
||||
{
|
||||
public static AocViolation Create(AocViolationCode code, string path, string message)
|
||||
=> new(code, code.ToErrorCode(), path, message);
|
||||
}
|
||||
@@ -1,34 +1,34 @@
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public enum AocViolationCode
|
||||
{
|
||||
None = 0,
|
||||
ForbiddenField,
|
||||
MergeAttempt,
|
||||
IdempotencyViolation,
|
||||
MissingProvenance,
|
||||
SignatureInvalid,
|
||||
DerivedFindingDetected,
|
||||
UnknownField,
|
||||
MissingRequiredField,
|
||||
InvalidTenant,
|
||||
InvalidSignatureMetadata,
|
||||
}
|
||||
|
||||
public static class AocViolationCodeExtensions
|
||||
{
|
||||
public static string ToErrorCode(this AocViolationCode code) => code switch
|
||||
{
|
||||
AocViolationCode.ForbiddenField => "ERR_AOC_001",
|
||||
AocViolationCode.MergeAttempt => "ERR_AOC_002",
|
||||
AocViolationCode.IdempotencyViolation => "ERR_AOC_003",
|
||||
AocViolationCode.MissingProvenance => "ERR_AOC_004",
|
||||
AocViolationCode.SignatureInvalid => "ERR_AOC_005",
|
||||
AocViolationCode.DerivedFindingDetected => "ERR_AOC_006",
|
||||
AocViolationCode.UnknownField => "ERR_AOC_007",
|
||||
AocViolationCode.MissingRequiredField => "ERR_AOC_004",
|
||||
AocViolationCode.InvalidTenant => "ERR_AOC_004",
|
||||
AocViolationCode.InvalidSignatureMetadata => "ERR_AOC_005",
|
||||
_ => "ERR_AOC_000",
|
||||
};
|
||||
}
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public enum AocViolationCode
|
||||
{
|
||||
None = 0,
|
||||
ForbiddenField,
|
||||
MergeAttempt,
|
||||
IdempotencyViolation,
|
||||
MissingProvenance,
|
||||
SignatureInvalid,
|
||||
DerivedFindingDetected,
|
||||
UnknownField,
|
||||
MissingRequiredField,
|
||||
InvalidTenant,
|
||||
InvalidSignatureMetadata,
|
||||
}
|
||||
|
||||
public static class AocViolationCodeExtensions
|
||||
{
|
||||
public static string ToErrorCode(this AocViolationCode code) => code switch
|
||||
{
|
||||
AocViolationCode.ForbiddenField => "ERR_AOC_001",
|
||||
AocViolationCode.MergeAttempt => "ERR_AOC_002",
|
||||
AocViolationCode.IdempotencyViolation => "ERR_AOC_003",
|
||||
AocViolationCode.MissingProvenance => "ERR_AOC_004",
|
||||
AocViolationCode.SignatureInvalid => "ERR_AOC_005",
|
||||
AocViolationCode.DerivedFindingDetected => "ERR_AOC_006",
|
||||
AocViolationCode.UnknownField => "ERR_AOC_007",
|
||||
AocViolationCode.MissingRequiredField => "ERR_AOC_004",
|
||||
AocViolationCode.InvalidTenant => "ERR_AOC_004",
|
||||
AocViolationCode.InvalidSignatureMetadata => "ERR_AOC_005",
|
||||
_ => "ERR_AOC_000",
|
||||
};
|
||||
}
|
||||
@@ -1,127 +1,127 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public interface IAocGuard
|
||||
{
|
||||
AocGuardResult Validate(JsonElement document, AocGuardOptions? options = null);
|
||||
}
|
||||
|
||||
public sealed class AocWriteGuard : IAocGuard
|
||||
{
|
||||
public AocGuardResult Validate(JsonElement document, AocGuardOptions? options = null)
|
||||
{
|
||||
options ??= AocGuardOptions.Default;
|
||||
var violations = ImmutableArray.CreateBuilder<AocViolation>();
|
||||
var presentTopLevel = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var property in document.EnumerateObject())
|
||||
{
|
||||
presentTopLevel.Add(property.Name);
|
||||
|
||||
if (AocForbiddenKeys.IsForbiddenTopLevel(property.Name))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.ForbiddenField, $"/{property.Name}", $"Field '{property.Name}' is forbidden in AOC documents."));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (AocForbiddenKeys.IsDerivedField(property.Name))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.DerivedFindingDetected, $"/{property.Name}", $"Derived field '{property.Name}' must not be written during ingestion."));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var required in options.RequiredTopLevelFields)
|
||||
{
|
||||
if (!document.TryGetProperty(required, out var element) || element.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingRequiredField, $"/{required}", $"Required field '{required}' is missing."));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (options.RequireTenant && string.Equals(required, "tenant", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (element.ValueKind != JsonValueKind.String || string.IsNullOrWhiteSpace(element.GetString()))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.InvalidTenant, "/tenant", "Tenant must be a non-empty string."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (document.TryGetProperty("upstream", out var upstream) && upstream.ValueKind == JsonValueKind.Object)
|
||||
{
|
||||
if (!upstream.TryGetProperty("content_hash", out var contentHash) || contentHash.ValueKind != JsonValueKind.String || string.IsNullOrWhiteSpace(contentHash.GetString()))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingProvenance, "/upstream/content_hash", "Upstream content hash is required."));
|
||||
}
|
||||
|
||||
if (!upstream.TryGetProperty("signature", out var signature) || signature.ValueKind != JsonValueKind.Object)
|
||||
{
|
||||
if (options.RequireSignatureMetadata)
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingProvenance, "/upstream/signature", "Signature metadata is required."));
|
||||
}
|
||||
}
|
||||
else if (options.RequireSignatureMetadata)
|
||||
{
|
||||
ValidateSignature(signature, violations);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingRequiredField, "/upstream", "Upstream metadata is required."));
|
||||
}
|
||||
|
||||
if (document.TryGetProperty("content", out var content) && content.ValueKind == JsonValueKind.Object)
|
||||
{
|
||||
if (!content.TryGetProperty("raw", out var raw) || raw.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingProvenance, "/content/raw", "Raw upstream payload must be preserved."));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingRequiredField, "/content", "Content metadata is required."));
|
||||
}
|
||||
|
||||
if (!document.TryGetProperty("linkset", out var linkset) || linkset.ValueKind != JsonValueKind.Object)
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingRequiredField, "/linkset", "Linkset metadata is required."));
|
||||
}
|
||||
|
||||
return AocGuardResult.FromViolations(violations);
|
||||
}
|
||||
|
||||
private static void ValidateSignature(JsonElement signature, ImmutableArray<AocViolation>.Builder violations)
|
||||
{
|
||||
if (!signature.TryGetProperty("present", out var presentElement) || presentElement.ValueKind is not (JsonValueKind.True or JsonValueKind.False))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.InvalidSignatureMetadata, "/upstream/signature/present", "Signature metadata must include 'present' boolean."));
|
||||
return;
|
||||
}
|
||||
|
||||
var signaturePresent = presentElement.GetBoolean();
|
||||
|
||||
if (!signaturePresent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!signature.TryGetProperty("format", out var formatElement) || formatElement.ValueKind != JsonValueKind.String || string.IsNullOrWhiteSpace(formatElement.GetString()))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.InvalidSignatureMetadata, "/upstream/signature/format", "Signature format is required when signature is present."));
|
||||
}
|
||||
|
||||
if (!signature.TryGetProperty("sig", out var sigElement) || sigElement.ValueKind != JsonValueKind.String || string.IsNullOrWhiteSpace(sigElement.GetString()))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.SignatureInvalid, "/upstream/signature/sig", "Signature payload is required when signature is present."));
|
||||
}
|
||||
|
||||
if (!signature.TryGetProperty("key_id", out var keyIdElement) || keyIdElement.ValueKind != JsonValueKind.String || string.IsNullOrWhiteSpace(keyIdElement.GetString()))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.InvalidSignatureMetadata, "/upstream/signature/key_id", "Signature key identifier is required when signature is present."));
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public interface IAocGuard
|
||||
{
|
||||
AocGuardResult Validate(JsonElement document, AocGuardOptions? options = null);
|
||||
}
|
||||
|
||||
public sealed class AocWriteGuard : IAocGuard
|
||||
{
|
||||
public AocGuardResult Validate(JsonElement document, AocGuardOptions? options = null)
|
||||
{
|
||||
options ??= AocGuardOptions.Default;
|
||||
var violations = ImmutableArray.CreateBuilder<AocViolation>();
|
||||
var presentTopLevel = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var property in document.EnumerateObject())
|
||||
{
|
||||
presentTopLevel.Add(property.Name);
|
||||
|
||||
if (AocForbiddenKeys.IsForbiddenTopLevel(property.Name))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.ForbiddenField, $"/{property.Name}", $"Field '{property.Name}' is forbidden in AOC documents."));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (AocForbiddenKeys.IsDerivedField(property.Name))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.DerivedFindingDetected, $"/{property.Name}", $"Derived field '{property.Name}' must not be written during ingestion."));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var required in options.RequiredTopLevelFields)
|
||||
{
|
||||
if (!document.TryGetProperty(required, out var element) || element.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingRequiredField, $"/{required}", $"Required field '{required}' is missing."));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (options.RequireTenant && string.Equals(required, "tenant", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (element.ValueKind != JsonValueKind.String || string.IsNullOrWhiteSpace(element.GetString()))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.InvalidTenant, "/tenant", "Tenant must be a non-empty string."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (document.TryGetProperty("upstream", out var upstream) && upstream.ValueKind == JsonValueKind.Object)
|
||||
{
|
||||
if (!upstream.TryGetProperty("content_hash", out var contentHash) || contentHash.ValueKind != JsonValueKind.String || string.IsNullOrWhiteSpace(contentHash.GetString()))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingProvenance, "/upstream/content_hash", "Upstream content hash is required."));
|
||||
}
|
||||
|
||||
if (!upstream.TryGetProperty("signature", out var signature) || signature.ValueKind != JsonValueKind.Object)
|
||||
{
|
||||
if (options.RequireSignatureMetadata)
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingProvenance, "/upstream/signature", "Signature metadata is required."));
|
||||
}
|
||||
}
|
||||
else if (options.RequireSignatureMetadata)
|
||||
{
|
||||
ValidateSignature(signature, violations);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingRequiredField, "/upstream", "Upstream metadata is required."));
|
||||
}
|
||||
|
||||
if (document.TryGetProperty("content", out var content) && content.ValueKind == JsonValueKind.Object)
|
||||
{
|
||||
if (!content.TryGetProperty("raw", out var raw) || raw.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingProvenance, "/content/raw", "Raw upstream payload must be preserved."));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingRequiredField, "/content", "Content metadata is required."));
|
||||
}
|
||||
|
||||
if (!document.TryGetProperty("linkset", out var linkset) || linkset.ValueKind != JsonValueKind.Object)
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.MissingRequiredField, "/linkset", "Linkset metadata is required."));
|
||||
}
|
||||
|
||||
return AocGuardResult.FromViolations(violations);
|
||||
}
|
||||
|
||||
private static void ValidateSignature(JsonElement signature, ImmutableArray<AocViolation>.Builder violations)
|
||||
{
|
||||
if (!signature.TryGetProperty("present", out var presentElement) || presentElement.ValueKind is not (JsonValueKind.True or JsonValueKind.False))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.InvalidSignatureMetadata, "/upstream/signature/present", "Signature metadata must include 'present' boolean."));
|
||||
return;
|
||||
}
|
||||
|
||||
var signaturePresent = presentElement.GetBoolean();
|
||||
|
||||
if (!signaturePresent)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!signature.TryGetProperty("format", out var formatElement) || formatElement.ValueKind != JsonValueKind.String || string.IsNullOrWhiteSpace(formatElement.GetString()))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.InvalidSignatureMetadata, "/upstream/signature/format", "Signature format is required when signature is present."));
|
||||
}
|
||||
|
||||
if (!signature.TryGetProperty("sig", out var sigElement) || sigElement.ValueKind != JsonValueKind.String || string.IsNullOrWhiteSpace(sigElement.GetString()))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.SignatureInvalid, "/upstream/signature/sig", "Signature payload is required when signature is present."));
|
||||
}
|
||||
|
||||
if (!signature.TryGetProperty("key_id", out var keyIdElement) || keyIdElement.ValueKind != JsonValueKind.String || string.IsNullOrWhiteSpace(keyIdElement.GetString()))
|
||||
{
|
||||
violations.Add(AocViolation.Create(AocViolationCode.InvalidSignatureMetadata, "/upstream/signature/key_id", "Signature key identifier is required when signature is present."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddAocGuard(this IServiceCollection services)
|
||||
{
|
||||
if (services is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
}
|
||||
|
||||
services.AddSingleton<IAocGuard, AocWriteGuard>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace StellaOps.Aoc;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddAocGuard(this IServiceCollection services)
|
||||
{
|
||||
if (services is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
}
|
||||
|
||||
services.AddSingleton<IAocGuard, AocWriteGuard>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0-rc.2.25502.107" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0-rc.2.25502.107" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,113 +1,113 @@
|
||||
using System.Text.Json;
|
||||
using StellaOps.Aoc;
|
||||
|
||||
namespace StellaOps.Aoc.Tests;
|
||||
|
||||
public sealed class AocWriteGuardTests
|
||||
{
|
||||
private static readonly AocWriteGuard Guard = new();
|
||||
|
||||
[Fact]
|
||||
public void Validate_ReturnsSuccess_ForMinimalValidDocument()
|
||||
{
|
||||
using var document = JsonDocument.Parse("""
|
||||
{
|
||||
"tenant": "default",
|
||||
"source": {"vendor": "osv"},
|
||||
"upstream": {
|
||||
"upstream_id": "GHSA-xxxx",
|
||||
"content_hash": "sha256:abc",
|
||||
"signature": { "present": false }
|
||||
},
|
||||
"content": {
|
||||
"format": "OSV",
|
||||
"raw": {"id": "GHSA-xxxx"}
|
||||
},
|
||||
"linkset": {}
|
||||
}
|
||||
""");
|
||||
|
||||
var result = Guard.Validate(document.RootElement);
|
||||
|
||||
Assert.True(result.IsValid);
|
||||
Assert.Empty(result.Violations);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_FlagsMissingTenant()
|
||||
{
|
||||
using var document = JsonDocument.Parse("""
|
||||
{
|
||||
"source": {"vendor": "osv"},
|
||||
"upstream": {
|
||||
"upstream_id": "GHSA-xxxx",
|
||||
"content_hash": "sha256:abc",
|
||||
"signature": { "present": false }
|
||||
},
|
||||
"content": {
|
||||
"format": "OSV",
|
||||
"raw": {"id": "GHSA-xxxx"}
|
||||
},
|
||||
"linkset": {}
|
||||
}
|
||||
""");
|
||||
|
||||
var result = Guard.Validate(document.RootElement);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Contains(result.Violations, v => v.ErrorCode == "ERR_AOC_004" && v.Path == "/tenant");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_FlagsForbiddenField()
|
||||
{
|
||||
using var document = JsonDocument.Parse("""
|
||||
{
|
||||
"tenant": "default",
|
||||
"severity": "high",
|
||||
"source": {"vendor": "osv"},
|
||||
"upstream": {
|
||||
"upstream_id": "GHSA-xxxx",
|
||||
"content_hash": "sha256:abc",
|
||||
"signature": { "present": false }
|
||||
},
|
||||
"content": {
|
||||
"format": "OSV",
|
||||
"raw": {"id": "GHSA-xxxx"}
|
||||
},
|
||||
"linkset": {}
|
||||
}
|
||||
""");
|
||||
|
||||
var result = Guard.Validate(document.RootElement);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Contains(result.Violations, v => v.ErrorCode == "ERR_AOC_001" && v.Path == "/severity");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_FlagsInvalidSignatureMetadata()
|
||||
{
|
||||
using var document = JsonDocument.Parse("""
|
||||
{
|
||||
"tenant": "default",
|
||||
"source": {"vendor": "osv"},
|
||||
"upstream": {
|
||||
"upstream_id": "GHSA-xxxx",
|
||||
"content_hash": "sha256:abc",
|
||||
"signature": { "present": true, "format": "dsse" }
|
||||
},
|
||||
"content": {
|
||||
"format": "OSV",
|
||||
"raw": {"id": "GHSA-xxxx"}
|
||||
},
|
||||
"linkset": {}
|
||||
}
|
||||
""");
|
||||
|
||||
var result = Guard.Validate(document.RootElement);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Contains(result.Violations, v => v.ErrorCode == "ERR_AOC_005" && v.Path.Contains("/sig"));
|
||||
}
|
||||
}
|
||||
using System.Text.Json;
|
||||
using StellaOps.Aoc;
|
||||
|
||||
namespace StellaOps.Aoc.Tests;
|
||||
|
||||
public sealed class AocWriteGuardTests
|
||||
{
|
||||
private static readonly AocWriteGuard Guard = new();
|
||||
|
||||
[Fact]
|
||||
public void Validate_ReturnsSuccess_ForMinimalValidDocument()
|
||||
{
|
||||
using var document = JsonDocument.Parse("""
|
||||
{
|
||||
"tenant": "default",
|
||||
"source": {"vendor": "osv"},
|
||||
"upstream": {
|
||||
"upstream_id": "GHSA-xxxx",
|
||||
"content_hash": "sha256:abc",
|
||||
"signature": { "present": false }
|
||||
},
|
||||
"content": {
|
||||
"format": "OSV",
|
||||
"raw": {"id": "GHSA-xxxx"}
|
||||
},
|
||||
"linkset": {}
|
||||
}
|
||||
""");
|
||||
|
||||
var result = Guard.Validate(document.RootElement);
|
||||
|
||||
Assert.True(result.IsValid);
|
||||
Assert.Empty(result.Violations);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_FlagsMissingTenant()
|
||||
{
|
||||
using var document = JsonDocument.Parse("""
|
||||
{
|
||||
"source": {"vendor": "osv"},
|
||||
"upstream": {
|
||||
"upstream_id": "GHSA-xxxx",
|
||||
"content_hash": "sha256:abc",
|
||||
"signature": { "present": false }
|
||||
},
|
||||
"content": {
|
||||
"format": "OSV",
|
||||
"raw": {"id": "GHSA-xxxx"}
|
||||
},
|
||||
"linkset": {}
|
||||
}
|
||||
""");
|
||||
|
||||
var result = Guard.Validate(document.RootElement);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Contains(result.Violations, v => v.ErrorCode == "ERR_AOC_004" && v.Path == "/tenant");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_FlagsForbiddenField()
|
||||
{
|
||||
using var document = JsonDocument.Parse("""
|
||||
{
|
||||
"tenant": "default",
|
||||
"severity": "high",
|
||||
"source": {"vendor": "osv"},
|
||||
"upstream": {
|
||||
"upstream_id": "GHSA-xxxx",
|
||||
"content_hash": "sha256:abc",
|
||||
"signature": { "present": false }
|
||||
},
|
||||
"content": {
|
||||
"format": "OSV",
|
||||
"raw": {"id": "GHSA-xxxx"}
|
||||
},
|
||||
"linkset": {}
|
||||
}
|
||||
""");
|
||||
|
||||
var result = Guard.Validate(document.RootElement);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Contains(result.Violations, v => v.ErrorCode == "ERR_AOC_001" && v.Path == "/severity");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_FlagsInvalidSignatureMetadata()
|
||||
{
|
||||
using var document = JsonDocument.Parse("""
|
||||
{
|
||||
"tenant": "default",
|
||||
"source": {"vendor": "osv"},
|
||||
"upstream": {
|
||||
"upstream_id": "GHSA-xxxx",
|
||||
"content_hash": "sha256:abc",
|
||||
"signature": { "present": true, "format": "dsse" }
|
||||
},
|
||||
"content": {
|
||||
"format": "OSV",
|
||||
"raw": {"id": "GHSA-xxxx"}
|
||||
},
|
||||
"linkset": {}
|
||||
}
|
||||
""");
|
||||
|
||||
var result = Guard.Validate(document.RootElement);
|
||||
|
||||
Assert.False(result.IsValid);
|
||||
Assert.Contains(result.Violations, v => v.ErrorCode == "ERR_AOC_005" && v.Path.Contains("/sig"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<OutputType>Exe</OutputType>
|
||||
<IsPackable>false</IsPackable>
|
||||
<UseConcelierTestInfra>false</UseConcelierTestInfra>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageReference Include="xunit.v3" Version="3.0.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Aoc/StellaOps.Aoc.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,10 +1,10 @@
|
||||
namespace StellaOps.Aoc.Tests;
|
||||
|
||||
public class UnitTest1
|
||||
{
|
||||
[Fact]
|
||||
public void Test1()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
namespace StellaOps.Aoc.Tests;
|
||||
|
||||
public class UnitTest1
|
||||
{
|
||||
[Fact]
|
||||
public void Test1()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
# API Governance Guild Charter
|
||||
|
||||
## Mission
|
||||
Enforce API contract quality through linting, compatibility checks, version policy automation, and changelog generation.
|
||||
|
||||
## Scope
|
||||
- Maintain lint rule set, compatibility diff tooling, and CI integration.
|
||||
- Gate PRs on contract validation, example coverage, and naming conventions.
|
||||
- Produce automated changelogs and deprecation notices from OAS diffs.
|
||||
- Coordinate with Notifications Studio for deprecation broadcasts.
|
||||
|
||||
## Definition of Done
|
||||
- CI gate prevents merging incompatible or non-conforming specs.
|
||||
- Version bump tooling produces signed changelog artifacts per release.
|
||||
- Governance documentation kept current in `/docs/contributing/api-contracts.md`.
|
||||
# API Governance Guild Charter
|
||||
|
||||
## Mission
|
||||
Enforce API contract quality through linting, compatibility checks, version policy automation, and changelog generation.
|
||||
|
||||
## Scope
|
||||
- Maintain lint rule set, compatibility diff tooling, and CI integration.
|
||||
- Gate PRs on contract validation, example coverage, and naming conventions.
|
||||
- Produce automated changelogs and deprecation notices from OAS diffs.
|
||||
- Coordinate with Notifications Studio for deprecation broadcasts.
|
||||
|
||||
## Definition of Done
|
||||
- CI gate prevents merging incompatible or non-conforming specs.
|
||||
- Version bump tooling produces signed changelog artifacts per release.
|
||||
- Governance documentation kept current in `/docs/contributing/api-contracts.md`.
|
||||
@@ -10,7 +10,7 @@
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| APIGOV-62-001 | TODO | API Governance Guild | APIGOV-61-001 | Build compatibility diff tool producing additive/breaking reports comparing prior release. | Diff output consumed in CI; failing on breaking changes unless override provided. |
|
||||
| APIGOV-62-002 | TODO | API Governance Guild, DevOps Guild | APIGOV-62-001 | Automate changelog generation and publish signed artifacts to `src/StellaOps.Sdk.Release` pipeline. | Changelog pipeline produces markdown + JSON; signatures verified; docs updated. |
|
||||
| APIGOV-62-002 | TODO | API Governance Guild, DevOps Guild | APIGOV-62-001 | Automate changelog generation and publish signed artifacts to `src/Sdk/StellaOps.Sdk.Release` pipeline. | Changelog pipeline produces markdown + JSON; signatures verified; docs updated. |
|
||||
|
||||
## Sprint 63 – Deprecation & Notifications
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
@@ -4,8 +4,8 @@
|
||||
Maintain OpenAPI 3.1 specifications for every StellaOps service, compose the aggregate spec, and ensure API contract consistency across releases.
|
||||
|
||||
## Scope
|
||||
- Author and review per-service OAS documents in `src/StellaOps.Api.OpenApi/<service>/openapi.yaml`.
|
||||
- Operate the aggregate composer producing `src/StellaOps.Api.OpenApi/stella.yaml`.
|
||||
- Author and review per-service OAS documents in `src/Api/StellaOps.Api.OpenApi/<service>/openapi.yaml`.
|
||||
- Operate the aggregate composer producing `src/Api/StellaOps.Api.OpenApi/stella.yaml`.
|
||||
- Provide shared components, schema libraries, and example catalogs.
|
||||
- Coordinate with service guilds on contract changes, examples, and versioning.
|
||||
- Own CI validation, linting, and compatibility diff tooling for OAS artifacts.
|
||||
@@ -1,19 +1,19 @@
|
||||
# API OpenAPI Task Board — Epic 17: SDKs & OpenAPI Docs
|
||||
|
||||
## Sprint 61 – Spec Foundations
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| OAS-61-001 | TODO | API Contracts Guild | — | Scaffold per-service OpenAPI 3.1 files with shared components, info blocks, and initial path stubs. | All services have baseline `openapi.yaml`; shared components library established; lint passes. |
|
||||
| OAS-61-002 | TODO | API Contracts Guild, DevOps Guild | OAS-61-001 | Implement aggregate composer (`stella.yaml`) resolving `$ref`s and merging shared components; wire into CI. | Aggregate spec builds deterministically; CI artifact published; documentation updated. |
|
||||
|
||||
## Sprint 62 – Examples & Error Envelope
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| OAS-62-001 | TODO | API Contracts Guild, Service Guilds | OAS-61-001 | Populate request/response examples for top 50 endpoints, including standard error envelope. | Examples validated via CI; error envelope consistent across services. |
|
||||
| OAS-62-002 | TODO | API Contracts Guild | OAS-61-002 | Add custom lint rules enforcing pagination, idempotency headers, naming conventions, and example coverage. | Lint job fails on violations; documentation for rules published. |
|
||||
|
||||
## Sprint 63 – Compatibility & Discovery
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| OAS-63-001 | TODO | API Contracts Guild | OAS-61-002 | Implement compatibility diff tooling comparing previous release specs; classify breaking vs additive changes. | Diff tool integrated in CI; PRs flagged on breaking changes. |
|
||||
| OAS-63-002 | TODO | API Contracts Guild, Gateway Guild | OAS-62-002 | Add `/.well-known/openapi` discovery endpoint schema metadata (extensions, version info). | Discovery endpoints defined in spec; linked to implementation tasks. |
|
||||
# API OpenAPI Task Board — Epic 17: SDKs & OpenAPI Docs
|
||||
|
||||
## Sprint 61 – Spec Foundations
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| OAS-61-001 | TODO | API Contracts Guild | — | Scaffold per-service OpenAPI 3.1 files with shared components, info blocks, and initial path stubs. | All services have baseline `openapi.yaml`; shared components library established; lint passes. |
|
||||
| OAS-61-002 | TODO | API Contracts Guild, DevOps Guild | OAS-61-001 | Implement aggregate composer (`stella.yaml`) resolving `$ref`s and merging shared components; wire into CI. | Aggregate spec builds deterministically; CI artifact published; documentation updated. |
|
||||
|
||||
## Sprint 62 – Examples & Error Envelope
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| OAS-62-001 | TODO | API Contracts Guild, Service Guilds | OAS-61-001 | Populate request/response examples for top 50 endpoints, including standard error envelope. | Examples validated via CI; error envelope consistent across services. |
|
||||
| OAS-62-002 | TODO | API Contracts Guild | OAS-61-002 | Add custom lint rules enforcing pagination, idempotency headers, naming conventions, and example coverage. | Lint job fails on violations; documentation for rules published. |
|
||||
|
||||
## Sprint 63 – Compatibility & Discovery
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| OAS-63-001 | TODO | API Contracts Guild | OAS-61-002 | Implement compatibility diff tooling comparing previous release specs; classify breaking vs additive changes. | Diff tool integrated in CI; PRs flagged on breaking changes. |
|
||||
| OAS-63-002 | TODO | API Contracts Guild, Gateway Guild | OAS-62-002 | Add `/.well-known/openapi` discovery endpoint schema metadata (extensions, version info). | Discovery endpoints defined in spec; linked to implementation tasks. |
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,15 @@
|
||||
# Attestation Envelope Guild Charter
|
||||
|
||||
## Mission
|
||||
Provide deterministic DSSE envelope handling with multi-signature support, canonical serialization, hashing, and integrity safeguards for all Stella attestations.
|
||||
|
||||
## Scope
|
||||
- DSSE encoding/decoding, canonical JSON handling, and detached payload support.
|
||||
- Multi-signature verification, key identification, and cryptographic primitives.
|
||||
- Integration with KMS drivers and transparency log witness utilities.
|
||||
- Fuzz and property testing for envelope parsing and normalization.
|
||||
|
||||
## Definition of Done
|
||||
- Envelope APIs produce canonical payloads and support multiple signatures deterministically.
|
||||
- Verification detects tampering, mismatched subjects, and unsupported algorithms.
|
||||
- Property and fuzz tests cover canonicalization and signature edge cases.
|
||||
# Attestation Envelope Guild Charter
|
||||
|
||||
## Mission
|
||||
Provide deterministic DSSE envelope handling with multi-signature support, canonical serialization, hashing, and integrity safeguards for all Stella attestations.
|
||||
|
||||
## Scope
|
||||
- DSSE encoding/decoding, canonical JSON handling, and detached payload support.
|
||||
- Multi-signature verification, key identification, and cryptographic primitives.
|
||||
- Integration with KMS drivers and transparency log witness utilities.
|
||||
- Fuzz and property testing for envelope parsing and normalization.
|
||||
|
||||
## Definition of Done
|
||||
- Envelope APIs produce canonical payloads and support multiple signatures deterministically.
|
||||
- Verification detects tampering, mismatched subjects, and unsupported algorithms.
|
||||
- Property and fuzz tests cover canonicalization and signature edge cases.
|
||||
@@ -1,13 +1,13 @@
|
||||
# Attestation Envelope Task Board — Epic 19: Attestor Console
|
||||
|
||||
## Sprint 72 – Foundations
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| ATTEST-ENVELOPE-72-001 | TODO | Envelope Guild | — | Implement DSSE canonicalization, JSON normalization, multi-signature structures, and hashing helpers. | Canonicalization deterministic (property tests); hash matches DSSE spec; unit tests green. |
|
||||
| ATTEST-ENVELOPE-72-002 | TODO | Envelope Guild | ATTEST-ENVELOPE-72-001 | Support compact and expanded JSON output, payload compression, and detached payload references. | API returns both variants; payload compression toggles tested; docs updated. |
|
||||
|
||||
## Sprint 73 – Crypto Integration
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| ATTEST-ENVELOPE-73-001 | TODO | Envelope Guild, KMS Guild | ATTEST-ENVELOPE-72-001 | Implement Ed25519 & ECDSA signature create/verify helpers, key identification (`keyid`) scheme, and error mapping. | Sign/verify tests pass with fixtures; invalid signatures produce deterministic errors. |
|
||||
| ATTEST-ENVELOPE-73-002 | TODO | Envelope Guild | ATTEST-ENVELOPE-73-001 | Add fuzz tests for envelope parsing, signature verification, and canonical JSON round-trips. | Fuzz suite integrated; coverage metrics recorded; no regressions. |
|
||||
# Attestation Envelope Task Board — Epic 19: Attestor Console
|
||||
|
||||
## Sprint 72 – Foundations
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| ATTEST-ENVELOPE-72-001 | TODO | Envelope Guild | — | Implement DSSE canonicalization, JSON normalization, multi-signature structures, and hashing helpers. | Canonicalization deterministic (property tests); hash matches DSSE spec; unit tests green. |
|
||||
| ATTEST-ENVELOPE-72-002 | TODO | Envelope Guild | ATTEST-ENVELOPE-72-001 | Support compact and expanded JSON output, payload compression, and detached payload references. | API returns both variants; payload compression toggles tested; docs updated. |
|
||||
|
||||
## Sprint 73 – Crypto Integration
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| ATTEST-ENVELOPE-73-001 | TODO | Envelope Guild, KMS Guild | ATTEST-ENVELOPE-72-001 | Implement Ed25519 & ECDSA signature create/verify helpers, key identification (`keyid`) scheme, and error mapping. | Sign/verify tests pass with fixtures; invalid signatures produce deterministic errors. |
|
||||
| ATTEST-ENVELOPE-73-002 | TODO | Envelope Guild | ATTEST-ENVELOPE-73-001 | Add fuzz tests for envelope parsing, signature verification, and canonical JSON round-trips. | Fuzz suite integrated; coverage metrics recorded; no regressions. |
|
||||
@@ -1,14 +1,14 @@
|
||||
# Attestation Payloads Guild Charter
|
||||
|
||||
## Mission
|
||||
Define strongly typed, versioned schemas for all attestation payloads and provide validation utilities for generating and verifying evidence.
|
||||
|
||||
## Scope
|
||||
- JSON Schemas, code generation, and documentation for each attestation type.
|
||||
- Normalization and validation logic shared across services, CLI, and SDKs.
|
||||
- Sample payloads and golden fixtures used in contract tests and docs.
|
||||
|
||||
## Definition of Done
|
||||
- Payload types compiled into Go/TypeScript models with validation helpers.
|
||||
- Schemas published with semantic versioning and change logs.
|
||||
- Golden samples maintained with acceptance tests and doc integration.
|
||||
# Attestation Payloads Guild Charter
|
||||
|
||||
## Mission
|
||||
Define strongly typed, versioned schemas for all attestation payloads and provide validation utilities for generating and verifying evidence.
|
||||
|
||||
## Scope
|
||||
- JSON Schemas, code generation, and documentation for each attestation type.
|
||||
- Normalization and validation logic shared across services, CLI, and SDKs.
|
||||
- Sample payloads and golden fixtures used in contract tests and docs.
|
||||
|
||||
## Definition of Done
|
||||
- Payload types compiled into Go/TypeScript models with validation helpers.
|
||||
- Schemas published with semantic versioning and change logs.
|
||||
- Golden samples maintained with acceptance tests and doc integration.
|
||||
@@ -1,13 +1,13 @@
|
||||
# Attestation Payloads Task Board — Epic 19: Attestor Console
|
||||
|
||||
## Sprint 72 – Schema Definition
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| ATTEST-TYPES-72-001 | TODO | Attestation Payloads Guild | — | Draft JSON Schemas for BuildProvenance v1, SBOMAttestation v1, VEXAttestation v1, ScanResults v1, PolicyEvaluation v1, RiskProfileEvidence v1, CustomEvidence v1. | Schemas validated with test fixtures; docs stubbed; versioned under `schemas/`. |
|
||||
| ATTEST-TYPES-72-002 | TODO | Attestation Payloads Guild | ATTEST-TYPES-72-001 | Generate Go/TS models from schemas with validation helpers and canonical JSON serialization. | Code generation integrated; lints pass; unit tests cover round-trips. |
|
||||
|
||||
## Sprint 73 – Fixtures & Docs
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| ATTEST-TYPES-73-001 | TODO | Attestation Payloads Guild | ATTEST-TYPES-72-002 | Create golden payload samples for each type; integrate into tests and documentation. | Golden fixtures stored; tests compare outputs; docs embed examples. |
|
||||
| ATTEST-TYPES-73-002 | TODO | Attestation Payloads Guild, Docs Guild | ATTEST-TYPES-73-001 | Publish schema reference docs (`/docs/attestor/payloads.md`) with annotated JSON examples. | Doc merged with banner; examples validated by tests. |
|
||||
# Attestation Payloads Task Board — Epic 19: Attestor Console
|
||||
|
||||
## Sprint 72 – Schema Definition
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| ATTEST-TYPES-72-001 | TODO | Attestation Payloads Guild | — | Draft JSON Schemas for BuildProvenance v1, SBOMAttestation v1, VEXAttestation v1, ScanResults v1, PolicyEvaluation v1, RiskProfileEvidence v1, CustomEvidence v1. | Schemas validated with test fixtures; docs stubbed; versioned under `schemas/`. |
|
||||
| ATTEST-TYPES-72-002 | TODO | Attestation Payloads Guild | ATTEST-TYPES-72-001 | Generate Go/TS models from schemas with validation helpers and canonical JSON serialization. | Code generation integrated; lints pass; unit tests cover round-trips. |
|
||||
|
||||
## Sprint 73 – Fixtures & Docs
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| ATTEST-TYPES-73-001 | TODO | Attestation Payloads Guild | ATTEST-TYPES-72-002 | Create golden payload samples for each type; integrate into tests and documentation. | Golden fixtures stored; tests compare outputs; docs embed examples. |
|
||||
| ATTEST-TYPES-73-002 | TODO | Attestation Payloads Guild, Docs Guild | ATTEST-TYPES-73-001 | Publish schema reference docs (`/docs/attestor/payloads.md`) with annotated JSON examples. | Doc merged with banner; examples validated by tests. |
|
||||
@@ -1,14 +1,14 @@
|
||||
# Attestation Verification Guild Charter
|
||||
|
||||
## Mission
|
||||
Implement the verification engine that enforces attestation policies, issuer trust, transparency requirements, and produces audit-ready reports.
|
||||
|
||||
## Scope
|
||||
- Verification pipeline integrating DSSE validation, issuer/key trust, Policy Studio rules, freshness checks, and transparency proofs.
|
||||
- Caching and reporting for verification results.
|
||||
- Error codes and explainability artifacts for UI/CLI consumption.
|
||||
|
||||
## Definition of Done
|
||||
- Verification passes/fails deterministically with detailed report structures.
|
||||
- Caching improves performance without sacrificing correctness.
|
||||
- Policies enforce scope-based rules and waivers, with unit/integration coverage.
|
||||
# Attestation Verification Guild Charter
|
||||
|
||||
## Mission
|
||||
Implement the verification engine that enforces attestation policies, issuer trust, transparency requirements, and produces audit-ready reports.
|
||||
|
||||
## Scope
|
||||
- Verification pipeline integrating DSSE validation, issuer/key trust, Policy Studio rules, freshness checks, and transparency proofs.
|
||||
- Caching and reporting for verification results.
|
||||
- Error codes and explainability artifacts for UI/CLI consumption.
|
||||
|
||||
## Definition of Done
|
||||
- Verification passes/fails deterministically with detailed report structures.
|
||||
- Caching improves performance without sacrificing correctness.
|
||||
- Policies enforce scope-based rules and waivers, with unit/integration coverage.
|
||||
@@ -1,13 +1,13 @@
|
||||
# Attestation Verification Task Board — Epic 19: Attestor Console
|
||||
|
||||
## Sprint 73 – Policy Integration
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| ATTEST-VERIFY-73-001 | TODO | Verification Guild, Policy Guild | VERPOL-73-001, ATTESTOR-73-002 | Implement verification engine: policy evaluation, issuer trust resolution, freshness, signature count, transparency checks; produce structured reports. | Engine returns report DTOs; policy rules honored; unit tests cover pass/fail scenarios. |
|
||||
| ATTEST-VERIFY-73-002 | TODO | Verification Guild | ATTEST-VERIFY-73-001 | Add caching layer keyed by `(subject, envelope_id, policy_version)` with TTL and invalidation on new evidence. | Cache reduces repeated verification cost; tests cover cache hits/misses. |
|
||||
|
||||
## Sprint 74 – Explainability & Observability
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| ATTEST-VERIFY-74-001 | TODO | Verification Guild, Observability Guild | ATTEST-VERIFY-73-001 | Emit telemetry (spans/metrics) tagged by subject, issuer, policy, result; integrate with dashboards. | Metrics visible; spans present; SLO thresholds defined. |
|
||||
| ATTEST-VERIFY-74-002 | TODO | Verification Guild, Docs Guild | ATTEST-VERIFY-73-001 | Document verification report schema and explainability in `/docs/attestor/workflows.md`. | Documentation merged; examples verified via tests. |
|
||||
# Attestation Verification Task Board — Epic 19: Attestor Console
|
||||
|
||||
## Sprint 73 – Policy Integration
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| ATTEST-VERIFY-73-001 | TODO | Verification Guild, Policy Guild | VERPOL-73-001, ATTESTOR-73-002 | Implement verification engine: policy evaluation, issuer trust resolution, freshness, signature count, transparency checks; produce structured reports. | Engine returns report DTOs; policy rules honored; unit tests cover pass/fail scenarios. |
|
||||
| ATTEST-VERIFY-73-002 | TODO | Verification Guild | ATTEST-VERIFY-73-001 | Add caching layer keyed by `(subject, envelope_id, policy_version)` with TTL and invalidation on new evidence. | Cache reduces repeated verification cost; tests cover cache hits/misses. |
|
||||
|
||||
## Sprint 74 – Explainability & Observability
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| ATTEST-VERIFY-74-001 | TODO | Verification Guild, Observability Guild | ATTEST-VERIFY-73-001 | Emit telemetry (spans/metrics) tagged by subject, issuer, policy, result; integrate with dashboards. | Metrics visible; spans present; SLO thresholds defined. |
|
||||
| ATTEST-VERIFY-74-002 | TODO | Verification Guild, Docs Guild | ATTEST-VERIFY-73-001 | Document verification report schema and explainability in `/docs/attestor/workflows.md`. | Documentation merged; examples verified via tests. |
|
||||
182
src/Attestor/StellaOps.Attestor.sln
Normal file
182
src/Attestor/StellaOps.Attestor.sln
Normal file
@@ -0,0 +1,182 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor", "StellaOps.Attestor", "{78C966F5-2242-D8EC-ADCA-A1A9C7F723A6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.Core", "StellaOps.Attestor\StellaOps.Attestor.Core\StellaOps.Attestor.Core.csproj", "{D44872A3-772A-43D7-B340-61253543F02B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.Infrastructure", "StellaOps.Attestor\StellaOps.Attestor.Infrastructure\StellaOps.Attestor.Infrastructure.csproj", "{BFADAB55-9D9D-456F-987B-A4536027BA77}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.Tests", "StellaOps.Attestor\StellaOps.Attestor.Tests\StellaOps.Attestor.Tests.csproj", "{E2546302-F0CD-43E6-9CD6-D4B5E711454C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.WebService", "StellaOps.Attestor\StellaOps.Attestor.WebService\StellaOps.Attestor.WebService.csproj", "{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Configuration", "..\__Libraries\StellaOps.Configuration\StellaOps.Configuration.csproj", "{0792B7D7-E298-4639-B3DC-AFAF427810E9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugins.Abstractions", "..\Authority\StellaOps.Authority\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj", "{E93D1212-2745-4AD7-AD42-7666952A60C5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography", "..\__Libraries\StellaOps.Cryptography\StellaOps.Cryptography.csproj", "{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Abstractions", "..\Authority\StellaOps.Authority\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj", "{ED2AB277-AA70-4593-869A-BB13DA55FD12}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.DependencyInjection", "..\__Libraries\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj", "{6E844D37-2714-496B-8557-8FA2BF1744E8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Client", "..\Authority\StellaOps.Authority\StellaOps.Auth.Client\StellaOps.Auth.Client.csproj", "{44EB6890-FB96-405B-8CEC-A1EEB38474CE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.ServerIntegration", "..\Authority\StellaOps.Authority\StellaOps.Auth.ServerIntegration\StellaOps.Auth.ServerIntegration.csproj", "{36FBCE51-0429-4F2B-87FD-95B37941001D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D44872A3-772A-43D7-B340-61253543F02B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D44872A3-772A-43D7-B340-61253543F02B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D44872A3-772A-43D7-B340-61253543F02B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D44872A3-772A-43D7-B340-61253543F02B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D44872A3-772A-43D7-B340-61253543F02B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D44872A3-772A-43D7-B340-61253543F02B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D44872A3-772A-43D7-B340-61253543F02B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D44872A3-772A-43D7-B340-61253543F02B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D44872A3-772A-43D7-B340-61253543F02B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D44872A3-772A-43D7-B340-61253543F02B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D44872A3-772A-43D7-B340-61253543F02B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D44872A3-772A-43D7-B340-61253543F02B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77}.Release|x64.Build.0 = Release|Any CPU
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77}.Release|x86.Build.0 = Release|Any CPU
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}.Release|x64.Build.0 = Release|Any CPU
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6}.Release|x86.Build.0 = Release|Any CPU
|
||||
{0792B7D7-E298-4639-B3DC-AFAF427810E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0792B7D7-E298-4639-B3DC-AFAF427810E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0792B7D7-E298-4639-B3DC-AFAF427810E9}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0792B7D7-E298-4639-B3DC-AFAF427810E9}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{0792B7D7-E298-4639-B3DC-AFAF427810E9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0792B7D7-E298-4639-B3DC-AFAF427810E9}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{0792B7D7-E298-4639-B3DC-AFAF427810E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0792B7D7-E298-4639-B3DC-AFAF427810E9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0792B7D7-E298-4639-B3DC-AFAF427810E9}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0792B7D7-E298-4639-B3DC-AFAF427810E9}.Release|x64.Build.0 = Release|Any CPU
|
||||
{0792B7D7-E298-4639-B3DC-AFAF427810E9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0792B7D7-E298-4639-B3DC-AFAF427810E9}.Release|x86.Build.0 = Release|Any CPU
|
||||
{E93D1212-2745-4AD7-AD42-7666952A60C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E93D1212-2745-4AD7-AD42-7666952A60C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E93D1212-2745-4AD7-AD42-7666952A60C5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E93D1212-2745-4AD7-AD42-7666952A60C5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E93D1212-2745-4AD7-AD42-7666952A60C5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E93D1212-2745-4AD7-AD42-7666952A60C5}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E93D1212-2745-4AD7-AD42-7666952A60C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E93D1212-2745-4AD7-AD42-7666952A60C5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E93D1212-2745-4AD7-AD42-7666952A60C5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E93D1212-2745-4AD7-AD42-7666952A60C5}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E93D1212-2745-4AD7-AD42-7666952A60C5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E93D1212-2745-4AD7-AD42-7666952A60C5}.Release|x86.Build.0 = Release|Any CPU
|
||||
{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}.Release|x64.Build.0 = Release|Any CPU
|
||||
{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{9AE76C3A-0712-4DDA-A751-D0E8D59BD7A1}.Release|x86.Build.0 = Release|Any CPU
|
||||
{ED2AB277-AA70-4593-869A-BB13DA55FD12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ED2AB277-AA70-4593-869A-BB13DA55FD12}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ED2AB277-AA70-4593-869A-BB13DA55FD12}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{ED2AB277-AA70-4593-869A-BB13DA55FD12}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{ED2AB277-AA70-4593-869A-BB13DA55FD12}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{ED2AB277-AA70-4593-869A-BB13DA55FD12}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{ED2AB277-AA70-4593-869A-BB13DA55FD12}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ED2AB277-AA70-4593-869A-BB13DA55FD12}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ED2AB277-AA70-4593-869A-BB13DA55FD12}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{ED2AB277-AA70-4593-869A-BB13DA55FD12}.Release|x64.Build.0 = Release|Any CPU
|
||||
{ED2AB277-AA70-4593-869A-BB13DA55FD12}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{ED2AB277-AA70-4593-869A-BB13DA55FD12}.Release|x86.Build.0 = Release|Any CPU
|
||||
{6E844D37-2714-496B-8557-8FA2BF1744E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6E844D37-2714-496B-8557-8FA2BF1744E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6E844D37-2714-496B-8557-8FA2BF1744E8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{6E844D37-2714-496B-8557-8FA2BF1744E8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{6E844D37-2714-496B-8557-8FA2BF1744E8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{6E844D37-2714-496B-8557-8FA2BF1744E8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{6E844D37-2714-496B-8557-8FA2BF1744E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6E844D37-2714-496B-8557-8FA2BF1744E8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6E844D37-2714-496B-8557-8FA2BF1744E8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{6E844D37-2714-496B-8557-8FA2BF1744E8}.Release|x64.Build.0 = Release|Any CPU
|
||||
{6E844D37-2714-496B-8557-8FA2BF1744E8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{6E844D37-2714-496B-8557-8FA2BF1744E8}.Release|x86.Build.0 = Release|Any CPU
|
||||
{44EB6890-FB96-405B-8CEC-A1EEB38474CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{44EB6890-FB96-405B-8CEC-A1EEB38474CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{44EB6890-FB96-405B-8CEC-A1EEB38474CE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{44EB6890-FB96-405B-8CEC-A1EEB38474CE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{44EB6890-FB96-405B-8CEC-A1EEB38474CE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{44EB6890-FB96-405B-8CEC-A1EEB38474CE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{44EB6890-FB96-405B-8CEC-A1EEB38474CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{44EB6890-FB96-405B-8CEC-A1EEB38474CE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{44EB6890-FB96-405B-8CEC-A1EEB38474CE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{44EB6890-FB96-405B-8CEC-A1EEB38474CE}.Release|x64.Build.0 = Release|Any CPU
|
||||
{44EB6890-FB96-405B-8CEC-A1EEB38474CE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{44EB6890-FB96-405B-8CEC-A1EEB38474CE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{36FBCE51-0429-4F2B-87FD-95B37941001D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{36FBCE51-0429-4F2B-87FD-95B37941001D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{36FBCE51-0429-4F2B-87FD-95B37941001D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{36FBCE51-0429-4F2B-87FD-95B37941001D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{36FBCE51-0429-4F2B-87FD-95B37941001D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{36FBCE51-0429-4F2B-87FD-95B37941001D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{36FBCE51-0429-4F2B-87FD-95B37941001D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{36FBCE51-0429-4F2B-87FD-95B37941001D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{36FBCE51-0429-4F2B-87FD-95B37941001D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{36FBCE51-0429-4F2B-87FD-95B37941001D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{36FBCE51-0429-4F2B-87FD-95B37941001D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{36FBCE51-0429-4F2B-87FD-95B37941001D}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{D44872A3-772A-43D7-B340-61253543F02B} = {78C966F5-2242-D8EC-ADCA-A1A9C7F723A6}
|
||||
{BFADAB55-9D9D-456F-987B-A4536027BA77} = {78C966F5-2242-D8EC-ADCA-A1A9C7F723A6}
|
||||
{E2546302-F0CD-43E6-9CD6-D4B5E711454C} = {78C966F5-2242-D8EC-ADCA-A1A9C7F723A6}
|
||||
{39CCDD3E-5802-4E72-BE0F-25F7172C74E6} = {78C966F5-2242-D8EC-ADCA-A1A9C7F723A6}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,24 +1,24 @@
|
||||
# Attestor Guild
|
||||
|
||||
## Mission
|
||||
Operate the StellaOps Attestor service: accept signed DSSE envelopes from the Signer over mTLS, submit them to Rekor v2, persist inclusion proofs, and expose verification APIs for downstream services and operators.
|
||||
|
||||
## Teams On Call
|
||||
- Team 11 (Attestor API)
|
||||
- Team 12 (Attestor Observability) — partners on logging, metrics, and alerting
|
||||
|
||||
## Operating Principles
|
||||
- Enforce mTLS + Authority tokens for every submission; never accept anonymous callers.
|
||||
- Deterministic hashing, canonical JSON, and idempotent Rekor interactions (`bundleSha256` is the source of truth).
|
||||
- Persist everything (entries, dedupe, audit) before acknowledging; background jobs must be resumable.
|
||||
- Structured logs + metrics for each stage (`validate`, `submit`, `proof`, `persist`, `archive`).
|
||||
- Update `TASKS.md`, architecture docs, and tests whenever behaviour changes.
|
||||
|
||||
# Attestor Guild
|
||||
|
||||
## Mission
|
||||
Operate the StellaOps Attestor service: accept signed DSSE envelopes from the Signer over mTLS, submit them to Rekor v2, persist inclusion proofs, and expose verification APIs for downstream services and operators.
|
||||
|
||||
## Teams On Call
|
||||
- Team 11 (Attestor API)
|
||||
- Team 12 (Attestor Observability) — partners on logging, metrics, and alerting
|
||||
|
||||
## Operating Principles
|
||||
- Enforce mTLS + Authority tokens for every submission; never accept anonymous callers.
|
||||
- Deterministic hashing, canonical JSON, and idempotent Rekor interactions (`bundleSha256` is the source of truth).
|
||||
- Persist everything (entries, dedupe, audit) before acknowledging; background jobs must be resumable.
|
||||
- Structured logs + metrics for each stage (`validate`, `submit`, `proof`, `persist`, `archive`).
|
||||
- Update `TASKS.md`, architecture docs, and tests whenever behaviour changes.
|
||||
|
||||
## Key Directories
|
||||
- `src/StellaOps.Attestor/StellaOps.Attestor.WebService/` — Minimal API host and HTTP surface.
|
||||
- `src/StellaOps.Attestor/StellaOps.Attestor.Core/` — Domain contracts, submission/verification pipelines.
|
||||
- `src/StellaOps.Attestor/StellaOps.Attestor.Infrastructure/` — Mongo, Redis, Rekor, and archival implementations.
|
||||
- `src/StellaOps.Attestor/StellaOps.Attestor.Tests/` — Unit and integration tests.
|
||||
- `src/Attestor/StellaOps.Attestor/StellaOps.Attestor.WebService/` — Minimal API host and HTTP surface.
|
||||
- `src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Core/` — Domain contracts, submission/verification pipelines.
|
||||
- `src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Infrastructure/` — Mongo, Redis, Rekor, and archival implementations.
|
||||
- `src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Tests/` — Unit and integration tests.
|
||||
|
||||
---
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\StellaOps.Attestor.Core\StellaOps.Attestor.Core.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0-rc.2.25502.107" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0-rc.2.25502.107" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0-rc.2.25502.107" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0-rc.2.25502.107" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="3.5.0" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.8.24" />
|
||||
<PackageReference Include="AWSSDK.S3" Version="3.7.307.6" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\StellaOps.Attestor.Core\StellaOps.Attestor.Core.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0-rc.2.25502.107" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0-rc.2.25502.107" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0-rc.2.25502.107" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0-rc.2.25502.107" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="3.5.0" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.8.24" />
|
||||
<PackageReference Include="AWSSDK.S3" Version="3.7.307.6" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,3 +1,4 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
@@ -19,7 +20,7 @@
|
||||
<ProjectReference Include="..\StellaOps.Attestor.WebService\StellaOps.Attestor.WebService.csproj" />
|
||||
<ProjectReference Include="..\StellaOps.Attestor.Infrastructure\StellaOps.Attestor.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\StellaOps.Attestor.Core\StellaOps.Attestor.Core.csproj" />
|
||||
<ProjectReference Include="..\..\StellaOps.Configuration\StellaOps.Configuration.csproj" />
|
||||
<ProjectReference Include="..\..\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.Configuration/StellaOps.Configuration.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.DependencyInjection/StellaOps.DependencyInjection.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,3 +1,4 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
@@ -20,11 +21,11 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\StellaOps.Attestor.Core\StellaOps.Attestor.Core.csproj" />
|
||||
<ProjectReference Include="..\StellaOps.Attestor.Infrastructure\StellaOps.Attestor.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\StellaOps.Configuration\StellaOps.Configuration.csproj" />
|
||||
<ProjectReference Include="..\..\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj" />
|
||||
<ProjectReference Include="..\..\StellaOps.Cryptography\StellaOps.Cryptography.csproj" />
|
||||
<ProjectReference Include="..\..\StellaOps.Authority\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\StellaOps.Authority\StellaOps.Auth.Client\StellaOps.Auth.Client.csproj" />
|
||||
<ProjectReference Include="..\..\StellaOps.Authority\StellaOps.Auth.ServerIntegration\StellaOps.Auth.ServerIntegration.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.Configuration/StellaOps.Configuration.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.DependencyInjection/StellaOps.DependencyInjection.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.Cryptography/StellaOps.Cryptography.csproj" />
|
||||
<ProjectReference Include="../../../Authority/StellaOps.Authority/StellaOps.Auth.Abstractions/StellaOps.Auth.Abstractions.csproj" />
|
||||
<ProjectReference Include="../../../Authority/StellaOps.Authority/StellaOps.Auth.Client/StellaOps.Auth.Client.csproj" />
|
||||
<ProjectReference Include="../../../Authority/StellaOps.Authority/StellaOps.Auth.ServerIntegration/StellaOps.Auth.ServerIntegration.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
303
src/Authority/StellaOps.Authority.sln
Normal file
303
src/Authority/StellaOps.Authority.sln
Normal file
@@ -0,0 +1,303 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority", "StellaOps.Authority", "{BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Abstractions", "StellaOps.Authority\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj", "{336F7E73-0D75-4308-A20B-E8AB7964D27C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Abstractions.Tests", "StellaOps.Authority\StellaOps.Auth.Abstractions.Tests\StellaOps.Auth.Abstractions.Tests.csproj", "{CD7D0B36-386B-455D-A14B-E7857C255C42}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Client", "StellaOps.Authority\StellaOps.Auth.Client\StellaOps.Auth.Client.csproj", "{F2CEB8F7-C65B-407E-A11F-B02A39237355}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Configuration", "..\__Libraries\StellaOps.Configuration\StellaOps.Configuration.csproj", "{BF48C3E7-E1E8-4869-973F-22554F146FCE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugins.Abstractions", "StellaOps.Authority\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj", "{91C7B100-D04A-4486-8A26-9D55234876D7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography", "..\__Libraries\StellaOps.Cryptography\StellaOps.Cryptography.csproj", "{00E2F0AF-32EC-4755-81AD-907532F48BBB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Client.Tests", "StellaOps.Authority\StellaOps.Auth.Client.Tests\StellaOps.Auth.Client.Tests.csproj", "{2346E499-C1F4-46C5-BB03-859FC56881D4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.ServerIntegration", "StellaOps.Authority\StellaOps.Auth.ServerIntegration\StellaOps.Auth.ServerIntegration.csproj", "{412DAFA7-FDEA-418C-995B-7C7F51D89E00}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.DependencyInjection", "..\__Libraries\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj", "{79CB2323-2370-419A-8B22-A193B3F3CE68}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.ServerIntegration.Tests", "StellaOps.Authority\StellaOps.Auth.ServerIntegration.Tests\StellaOps.Auth.ServerIntegration.Tests.csproj", "{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority", "StellaOps.Authority\StellaOps.Authority\StellaOps.Authority.csproj", "{614EDC46-4654-40F7-A779-8F127B8FD956}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugin.Standard", "StellaOps.Authority\StellaOps.Authority.Plugin.Standard\StellaOps.Authority.Plugin.Standard.csproj", "{4B12E120-E39B-44A7-A25E-D3151D5AE914}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Plugin", "..\__Libraries\StellaOps.Plugin\StellaOps.Plugin.csproj", "{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Storage.Mongo", "StellaOps.Authority\StellaOps.Authority.Storage.Mongo\StellaOps.Authority.Storage.Mongo.csproj", "{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.DependencyInjection", "..\__Libraries\StellaOps.Cryptography.DependencyInjection\StellaOps.Cryptography.DependencyInjection.csproj", "{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Security", "..\__Libraries\StellaOps.Auth.Security\StellaOps.Auth.Security.csproj", "{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugin.Standard.Tests", "StellaOps.Authority\StellaOps.Authority.Plugin.Standard.Tests\StellaOps.Authority.Plugin.Standard.Tests.csproj", "{168986E2-E127-4E03-BE45-4CC306E4E880}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugins.Abstractions.Tests", "StellaOps.Authority\StellaOps.Authority.Plugins.Abstractions.Tests\StellaOps.Authority.Plugins.Abstractions.Tests.csproj", "{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Tests", "StellaOps.Authority\StellaOps.Authority.Tests\StellaOps.Authority.Tests.csproj", "{24BBDF59-7B30-4620-8464-BDACB1AEF49D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42}.Release|x64.Build.0 = Release|Any CPU
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355}.Release|x86.Build.0 = Release|Any CPU
|
||||
{BF48C3E7-E1E8-4869-973F-22554F146FCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BF48C3E7-E1E8-4869-973F-22554F146FCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BF48C3E7-E1E8-4869-973F-22554F146FCE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{BF48C3E7-E1E8-4869-973F-22554F146FCE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{BF48C3E7-E1E8-4869-973F-22554F146FCE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{BF48C3E7-E1E8-4869-973F-22554F146FCE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{BF48C3E7-E1E8-4869-973F-22554F146FCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BF48C3E7-E1E8-4869-973F-22554F146FCE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BF48C3E7-E1E8-4869-973F-22554F146FCE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{BF48C3E7-E1E8-4869-973F-22554F146FCE}.Release|x64.Build.0 = Release|Any CPU
|
||||
{BF48C3E7-E1E8-4869-973F-22554F146FCE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{BF48C3E7-E1E8-4869-973F-22554F146FCE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7}.Release|x64.Build.0 = Release|Any CPU
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7}.Release|x86.Build.0 = Release|Any CPU
|
||||
{00E2F0AF-32EC-4755-81AD-907532F48BBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{00E2F0AF-32EC-4755-81AD-907532F48BBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{00E2F0AF-32EC-4755-81AD-907532F48BBB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{00E2F0AF-32EC-4755-81AD-907532F48BBB}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{00E2F0AF-32EC-4755-81AD-907532F48BBB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{00E2F0AF-32EC-4755-81AD-907532F48BBB}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{00E2F0AF-32EC-4755-81AD-907532F48BBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{00E2F0AF-32EC-4755-81AD-907532F48BBB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{00E2F0AF-32EC-4755-81AD-907532F48BBB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{00E2F0AF-32EC-4755-81AD-907532F48BBB}.Release|x64.Build.0 = Release|Any CPU
|
||||
{00E2F0AF-32EC-4755-81AD-907532F48BBB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{00E2F0AF-32EC-4755-81AD-907532F48BBB}.Release|x86.Build.0 = Release|Any CPU
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4}.Release|x64.Build.0 = Release|Any CPU
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4}.Release|x86.Build.0 = Release|Any CPU
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00}.Release|x64.Build.0 = Release|Any CPU
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00}.Release|x86.Build.0 = Release|Any CPU
|
||||
{79CB2323-2370-419A-8B22-A193B3F3CE68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{79CB2323-2370-419A-8B22-A193B3F3CE68}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{79CB2323-2370-419A-8B22-A193B3F3CE68}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{79CB2323-2370-419A-8B22-A193B3F3CE68}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{79CB2323-2370-419A-8B22-A193B3F3CE68}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{79CB2323-2370-419A-8B22-A193B3F3CE68}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{79CB2323-2370-419A-8B22-A193B3F3CE68}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{79CB2323-2370-419A-8B22-A193B3F3CE68}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{79CB2323-2370-419A-8B22-A193B3F3CE68}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{79CB2323-2370-419A-8B22-A193B3F3CE68}.Release|x64.Build.0 = Release|Any CPU
|
||||
{79CB2323-2370-419A-8B22-A193B3F3CE68}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{79CB2323-2370-419A-8B22-A193B3F3CE68}.Release|x86.Build.0 = Release|Any CPU
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}.Release|x64.Build.0 = Release|Any CPU
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3}.Release|x86.Build.0 = Release|Any CPU
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956}.Release|x64.Build.0 = Release|Any CPU
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956}.Release|x86.Build.0 = Release|Any CPU
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914}.Release|x64.Build.0 = Release|Any CPU
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7F9552C7-7E41-4EA6-9F5E-17E8049C9F10}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}.Release|x64.Build.0 = Release|Any CPU
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A}.Release|x86.Build.0 = Release|Any CPU
|
||||
{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}.Release|x64.Build.0 = Release|Any CPU
|
||||
{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{208FE840-FFDD-43A5-9F64-F1F3C45C51F7}.Release|x86.Build.0 = Release|Any CPU
|
||||
{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}.Release|x64.Build.0 = Release|Any CPU
|
||||
{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{6EE9BB3A-A55F-4FDC-95F1-9304DB341AB1}.Release|x86.Build.0 = Release|Any CPU
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880}.Release|x64.Build.0 = Release|Any CPU
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880}.Release|x86.Build.0 = Release|Any CPU
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3}.Release|x86.Build.0 = Release|Any CPU
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{336F7E73-0D75-4308-A20B-E8AB7964D27C} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
{CD7D0B36-386B-455D-A14B-E7857C255C42} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
{F2CEB8F7-C65B-407E-A11F-B02A39237355} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
{91C7B100-D04A-4486-8A26-9D55234876D7} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
{2346E499-C1F4-46C5-BB03-859FC56881D4} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
{412DAFA7-FDEA-418C-995B-7C7F51D89E00} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
{BE1E685F-33D8-47E5-B4FA-BC4DDED255D3} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
{614EDC46-4654-40F7-A779-8F127B8FD956} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
{4B12E120-E39B-44A7-A25E-D3151D5AE914} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
{1FFF91AB-C2D2-4A12-A77B-AB9806116F7A} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
{168986E2-E127-4E03-BE45-4CC306E4E880} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
{A461EFE2-CBB1-4650-9CA0-05CECFAC3AE3} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
{24BBDF59-7B30-4620-8464-BDACB1AEF49D} = {BDB24B64-FE4E-C4BD-9F80-9428F98EDF6F}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -14,7 +14,7 @@ Own the StellaOps Authority host service: ASP.NET minimal API, OpenIddict flows,
|
||||
- Coordinate with plugin teams before altering plugin-facing contracts.
|
||||
|
||||
## Key Directories
|
||||
- `src/StellaOps.Authority/` — host app
|
||||
- `src/StellaOps.Authority.Tests/` — integration/unit tests
|
||||
- `src/StellaOps.Authority.Storage.Mongo/` — data access helpers
|
||||
- `src/StellaOps.Authority.Plugin.Standard/` — default identity provider plugin
|
||||
- `src/Authority/StellaOps.Authority/` — host app
|
||||
- `src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/` — integration/unit tests
|
||||
- `src/Authority/StellaOps.Authority/StellaOps.Authority.Storage.Mongo/` — data access helpers
|
||||
- `src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Standard/` — default identity provider plugin
|
||||
@@ -1,54 +1,54 @@
|
||||
using StellaOps.Auth.Abstractions;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Auth.Abstractions.Tests;
|
||||
|
||||
public class StellaOpsScopesTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(StellaOpsScopes.AdvisoryRead)]
|
||||
[InlineData(StellaOpsScopes.AdvisoryIngest)]
|
||||
[InlineData(StellaOpsScopes.VexRead)]
|
||||
[InlineData(StellaOpsScopes.VexIngest)]
|
||||
[InlineData(StellaOpsScopes.AocVerify)]
|
||||
[InlineData(StellaOpsScopes.SignalsRead)]
|
||||
[InlineData(StellaOpsScopes.SignalsWrite)]
|
||||
[InlineData(StellaOpsScopes.SignalsAdmin)]
|
||||
[InlineData(StellaOpsScopes.PolicyWrite)]
|
||||
[InlineData(StellaOpsScopes.PolicyAuthor)]
|
||||
[InlineData(StellaOpsScopes.PolicySubmit)]
|
||||
[InlineData(StellaOpsScopes.PolicyApprove)]
|
||||
[InlineData(StellaOpsScopes.PolicyReview)]
|
||||
[InlineData(StellaOpsScopes.PolicyOperate)]
|
||||
[InlineData(StellaOpsScopes.PolicyAudit)]
|
||||
[InlineData(StellaOpsScopes.PolicyRun)]
|
||||
[InlineData(StellaOpsScopes.PolicySimulate)]
|
||||
[InlineData(StellaOpsScopes.FindingsRead)]
|
||||
[InlineData(StellaOpsScopes.EffectiveWrite)]
|
||||
[InlineData(StellaOpsScopes.GraphRead)]
|
||||
[InlineData(StellaOpsScopes.VulnRead)]
|
||||
[InlineData(StellaOpsScopes.GraphWrite)]
|
||||
[InlineData(StellaOpsScopes.GraphExport)]
|
||||
[InlineData(StellaOpsScopes.GraphSimulate)]
|
||||
[InlineData(StellaOpsScopes.OrchRead)]
|
||||
[InlineData(StellaOpsScopes.OrchOperate)]
|
||||
[InlineData(StellaOpsScopes.ExportViewer)]
|
||||
[InlineData(StellaOpsScopes.ExportOperator)]
|
||||
[InlineData(StellaOpsScopes.ExportAdmin)]
|
||||
public void All_IncludesNewScopes(string scope)
|
||||
{
|
||||
Assert.Contains(scope, StellaOpsScopes.All);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Advisory:Read", StellaOpsScopes.AdvisoryRead)]
|
||||
[InlineData(" VEX:Ingest ", StellaOpsScopes.VexIngest)]
|
||||
[InlineData("AOC:VERIFY", StellaOpsScopes.AocVerify)]
|
||||
[InlineData(" Signals:Write ", StellaOpsScopes.SignalsWrite)]
|
||||
[InlineData("Policy:Author", StellaOpsScopes.PolicyAuthor)]
|
||||
[InlineData("Export.Admin", StellaOpsScopes.ExportAdmin)]
|
||||
public void Normalize_NormalizesToLowerCase(string input, string expected)
|
||||
{
|
||||
Assert.Equal(expected, StellaOpsScopes.Normalize(input));
|
||||
}
|
||||
}
|
||||
using StellaOps.Auth.Abstractions;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Auth.Abstractions.Tests;
|
||||
|
||||
public class StellaOpsScopesTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(StellaOpsScopes.AdvisoryRead)]
|
||||
[InlineData(StellaOpsScopes.AdvisoryIngest)]
|
||||
[InlineData(StellaOpsScopes.VexRead)]
|
||||
[InlineData(StellaOpsScopes.VexIngest)]
|
||||
[InlineData(StellaOpsScopes.AocVerify)]
|
||||
[InlineData(StellaOpsScopes.SignalsRead)]
|
||||
[InlineData(StellaOpsScopes.SignalsWrite)]
|
||||
[InlineData(StellaOpsScopes.SignalsAdmin)]
|
||||
[InlineData(StellaOpsScopes.PolicyWrite)]
|
||||
[InlineData(StellaOpsScopes.PolicyAuthor)]
|
||||
[InlineData(StellaOpsScopes.PolicySubmit)]
|
||||
[InlineData(StellaOpsScopes.PolicyApprove)]
|
||||
[InlineData(StellaOpsScopes.PolicyReview)]
|
||||
[InlineData(StellaOpsScopes.PolicyOperate)]
|
||||
[InlineData(StellaOpsScopes.PolicyAudit)]
|
||||
[InlineData(StellaOpsScopes.PolicyRun)]
|
||||
[InlineData(StellaOpsScopes.PolicySimulate)]
|
||||
[InlineData(StellaOpsScopes.FindingsRead)]
|
||||
[InlineData(StellaOpsScopes.EffectiveWrite)]
|
||||
[InlineData(StellaOpsScopes.GraphRead)]
|
||||
[InlineData(StellaOpsScopes.VulnRead)]
|
||||
[InlineData(StellaOpsScopes.GraphWrite)]
|
||||
[InlineData(StellaOpsScopes.GraphExport)]
|
||||
[InlineData(StellaOpsScopes.GraphSimulate)]
|
||||
[InlineData(StellaOpsScopes.OrchRead)]
|
||||
[InlineData(StellaOpsScopes.OrchOperate)]
|
||||
[InlineData(StellaOpsScopes.ExportViewer)]
|
||||
[InlineData(StellaOpsScopes.ExportOperator)]
|
||||
[InlineData(StellaOpsScopes.ExportAdmin)]
|
||||
public void All_IncludesNewScopes(string scope)
|
||||
{
|
||||
Assert.Contains(scope, StellaOpsScopes.All);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Advisory:Read", StellaOpsScopes.AdvisoryRead)]
|
||||
[InlineData(" VEX:Ingest ", StellaOpsScopes.VexIngest)]
|
||||
[InlineData("AOC:VERIFY", StellaOpsScopes.AocVerify)]
|
||||
[InlineData(" Signals:Write ", StellaOpsScopes.SignalsWrite)]
|
||||
[InlineData("Policy:Author", StellaOpsScopes.PolicyAuthor)]
|
||||
[InlineData("Export.Admin", StellaOpsScopes.ExportAdmin)]
|
||||
public void Normalize_NormalizesToLowerCase(string input, string expected)
|
||||
{
|
||||
Assert.Equal(expected, StellaOpsScopes.Normalize(input));
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user