Compare commits
3 Commits
1d962ee6fc
...
89543de7f1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89543de7f1 | ||
|
|
bf2bf4b395 | ||
|
|
ff0eca3a51 |
8
NOTICE.md
Normal file
8
NOTICE.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Third-Party Notices
|
||||
|
||||
This project bundles or links against the following third-party components in the scanner Ruby analyzer implementation:
|
||||
|
||||
- **tree-sitter** (MIT License, © 2018 Max Brunsfeld)
|
||||
- **tree-sitter-ruby** (MIT License, © 2016 Rob Rix)
|
||||
|
||||
License texts are available under third-party-licenses/.
|
||||
@@ -29,10 +29,7 @@
|
||||
<package pattern="Microsoft.IdentityModel.Abstractions" />
|
||||
<package pattern="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
||||
<package pattern="Google.Protobuf" />
|
||||
<package pattern="Grpc.*" />
|
||||
<package pattern="Microsoft.Bcl.AsyncInterfaces" />
|
||||
<package pattern="System.Memory" />
|
||||
<package pattern="System.Runtime.CompilerServices.Unsafe" />
|
||||
<package pattern="Grpc.*" />
|
||||
</packageSource>
|
||||
<packageSource key="dotnet-public">
|
||||
<package pattern="Microsoft.Extensions.*" />
|
||||
|
||||
@@ -107,23 +107,43 @@ services:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
attestor:
|
||||
image: registry.stella-ops.org/stellaops/attestor@sha256:1ff0a3124d66d3a2702d8e421df40fbd98cc75cb605d95510598ebbae1433c50
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- signer
|
||||
environment:
|
||||
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
|
||||
ATTESTOR__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017"
|
||||
ports:
|
||||
- "${ATTESTOR_PORT:-8442}:8442"
|
||||
networks:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
concelier:
|
||||
image: registry.stella-ops.org/stellaops/concelier@sha256:29e2e1a0972707e092cbd3d370701341f9fec2aa9316fb5d8100480f2a1c76b5
|
||||
restart: unless-stopped
|
||||
attestor:
|
||||
image: registry.stella-ops.org/stellaops/attestor@sha256:1ff0a3124d66d3a2702d8e421df40fbd98cc75cb605d95510598ebbae1433c50
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- signer
|
||||
environment:
|
||||
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
|
||||
ATTESTOR__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017"
|
||||
ports:
|
||||
- "${ATTESTOR_PORT:-8442}:8442"
|
||||
networks:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
issuer-directory:
|
||||
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- mongo
|
||||
- authority
|
||||
environment:
|
||||
ISSUERDIRECTORY__CONFIG: "/etc/issuer-directory.yaml"
|
||||
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
|
||||
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
|
||||
ISSUERDIRECTORY__MONGO__CONNECTIONSTRING: "${ISSUER_DIRECTORY_MONGO_CONNECTION_STRING}"
|
||||
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
|
||||
volumes:
|
||||
- ../../etc/issuer-directory.yaml:/etc/issuer-directory.yaml:ro
|
||||
ports:
|
||||
- "${ISSUER_DIRECTORY_PORT:-8447}:8080"
|
||||
networks:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
concelier:
|
||||
image: registry.stella-ops.org/stellaops/concelier@sha256:29e2e1a0972707e092cbd3d370701341f9fec2aa9316fb5d8100480f2a1c76b5
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- mongo
|
||||
- minio
|
||||
|
||||
@@ -107,25 +107,45 @@ services:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
attestor:
|
||||
image: registry.stella-ops.org/stellaops/attestor@sha256:5cc417948c029da01dccf36e4645d961a3f6d8de7e62fe98d845f07cd2282114
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- signer
|
||||
environment:
|
||||
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
|
||||
ATTESTOR__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017"
|
||||
ports:
|
||||
- "${ATTESTOR_PORT:-8442}:8442"
|
||||
networks:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
concelier:
|
||||
image: registry.stella-ops.org/stellaops/concelier@sha256:dafef3954eb4b837e2c424dd2d23e1e4d60fa83794840fac9cd3dea1d43bd085
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- mongo
|
||||
attestor:
|
||||
image: registry.stella-ops.org/stellaops/attestor@sha256:5cc417948c029da01dccf36e4645d961a3f6d8de7e62fe98d845f07cd2282114
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- signer
|
||||
environment:
|
||||
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
|
||||
ATTESTOR__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017"
|
||||
ports:
|
||||
- "${ATTESTOR_PORT:-8442}:8442"
|
||||
networks:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
issuer-directory:
|
||||
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- mongo
|
||||
- authority
|
||||
environment:
|
||||
ISSUERDIRECTORY__CONFIG: "/etc/issuer-directory.yaml"
|
||||
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
|
||||
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
|
||||
ISSUERDIRECTORY__MONGO__CONNECTIONSTRING: "${ISSUER_DIRECTORY_MONGO_CONNECTION_STRING}"
|
||||
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
|
||||
volumes:
|
||||
- ../../etc/issuer-directory.yaml:/etc/issuer-directory.yaml:ro
|
||||
ports:
|
||||
- "${ISSUER_DIRECTORY_PORT:-8447}:8080"
|
||||
networks:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
concelier:
|
||||
image: registry.stella-ops.org/stellaops/concelier@sha256:dafef3954eb4b837e2c424dd2d23e1e4d60fa83794840fac9cd3dea1d43bd085
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- mongo
|
||||
- minio
|
||||
environment:
|
||||
CONCELIER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017"
|
||||
|
||||
@@ -112,24 +112,44 @@ services:
|
||||
- frontdoor
|
||||
labels: *release-labels
|
||||
|
||||
attestor:
|
||||
image: registry.stella-ops.org/stellaops/attestor@sha256:0534985f978b0b5d220d73c96fddd962cd9135f616811cbe3bff4666c5af568f
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- signer
|
||||
environment:
|
||||
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
|
||||
ATTESTOR__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017"
|
||||
ports:
|
||||
- "${ATTESTOR_PORT:-8442}:8442"
|
||||
networks:
|
||||
- stellaops
|
||||
- frontdoor
|
||||
labels: *release-labels
|
||||
|
||||
concelier:
|
||||
image: registry.stella-ops.org/stellaops/concelier@sha256:c58cdcaee1d266d68d498e41110a589dd204b487d37381096bd61ab345a867c5
|
||||
restart: unless-stopped
|
||||
attestor:
|
||||
image: registry.stella-ops.org/stellaops/attestor@sha256:0534985f978b0b5d220d73c96fddd962cd9135f616811cbe3bff4666c5af568f
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- signer
|
||||
environment:
|
||||
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
|
||||
ATTESTOR__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017"
|
||||
ports:
|
||||
- "${ATTESTOR_PORT:-8442}:8442"
|
||||
networks:
|
||||
- stellaops
|
||||
- frontdoor
|
||||
labels: *release-labels
|
||||
|
||||
issuer-directory:
|
||||
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- mongo
|
||||
- authority
|
||||
environment:
|
||||
ISSUERDIRECTORY__CONFIG: "/etc/issuer-directory.yaml"
|
||||
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
|
||||
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
|
||||
ISSUERDIRECTORY__MONGO__CONNECTIONSTRING: "${ISSUER_DIRECTORY_MONGO_CONNECTION_STRING}"
|
||||
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
|
||||
volumes:
|
||||
- ../../etc/issuer-directory.yaml:/etc/issuer-directory.yaml:ro
|
||||
ports:
|
||||
- "${ISSUER_DIRECTORY_PORT:-8447}:8080"
|
||||
networks:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
concelier:
|
||||
image: registry.stella-ops.org/stellaops/concelier@sha256:c58cdcaee1d266d68d498e41110a589dd204b487d37381096bd61ab345a867c5
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- mongo
|
||||
- minio
|
||||
|
||||
@@ -107,22 +107,42 @@ services:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
attestor:
|
||||
image: registry.stella-ops.org/stellaops/attestor@sha256:0534985f978b0b5d220d73c96fddd962cd9135f616811cbe3bff4666c5af568f
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- signer
|
||||
environment:
|
||||
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
|
||||
ATTESTOR__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017"
|
||||
ports:
|
||||
- "${ATTESTOR_PORT:-8442}:8442"
|
||||
networks:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
concelier:
|
||||
image: registry.stella-ops.org/stellaops/concelier@sha256:c58cdcaee1d266d68d498e41110a589dd204b487d37381096bd61ab345a867c5
|
||||
attestor:
|
||||
image: registry.stella-ops.org/stellaops/attestor@sha256:0534985f978b0b5d220d73c96fddd962cd9135f616811cbe3bff4666c5af568f
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- signer
|
||||
environment:
|
||||
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
|
||||
ATTESTOR__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017"
|
||||
ports:
|
||||
- "${ATTESTOR_PORT:-8442}:8442"
|
||||
networks:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
issuer-directory:
|
||||
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- mongo
|
||||
- authority
|
||||
environment:
|
||||
ISSUERDIRECTORY__CONFIG: "/etc/issuer-directory.yaml"
|
||||
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
|
||||
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
|
||||
ISSUERDIRECTORY__MONGO__CONNECTIONSTRING: "${ISSUER_DIRECTORY_MONGO_CONNECTION_STRING}"
|
||||
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
|
||||
volumes:
|
||||
- ../../etc/issuer-directory.yaml:/etc/issuer-directory.yaml:ro
|
||||
ports:
|
||||
- "${ISSUER_DIRECTORY_PORT:-8447}:8080"
|
||||
networks:
|
||||
- stellaops
|
||||
labels: *release-labels
|
||||
|
||||
concelier:
|
||||
image: registry.stella-ops.org/stellaops/concelier@sha256:c58cdcaee1d266d68d498e41110a589dd204b487d37381096bd61ab345a867c5
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- mongo
|
||||
|
||||
10
deploy/compose/env/airgap.env.example
vendored
10
deploy/compose/env/airgap.env.example
vendored
@@ -8,9 +8,13 @@ RUSTFS_HTTP_PORT=8080
|
||||
AUTHORITY_ISSUER=https://authority.airgap.local
|
||||
AUTHORITY_PORT=8440
|
||||
SIGNER_POE_INTROSPECT_URL=file:///offline/poe/introspect.json
|
||||
SIGNER_PORT=8441
|
||||
ATTESTOR_PORT=8442
|
||||
CONCELIER_PORT=8445
|
||||
SIGNER_PORT=8441
|
||||
ATTESTOR_PORT=8442
|
||||
# Secrets for Issuer Directory are provided via issuer-directory.mongo.env (see etc/secrets/issuer-directory.mongo.secret.example).
|
||||
ISSUER_DIRECTORY_PORT=8447
|
||||
ISSUER_DIRECTORY_MONGO_CONNECTION_STRING=mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017
|
||||
ISSUER_DIRECTORY_SEED_CSAF=true
|
||||
CONCELIER_PORT=8445
|
||||
SCANNER_WEB_PORT=8444
|
||||
UI_PORT=9443
|
||||
NATS_CLIENT_PORT=24222
|
||||
|
||||
10
deploy/compose/env/dev.env.example
vendored
10
deploy/compose/env/dev.env.example
vendored
@@ -8,9 +8,13 @@ RUSTFS_HTTP_PORT=8080
|
||||
AUTHORITY_ISSUER=https://authority.localtest.me
|
||||
AUTHORITY_PORT=8440
|
||||
SIGNER_POE_INTROSPECT_URL=https://licensing.svc.local/introspect
|
||||
SIGNER_PORT=8441
|
||||
ATTESTOR_PORT=8442
|
||||
CONCELIER_PORT=8445
|
||||
SIGNER_PORT=8441
|
||||
ATTESTOR_PORT=8442
|
||||
# Secrets for Issuer Directory are provided via issuer-directory.mongo.env (see etc/secrets/issuer-directory.mongo.secret.example).
|
||||
ISSUER_DIRECTORY_PORT=8447
|
||||
ISSUER_DIRECTORY_MONGO_CONNECTION_STRING=mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017
|
||||
ISSUER_DIRECTORY_SEED_CSAF=true
|
||||
CONCELIER_PORT=8445
|
||||
SCANNER_WEB_PORT=8444
|
||||
UI_PORT=8443
|
||||
NATS_CLIENT_PORT=4222
|
||||
|
||||
10
deploy/compose/env/prod.env.example
vendored
10
deploy/compose/env/prod.env.example
vendored
@@ -10,9 +10,13 @@ RUSTFS_HTTP_PORT=8080
|
||||
AUTHORITY_ISSUER=https://authority.prod.stella-ops.org
|
||||
AUTHORITY_PORT=8440
|
||||
SIGNER_POE_INTROSPECT_URL=https://licensing.prod.stella-ops.org/introspect
|
||||
SIGNER_PORT=8441
|
||||
ATTESTOR_PORT=8442
|
||||
CONCELIER_PORT=8445
|
||||
SIGNER_PORT=8441
|
||||
ATTESTOR_PORT=8442
|
||||
# Secrets for Issuer Directory are provided via issuer-directory.mongo.env (see etc/secrets/issuer-directory.mongo.secret.example).
|
||||
ISSUER_DIRECTORY_PORT=8447
|
||||
ISSUER_DIRECTORY_MONGO_CONNECTION_STRING=mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017
|
||||
ISSUER_DIRECTORY_SEED_CSAF=true
|
||||
CONCELIER_PORT=8445
|
||||
SCANNER_WEB_PORT=8444
|
||||
UI_PORT=8443
|
||||
NATS_CLIENT_PORT=4222
|
||||
|
||||
10
deploy/compose/env/stage.env.example
vendored
10
deploy/compose/env/stage.env.example
vendored
@@ -8,9 +8,13 @@ RUSTFS_HTTP_PORT=8080
|
||||
AUTHORITY_ISSUER=https://authority.stage.stella-ops.internal
|
||||
AUTHORITY_PORT=8440
|
||||
SIGNER_POE_INTROSPECT_URL=https://licensing.stage.stella-ops.internal/introspect
|
||||
SIGNER_PORT=8441
|
||||
ATTESTOR_PORT=8442
|
||||
CONCELIER_PORT=8445
|
||||
SIGNER_PORT=8441
|
||||
ATTESTOR_PORT=8442
|
||||
# Secrets for Issuer Directory are provided via issuer-directory.mongo.env (see etc/secrets/issuer-directory.mongo.secret.example).
|
||||
ISSUER_DIRECTORY_PORT=8447
|
||||
ISSUER_DIRECTORY_MONGO_CONNECTION_STRING=mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017
|
||||
ISSUER_DIRECTORY_SEED_CSAF=true
|
||||
CONCELIER_PORT=8445
|
||||
SCANNER_WEB_PORT=8444
|
||||
UI_PORT=8443
|
||||
NATS_CLIENT_PORT=4222
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
image: registry.stella-ops.org/stellaops/authority@sha256:a8e8faec44a579aa5714e58be835f25575710430b1ad2ccd1282a018cd9ffcdd
|
||||
- name: signer
|
||||
image: registry.stella-ops.org/stellaops/signer@sha256:8bfef9a75783883d49fc18e3566553934e970b00ee090abee9cb110d2d5c3298
|
||||
- name: attestor
|
||||
image: registry.stella-ops.org/stellaops/attestor@sha256:5cc417948c029da01dccf36e4645d961a3f6d8de7e62fe98d845f07cd2282114
|
||||
- name: scanner-web
|
||||
image: registry.stella-ops.org/stellaops/scanner-web@sha256:e0dfdb087e330585a5953029fb4757f5abdf7610820a085bd61b457dbead9a11
|
||||
- name: attestor
|
||||
image: registry.stella-ops.org/stellaops/attestor@sha256:5cc417948c029da01dccf36e4645d961a3f6d8de7e62fe98d845f07cd2282114
|
||||
- name: issuer-directory-web
|
||||
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
|
||||
- name: scanner-web
|
||||
image: registry.stella-ops.org/stellaops/scanner-web@sha256:e0dfdb087e330585a5953029fb4757f5abdf7610820a085bd61b457dbead9a11
|
||||
- name: scanner-worker
|
||||
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:92dda42f6f64b2d9522104a5c9ffb61d37b34dd193132b68457a259748008f37
|
||||
- name: concelier
|
||||
|
||||
@@ -45,11 +45,11 @@ Authority persists every issued token in MongoDB so operators can audit or revok
|
||||
- **Client ID**: `console-web`
|
||||
- **Grants**: `authorization_code` (PKCE required), `refresh_token`
|
||||
- **Audience**: `console`
|
||||
- **Scopes**: `openid`, `profile`, `email`, `advisory:read`, `advisory-ai:view`, `vex:read`, `aoc:verify`, `findings:read`, `orch:read`, `vuln:read`
|
||||
- **Scopes**: `openid`, `profile`, `email`, `advisory:read`, `advisory-ai:view`, `vex:read`, `aoc:verify`, `findings:read`, `orch:read`, `vuln:view`, `vuln:investigate`, `vuln:operate`, `vuln:audit`
|
||||
- **Redirect URIs** (defaults): `https://console.stella-ops.local/oidc/callback`
|
||||
- **Post-logout redirect**: `https://console.stella-ops.local/`
|
||||
- **Tokens**: Access tokens inherit the global 2 minute lifetime; refresh tokens remain short-lived (30 days) and can be exchanged silently via `/token`.
|
||||
- **Roles**: Assign Authority role `Orch.Viewer` (exposed to tenants as `role/orch-viewer`) when operators need read-only access to Orchestrator telemetry via Console dashboards. Policy Studio ships dedicated roles (`role/policy-author`, `role/policy-reviewer`, `role/policy-approver`, `role/policy-operator`, `role/policy-auditor`) that align with the new `policy:*` scope family; issue them per tenant so audit trails remain scoped.
|
||||
- **Roles**: Assign Authority role `Orch.Viewer` (exposed to tenants as `role/orch-viewer`) when operators need read-only access to Orchestrator telemetry via Console dashboards. Policy Studio ships dedicated roles (`role/policy-author`, `role/policy-reviewer`, `role/policy-approver`, `role/policy-operator`, `role/policy-auditor`) plus the new attestation verbs (`policy:publish`, `policy:promote`) that align with the `policy:*` scope family; issue them per tenant so audit trails remain scoped and interactive attestations stay attributable.
|
||||
|
||||
Configuration sample (`etc/authority.yaml.sample`) seeds the client with a confidential secret so Console can negotiate the code exchange on the backend while browsers execute the PKCE dance.
|
||||
|
||||
@@ -91,7 +91,8 @@ Resource servers (Concelier WebService, Backend, Agent) **must not** assume in-m
|
||||
- Client credentials that request `advisory:ingest`, `advisory:read`, `advisory-ai:view`, `advisory-ai:operate`, `advisory-ai:admin`, `vex:ingest`, `vex:read`, `signals:read`, `signals:write`, `signals:admin`, or `aoc:verify` now fail fast when the client registration lacks a tenant hint. Issued tokens are re-validated against persisted tenant metadata, and Authority rejects any cross-tenant replay (`invalid_client`/`invalid_token`), ensuring aggregation-only workloads remain tenant-scoped.
|
||||
- Client credentials that request `export.viewer`, `export.operator`, or `export.admin` must provide a tenant hint. Requests for `export.admin` also need accompanying `export_reason` and `export_ticket` parameters; Authority returns `invalid_request` when either value is missing and records the denial in token audit events.
|
||||
- Client credentials that request `notify.viewer`, `notify.operator`, or `notify.admin` must provide a tenant hint. Authority records scope violations when tenancy is missing and emits `authority.notify.scope_violation` audit metadata so operators can trace denied requests.
|
||||
- Policy Studio scopes (`policy:author`, `policy:review`, `policy:approve`, `policy:operate`, `policy:audit`, `policy:simulate`, `policy:run`, `policy:activate`) require a tenant assignment; Authority rejects tokens missing the hint with `invalid_client` and records `scope.invalid` metadata for auditing.
|
||||
- Policy Studio scopes (`policy:author`, `policy:review`, `policy:approve`, `policy:operate`, `policy:publish`, `policy:promote`, `policy:audit`, `policy:simulate`, `policy:run`, `policy:activate`) require a tenant assignment; Authority rejects tokens missing the hint with `invalid_client` and records `scope.invalid` metadata for auditing. The `policy:publish`/`policy:promote` scopes are interactive-only and demand additional metadata (see “Policy attestation metadata” below).
|
||||
- Policy attestation tokens must include three parameters: `policy_reason` (≤512 chars describing why the attestation is being produced), `policy_ticket` (≤128 chars change/request reference), and `policy_digest` (32–128 char hex digest of the policy package). Authority rejects requests missing any value, over the limits, or providing a non-hex digest. Password-grant issuance stamps these values into the resulting token/audit trail and enforces a five-minute fresh-auth window via the `auth_time` claim.
|
||||
- Task Pack scopes (`packs.read`, `packs.write`, `packs.run`, `packs.approve`) require a tenant assignment; Authority rejects tokens missing the hint with `invalid_client` and logs `authority.pack_scope_violation` metadata for audit correlation.
|
||||
- **AOC pairing guardrails** – Tokens that request `advisory:read`, `advisory-ai:view`, `advisory-ai:operate`, `advisory-ai:admin`, `vex:read`, or any `signals:*` scope must also request `aoc:verify`. Authority rejects mismatches with `invalid_scope` (e.g., `Scope 'aoc:verify' is required when requesting advisory/advisory-ai/vex read scopes.` or `Scope 'aoc:verify' is required when requesting signals scopes.`) so automation surfaces deterministic errors.
|
||||
- **Signals ingestion guardrails** – Sensors and services requesting `signals:write`/`signals:admin` must also request `aoc:verify`; Authority records the `authority.aoc_scope_violation` tag when the pairing is missing so operators can trace failing sensors immediately.
|
||||
@@ -110,7 +111,7 @@ Resource servers (Concelier WebService, Backend, Agent) **must not** assume in-m
|
||||
| `export-center-admin` | Export Center administrative automation | `export.viewer`, `export.operator`, `export.admin` | `dpop` | `tenant-default` |
|
||||
| `notify-service` | Notify WebService API | `notify.viewer`, `notify.operator` | `dpop` | `tenant-default` |
|
||||
| `notify-admin` | Notify administrative automation | `notify.viewer`, `notify.operator`, `notify.admin` | `dpop` | `tenant-default` |
|
||||
| `vuln-explorer-ui` | Vuln Explorer UI/API | `vuln:read` | `dpop` | `tenant-default` |
|
||||
| `vuln-explorer-ui` | Vuln Explorer UI/API | `vuln:view`, `vuln:investigate`, `vuln:operate`, `vuln:audit` | `dpop` | `tenant-default` |
|
||||
| `signals-uploader` | Reachability sensor ingestion | `signals:write`, `signals:read`, `aoc:verify` | `dpop` | `tenant-default` |
|
||||
|
||||
> **Secret hygiene (2025‑10‑27):** The repository includes a convenience `etc/authority.yaml` for compose/helm smoke tests. Every entry’s `secretFile` points to `etc/secrets/*.secret`, which ship with `*-change-me` placeholders—replace them with strong values (and wire them through your vault/secret manager) before issuing tokens in CI, staging, or production.
|
||||
@@ -119,6 +120,18 @@ For factory provisioning, issue sensors the **SignalsUploader** role template (`
|
||||
|
||||
These registrations are provided as examples in `etc/authority.yaml.sample`. Clone them per tenant (for example `concelier-tenant-a`, `concelier-tenant-b`) so tokens remain tenant-scoped by construction.
|
||||
|
||||
### Policy attestation metadata
|
||||
|
||||
- **Interactive only.** `policy:publish` and `policy:promote` are restricted to password/device-code flows (Console, CLI) and are rejected when requested via client credentials or app secrets. Tokens inherit the 5-minute fresh-auth window; resource servers reject stale tokens and emit `authority.policy_attestation_validated=false`.
|
||||
- **Mandatory parameters.** Requests must include:
|
||||
- `policy_reason` (≤512 chars) — human-readable justification (e.g., “Promote tenant A baseline to production”).
|
||||
- `policy_ticket` (≤128 chars) — change request / CAB identifier (e.g., `CR-2025-1102`).
|
||||
- `policy_digest` — lowercase hex digest (32–128 characters) of the policy bundle being published/promoted.
|
||||
- **Audit surfaces.** On success, the metadata is copied into the access token (`stellaops:policy_reason`, `stellaops:policy_ticket`, `stellaops:policy_digest`, `stellaops:policy_operation`) and recorded in [`authority.password.grant`] audit events as `policy.*` properties.
|
||||
- **Failure modes.** Missing/blank parameters, over-length values, or non-hex digests trigger `invalid_request` responses and `authority.policy_attestation_denied` audit tags. CLI/Console must bubble these errors to operators and provide retry UX.
|
||||
- **CLI / Console UX.** The CLI stores attestation metadata in `stella.toml` (`authority.policy.publishReason`, `authority.policy.publishTicket`) or accepts `STELLA_POLICY_REASON` / `STELLA_POLICY_TICKET` / `STELLA_POLICY_DIGEST` environment variables. Console prompts operators for the same trio before issuing attestation tokens and refuses to cache values longer than the session.
|
||||
- **Automation guidance.** CI workflows should compute the policy digest ahead of time (for example `sha256sum policy-package.tgz | cut -d' ' -f1`) and inject the reason/ticket/digest into CLI environment variables immediately before invoking `stella auth login --scope policy:publish`.
|
||||
|
||||
Graph Explorer introduces dedicated scopes: `graph:write` for Cartographer build jobs, `graph:read` for query/read operations, `graph:export` for long-running export downloads, and `graph:simulate` for what-if overlays. Assign only the scopes a client actually needs to preserve least privilege—UI-facing clients should typically request read/export access, while background services (Cartographer, Scheduler) require write privileges.
|
||||
|
||||
#### Least-privilege guidance for graph clients
|
||||
@@ -140,11 +153,18 @@ Graph Explorer introduces dedicated scopes: `graph:write` for Cartographer build
|
||||
- **Administrative controls** – Changes to channel secrets, quiet hours, or escalation policies require `notify.admin`. Authority logs these operations and surfaces `authority.notify.scope_violation` when tokens omit the scope or tenant.
|
||||
- **Least privilege** – Assign `notify.admin` sparingly (platform operations, DR automation). Day-to-day rule editing should rely on `notify.operator` scoped per tenant.
|
||||
|
||||
#### Vuln Explorer permalinks
|
||||
#### Vuln Explorer scopes, ABAC, and permalinks
|
||||
|
||||
- **Scope** – `vuln:read` authorises Vuln Explorer to fetch advisory/linkset evidence and issue shareable links. Assign it only to front-end/API clients that must render vulnerability details.
|
||||
- **Signed links** – `POST /permalinks/vuln` (requires `vuln:read`) accepts `{ "tenant": "tenant-a", "resourceKind": "vulnerability", "state": { ... }, "expiresInSeconds": 86400 }` and returns a JWT (`token`) plus `issuedAt`/`expiresAt`. The token embeds the tenant, requested state, and `vuln:read` scope and is signed with the same Authority signing keys published via `/jwks`.
|
||||
- **Validation** – Resource servers verify the permalink using cached JWKS: check signature, ensure the tenant matches the current request context, honour the expiry, and enforce the contained `vuln:read` scope. The payload’s `resource.state` block is opaque JSON so UIs can round-trip filters/search terms without new schema changes.
|
||||
- **Scopes** – `vuln:view` unlocks read-only access and permalink issuance, `vuln:investigate` allows triage actions (assignment, comments, remediation notes), `vuln:operate` unlocks state transitions and workflow execution, and `vuln:audit` exposes immutable ledgers/exports. The legacy `vuln:read` scope is still emitted for backward compatibility but new clients should request the granular scopes.
|
||||
- **ABAC attributes** – Tenant roles can project attribute filters (`env`, `owner`, `business_tier`) via the `attributes` block in `authority.yaml` (see the sample `role/vuln-*` definitions). Authority now enforces the same filters on token issuance: client-credential requests must supply `vuln_env`, `vuln_owner`, and `vuln_business_tier` parameters when multiple values are configured, and the values must match the configured allow-list (or `*`). The accepted value pattern is `[a-z0-9:_-]{1,128}`. Issued tokens embed the resolved filters as `stellaops:vuln_env`, `stellaops:vuln_owner`, and `stellaops:vuln_business_tier` claims, and Authority persists the resulting actor chain plus service-account metadata in Mongo for auditability.
|
||||
- **Service accounts** – Delegated Vuln Explorer identities (`svc-vuln-*`) should include the attribute filters in their seed definition. Authority enforces the supplied `attributes` during issuance and stores the selected values on the delegation token, making downstream revocation/audit exports aware of the effective ABAC envelope.
|
||||
- **Token request parameters** – Minimum metadata for Vuln Explorer service accounts:
|
||||
- `service_account`: requested service-account id (still required).
|
||||
- `vuln_env`: single value or `*` (required when multiple environments are configured).
|
||||
- `vuln_owner`: owning team/code; optional only when the service account allows a single value.
|
||||
- `vuln_business_tier`: business criticality tier (`tier-1`, `tier-2`, etc.).
|
||||
Authority rejects missing parameters with `invalid_request` and records the violation via `authority.vuln_attr_*` audit properties.
|
||||
- **Signed links** – `POST /permalinks/vuln` requires `vuln:view`. The resulting JWT carries `vuln:view` plus the transitional `vuln:read` scope to preserve older consumers. Validation remains unchanged: verify the signature against `/jwks`, confirm tenant alignment, honour expiry, and enforce the scopes before honouring the permalink payload.
|
||||
|
||||
## 4. Revocation Pipeline
|
||||
Authority centralises revocation in `authority_revocations` with deterministic categories:
|
||||
@@ -410,6 +430,75 @@ curl -u orch-admin:s3cr3t! \
|
||||
|
||||
CLI clients configure these values via `Authority.BackfillReason` / `Authority.BackfillTicket` (environment variables `STELLAOPS_ORCH_BACKFILL_REASON` and `STELLAOPS_ORCH_BACKFILL_TICKET`). Tokens missing either field are rejected with `invalid_request`; audit events store the supplied values as `backfill.reason` and `backfill.ticket`.
|
||||
|
||||
### 7.4 Delegated service accounts
|
||||
|
||||
StellaOps Authority issues short-lived delegated tokens for service accounts so automation can operate on behalf of a tenant without sharing the underlying client identity.
|
||||
|
||||
**Configuration summary**
|
||||
|
||||
```yaml
|
||||
delegation:
|
||||
quotas:
|
||||
maxActiveTokens: 50
|
||||
serviceAccounts:
|
||||
- accountId: "svc-observer"
|
||||
tenant: "tenant-default"
|
||||
displayName: "Observability Exporter"
|
||||
description: "Delegated identity used by Export Center to read findings."
|
||||
enabled: true
|
||||
allowedScopes: [ "jobs:read", "findings:read" ]
|
||||
authorizedClients: [ "export-center-worker" ]
|
||||
|
||||
tenants:
|
||||
- name: "tenant-default"
|
||||
delegation:
|
||||
maxActiveTokens: 25
|
||||
```
|
||||
|
||||
* `delegation.quotas.maxActiveTokens` caps concurrent delegated tokens per tenant. Authority enforces both a tenant-wide ceiling and a per-account ceiling (the same value by default).
|
||||
* `serviceAccounts[].allowedScopes` lists scopes that the delegate may request. Requests for scopes outside this set return `invalid_scope`.
|
||||
* `serviceAccounts[].authorizedClients` restricts which OAuth clients may assume the delegate. Leave empty to allow any tenant client.
|
||||
* `tenants[].delegation.maxActiveTokens` optionally overrides the quota for a specific tenant.
|
||||
|
||||
**Bootstrap administration**
|
||||
|
||||
Bootstrap operators can inspect and rotate delegated identities via the internal API group:
|
||||
|
||||
```text
|
||||
GET /internal/service-accounts?tenant={tenantId}
|
||||
GET /internal/service-accounts/{accountId}/tokens
|
||||
POST /internal/service-accounts/{accountId}/revocations
|
||||
```
|
||||
|
||||
Requests must include the bootstrap API key header (`X-StellaOps-Bootstrap-Key`). Listing returns the seeded accounts with their configuration; the token listing call shows currently active delegation tokens (status, client, scopes, actor chain) and the revocation endpoint supports bulk or targeted token revocation with audit logging.
|
||||
|
||||
Bootstrap seeding reuses the existing Mongo `_id`/`createdAt` values. When Authority restarts with updated configuration it upserts documents without mutating immutable fields, avoiding duplicate or conflicting service-account records.
|
||||
|
||||
**Requesting a delegated token**
|
||||
|
||||
```bash
|
||||
curl -u export-center-worker:s3cr3t \
|
||||
-d 'grant_type=client_credentials' \
|
||||
-d 'scope=jobs:read findings:read' \
|
||||
-d 'service_account=svc-observer' \
|
||||
https://authority.example.com/token
|
||||
```
|
||||
|
||||
Optional `delegation_actor` metadata appends an identity to the actor chain:
|
||||
|
||||
```bash
|
||||
-d 'delegation_actor=pipeline://exporter/step/42'
|
||||
```
|
||||
|
||||
**Token shape & observability**
|
||||
|
||||
* Access tokens include `stellaops:service_account` and an `act` claim describing the caller hierarchy (`client_id` ⇒ optional `delegation_actor`).
|
||||
* `authority_tokens` records `tokenKind = "service_account"`, the `serviceAccountId`, and the normalized `actorChain[]`.
|
||||
* Audit events (`authority.client_credentials.grant`) emit `delegation.service_account`, `delegation.actor`, and quota outcomes (`delegation.quota.exceeded = true/false`).
|
||||
* When quota limits are exceeded Authority returns `invalid_request` (`Delegation token quota exceeded for tenant/service account`) and annotates the audit log.
|
||||
|
||||
Delegated tokens still honour scope validation, tenant enforcement, sender constraints (DPoP/mTLS), and fresh-auth checks.
|
||||
|
||||
## 8. Offline & Sovereign Operation
|
||||
- **No outbound dependencies:** Authority only contacts MongoDB and local plugins. Discovery and JWKS are cached by clients with offline tolerances (`AllowOfflineCacheFallback`, `OfflineCacheTolerance`). Operators should mirror these responses for air-gapped use.
|
||||
- **Structured logging:** Every revocation export, signing rotation, bootstrap action, and token issuance emits structured logs with `traceId`, `client_id`, `subjectId`, and `network.remoteIp` where applicable. Mirror logs to your SIEM to retain audit trails without central connectivity.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,20 @@
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| DOCS-SCANNER-BENCH-62-001 | DONE (2025-11-02) | Docs Guild, Scanner Guild | — | Maintain scanner comparison docs for Trivy, Grype, and Snyk; refresh deep dives and ecosystem matrix with source-linked implementation notes. | Comparison docs updated; matrix synced; deep dives cite source paths and highlight coverage gaps. |
|
||||
| DOCS-SCANNER-BENCH-62-002 | TODO | Docs Guild, Product Guild | DOCS-SCANNER-BENCH-62-001 | Collect Windows/macOS analyzer demand signals per `docs/benchmarks/scanner/windows-macos-demand.md`. | Demand summary produced; intake form updated; design spike criteria evaluated. |
|
||||
| DOCS-SCANNER-BENCH-62-003 | TODO | Docs Guild, Product Guild | DOCS-SCANNER-BENCH-62-002 | Capture Python lockfile / editable install requirements and document policy guidance once design completes. | Demand notes merged; policy template drafted. |
|
||||
| DOCS-SCANNER-BENCH-62-004 | TODO | Docs Guild, Java Analyzer Guild | DOCS-SCANNER-BENCH-62-003 | Document Java lockfile ingestion plan and associated policy templates per `scanning-gaps-stella-misses-from-competitors.md`. | Draft guidance published; policy examples reviewed. |
|
||||
| DOCS-SCANNER-BENCH-62-005 | TODO | Docs Guild, Go Analyzer Guild | DOCS-SCANNER-BENCH-62-004 | Document Go stripped-binary fallback enrichment guidance once implementation lands. | Docs updated with inferred module policy patterns. |
|
||||
| DOCS-SCANNER-BENCH-62-006 | TODO | Docs Guild, Rust Analyzer Guild | DOCS-SCANNER-BENCH-62-005 | Document Rust fingerprint enrichment guidance and policy examples. | Docs cover heuristic vs authoritative crate handling. |
|
||||
| DOCS-SCANNER-BENCH-62-007 | DOING (2025-11-02) | Docs Guild, Security Guild | DOCS-SCANNER-BENCH-62-006 | Produce secret leak detection documentation (rules, policy templates) once implementation lands. | Docs include rule bundle guidance and policy patterns. |
|
||||
| DOCS-SCANNER-BENCH-62-008 | TODO | Docs Guild, EntryTrace Guild | DOCS-SCANNER-BENCH-62-007 | Publish EntryTrace explain/heuristic maintenance guide per `scanning-gaps-stella-misses-from-competitors.md`. | Guide covers cadence, contribution workflow, and policy predicates. |
|
||||
| DOCS-SCANNER-BENCH-62-009 | DONE (2025-11-02) | Docs Guild, Ruby Analyzer Guild | DOCS-SCANNER-BENCH-62-008 | Extend Ruby ecosystem gap analysis in `scanning-gaps-stella-misses-from-competitors.md` with implementation notes, detection tables, and backlog mapping. | Ruby section updated with competitor techniques, task linkage, and scoring rationale. |
|
||||
| DOCS-SCANNER-BENCH-62-010 | DONE (2025-11-02) | Docs Guild, PHP Analyzer Guild | DOCS-SCANNER-BENCH-62-009 | Document PHP analyzer parity gaps with detection technique tables and policy hooks. | PHP section merged with plan references and backlog linkage. |
|
||||
| DOCS-SCANNER-BENCH-62-011 | DONE (2025-11-02) | Docs Guild, Language Analyzer Guild | DOCS-SCANNER-BENCH-62-010 | Capture Deno runtime gap analysis versus competitors, including detection/merge strategy table. | Deno section added with implementation notes and backlog callouts. |
|
||||
| DOCS-SCANNER-BENCH-62-012 | DONE (2025-11-02) | Docs Guild, Language Analyzer Guild | DOCS-SCANNER-BENCH-62-011 | Add Dart ecosystem comparison and task linkage in `scanning-gaps-stella-misses-from-competitors.md`. | Dart section present with detection table, backlog references, and scoring. |
|
||||
| DOCS-SCANNER-BENCH-62-013 | DONE (2025-11-02) | Docs Guild, Swift Analyzer Guild | DOCS-SCANNER-BENCH-62-012 | Expand Swift coverage analysis with implementation techniques and policy considerations. | Swift section integrated with detection table and backlog references. |
|
||||
| DOCS-SCANNER-BENCH-62-014 | DONE (2025-11-02) | Docs Guild, Runtime Guild | DOCS-SCANNER-BENCH-62-013 | Detail Kubernetes/VM target coverage gaps and interplay with Zastava/Runtime docs. | Target coverage section merged with detection/merging approach and action items. |
|
||||
| DOCS-SCANNER-BENCH-62-015 | DONE (2025-11-02) | Docs Guild, Export Center Guild | DOCS-SCANNER-BENCH-62-014 | Document DSSE/Rekor operator enablement guidance from competitor comparison. | DSSE section aligned with Export Center backlog and detection merge table. |
|
||||
|
||||
## Air-Gapped Mode (Epic 16)
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
@@ -115,7 +129,8 @@
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|----|--------|----------|------------|-------------|---------------|
|
||||
| DOCS-LNM-22-007 | TODO | Docs Guild, Observability Guild | CONCELIER-LNM-21-005, EXCITITOR-LNM-21-005, DEVOPS-LNM-22-002 | Publish `/docs/observability/aggregation.md` with metrics/traces/logs/SLOs. | Observability doc merged; dashboards referenced; checklist appended. |
|
||||
| DOCS-LNM-22-008 | TODO | Docs Guild, DevOps Guild | MERGE-LNM-21-001, CONCELIER-LNM-21-102 | Write `/docs/migration/no-merge.md` describing migration plan, backfill steps, rollback, feature flags. | Migration doc approved by stakeholders; checklist appended. |
|
||||
| DOCS-LNM-22-008 | DONE (2025-11-03) | Docs Guild, DevOps Guild | MERGE-LNM-21-001, CONCELIER-LNM-21-102 | Write `/docs/migration/no-merge.md` describing migration plan, backfill steps, rollback, feature flags. | Migration doc approved by stakeholders; checklist appended. |
|
||||
> 2025-11-03: Moved to DOING to align playbook structure, then published `docs/migration/no-merge.md` with rollout/backfill/rollback guidance plus readiness checklist; awaiting stakeholder approval note.
|
||||
|
||||
## Policy Engine + Editor v1
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
Air-Gapped Mode is the supported operating profile for deployments with **zero external egress**. All inputs arrive via signed mirror bundles, and every surface (CLI, Console, APIs, schedulers, scanners) operates under sealed-network constraints while preserving Aggregation-Only Contract invariants.
|
||||
|
||||
- **Primary components:** Web Services API, Console, CLI, Orchestrator, Task Runner, Conseiller (Feedser), Excitator (VEXer), Policy Engine, Findings Ledger, Export Center, Authority & Tenancy, Notifications, Observability & Forensics.
|
||||
- **Primary components:** Web Services API, Console, CLI, Orchestrator, Task Runner, Conselier (formerly Feedser), Excitor (formerly Vexer), Policy Engine, Findings Ledger, Export Center, Authority & Tenancy, Notifications, Observability & Forensics.
|
||||
- **Surfaces:** offline bootstrap, mirror ingestion, deterministic jobs, offline advisories/VEX/policy packs/notifications, evidence exports.
|
||||
- **Dependencies:** Export Center, Containerized Distribution, Authority-backed scopes & tenancy, Observability & Forensics, Policy Studio.
|
||||
|
||||
@@ -15,7 +15,7 @@ Air-Gapped Mode is the supported operating profile for deployments with **zero e
|
||||
1. **Zero egress:** all outbound network calls are disabled unless explicitly allowed. Any feature requiring online data must degrade gracefully with clear UX messaging.
|
||||
2. **Deterministic inputs:** the platform accepts only signed Mirror Bundles (advisories, VEX, policy packs, vendor feeds, images, dashboards). Bundles carry provenance attestations and chain-of-custody manifests.
|
||||
3. **Auditable exchange:** every import/export records provenance, signatures, and operator identity. Evidence bundles and reports remain verifiable offline.
|
||||
4. **Aggregation-Only Contract compliance:** Conseiller and Excitator continue to aggregate without mutating source records, even when ingesting mirrored feeds.
|
||||
4. **Aggregation-Only Contract compliance:** Conseiller and Excitor continue to aggregate without mutating source records, even when ingesting mirrored feeds.
|
||||
5. **Operator ergonomics:** offline bootstrap, upgrade, and verification steps are reproducible and scripted.
|
||||
|
||||
## Lifecycle & modes
|
||||
@@ -44,7 +44,7 @@ Air-Gapped Mode is the supported operating profile for deployments with **zero e
|
||||
| --- | --- |
|
||||
| Export Center | Produce full/delta mirror bundles, signed manifests, provenance attestations. |
|
||||
| Authority & Tenancy | Provide offline scope enforcement, short-lived tokens, revocation via local CRLs. |
|
||||
| Conseiller / Excitator | Ingest mirrored advisories/VEX, enforce AOC, versioned observations. |
|
||||
| Conseiller / Excitor | Ingest mirrored advisories/VEX, enforce AOC, versioned observations. |
|
||||
| Policy Engine & Findings Ledger | Replay evaluations using offline feeds, emit explain traces, support sealed-mode hints. |
|
||||
| Notifications | Deliver locally via approved channels (email relay, webhook proxies) or queue for manual export. |
|
||||
| Observability | Collect metrics/logs/traces locally, generate forensic bundles for external analysis. |
|
||||
@@ -57,6 +57,8 @@ Air-Gapped Mode is the supported operating profile for deployments with **zero e
|
||||
- **Key rotation:** plan for offline key ceremonies; Export Center and Authority document rotation playbooks.
|
||||
- **Authority scopes:** enforce `airgap:status:read`, `airgap:import`, and `airgap:seal` via tenant-scoped roles; require operator reason/ticket metadata for sealing.
|
||||
- **Incident response:** maintain scripts for replaying imports, regenerating manifests, and exporting forensic data without egress.
|
||||
- **EgressPolicy facade:** all services route outbound calls through `StellaOps.AirGap.Policy`. In sealed mode `EgressPolicy` enforces the `airgap.egressAllowlist`, auto-permits loopback targets, and raises `AIRGAP_EGRESS_BLOCKED` exceptions with remediation text (add host to allowlist or coordinate break-glass). Unsealed mode logs intents but does not block, giving operators a single toggle for rehearsals. Task Runner now feeds every `run.egress` declaration and runtime network hint into the shared policy during planning, preventing sealed-mode packs from executing unless destinations are declared and allow-listed.
|
||||
- **Linting/CI:** enable the `StellaOps.AirGap.Policy.Analyzers` package in solution-level analyzers so CI fails on raw `HttpClient` usage. The analyzer emits `AIRGAP001` and the bundled code fix rewrites to `EgressHttpClientFactory.Create(...)`; treat analyzer warnings as errors in sealed-mode pipelines.
|
||||
|
||||
## Testing & verification
|
||||
|
||||
|
||||
18
docs/api/scanner/README.md
Normal file
18
docs/api/scanner/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Scanner API Docs — Windows/macOS Coverage (Draft)
|
||||
|
||||
This directory collects interim artefacts tracking customer demand and roadmap readiness for extending Scanner coverage to Windows and macOS.
|
||||
|
||||
## Files
|
||||
- `windows-coverage.md` — narrative summary of customer signals and required artefacts.
|
||||
- `windows-macos-summary.md` — dashboard-style snapshot (counts, cross-references) updated after each discovery cycle.
|
||||
|
||||
## Related resources
|
||||
- `../../modules/scanner/design/README.md`
|
||||
- `../../benchmarks/scanner/windows-macos-demand.md`
|
||||
- `../../benchmarks/scanner/windows-macos-interview-template.md`
|
||||
- `../../modules/scanner/design/macos-analyzer.md`
|
||||
- `../../modules/scanner/design/windows-analyzer.md`
|
||||
- `../../modules/policy/windows-package-readiness.md`
|
||||
- `../../modules/policy/secret-leak-detection-readiness.md`
|
||||
|
||||
> Note: replace these working notes with formal API documentation once Windows/macOS analyzer endpoints are defined.
|
||||
50
docs/api/scanner/windows-coverage.md
Normal file
50
docs/api/scanner/windows-coverage.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Scanner API — Windows/macOS Coverage Signals (Draft)
|
||||
|
||||
> Audience: Solutions engineers, product managers, guild leads coordinating Windows/macOS roadmap
|
||||
> Status: Informational; update as interviews conclude
|
||||
|
||||
## Summary
|
||||
| Region | Accounts referenced | Primary workloads | Demand strength (1-5) | Blocking? | Notes |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| North America | Northwind Health Services; FinSecure Corp | macOS CI runners; Windows Server 2019 workloads | 4-5 | macOS: evaluation; Windows: blocking | Demo 2025-11-10; Security decision due 2025-11-07. |
|
||||
| EMEA | — | — | — | — | — |
|
||||
| APAC | — | — | — | — | — |
|
||||
| Gov / Regulated | — | — | — | — | — |
|
||||
|
||||
### Key drivers
|
||||
- Customers with regulated Windows Server/desktop estates lack deterministic SBOM coverage and provenance.
|
||||
- macOS development shops (Mobile, Gaming) require entitlements/notarization evidence for compliance.
|
||||
- Offline/air-gapped environments need signed rule bundles and feed mirrors for Windows/macOS ecosystems.
|
||||
|
||||
### Competitive landscape
|
||||
- Trivy/Grype/Snyk remain Linux-focused; Windows/macOS features are roadmap items or SaaS-only.
|
||||
- Opportunity to differentiate via deterministic evidence, policy integration, and offline parity.
|
||||
|
||||
### Design references
|
||||
- `../../modules/scanner/design/macos-analyzer.md`
|
||||
- `../../modules/scanner/design/windows-analyzer.md`
|
||||
|
||||
### Action items
|
||||
- Maintain region rows using interview summaries from `docs/benchmarks/scanner/windows-macos-demand.md` (last update 2025-11-03; capture via the interview template).
|
||||
- Track readiness decisions by updating POLICY-READINESS-0001/0002 status and recording outcomes in the summary table.
|
||||
- Align backlog references (`SCANNER-ENG-0020..0027`, `DOCS-SCANNER-BENCH-62-016`) with product prioritisation after each roadmap review.
|
||||
|
||||
### Open blockers
|
||||
- FinSecure PCI audit pending POLICY-READINESS-0002 decision (due 2025-11-07); unblock Windows analyzer spike scheduling.
|
||||
- Northwind macOS readiness workshop scheduled 2025-11-10; capture masking/telemetry decisions for POLICY-READINESS-0001.
|
||||
|
||||
## Interview log (selected)
|
||||
| Date | Customer | Platform focus | Signal summary | Strength (1-5) | Follow-up |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 2025-11-03 | Northwind Health Services | macOS | Needs notarization/entitlement visibility for CI runners | 4 | Demo 2025-11-10 with Product; feed findings into POLICY-READINESS-0001. |
|
||||
| 2025-11-03 | FinSecure Corp | Windows | Requires MSI/WinSxS SBOM + signed driver attestations for PCI audit | 5 | Security guild to resolve Authenticode posture (POLICY-READINESS-0002) by 2025-11-07. |
|
||||
|
||||
## Required artefacts
|
||||
- Maintain interview notes using `docs/benchmarks/scanner/windows-macos-interview-template.md`.
|
||||
- Update demand tracker tables in `docs/benchmarks/scanner/windows-macos-demand.md`.
|
||||
- Sync backlog entries in `docs/modules/scanner/TASKS.md` and `docs/scanner/design/*.md`.
|
||||
|
||||
## Next steps
|
||||
1. Collect at least three qualified Windows and macOS requests; update summary table.
|
||||
2. Present findings to Scanner Guild for prioritisation (target Sprint 133 design spike).
|
||||
3. Coordinate policy readiness briefs (`docs/modules/policy/windows-package-readiness.md`) and design docs (`design/macos-analyzer.md`, `design/windows-analyzer.md`).
|
||||
37
docs/api/scanner/windows-macos-summary.md
Normal file
37
docs/api/scanner/windows-macos-summary.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Scanner API — Windows/macOS Coverage Dashboard (Draft)
|
||||
|
||||
> Owners: Product Guild, Scanner Guild • Status: living document updated every sprint
|
||||
|
||||
## At-a-glance metrics (Sprint 132 intake)
|
||||
- macOS demand entries logged: 1 (Northwind Health Services, 2025-11-03)
|
||||
- Windows demand entries logged: 1 (FinSecure Corp, 2025-11-03)
|
||||
- Qualified customers awaiting roadmap response: 1 (FinSecure PCI blocker)
|
||||
- Open policy readiness items: POLICY-READINESS-0001, POLICY-READINESS-0002
|
||||
|
||||
## Cross-reference
|
||||
| Resource | Purpose |
|
||||
| --- | --- |
|
||||
| docs/benchmarks/scanner/windows-macos-demand.md | Signal log & next actions |
|
||||
| docs/benchmarks/scanner/windows-macos-interview-template.md | Interview capture template |
|
||||
| docs/benchmarks/scanner/deep-dives/macos.md | macOS implementation roadmap |
|
||||
| docs/benchmarks/scanner/deep-dives/windows.md | Windows implementation roadmap |
|
||||
| docs/modules/scanner/design/macos-analyzer.md | Detailed macOS design |
|
||||
| docs/modules/scanner/design/windows-analyzer.md | Detailed Windows design |
|
||||
| docs/modules/policy/windows-package-readiness.md | Policy readiness for Windows packages |
|
||||
| docs/modules/policy/secret-leak-detection-readiness.md | Policy readiness for secrets |
|
||||
| docs/modules/scanner/TASKS.md | Engineering backlog (SCANNER-ENG-0020..0027) |
|
||||
| docs/modules/policy/TASKS.md | Policy readiness tasks |
|
||||
| docs/api/scanner/windows-coverage.md | Narrative summary |
|
||||
|
||||
## Maintenance cadence
|
||||
- Update metrics and cross-links after each customer signal or roadmap checkpoint.
|
||||
- Ensure DOCS-SCANNER-BENCH-62-002/016 status mirrors demand tracker progress.
|
||||
|
||||
## Upcoming milestones
|
||||
- 2025-11-07: POLICY-READINESS-0002 Authenticode/feed decision for FinSecure (unblocks Windows analyzer spike).
|
||||
- 2025-11-10: POLICY-READINESS-0001 workshop during Northwind demo to finalise masking/telemetry posture.
|
||||
|
||||
## Recent updates
|
||||
- 2025-11-03: Logged Northwind Health Services (macOS) & FinSecure Corp (Windows); awaiting POLICY-READINESS-0001/0002 decisions before scheduling analyzer spikes.
|
||||
|
||||
Last updated: 2025-11-03 (initial demand entries logged).
|
||||
@@ -1,51 +1,51 @@
|
||||
# SDK & OpenAPI Program
|
||||
|
||||
> Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.
|
||||
|
||||
## Overview
|
||||
|
||||
The SDK & OpenAPI program delivers canonical OpenAPI 3.1 contracts for every Stella Ops surface, plus officially supported SDKs (TypeScript/Node, Python, Go, Java, C#). It ensures backwards-compatible evolution, documentation, and offline availability.
|
||||
|
||||
- **Primary components:** API Gateway, Web Services, Policy Engine, Conseiller, Excitator, Orchestrator, Findings Ledger, Export Center, Authority & Tenancy, Console, CLI.
|
||||
- **Surfaces:** OpenAPI specs, language SDKs, developer portal, examples, mock server, conformance tests, changelog feeds, deprecation notices.
|
||||
- **Dependencies:** Authority scopes/tenancy, CLI parity, Export Center, Notifications, Air-Gapped Mode, Observability.
|
||||
|
||||
## Program pillars
|
||||
|
||||
1. **Contract-first:** treat OpenAPI specs as the source of truth. CI validates schemas, compatibility, and documentation generation.
|
||||
2. **SDK parity:** language SDKs cover the same surfaces with deterministic clients, pagination helpers, and typed models mirroring Aggregation-Only Contract semantics.
|
||||
3. **Version discipline:** semantic versioning for specs and SDKs, release notes, deprecation windows, and automated change alerts via Notifications.
|
||||
4. **Offline readiness:** specs and SDK bundles ship in Mirror Bundles for air-gapped environments; examples include smoke tests.
|
||||
5. **Observability:** telemetry around SDK usage, spec download metrics, and error reporting funnels back into product decisions.
|
||||
|
||||
## Deliverables
|
||||
|
||||
| Workstream | Deliverable |
|
||||
| --- | --- |
|
||||
| Spec authoring | Unified OpenAPI 3.1 documents per service plus aggregate spec; lint rules; schema registries. |
|
||||
| SDK generation | Language-specific clients with idiomatic ergonomics, retries, pagination, long-running operation helpers, unit + integration tests. |
|
||||
| Dev portal | Consolidated documentation, guides, changelog, copy/paste examples, quickstart scripts. |
|
||||
| Testing | Contract tests against staging, mock server for integration tests, compatibility verification per release. |
|
||||
| Release ops | Automated CI pipelines, version bump workflows, release notes, deprecation policies. |
|
||||
|
||||
## Guardrails
|
||||
|
||||
- **Aggregation-Only Contract compliance:** SDKs expose raw advisory/VEX objects without hidden merges; all derived fields require explicit Policy Engine calls.
|
||||
- **Security:** enforce scopes via SDK configuration; redact secrets; support DPoP/mTLS and offline token provisioning.
|
||||
- **Compatibility:** maintain backwards-compatible paths for at least two minor releases; log warnings on deprecated endpoints.
|
||||
- **Documentation:** publish examples for common workflows (scan, policy evaluate, export, attestation) with language parity.
|
||||
|
||||
## Roadmap checkpoints
|
||||
|
||||
1. Baseline OpenAPI specs extracted from gateway, validated, and published.
|
||||
2. TypeScript/Node SDK as pilot, followed by Python and Go.
|
||||
3. Developer portal launch with SDK docs, quickstarts, and mock server.
|
||||
4. Offline kit integration (mirror bundles include specs + SDK tarballs).
|
||||
5. Runtime alerting for breaking changes and dependency vulnerabilities.
|
||||
|
||||
## References
|
||||
|
||||
- API gateway integration: `docs/modules/platform/architecture-overview.md`
|
||||
- Policy/Findings models: `docs/modules/policy/architecture.md`, `docs/modules/vuln-explorer/architecture.md`
|
||||
- Export bundle distribution: `docs/modules/export-center/overview.md`
|
||||
- Offline workflows: `docs/airgap/airgap-mode.md`
|
||||
# SDK & OpenAPI Program
|
||||
|
||||
> Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.
|
||||
|
||||
## Overview
|
||||
|
||||
The SDK & OpenAPI program delivers canonical OpenAPI 3.1 contracts for every Stella Ops surface, plus officially supported SDKs (TypeScript/Node, Python, Go, Java, C#). It ensures backwards-compatible evolution, documentation, and offline availability.
|
||||
|
||||
- **Primary components:** API Gateway, Web Services, Policy Engine, Conseiller, Excitor, Orchestrator, Findings Ledger, Export Center, Authority & Tenancy, Console, CLI.
|
||||
- **Surfaces:** OpenAPI specs, language SDKs, developer portal, examples, mock server, conformance tests, changelog feeds, deprecation notices.
|
||||
- **Dependencies:** Authority scopes/tenancy, CLI parity, Export Center, Notifications, Air-Gapped Mode, Observability.
|
||||
|
||||
## Program pillars
|
||||
|
||||
1. **Contract-first:** treat OpenAPI specs as the source of truth. CI validates schemas, compatibility, and documentation generation.
|
||||
2. **SDK parity:** language SDKs cover the same surfaces with deterministic clients, pagination helpers, and typed models mirroring Aggregation-Only Contract semantics.
|
||||
3. **Version discipline:** semantic versioning for specs and SDKs, release notes, deprecation windows, and automated change alerts via Notifications.
|
||||
4. **Offline readiness:** specs and SDK bundles ship in Mirror Bundles for air-gapped environments; examples include smoke tests.
|
||||
5. **Observability:** telemetry around SDK usage, spec download metrics, and error reporting funnels back into product decisions.
|
||||
|
||||
## Deliverables
|
||||
|
||||
| Workstream | Deliverable |
|
||||
| --- | --- |
|
||||
| Spec authoring | Unified OpenAPI 3.1 documents per service plus aggregate spec; lint rules; schema registries. |
|
||||
| SDK generation | Language-specific clients with idiomatic ergonomics, retries, pagination, long-running operation helpers, unit + integration tests. |
|
||||
| Dev portal | Consolidated documentation, guides, changelog, copy/paste examples, quickstart scripts. |
|
||||
| Testing | Contract tests against staging, mock server for integration tests, compatibility verification per release. |
|
||||
| Release ops | Automated CI pipelines, version bump workflows, release notes, deprecation policies. |
|
||||
|
||||
## Guardrails
|
||||
|
||||
- **Aggregation-Only Contract compliance:** SDKs expose raw advisory/VEX objects without hidden merges; all derived fields require explicit Policy Engine calls.
|
||||
- **Security:** enforce scopes via SDK configuration; redact secrets; support DPoP/mTLS and offline token provisioning.
|
||||
- **Compatibility:** maintain backwards-compatible paths for at least two minor releases; log warnings on deprecated endpoints.
|
||||
- **Documentation:** publish examples for common workflows (scan, policy evaluate, export, attestation) with language parity.
|
||||
|
||||
## Roadmap checkpoints
|
||||
|
||||
1. Baseline OpenAPI specs extracted from gateway, validated, and published.
|
||||
2. TypeScript/Node SDK as pilot, followed by Python and Go.
|
||||
3. Developer portal launch with SDK docs, quickstarts, and mock server.
|
||||
4. Offline kit integration (mirror bundles include specs + SDK tarballs).
|
||||
5. Runtime alerting for breaking changes and dependency vulnerabilities.
|
||||
|
||||
## References
|
||||
|
||||
- API gateway integration: `docs/modules/platform/architecture-overview.md`
|
||||
- Policy/Findings models: `docs/modules/policy/architecture.md`, `docs/modules/vuln-explorer/architecture.md`
|
||||
- Export bundle distribution: `docs/modules/export-center/overview.md`
|
||||
- Offline workflows: `docs/airgap/airgap-mode.md`
|
||||
|
||||
26
docs/benchmarks/scanner/README.md
Normal file
26
docs/benchmarks/scanner/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Scanner Benchmarks & Coverage Dossiers
|
||||
|
||||
This directory aggregates competitive analyses, deep dives, and demand signals that inform the Scanner roadmap.
|
||||
|
||||
## Structure
|
||||
- `../../scanner-feature-comparison-*.md` — high-level feature comparisons versus Trivy, Grype, Snyk.
|
||||
- `deep-dives/` — ecosystem-specific implementation deep dives (languages, OS packages, secrets, macOS, Windows, etc.).
|
||||
- `scanning-gaps-stella-misses-from-competitors.md` — gap analysis with scorecards, implementation plans, and backlog references.
|
||||
- `windows-macos-demand.md` — demand tracker and next actions for Windows/macOS coverage.
|
||||
- `windows-macos-interview-template.md` — structured questionnaire for customer discovery.
|
||||
|
||||
## Quick links
|
||||
- macOS: `deep-dives/macos.md`, `../../modules/scanner/design/macos-analyzer.md`.
|
||||
- Windows: `deep-dives/windows.md`, `../../modules/scanner/design/windows-analyzer.md`.
|
||||
- Policy readiness: `../../modules/policy/secret-leak-detection-readiness.md`, `../../modules/policy/windows-package-readiness.md`.
|
||||
- API dashboards: `../../api/scanner/windows-coverage.md`, `../../api/scanner/windows-macos-summary.md`.
|
||||
|
||||
## Maintenance tips
|
||||
- When new interview signals are logged, update `windows-macos-demand.md`, the API dashboards, and cross-link relevant design docs.
|
||||
- Ensure gap scorecards reflect the latest findings and backlog IDs.
|
||||
- Keep feature comparison docs aligned with deep dive updates.
|
||||
|
||||
## Backlog references
|
||||
- Engineering: see `../../modules/scanner/TASKS.md` (SCANNER-ENG-0020..0027).
|
||||
- Docs: `../../docs/TASKS.md` (DOCS-SCANNER-BENCH-62-016).
|
||||
- Policy: `../../modules/policy/TASKS.md` (POLICY-READINESS-0001/0002).
|
||||
48
docs/benchmarks/scanner/deep-dives/macos.md
Normal file
48
docs/benchmarks/scanner/deep-dives/macos.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# macOS Package Ecosystem — Coverage Deep Dive
|
||||
|
||||
## Competitor snapshot
|
||||
- **Trivy**: Official coverage tables list only Linux distributions (Alpine/Wolfi, Debian/Ubuntu, RHEL family, SUSE, Photon, Amazon, Bottlerocket). No analyzer exists for Homebrew, Mac App Store receipts, or `.app` bundles.
|
||||
- **Grype**: Mirrors Syft catalogers that target Linux package managers; no matchers for Homebrew formulae, pkgutil receipts, or macOS frameworks.
|
||||
- **Snyk CLI**: Container and open-source scans are routed through the SaaS backend; macOS host package analysis is not advertised or documented.
|
||||
|
||||
## Proposed StellaOps roadmap
|
||||
See also: `../../modules/scanner/design/macos-analyzer.md` for the in-depth design brief.
|
||||
1. **Homebrew cellar collector**
|
||||
- Parse `/usr/local/Cellar` and `/opt/homebrew/Cellar` manifest files plus taps metadata to enumerate installed formulae/casks.
|
||||
- Normalize tap origin, version, revision, and bottle source; map to `pkg:brew/{tap}/{name}@{version}` PURLs.
|
||||
2. **System receipt inventory**
|
||||
- Use `pkgutil --pkgs --pkg-info-plist` style parsing against `/var/db/receipts/*.bom` to capture Apple installer packages and third-party pkg receipts.
|
||||
- Record CFBundleIdentifier, install timestamps, and BOM file hashes to feed deterministic provenance.
|
||||
3. **Application bundle inspection**
|
||||
- Scan `/Applications`, `/System/Applications`, and `/Users/*/Applications` for `.app` bundles.
|
||||
- Extract Info.plist data (bundle id/version), embedded frameworks, entitlements, and code signing certificates.
|
||||
4. **Policy alignment**
|
||||
- Emit capability hints (network, TCC categories) for Policy Engine gating.
|
||||
- Provide allow lists for signed Apple system components versus third-party apps.
|
||||
5. **Offline parity**
|
||||
- Mirror Homebrew tap metadata snapshots and entitlements schema inside Offline Kit.
|
||||
- Package notarization certificate bundles and CRL/OCSP cache guidance for air-gapped verification.
|
||||
|
||||
## Detection technique comparison
|
||||
| Technique | Artifacts | Merge strategy | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| Homebrew cellar parsing | Cellar manifests, `INSTALL_RECEIPT.json`, tap metadata | Produce per-formula component records keyed by tap + version; merge duplicates by canonical tap origin; attach bottle SHA256 for provenance. | Requires tap snapshot to ensure deterministic version resolution. |
|
||||
| pkgutil receipt parsing | `/var/db/receipts/*.plist` + `.bom` files | Build component entries for Apple/third-party installer packages; merge with bundle evidence when matching CFBundleIdentifier. | Provides authoritative install-time metadata including install source. |
|
||||
| `.app` bundle inspection | Info.plist, CodeResources, entitlements, embedded frameworks | Emit capability records (e.g., `tcc.camera`, `network.client`); merge with receipts when bundle id matches. | Must preserve signing chain and team identifier; store hash of CodeDirectory. |
|
||||
| Launch daemon/service mapping | `/Library/LaunchDaemons`, `/Library/LaunchAgents`, `launchctl print` exports | (Planned) Attach runtime usage hints for Policy Engine and EntryTrace cross-module alignment. | Helps differentiate dormant apps from active services. |
|
||||
| Competitor baseline | — | No competitor evidence to merge; Trivy/Grype/Snyk lack macOS analyzers. | Presents differentiation opportunity once demand justifies investment. |
|
||||
|
||||
## Backlog / coordination
|
||||
- Keep demand capture in `docs/benchmarks/scanner/windows-macos-demand.md` up to date; once thresholds are met, open:
|
||||
- `SCANNER-ENG-00xx` (macOS cellar/receipt analyzer design spike).
|
||||
- `DOCS-SCANNER-BENCH-62-002` (this doc’s parent task) — exit criteria: demand summary + design scope recommendation.
|
||||
- Policy task to define macOS capability predicates (entitlements, notarization state).
|
||||
- Align with Offline Kit guild on notarization/CRL packaging and tap mirroring strategy.
|
||||
|
||||
## Open design questions
|
||||
| Topic | Question | Owner |
|
||||
| --- | --- | --- |
|
||||
| Notarization verification | Should scanner verify Apple notarization tickets or delegate to Policy Engine? | Security Guild |
|
||||
| Entitlement taxonomy | How granular should capability predicates be (per entitlement vs grouped categories)? | Policy Guild |
|
||||
| User-space scope | Do we scan per-user Homebrew installs and sandboxed app containers? | Scanner Guild |
|
||||
| Performance | Do we cache receipts/bundle metadata between scans given large `.app` trees? | Scanner + Surface Guilds |
|
||||
@@ -4,20 +4,21 @@
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| .NET | Dependency retrieval | Snyk | No pre-build lock/config ingestion (installed `deps.json` only). | No runtime graph; ignores `runtimeconfig`/installed assemblies. | Relies on Syft `deps.json` catalogs; no layer-aware runtime context. | Requires authenticated SaaS analysis; projects often need restore/build before scanning. | Evaluate adding lockfile analyzer parity (track via Scanner .NET guild tasks). | [dotnet.md](dotnet.md) |
|
||||
| .NET | Runtime metadata & signing | StellaOps | Authenticode inspection optional; Windows-only coverage pending. | Does not capture signer metadata or assembly hashes. | No authenticode or RID metadata captured; package fields only. | No runtimeconfig/authenticode data; focuses on dependency manifests. | Harden Authenticode integration & document Windows variants. | [dotnet.md](dotnet.md) |
|
||||
| Node.js | Workspace & pnpm resolution | Tie (StellaOps / Snyk) | Lack of pnpm lock validator tooling for CLI users. | pnpm virtual store resolved only via lockfile semantics; skips actual installs. | Depends on Syft catalogers; lacks pnpm workspace policy controls or dedupe tuning. | Manifest-based plugins (npm/yarn/pnpm) send dependency graphs to Snyk API; offline unsupported. | Add pnpm validator CLI story; share results with Surface Env guild. | [nodejs.md](nodejs.md) |
|
||||
| Node.js | Workspace & pnpm resolution | Tie (StellaOps / Snyk) | Lack of pnpm lock validator tooling for CLI users. | pnpm virtual store resolved only via lockfile semantics; skips actual installs. | Depends on Syft catalogers; lacks pnpm workspace policy controls or dedupe tuning. | Manifest-based plugins (npm/yarn/pnpm) send dependency graphs to Snyk API; offline unsupported. | Track lockfile validator plan (`scanning-gaps-stella-misses-from-competitors.md`) and file analyzer/CLI backlog items. | [nodejs.md](nodejs.md) |
|
||||
| Node.js | Usage tracking | StellaOps | EntryTrace launcher catalog requires regular updates. | No runtime usage model; inventory-only. | No runtime usage modelling; reports inventory only. | No runtime usage modelling (inventory only). | Establish cadence for launcher catalog review (EntryTrace TASKS). | [nodejs.md](nodejs.md) |
|
||||
| Python | Evidence source | Tie (StellaOps / Trivy) | Build-only repos need supplemental workflow. | Accepts stale lockfiles; installed evidence optional. | Leverages Syft-installed metadata; build-only projects need external flow. | Requires language environment & build; manifest graph sent to Snyk service. | Scope CLI guidance for build-only repos in docs backlog. | [python.md](python.md) |
|
||||
| Python | Evidence source | Tie (StellaOps / Trivy) | Build-only repos need supplemental workflow. | Accepts stale lockfiles; installed evidence optional. | Leverages Syft-installed metadata; build-only projects need external flow. | Requires language environment & build; manifest graph sent to Snyk service. | Track Python lockfile parity plan (`scanning-gaps-stella-misses-from-competitors.md`) in analyzer backlog. | [python.md](python.md) |
|
||||
| Python | Usage awareness | StellaOps | EntryTrace hints dependent on shell heuristic coverage. | Missing runtime usage context entirely. | No runtime usage awareness. | No runtime usage metadata. | Expand EntryTrace shell heuristic coverage. | [python.md](python.md) |
|
||||
| Java | Archive evidence | Tie (StellaOps / Snyk) | Gradle/SBT lockfiles out of scope; relies on observed archives. | No archive hash locators; depends on Java DB availability. | Relies on Syft archive metadata without manifest hashing/attestation. | Relies on Maven/Gradle plugins; no archive hashing or offline support. | Track Gradle/SBT ingestion feasibility (Java analyzer task board). | [java.md](java.md) |
|
||||
| Go | Stripped binaries | StellaOps | Fallback components limited to hash + binary metadata. | Drops binaries lacking build info; no fallback reporting. | Skips pseudo-version binaries without build info; no hashed fallback. | Go plugin inspects modules via manifests; binaries without modules not analysed. | Investigate richer fallback metadata (Go analyzer backlog). | [golang.md](golang.md) |
|
||||
| Rust | Binary heuristics | StellaOps | Fingerprint coverage incomplete for niche toolchains. | Unmatched binaries ignored; no fallback crates. | No fallback for binaries lacking Cargo metadata; depends on Syft crate data. | No Rust/Cargo support in CLI plugins. | Expand fingerprint signatures; note in Rust analyzer tasks. | [rust.md](rust.md) |
|
||||
| Java | Archive evidence | Tie (StellaOps / Snyk) | Gradle/SBT lockfiles out of scope; relies on observed archives. | No archive hash locators; depends on Java DB availability. | Relies on Syft archive metadata without manifest hashing/attestation. | Relies on Maven/Gradle plugins; no archive hashing or offline support. | Execute Java lockfile plan (`scanning-gaps-stella-misses-from-competitors.md`) and log analyzer/CLI backlog items. | [java.md](java.md) |
|
||||
| Go | Stripped binaries | StellaOps | Fallback components limited to hash + binary metadata. | Drops binaries lacking build info; no fallback reporting. | Skips pseudo-version binaries without build info; no hashed fallback. | Go plugin inspects modules via manifests; binaries without modules not analysed. | Execute Go fallback enrichment plan (`scanning-gaps-stella-misses-from-competitors.md`) to add inferred metadata & policy hooks. | [golang.md](golang.md) |
|
||||
| Rust | Binary heuristics | StellaOps | Fingerprint coverage incomplete for niche toolchains. | Unmatched binaries ignored; no fallback crates. | No fallback for binaries lacking Cargo metadata; depends on Syft crate data. | No Rust/Cargo support in CLI plugins. | Execute Rust fingerprint plan (`scanning-gaps-stella-misses-from-competitors.md`) and update analyzer backlog. | [rust.md](rust.md) |
|
||||
| OS packages | Linux distro coverage & provenance | Tie (StellaOps / Grype) | Requires RustFS/object store deployment for full replay; Windows packaging still out of scope. | No per-layer fragment storage; provenance limited; Windows support likewise minimal. | No per-layer provenance; shares Syft catalog and Anchore DB only. | Snyk Container scanning depends on SaaS API; no per-layer provenance. | Document RustFS dependency & offline alternatives in ops backlog; evaluate Windows pkg roadmap. | [os-packages.md](os-packages.md) |
|
||||
| OS packages | Linux flavor support (Alpine/Wolfi/Chainguard, Debian/Ubuntu, RHEL/Alma/Rocky, SUSE, Amazon/Bottlerocket) | Tie (Trivy / Snyk) | Windows/macOS package ecosystems still pending. | Coverage relies on package DB adapters; per-distro nuances (e.g., Chainguard signatures) not attested. | Supports major Linux feeds but no Windows/macOS package analyzers. | Supports documented distro list via Snyk Container but requires cloud connectivity. | Track demand for non-Linux package analyzers; document distro mapping in os-packages deep dive. | [os-packages.md](os-packages.md) |
|
||||
| OS packages | Windows/macOS coverage | — | No Windows/macOS analyzer; backlog item for offline parity. | Coverage docs enumerate Linux distributions only; Windows/macOS packages unsupported. | Syft matchers focus on Linux ecosystems; Windows/macOS packages unsupported. | Coverage depends on Snyk’s SaaS service; no offline assurance for Windows/macOS packages. | Capture demand for Windows/macOS analyzers and scope feasibility. | [os-packages.md](os-packages.md) |
|
||||
| macOS packages | Coverage & provenance | StellaOps (future) | macOS analyzer not implemented yet; design captured in deep dive. | No macOS analyzers (Linux only). | No macOS analyzers (Linux only). | No macOS host scanning; SaaS container focus only. | Advance demand capture (`windows-macos-demand.md`); open macOS design spike once threshold met. | [macos.md](macos.md) |
|
||||
| Windows packages | Coverage & provenance | StellaOps (future) | Windows analyzer family not yet implemented; design brief in progress. | No Windows coverage beyond containers. | Syft/Grype lack Windows collectors; Anchore feeds Linux-only. | SaaS host scanning only; no offline or deterministic evidence. | Capture demand signals; scope Windows analyzer spike when thresholds met. | [windows.md](windows.md) |
|
||||
| Secrets | Handling posture | StellaOps | No leak scanning by design; Surface.Secrets manages retrieval/rotation with tenant scopes. | Leak detections lack governance hooks; operators must track rule updates. | No secret management abstraction; credentials configured manually. | Requires SaaS backend for secret scanning; no offline posture or secret storage guidance. | Document governance patterns for Surface.Secrets users and recommended companion tooling. | [secrets.md](secrets.md) |
|
||||
| Secrets | Detection technique | Trivy | No content scanning; relies on Surface.Secrets integrations. | Regex/entropy detectors with configurable allow/deny lists across files/bytecode. | No detector available; Syft/Grype skip leak scanning entirely. | Snyk Code/Snyk secrets require uploading code to SaaS; offline detection unavailable. | Provide guidance on pairing Surface with third-party leak scanners; evaluate optional plugin strategy. | [secrets.md](secrets.md) |
|
||||
| EntryTrace | Runtime command resolution | StellaOps | Shell/language launcher coverage needs continuous tuning. | Not supported. | Not available. | Not available. | Continue EntryTrace backlog (SURFACE-ENTRYTRACE stories). | — |
|
||||
| DSSE / Rekor | Attested SBOM/report signing | StellaOps | Rekor v2 adoption requires operator enablement guidance. | Not supported. | No attestation or transparency log integration. | No attestation workflow. | Add operator playbook updates in Export Center backlog. | — |
|
||||
| Secrets | Detection technique | Trivy | No content scanning; relies on Surface.Secrets integrations. | Regex/entropy detectors with configurable allow/deny lists across files/bytecode. | No detector available; Syft/Grype skip leak scanning entirely. | Snyk Code/Snyk secrets require uploading code to SaaS; offline detection unavailable. | Execute secrets leak detection plan (`scanning-gaps-stella-misses-from-competitors.md`) and plan policy templates. | [secrets.md](secrets.md) |
|
||||
| EntryTrace | Runtime command resolution | StellaOps | Shell/language launcher coverage needs continuous tuning. | Not supported. | Not available. | Not available. | Maintain EntryTrace plan (`scanning-gaps-stella-misses-from-competitors.md`) and backlog cadence. | — |
|
||||
| DSSE / Rekor | Attested SBOM/report signing | StellaOps | Rekor v2 adoption requires operator enablement guidance. | Not supported. | No attestation or transparency log integration. | No attestation workflow. | Already covered by Export Center backlog (no additional plan required). | — |
|
||||
| Ruby | Language analyzer parity | Snyk | No Ruby analyzer implementation yet. | Lacks runtime usage/EntryTrace integration. | Supports Ruby via matcher but lacks runtime usage/attestation. | Supported through rubygems plugin (SaaS dependency graph). | Prioritise Ruby analyzer work (see `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby/TASKS.md`). | — |
|
||||
| PHP | Language analyzer parity | Snyk | No PHP analyzer implementation yet. | No usage or evidence beyond lockfiles. | Composer handled via generic matcher; no runtime evidence. | Supported through PHP Composer plugin (requires Snyk API). | Track PHP analyzer backlog (`...Lang.Php/TASKS.md`). | — |
|
||||
| Deno | Language analyzer parity | Trivy | Analyzer not yet implemented (tasks pending). | None (lockfile support limited but present). | No Deno support. | No Deno plugin. | Execute Deno analyzer epics in `...Lang.Deno/TASKS.md`. | — |
|
||||
@@ -25,4 +26,4 @@
|
||||
| Swift | Language analyzer parity | Snyk | No Swift support today. | Supports Package.resolved parsing but no runtime usage. | No Swift support. | Supported via swift plugin but SaaS-only. | Evaluate need for Swift analyzer based on customer demand. | — |
|
||||
| SAST | Application code analysis | Snyk | No built-in SAST engine. | No SAST engine (focus on vuln & config). | No SAST support (SBOM matching only). | Requires SaaS upload of code; privacy considerations. | Evaluate integration points with existing SAST tooling / document partner options. | [sast.md](sast.md) |
|
||||
| IaC / Misconfiguration | Built-in scanning | Snyk | No misconfiguration analyzer (policy engine focuses on runtime evidence). | Ships IaC scanning but lacks deterministic replay. | No IaC or misconfiguration scanners (vulnerability-only). | Handled via Snyk IaC (`snyk iac test`) with SaaS policy engine. | Coordinate with Policy/Surface guild on IaC roadmap assessment. | — |
|
||||
| Kubernetes / VM targets | Target coverage breadth | Tie (Trivy / Snyk) | Scanner limited to images/filesystems; relies on other modules for runtime posture. | Supported but lacks attestation pipeline. | Scans images/filesystems; no live cluster or VM state analysis. | Snyk Container/K8s scanning available but cloud-managed; no offline runtime attestation. | Document complementary modules (Zastava/Runtime) in comparison appendix. | — |
|
||||
| Kubernetes / VM targets | Target coverage breadth | Tie (Trivy / Snyk) | Scanner limited to images/filesystems; relies on other modules for runtime posture. | Supported but lacks attestation pipeline. | Scans images/filesystems; no live cluster or VM state analysis. | Snyk Container/K8s scanning available but cloud-managed; no offline runtime attestation. | Document complementary modules (Zastava/Runtime) in comparison appendix. | — |
|
||||
|
||||
@@ -29,6 +29,14 @@
|
||||
- **Metadata depth**: StellaOps records extensive vendor metadata and file evidence for replay; Trivy, Snyk, and Grype focus on match-relevant fields from their feeds.
|
||||
- **Provenance**: StellaOps’ outputs integrate directly with attestation/diff pipelines, while Trivy, Snyk, and Grype assume downstream tools consume package lists without replay requirements.
|
||||
|
||||
### Detection technique comparison
|
||||
| Tool | Detection technique(s) | Merge / result handling | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| **StellaOps** | Deterministic DB parsing via `StellaOps.Scanner.Analyzers.OS.(Apk|Dpkg|Rpm)`; fragment mapping via `OsComponentMapper`; provenance persisted in Surface.FS. | Analyzer outputs become `LayerComponentFragment`s stored in `ScanAnalysisStore`; SBOM assembly composes inventory/usage views while preserving layer digests and metadata for diffs + attestations. | Supports offline replay, DSSE binding, and policy joins with Concelier advisories. |
|
||||
| **Trivy** | Layer walkers + distro parsers in `pkg/fanal/analyzer/pkg/*`; optional manifest enrichment using vendor feeds. | Packages aggregated per artifact; provenance/layer context not persisted, leaving downstream tooling to interpret results. | Coverage matrix enumerated in `docs/docs/coverage/os/*.md`. |
|
||||
| **Grype** | Syft catalogers + matchers in `grype/matcher/{apk,dpkg,rpm}` leveraging Anchore feeds. | Matchers run against Syft inventory and Anchore DB; no layer fragments retained. | Determinism depends on feed snapshots. |
|
||||
| **Snyk** | Container scans upload image metadata to SaaS for analysis. | Results surfaced via SaaS dashboards/API; no local merge or provenance data. | Requires network connectivity; offline unsupported. |
|
||||
|
||||
### References
|
||||
- [t1] `/tmp/trivy-src/docs/docs/coverage/os/index.md`
|
||||
- [s1] `/tmp/snyk-cli/README.md`
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Secret Handling
|
||||
|
||||
## StellaOps approach
|
||||
- Detailed Policy/Security briefing: `../../modules/policy/secret-leak-detection-readiness.md`.
|
||||
- Secrets treated as operational inputs delivered through Surface.Secrets (`src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets` and documented in `docs/modules/scanner/design/surface-secrets.md`).
|
||||
- Providers support Kubernetes Secrets, file-based bundles, and inline definitions; configuration resolved via Surface.Env with validation gates from Surface.Validation.
|
||||
- Secret placeholders (`secret://type/name`) are resolved before analyzers execute, with results wrapped in secure handles and rotation metadata checked at startup.
|
||||
@@ -26,6 +27,15 @@
|
||||
- **Workflow**: StellaOps’ secret lifecycle is pre-scan configuration; Trivy and Snyk analyse content at scan time (Snyk requiring SaaS connectivity), and Grype requires external tooling for leak detection.
|
||||
- **Determinism**: StellaOps avoids non-deterministic leak scans; Trivy and Snyk’s detectors may evolve with rule updates; Grype remains deterministic by not attempting secret discovery.
|
||||
|
||||
### Detection technique comparison
|
||||
| Tool | Detection technique(s) | Merge / result handling | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| **StellaOps (current)** | `Surface.Secrets` providers fetch credentials at runtime; no leak scanning today. | Secrets resolve to opaque handles stored in scan metadata; no SBOM entries emitted. | Deterministic and explainable; avoids exposing payloads. |
|
||||
| **StellaOps (planned)** | `StellaOps.Scanner.Analyzers.Secrets` plug-in executing signed rule bundles. | Findings inserted into `ScanAnalysisStore` as `secret.leak` evidence; Policy Engine merges with component context and lattice scores. | Rules packaged offline; CLI/reporting masks payloads while surfacing rule IDs. |
|
||||
| **Trivy** | Regex + entropy detectors under `pkg/fanal/secret` (configurable via `trivy-secret.yaml`). | Detectors aggregate per file; results exported alongside vulnerability findings without provenance binding. | Ships built-in rule sets; users can add allow/block lists. |
|
||||
| **Snyk** | Snyk Code SaaS classifiers invoked by CLI plugin (`src/lib/plugins/sast`). | Source uploaded to SaaS; issues returned with severity + remediation; no offline merge with SBOM data. | Requires authenticated cloud access; rules evolve server-side. |
|
||||
| **Grype** | None (focuses on vulnerability matching). | — | Operators must integrate separate tooling for leak detection. |
|
||||
|
||||
### References
|
||||
- [s1] `/tmp/snyk-cli/src/lib/plugins/sast`
|
||||
- [s2] `/tmp/snyk-cli/README.md`
|
||||
|
||||
47
docs/benchmarks/scanner/deep-dives/windows.md
Normal file
47
docs/benchmarks/scanner/deep-dives/windows.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Windows Package Ecosystem — Coverage Deep Dive
|
||||
|
||||
## Competitor snapshot
|
||||
- **Trivy**: No analyzers for Windows Installer (MSI), WinSxS manifests, or Chocolatey feeds. Official coverage tables enumerate Linux distributions only.
|
||||
- **Grype**: Syft catalogers focus on Linux ecosystems; no Windows package collectors or matchers are available.
|
||||
- **Snyk CLI**: Container/open-source scans rely on SaaS services; Windows host-level package scanning is not advertised. Snyk AppRisk references depend on SaaS integrations rather than offline collectors.
|
||||
|
||||
## Proposed StellaOps roadmap
|
||||
In-depth design detail lives in `../../modules/scanner/design/windows-analyzer.md`.
|
||||
1. **MSI/WinSxS collector**
|
||||
- Traverse `Windows/WinSxS/Manifests` and `Windows/Installer` to harvest component manifests, linking to installed products via the installer database.
|
||||
- Parse MSI tables (Product, Component, File) to emit authoritative component records with product codes, upgrade codes, and install context.
|
||||
2. **Chocolatey/NuGet-based packages**
|
||||
- Inspect `ProgramData/Chocolatey/lib` and `ProgramData/Chocolatey/packages.config` for package metadata, including embedded nuspec files and checksums.
|
||||
- Resolve package sources and cache feed metadata to support offline replay.
|
||||
3. **Registry-backed inventory**
|
||||
- Query `HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall` and equivalent Wow6432Node path to capture legacy installers (EXE/PDB) with version/signature hints.
|
||||
- Record install source, publisher, and install location for cross-reference with filesystem collectors.
|
||||
4. **Capability signals**
|
||||
- Detect installed services (`System32/config/SYSTEM` registry hive), scheduled tasks, and driver packages to feed Policy Engine capability predicates.
|
||||
- Capture Authenticode signatures and catalog (.cat) references to support trust enforcement.
|
||||
5. **Offline parity**
|
||||
- Package MSI schema definitions, Chocolatey feed snapshots, and Windows update catalog indexes into Offline Kit bundles.
|
||||
- Provide hashing guidance for large binaries to avoid excessive Offline Kit growth (use external CAS references where possible).
|
||||
|
||||
## Detection technique comparison
|
||||
| Technique | Artifacts | Merge strategy | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| MSI database parsing | `Windows/Installer/*.msi` database tables (Product, Component, File) | Emit component records keyed by ProductCode/ComponentCode; merge with WinSxS manifests using file hashes. | Requires custom MSI reader (Jet/COM-free) compatible with offline bundles. |
|
||||
| WinSxS manifest enumeration | `Windows/WinSxS/Manifests/*.manifest` | Map assemblies to catalog signatures and MSP patches; merge with MSI output for provenance. | Provides side-by-side assembly version info and language resources. |
|
||||
| Chocolatey package inspection | `ProgramData/Chocolatey/lib/*/tools` & nuspec metadata | Produce package records with source feed URL, checksum, install scripts. | Feed metadata snapshot required to resolve dependencies offline. |
|
||||
| Registry uninstall keys | `HKLM/HKCU ... /Uninstall/*` | Fill gaps for legacy installers (non-MSI); merge by install path and display name with file system evidence. | Use hive exports during scan to avoid registry API dependencies. |
|
||||
| Service/driver mapping | `System32/config/SYSTEM` hive, `System32/DriverStore/FileRepository` | Generate capability overlays (services, drivers) for Policy Engine gating. | Helps differentiate drivers requiring elevated scrutiny (e.g., kernel-mode). |
|
||||
| Competitor baseline | — | No competitor tool offers deterministic Windows package coverage with offline support. | Opportunity to differentiate once demand justifies scope. |
|
||||
|
||||
## Backlog / coordination
|
||||
- Follow demand capture in `docs/benchmarks/scanner/windows-macos-demand.md`. Once Windows signals meet thresholds, open engineering backlog (see proposed IDs below).
|
||||
- Coordinate with Offline Kit guild on distributing MSI schema, Chocolatey feed snapshots, and driver catalog signatures.
|
||||
- Engage Policy guild on required predicates (Authenticode trust, driver risk classes, service start modes).
|
||||
|
||||
## Open design questions
|
||||
| Topic | Question | Owner |
|
||||
| --- | --- | --- |
|
||||
| MSI parsing library | Build custom reader or embed open-source MSI parser? Must be AGPL-compatible and offline-ready. | Scanner Guild |
|
||||
| Driver risk classification | Should Policy Engine treat kernel-mode drivers differently by default? | Policy Guild |
|
||||
| Authenticodes & catalogs | Where do we verify signature/certificate revocation (scanner vs policy)? | Security Guild |
|
||||
| Registry access | Will scanner access registry hives directly or require pre-extracted exports? | Scanner + Ops Guild |
|
||||
@@ -0,0 +1,604 @@
|
||||
# Scanning Gaps — Competitor Techniques Missing in StellaOps
|
||||
|
||||
## .NET lockfile ingestion (Trivy, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 4 | Enterprise tenants request pre-build dependency evidence for audits. |
|
||||
| Competitive risk | 4 | Trivy and Snyk already parse NuGet lockfiles. |
|
||||
| Engineering effort | 3 | Collector plus CLI toggle is moderate effort. |
|
||||
| Policy/config impact | 4 | Policies must handle declared-only components. |
|
||||
| Offline/air-gap impact | 3 | Offline-friendly; bundle size increases slightly. |
|
||||
|
||||
- **Competitor capability**: Trivy parses `packages.lock.json` / `packages.config` and Snyk uploads manifest graphs, enabling pre-build dependency visibility.
|
||||
- **StellaOps gap**: Scanner currently inspects installed artifacts only (deps/runtimeconfig/assemblies); lockfiles are ignored.
|
||||
- **Proposed plan**:
|
||||
1. Add optional lockfile collectors under `StellaOps.Scanner.Analyzers.Lang.DotNet` that parse NuGet lockfiles without requiring restore, emitting auxiliary component records linked to installation evidence when present.
|
||||
2. Extend Surface.Validation to gate lockfile parsing (size, tenant policy) and Surface.Secrets for private feed credentials when resolving lockfile registries.
|
||||
3. Feed parsed lockfile metadata into Policy Engine via a new evidence flag so policy can distinguish “declared but not installed” dependencies.
|
||||
4. Provide CLI toggle (`--dotnet-lockfiles`) and document policy defaults (fail if declarations lack runtime evidence unless waiver).
|
||||
- **Policy considerations**: Introduce policy template allowing tenants to require lockfile parity or suppress pre-build-only components; leverage existing lattice logic to down-rank vulnerabilities lacking runtime evidence.
|
||||
- **Next actions**: open analyzer story (SCANNER-ANALYZERS-LANG-DOTNET) and doc task for policy guidance once design is finalized.
|
||||
|
||||
### Implementation details
|
||||
- Collectors live under `StellaOps.Scanner.Analyzers.Lang.DotNet`:
|
||||
- `DotNetDependencyCollector` (existing) resolves installed assemblies via `*.deps.json`, `*.runtimeconfig.json`, and manifest metadata.
|
||||
- New `DotNetLockfileCollector` (plan) will parse `packages.lock.json` / `packages.config` without executing restore, emitting records flagged `DeclaredOnly`.
|
||||
- Surface integrations:
|
||||
- `Surface.Validation` controls lockfile parsing size, repository allowlists, and opt-in behaviour.
|
||||
- `Surface.Secrets` provides credentials for private NuGet feeds referenced in lockfiles.
|
||||
- Merging pipeline:
|
||||
- `DotNetPackageAggregator` will merge installed and declared records by package key (id + version) with precedence rules (installed evidence supersedes declared-only).
|
||||
- Policy Engine receives both authoritative and declared-only evidence, enabling parity checks and waivers.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Installed runtime evidence | `*.deps.json`, `*.runtimeconfig.json`, assemblies, authenticode metadata | `DotNetDependencyCollector`, `DotNetPackageAggregator`, optional `IDotNetAuthenticodeInspector` | Produces authoritative components (inventory + usage) keyed by assembly path and package id. |
|
||||
| Lockfile ingestion (planned) | `packages.lock.json`, `packages.config`, restore graph metadata | `DotNetLockfileCollector` (new), integrated into `DotNetPackageAggregator` | Emits `DeclaredOnly` components; merged with installed evidence by package id/version; unresolved entries flagged for policy. |
|
||||
| Runtime usage linkage | EntryTrace outputs | `EntryTrace` integration via `LanguageAnalyzerContext.UsageHints` | Marks components used by entrypoint closure; policy and explain traces highlight runtime relevance. |
|
||||
|
||||
## Node.js pnpm lock validation (Trivy, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 3 | Monorepo customers asking for pnpm parity; moderate demand. |
|
||||
| Competitive risk | 4 | Competitors advertise pnpm support, creating parity pressure. |
|
||||
| Engineering effort | 3 | Collector and CLI work similar to .NET lockfile effort. |
|
||||
| Policy/config impact | 4 | Requires policy predicates and explain updates. |
|
||||
| Offline/air-gap impact | 3 | Offline-compatible with additional parser rules bundled. |
|
||||
|
||||
- **Competitor capability**: Trivy and Snyk parse pnpm/yarn/npm lockfiles even when `node_modules` is absent, surfacing dependency graphs pre-install for policy gating.
|
||||
- **StellaOps gap**: Scanner requires installed artifacts; there is no CLI helper to validate pnpm lockfiles or compare declared vs installed packages ahead of a scan.
|
||||
- **Proposed plan**:
|
||||
1. Introduce a lockfile-only collector under `StellaOps.Scanner.Analyzers.Lang.Node` that decodes `pnpm-lock.yaml`, `package-lock.json`, and `yarn.lock`, emitting provisional component records with provenance flag `DeclaredOnly`.
|
||||
2. Expose a CLI verb (`stella node lock-validate`) that runs the collector without enqueuing a full scan, honouring Surface.Validation controls (max lockfile size, allowed registries) and Surface.Secrets for private registries.
|
||||
3. Persist lockfile-derived dependencies alongside installed evidence so Policy Engine can enforce parity via new predicates (e.g., `node.lock.declaredMissing`, `node.lock.registryDisallowed`).
|
||||
4. Extend EntryTrace explain output (and policy explain traces) to highlight packages present in runtime closure but missing from lockfiles—or declared-only artifacts not shipped in the image.
|
||||
- **Policy considerations**: Provide sample policies that fail builds when lockfiles reference disallowed registries or when declared packages lack runtime evidence; use lattice weighting to downgrade issues limited to declared-only components.
|
||||
- **Next actions**: open analyzer story (SCANNER-ANALYZERS-LANG-NODE) plus CLI story for lock validation, and schedule Docs Guild update covering the new policy predicates.
|
||||
|
||||
### Implementation details
|
||||
- Collectors under `StellaOps.Scanner.Analyzers.Lang.Node`:
|
||||
- Existing `NodePackageCollector` walks `package.json` evidence across workspaces.
|
||||
- Planned `NodeLockfileCollector` will parse `pnpm-lock.yaml`, `package-lock.json`, `yarn.lock`.
|
||||
- Surface integrations:
|
||||
- `Surface.Validation` to constrain lockfile size, allowed registries, and CLI access for `stella node lock-validate`.
|
||||
- `Surface.Secrets` for private registry credentials when validating lockfiles.
|
||||
- Merge strategy:
|
||||
- `LanguageAnalyzerContext` merges installed and declared components; declared-only entries are flagged (`DeclaredOnly`) and kept for policy comparison.
|
||||
- EntryTrace usage hints link runtime scripts to packages, influencing policy weights and explain traces.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Installed package evidence | `package.json` + `node_modules` tree | `NodePackageCollector` | Produces authoritative components with install paths and workspace metadata. |
|
||||
| Lockfile ingestion (planned) | `pnpm-lock.yaml`, `package-lock.json`, `yarn.lock` | `NodeLockfileCollector` (new) | Emits declared dependency graph with provenance; merged by package name/version; discrepancies flagged for policy. |
|
||||
| Runtime usage linkage | EntryTrace launcher catalog (npm/yarn scripts, node entrypoints) | `EntryTrace` + `LanguageAnalyzerContext.UsageHints` | Annotates components used at runtime; unresolved launchers produce explain-trace diagnostics. |
|
||||
|
||||
## Python lockfile & editable install coverage (Trivy, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 3 | Editable install coverage requested by regulated Python users. |
|
||||
| Competitive risk | 3 | Trivy supports multiple lock formats; Snyk SaaS highlights poetry support. |
|
||||
| Engineering effort | 3 | Collector and editable path resolution are moderate effort. |
|
||||
| Policy/config impact | 4 | Policy needs knobs for declared-only vs runtime packages. |
|
||||
| Offline/air-gap impact | 3 | Offline workable while packaging parser tooling. |
|
||||
|
||||
- **Competitor capability**: Trivy parses Poetry/Pipenv/pip lockfiles (including editable installs) and Snyk uploads manifest graphs, exposing declared dependencies even when virtualenvs are absent.
|
||||
- **StellaOps gap**: Scanner relies on installed `dist-info` metadata; editable installs or source-only lockfiles are skipped, and there is no automated parity check between declared requirements and runtime usage.
|
||||
- **Proposed plan**:
|
||||
1. Add a lockfile collector in `StellaOps.Scanner.Analyzers.Lang.Python` that reads `poetry.lock`, `Pipfile.lock`, `requirements.txt` (including VCS URLs), tagging results as `DeclaredOnly`.
|
||||
2. Detect editable installs by parsing `pyproject.toml` / `setup.cfg`, resolving editable paths with Surface.FS, and linking to EntryTrace usage to ensure runtime awareness.
|
||||
3. Provide CLI support (`stella python lock-validate`) to diff declared vs installed artifacts, enforcing Surface.Validation constraints (lockfile size, allowed indexes) and Surface.Secrets for private PyPI mirrors.
|
||||
4. Persist declarative evidence separately so Policy Engine can evaluate predicates like `python.lock.declaredMissing` and `python.lock.indexDisallowed`.
|
||||
5. Extend explain traces to highlight editable or declared-only packages lacking runtime deployment, aiding remediation.
|
||||
- **Policy considerations**: Ship policy templates distinguishing declared-only vs runtime packages, with lattice-based weighting to reduce noise when usage is absent; allow tenants to enforce registry allowlists.
|
||||
- **Next actions**: create analyzer and CLI backlog items in the Python guild, plus Docs Guild task to cover new policy knobs once design is complete.
|
||||
|
||||
### Implementation details
|
||||
- Collectors under `StellaOps.Scanner.Analyzers.Lang.Python`:
|
||||
- Existing analyzer reads installed `*.dist-info` metadata via `PythonDistributionLoader`.
|
||||
- Planned lockfile collector parses `poetry.lock`, `Pipfile.lock`, `requirements.txt` (including VCS refs).
|
||||
- Editable installs:
|
||||
- Detect via `pyproject.toml` / `setup.cfg` markers; use `Surface.FS` to resolve local paths and mark components as editable.
|
||||
- Surface & policy integrations:
|
||||
- `Surface.Validation` constrains lockfile size and allowed indexes; `Surface.Secrets` handles private index credentials.
|
||||
- Policy Engine receives new flags (`DeclaredOnly`, `EditablePath`) to drive parity checks.
|
||||
- CLI workflow: `stella python lock-validate` (planned) will reuse collectors without scheduling full scans.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Installed distributions | `*.dist-info` directories, RECORD, METADATA | `PythonLanguageAnalyzer` | Produces authoritative components with file hashes and EntryTrace usage hints. |
|
||||
| Lockfile ingestion (planned) | `poetry.lock`, `Pipfile.lock`, `requirements.txt` | Planned lockfile collector integrated with analyzer | Emits declared dependency graph, tagged `DeclaredOnly`; merged by package name/version. |
|
||||
| Editable install resolution | Local source directories referenced in lockfiles (`path =`, `editable = true`) | New editable resolver leveraging `Surface.FS` | Links editable packages to actual source paths; policy distinguishes editable vs packaged artefacts. |
|
||||
|
||||
## Java build-tool lockfile ingestion (Trivy, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 3 | Platform teams running Gradle/SBT builds request parity for pre-build evidence. |
|
||||
| Competitive risk | 4 | Trivy supports Gradle/SBT lockfiles and Snyk ships Maven/Gradle/SBT plugins. |
|
||||
| Engineering effort | 3 | Requires new lockfile collectors plus CLI wiring; moderate complexity. |
|
||||
| Policy/config impact | 3 | Policy must handle declared-only Java components and disallowed repositories. |
|
||||
| Offline/air-gap impact | 3 | Works offline but needs packaged parsers and repository allowlists. |
|
||||
|
||||
- **Competitor capability**: Trivy parses Gradle/Maven/SBT lockfiles and Snyk relies on dedicated plugins to surface declared dependencies even before artifacts are built.
|
||||
- **StellaOps gap**: Scanner inspects installed archives only; it ignores Gradle/SBT lockfiles and lacks a workflow to compare declared dependencies against runtime archives.
|
||||
- **Proposed plan**:
|
||||
1. Introduce lockfile collectors under `StellaOps.Scanner.Analyzers.Lang.Java` to parse `gradle.lockfile`, `pom.xml`/`pom.lock`, and `build.sbt` output, emitting `DeclaredOnly` components with repository metadata.
|
||||
2. Extend Surface.Validation for Java lockfiles (size limits, allowed repositories) and leverage Surface.Secrets for private Maven repository credentials.
|
||||
3. Provide a CLI verb (`stella java lock-validate`) to diff declared vs installed archives without running a full scan, emitting policy-ready diagnostics.
|
||||
4. Persist declarative evidence so Policy Engine can evaluate predicates (`java.lock.declaredMissing`, `java.lock.repoDisallowed`) and feed explain traces highlighting gaps.
|
||||
- **Policy considerations**: Supply templates enforcing repository allowlists and declared-vs-runtime parity, using lattice weights to downgrade issues that never reach runtime.
|
||||
- **Next actions**: log analyzer/CLI backlog stories with the Java guild and plan Docs Guild updates for new policy knobs once design stabilises.
|
||||
|
||||
### Implementation details
|
||||
- Collectors under `StellaOps.Scanner.Analyzers.Lang.Java`:
|
||||
- Existing analyzer normalises installed JAR/WAR/EAR archives and extracts `MANIFEST.MF`, `pom.properties`.
|
||||
- Planned lockfile collectors will ingest `gradle.lockfile`, Maven `pom.xml`/`pom.lock`, and `build.sbt` outputs.
|
||||
- Surface integrations:
|
||||
- `Surface.Validation` enforces lockfile size and repository allowlists; `Surface.Secrets` supplies credentials for private Maven repositories.
|
||||
- Merge strategy:
|
||||
- New collector emits `DeclaredOnly` components with repository metadata; `JavaLanguageAnalyzer` merges them with observed archives keyed by `groupId:artifactId:version`.
|
||||
- EntryTrace usage hints link runtime launchers to archives, enabling policy to prioritise used components.
|
||||
- CLI tooling:
|
||||
- `stella java lock-validate` (planned) exposes lockfile parity checks without full scan scheduling, reusing collectors.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Installed archives | JAR/WAR/EAR/PAR files, `MANIFEST.MF`, `pom.properties` | `JavaLanguageAnalyzer` | Produces authoritative components with archive hashes and runtime usage hints. |
|
||||
| Lockfile ingestion (planned) | `gradle.lockfile`, Maven `pom.xml`/`pom.lock`, SBT build metadata | Planned lockfile collectors integrated with analyzer | Emits declared dependency entries (repository + checksum); merged on GAV coordinates with priority to installed evidence. |
|
||||
| Runtime linkage | EntryTrace wrapper catalogue (java -jar, jetty, etc.) | `EntryTrace` integration | Marks archives invoked at runtime; unresolved launchers surfaced with remediation hints. |
|
||||
|
||||
## Go stripped binary enrichment (Trivy, Grype)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 3 | Teams shipping minimal Go binaries want richer provenance for runtime attestations. |
|
||||
| Competitive risk | 3 | Trivy/Grype skip hashed fallbacks, but customers compare hashed provenance across tools. |
|
||||
| Engineering effort | 2 | Extend fallback hashing with symbol inference; low-medium effort. |
|
||||
| Policy/config impact | 3 | Policy needs knobs to treat inferred modules differently from authoritative results. |
|
||||
| Offline/air-gap impact | 3 | Offline-friendly; requires bundling symbol parser logic. |
|
||||
|
||||
- **Competitor capability**: Trivy and Grype skip binaries without Go build info, leaving stripped binaries without component coverage.
|
||||
- **StellaOps gap**: StellaOps emits hashed fallback components but lacks inferred module names, confidence scoring, and policy integration.
|
||||
- **Proposed plan**:
|
||||
1. Enhance `GoBinaryScanner` fallback path to parse symbol tables (DWARF/ELF) and infer module/package names, tagging results with confidence metrics.
|
||||
2. Persist inferred metadata separately so Policy Engine can weight `go.inferred` components differently from authoritative modules.
|
||||
3. Expose CLI detail (`--go-fallback-detail`) and explain trace entries highlighting hashed/inferred provenance for stripped binaries.
|
||||
4. Update attestation manifests to surface inferred modules, enabling policy-controlled downgrade rather than omission.
|
||||
- **Policy considerations**: Extend policy predicates to differentiate authoritative vs inferred Go modules; adjust lattice weights to reduce noise while keeping visibility.
|
||||
- **Next actions**: create analyzer backlog story for enhanced fallback parsing and Docs Guild task to document policy/CLI behaviour.
|
||||
|
||||
### Implementation details
|
||||
- Analyzer: `StellaOps.Scanner.Analyzers.Lang.Go/GoLanguageAnalyzer` currently extracts Go build info (`module`, `buildSettings`) and DWARF metadata when available.
|
||||
- Fallback enhancements (planned):
|
||||
- Extend `GoBinaryScanner` to parse ELF/Mach-O symbol tables when build info is missing.
|
||||
- Maintain fingerprint catalogue under `StellaOps.Scanner.Analyzers.Lang.Go.Fingerprints` with signed updates for Offline Kit.
|
||||
- Surface & policy:
|
||||
- `Surface.Validation` governs fallback enablement; configuration stored alongside analyzer options.
|
||||
- Policy Engine will recognise inferred components via new flags (e.g., `go.inferred`), influencing lattice weights.
|
||||
- CLI and explain:
|
||||
- Introduce `--go-fallback-detail` to surface hashed vs inferred provenance.
|
||||
- Explain traces include confidence scores and recommended remediation (e.g., rebuild with `-buildvcs`).
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Authoritative build info | Go binary `buildinfo` section, DWARF metadata | `GoLanguageAnalyzer` | Produces authoritative modules with version/build metadata. |
|
||||
| Fallback hashing | Binary bytes when build info missing | Existing fallback path in `GoBinaryScanner` | Emits hashed component (`sha256:...`) with `Fallback` flag for policy downgrading. |
|
||||
| Symbol-based inference (planned) | ELF/Mach-O symbols, DWARF line info | Planned enhancement to `GoBinaryScanner` with fingerprint catalogue | Maps symbols to modules/packages, tagging confidence scores; merged with hashed fallback for explainability. |
|
||||
|
||||
## Rust fingerprint coverage (Trivy, Grype)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 3 | Regulated teams running Rust microservices want deterministic evidence even for stripped binaries. |
|
||||
| Competitive risk | 3 | Competitors drop stripped binaries entirely; StellaOps can differentiate by improving heuristics. |
|
||||
| Engineering effort | 3 | Requires enhancing fingerprint catalogue and symbol inference; moderate effort. |
|
||||
| Policy/config impact | 3 | Policy needs knobs to treat heuristic vs authoritative crates differently. |
|
||||
| Offline/air-gap impact | 3 | Offline-compatible; must distribute updated fingerprint datasets with Offline Kit. |
|
||||
|
||||
- **Competitor capability**: Trivy and Grype skip Rust binaries lacking Cargo metadata, offering no fallback or runtime insight.
|
||||
- **StellaOps gap**: Although StellaOps stores hashed fallback and fingerprint components, coverage for niche toolchains and stripped binaries remains limited, reducing explainability.
|
||||
- **Proposed plan**:
|
||||
1. Expand the fingerprint catalogue (`RustAnalyzerCollector`) with additional signature sources (e.g., crate fingerprint DB, community-sourced hash lists) and version inference heuristics.
|
||||
2. Parse symbol tables for stripped binaries (DWARF, `--build-id`) to infer crate names and link them to fingerprints, tagging results with confidence scores.
|
||||
3. Surface inferred vs authoritative crates distinctly in explain traces and CLI output (`--rust-fingerprint-detail`) so operators know when evidence is heuristic.
|
||||
4. Publish policy predicates (`rust.fingerprint.confidence`) allowing tenants to warn/fail when only heuristic evidence exists.
|
||||
- **Policy considerations**: Extend lattice weights to downgrade heuristic-only findings while still surfacing them; provide policy templates for regulated environments.
|
||||
- **Next actions**: open analyzer backlog story for fingerprint enrichment, schedule Docs Guild update for policy guidance, and coordinate Offline Kit team to package updated fingerprint datasets.
|
||||
|
||||
## OS packages — Windows/macOS coverage (Trivy, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 2 | Requests are emerging but not yet widespread; gathering signals via `windows-macos-demand.md`. |
|
||||
| Competitive risk | 3 | Competitors currently focus on Linux; future announcements could increase pressure. |
|
||||
| Engineering effort | 4 | Full Windows/macOS analyzer support would require new parsers, evidence models, and Offline Kit updates. |
|
||||
| Policy/config impact | 3 | Policy must account for OS-specific package sources and signing requirements. |
|
||||
| Offline/air-gap impact | 4 | Supporting Windows/macOS would significantly expand Offline Kit footprint and mirroring workflows. |
|
||||
|
||||
- **Competitor capability**: Trivy and Grype document Linux distribution coverage; Snyk Container relies on SaaS services and likewise focuses on Linux bases. None offer first-class offline Windows/macOS package scanning today.
|
||||
- **StellaOps gap**: Platform currently scopes scanners to Linux; regulated customers with Windows/macOS workloads need clarity on future coverage.
|
||||
- **Proposed plan**:
|
||||
1. Continue demand intake per `docs/benchmarks/scanner/windows-macos-demand.md`, capturing customer interviews, sales telemetry, and community updates.
|
||||
2. If demand crosses the documented threshold, scope a design spike covering evidence models (e.g., MSI, Chocolatey, Homebrew), Surface integration, and policy ramifications.
|
||||
3. Document interim guidance for hybrid workflows (e.g., importing third-party SBOMs) while native analyzers are out of scope.
|
||||
- **Policy considerations**: Policies would need repository allowlists, signing requirements, and OS-specific mitigations; defer concrete templates until design spike completes.
|
||||
- **Next actions**: Execute tasks DOCS-SCANNER-BENCH-62-002/003/004/005/006 as demand signals accrue; only open engineering backlog after demand review approves scope expansion.
|
||||
|
||||
### Implementation details
|
||||
- **StellaOps**:
|
||||
- Linux analyzers live under `StellaOps.Scanner.Analyzers.OS.(Apk|Dpkg|Rpm)` and inherit from `OsPackageAnalyzerBase`, which normalises package metadata, file evidence, and vendor fields before persisting content-addressed fragments via Surface.FS.
|
||||
- Analyzer results are converted to `LayerComponentFragment`s by `OsComponentMapper` and cached inside the worker `ScanAnalysisStore`; downstream SBOM assembly keeps layer digests and provenance so usage/inventory views can be replayed deterministically.
|
||||
- Export Center binds OS fragments to DSSE attestations through Signer/Attestor so operators can prove provenance for every package list in offline bundles.
|
||||
- **Trivy**:
|
||||
- Package analyzers under `pkg/fanal/analyzer/pkg/(apk|dpkg|rpm)` walk layer file systems and emit `types.Package` results; the upstream coverage matrix in `docs/docs/coverage/os/*.md` drives which distro manifests and feeds ship with Trivy releases.
|
||||
- Results are flattened per artifact, leaving layer attribution to Syft-style catalog walks; provenance and diffing are delegated to downstream tooling.
|
||||
- **Grype**:
|
||||
- Delegates cataloguing to Syft, then applies matchers in `grype/matcher/{apk,dpkg,rpm}` that resolve distro namespaces and fix statuses using Anchore feeds.
|
||||
- Evidence is matched at scan time without long-lived fragments, so reproducibility depends on feed snapshots rather than packaged artifacts.
|
||||
- **Snyk**:
|
||||
- `snyk container test` uploads image metadata to Snyk SaaS; coverage is dictated by the hosted service and cannot run offline.
|
||||
- No layer-aware evidence is returned; operators rely on SaaS reports for package presence and risk.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Layer package DB parsing | apk, dpkg, rpm status/databases per layer | `StellaOps.Scanner.Analyzers.OS.(Apk|Dpkg|Rpm)` + Surface.FS | Emits `OSPackageRecord` fragments tagged with layer digest; `OsComponentMapper` writes `LayerComponentFragment`s that SBOM assembly uses to build inventory/usage views with provenance. |
|
||||
| Manifest + attestation binding | Distro manifest attestations, vendor signatures | Export Center + Signer/Attestor hand-off | Couples OS fragments with DSSE/Rekor proofs; Policy Engine verifies signatures before promotion gates. |
|
||||
| Linux distro enrichment | Vendor advisory feeds, package-to-CVE mapping | Concelier + Policy Engine | Concelier ingests advisory metadata; Policy joins advisories with package fragments to produce lattice-scored findings. |
|
||||
| External SBOM import (interim) | Third-party SBOMs for Windows/macOS | Scanner SBOM import API (planned) | Declared-only entries are merged with runtime evidence; policy downgrades unmatched declarations until native analyzers exist. |
|
||||
|
||||
## macOS package coverage (Trivy, Grype, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 2 | macOS coverage requests surface intermittently; demand capture ongoing via `windows-macos-demand.md`. |
|
||||
| Competitive risk | 2 | Competitors lack macOS analyzers today, but roadmap announcements could erode differentiation quickly. |
|
||||
| Engineering effort | 4 | Requires new collectors (Homebrew, pkgutil receipts, `.app` bundles) plus Offline Kit tap mirroring. |
|
||||
| Policy/config impact | 4 | Policies must reason over entitlements, notarization, and signed bundle provenance. |
|
||||
| Offline/air-gap impact | 4 | Tap metadata, notarization caches, and entitlement schemas must ship offline. |
|
||||
|
||||
- **Competitor capability**: None of Trivy, Grype, or Snyk provide macOS host/package coverage; their documentation lists Linux-only ecosystems.
|
||||
- **StellaOps gap**: No macOS analyzers exist; design work is captured in `docs/benchmarks/scanner/deep-dives/macos.md` but implementation/backlog stories are not yet opened.
|
||||
- **Proposed plan**:
|
||||
1. Finalise demand assessment (DOCS-SCANNER-BENCH-62-002) using customer interviews, sales telemetry, and support tags.
|
||||
2. Scope macOS analyzer design spike covering Homebrew cellar parsing, pkgutil receipt ingestion, and `.app` bundle inspection; include entitlements/notarization strategy.
|
||||
3. Define Policy Engine predicates for entitlements, notarization status, bundle signing chain, and tenant allow lists.
|
||||
4. Coordinate with Offline Kit guild on mirroring tap metadata, notarization caches, and CRL/OCSP content for air-gapped operation.
|
||||
- **Milestones**: Northwind Health Services demo (2025-11-10) doubles as POLICY-READINESS-0001 workshop to finalise masking/telemetry defaults before spike approval.
|
||||
- **Policy considerations**: Need predicates for `macos.entitlement`, `macos.notarized`, `macos.bundle.teamId`, and severity rules for unsigned or unnotarized software; waivers should bind to bundle hash + signer.
|
||||
- **Next actions**: Keep `windows-macos-demand.md` updated, prepare design brief once threshold met, and log engineering backlog items (SCANNER-ENG-00xx) for macOS collectors and policy integration.
|
||||
|
||||
### Implementation details
|
||||
- **Design references**: `docs/benchmarks/scanner/deep-dives/macos.md` captures proposed collectors (Homebrew, receipts, bundles) and open questions for Security/Policy guilds.
|
||||
- **Collector outline**:
|
||||
- Homebrew collector enumerates Cellar manifests under `/usr/local/Cellar` and `/opt/homebrew/Cellar`, mapping taps to PURLs and retaining bottle SHA256 for provenance.
|
||||
- pkgutil collector parses `/var/db/receipts/*.plist` and `.bom` files to record installer package metadata with deterministic hashes.
|
||||
- Bundle inspector walks `.app` directories, extracting Info.plist, entitlements, embedded frameworks, and code signing chains.
|
||||
- **Merge strategy**: Collectors will emit component fragments keyed by bundle/tap identifiers; planned aggregator merges receipts and cellular data where identifiers match, tagging capabilities for Policy Engine.
|
||||
- **Offline requirements**: Bundle signed rule packs (tap metadata snapshots, entitlements schema) with Offline Kit; ensure notarization cache instructions are documented.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Homebrew cellar parsing (planned) | Cellar manifests, `INSTALL_RECEIPT.json`, tap metadata | Planned `StellaOps.Scanner.Analyzers.OS.Mac.Homebrew` | Emits component records keyed by tap + version; merges duplicates and attaches bottle hashes for provenance. |
|
||||
| pkgutil receipt parsing (planned) | `/var/db/receipts/*.plist` and `.bom` | Planned `StellaOps.Scanner.Analyzers.OS.Mac.Receipts` | Records installer packages with bundle identifiers; merges with bundle evidence when identifiers align. |
|
||||
| `.app` bundle inspection (planned) | Info.plist, CodeResources, entitlements, signing certs | Planned `StellaOps.Scanner.Analyzers.OS.Mac.Bundles` | Produces capability evidence (entitlements, hardened runtime) and links to receipts/Homebrew entries via bundle id. |
|
||||
| Launch agent/daemon analysis (planned) | `/Library/Launch*` manifests, `launchctl` exports | Planned runtime usage mapper | Augments EntryTrace usage hints to distinguish active services. |
|
||||
| Competitor baseline | — | Trivy/Grype/Snyk | No macOS host analyzers; coverage limited to Linux/container contexts. |
|
||||
|
||||
## Windows package coverage (Trivy, Grype, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 3 | Windows Server/container adopters continue to request evidence parity; demand captured via `windows-macos-demand.md`. |
|
||||
| Competitive risk | 2 | Competitors lack Windows analyzers today but could narrow the gap with roadmap announcements. |
|
||||
| Engineering effort | 5 | Requires MSI/WinSxS parsers, registry collectors, Chocolatey handling, and extensive Offline Kit work. |
|
||||
| Policy/config impact | 4 | Policies must interpret Authenticode trust, driver/service posture, and legacy installer artefacts. |
|
||||
| Offline/air-gap impact | 5 | Need to package MSI schemas, feed snapshots, and certificate bundles; storage overhead is significant. |
|
||||
|
||||
- **Competitor capability**: Trivy, Grype, and Snyk do not ship Windows host analyzers; tooling focuses on Linux ecosystems and SaaS flows.
|
||||
- **StellaOps gap**: No Windows analyzers exist yet; design outline under `docs/benchmarks/scanner/deep-dives/windows.md`.
|
||||
- **Proposed plan**:
|
||||
1. Complete demand validation and prioritisation (DOCS-SCANNER-BENCH-62-002) alongside macOS signals.
|
||||
2. Execute engineering spike covering MSI/WinSxS parsing, Chocolatey inventory, and registry-based fallbacks.
|
||||
3. Define Policy Engine predicates for Authenticode, driver risk, service start mode, and Chocolatey provenance.
|
||||
4. Coordinate Offline Kit packaging strategy for MSI schemas, feed snapshots, and certificate revocation caches.
|
||||
- **Policy considerations**: Introduce predicates such as `windows.package.signed(teamId?)`, `windows.driver.kernelMode`, `windows.service.startType`, and waivers tied to product code + signature thumbprint.
|
||||
- **Next actions**: Maintain demand tracker, execute DOCS-SCANNER-BENCH-62-016, refine `docs/modules/scanner/design/windows-analyzer.md`, and open SCANNER-ENG-0024..0027 backlog tickets for collector and policy work once demand threshold is confirmed.
|
||||
- **Milestones**: POLICY-READINESS-0002 Authenticode/feed decision due 2025-11-07 (FinSecure PCI blocker) gates Windows analyzer spikes.
|
||||
|
||||
### Implementation details
|
||||
- **Design references**: `docs/benchmarks/scanner/deep-dives/windows.md`, `docs/modules/scanner/design/windows-analyzer.md`, `docs/api/scanner/windows-coverage.md`.
|
||||
- **Policy readiness**: see `docs/modules/policy/windows-package-readiness.md` for predicate requirements, waiver model, and offline guidance.
|
||||
- **Collector outline**:
|
||||
- MSI/WinSxS collector to parse installer databases/manifests and correlate via file hashes.
|
||||
- Chocolatey collector to read nuspec metadata and install scripts, retaining feed provenance.
|
||||
- Registry collector to harvest uninstall/service keys, linking to filesystem artefacts and signatures.
|
||||
- **Merge strategy**: Planned `WindowsComponentMapper` merges MSI, WinSxS, Chocolatey, and registry evidence into unified fragments with provenance metadata; capability overlays capture services/drivers.
|
||||
- **Offline requirements**: Bundle MSI schema definitions, Chocolatey feed snapshots, Windows Update catalog hashes, and certificate chains; document cache priming steps for air-gapped environments.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| MSI database parsing (planned) | `Windows/Installer/*.msi` Product/Component/File tables | Planned `StellaOps.Scanner.Analyzers.OS.Windows.Msi` | Emits component records keyed by product/component codes; merges with WinSxS manifests via file hashes. |
|
||||
| WinSxS manifest parsing (planned) | `Windows/WinSxS/Manifests/*.manifest`, catalog files | Planned `StellaOps.Scanner.Analyzers.OS.Windows.WinSxS` | Maps assemblies to catalogs and MSP patches; merges with MSI output for provenance. |
|
||||
| Chocolatey package parsing (planned) | `ProgramData/Chocolatey/lib/*`, nuspec metadata | Planned `StellaOps.Scanner.Analyzers.OS.Windows.Choco` | Records package evidence with feed provenance; merges with registry uninstall data. |
|
||||
| Registry fallback (planned) | Exported uninstall/service hives | Planned `StellaOps.Scanner.Analyzers.OS.Windows.Registry` | Fills gaps for legacy installers and services; merges evidence by install path/signature. |
|
||||
| Service/driver capability mapping (planned) | SYSTEM hive, DriverStore manifest | Planned capability overlay | Emits runtime capability records (drivers/services) for Policy Engine gating. |
|
||||
| Competitor baseline | — | Trivy/Grype/Snyk | No Windows host analyzers; operators depend on external tooling. |
|
||||
|
||||
## Secrets leak detection (Trivy, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 4 | Security and compliance teams expect leak detection in parity with Trivy/Snyk. |
|
||||
| Competitive risk | 4 | Trivy and Snyk market built-in secret scanners; lack of parity is visible. |
|
||||
| Engineering effort | 4 | Requires deterministic scanner pipeline, rule packaging, and explainability. |
|
||||
| Policy/config impact | 5 | Policy must gate rule sets, severities, and privacy guarantees. |
|
||||
| Offline/air-gap impact | 3 | Rule packs must be versioned and bundled with Offline Kit. |
|
||||
|
||||
- **Competitor capability**: Trivy ships regex/entropy secret analyzers with configurable rule packs; Snyk Code offers SaaS-based secret detection.
|
||||
- **StellaOps gap**: Scanner intentionally avoids leak detection to preserve determinism, leaving customers without first-party secret scanning.
|
||||
- **Proposed plan**:
|
||||
1. Implement a deterministic secret scanner plugin (`StellaOps.Scanner.Analyzers.Secrets`) supporting rule bundles signed and versioned for offline parity.
|
||||
2. Provide rule configuration via Surface.Validation (rule allowlists, target paths) and Surface.Secrets to manage sensitive allow rules.
|
||||
3. Emit findings into Policy Engine with new evidence types (`secret.leak`) so policies can enforce severity thresholds, ticket workflows, or waivers.
|
||||
4. Offer CLI verb (`stella secrets scan`) and integration into existing scan workflows behind an opt-in flag.
|
||||
5. Expose explain traces detailing rule IDs, masked snippets, and remediation guidance while upholding privacy constraints.
|
||||
- **Policy considerations**: Deliver policy templates for severity gating, rule packs per tenant, and privacy controls; lattice logic should discount low-confidence matches.
|
||||
- **Next actions**: Track execution via SCANNER-ENG-0007 (design/implementation) and DOCS-SCANNER-BENCH-62-007 (policy/docs); bundle signed rule packs for Offline Kit distribution once analyzer stories land.
|
||||
|
||||
### Implementation details
|
||||
- **StellaOps**:
|
||||
- Operational secret retrieval flows through `Surface.Secrets` providers (Kubernetes, file bundle, inline) with validation policies enforced by `Surface.Validation`; handles remain opaque to analyzers.
|
||||
- Planned `StellaOps.Scanner.Analyzers.Secrets` plug-in will execute deterministic rule bundles signed by the Export Center signing stack; findings land in `ScanAnalysisStore` alongside component fragments.
|
||||
- Policy Engine will ingest `secret.leak` evidence with lattice hints (`confidence`, `rule.id`, `masking.applied`) so tenants can tune severities and approvals.
|
||||
- **Trivy**:
|
||||
- Secret detection is implemented in `pkg/fanal/secret` with detectors combining regex and entropy heuristics; rules merge into `Result` objects per file with severity weighting.
|
||||
- Configuration is provided via `trivy-secret.yaml`, enabling per-rule enable/disable and allow lists.
|
||||
- **Snyk**:
|
||||
- CLI delegates to Snyk Code (`src/lib/plugins/sast`) which uploads source or image contents to SaaS for analysis; results stream back as issue JSON with remediation tips.
|
||||
- Offline execution is unsupported; rule updates ship server-side.
|
||||
- **Grype**:
|
||||
- No leak detection analyzer; secrets are only used for registry authentication options.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Operational secret retrieval | `secret://` references resolved via `Surface.Secrets` providers | Surface.Secrets, Surface.Validation | Injects handles at runtime only; provenance recorded in scan metadata, nothing added to SBOM inventory. |
|
||||
| Deterministic leak detection (planned) | File contents, archives, bytecode, container layers | `StellaOps.Scanner.Analyzers.Secrets` plug-in | Produces `secret.leak` records stored in `ScanAnalysisStore`; Policy Engine correlates with component metadata for context-aware enforcement. |
|
||||
| Policy gating and reporting | Secret evidence + policy templates | Policy Engine, CLI/Export Center | Lattice scores combine confidence + severity; CLI/report output masks payloads while referencing rule IDs for explainability. |
|
||||
| Competitor leak scanning | Regex/entropy rule sets, SaaS classifiers | Trivy `pkg/fanal/secret`; Snyk Code service | Trivy merges detectors per file; Snyk relies on SaaS analysis; neither binds results to SBOM evidence or deterministic attestations. |
|
||||
|
||||
## EntryTrace runtime command resolution (Trivy, Grype, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 4 | Runtime teams rely on EntryTrace to separate inventory vs usage for policy decisions. |
|
||||
| Competitive risk | 4 | Competitors lack equivalent capability; maintaining lead is critical marketing differentiator. |
|
||||
| Engineering effort | 3 | Requires ongoing heuristics updates and parser maintenance for shells and launchers. |
|
||||
| Policy/config impact | 3 | Policy uses EntryTrace outputs; enhancements must keep explainability stable. |
|
||||
| Offline/air-gap impact | 2 | Heuristic catalog updates are lightweight and ship with Offline Kit. |
|
||||
|
||||
- **Competitor capability**: Trivy, Grype, and Snyk do not offer runtime command resolution comparable to EntryTrace.
|
||||
- **StellaOps gap**: To maintain leadership, EntryTrace heuristics must expand to new shells/launchers and provide richer explainability for policy consumers.
|
||||
- **Proposed plan**:
|
||||
1. Establish a quarterly EntryTrace heuristic review cadence to ingest new shell patterns and language launchers (npm/yarn, poetry, bundle exec, etc.).
|
||||
2. Add explain-trace improvements (confidence scores, unresolved reason catalog) so Policy Engine and UI can surface actionable guidance when resolution fails.
|
||||
3. Provide a CLI report (`stella entrytrace explain`) summarising resolved/unresolved paths with remediation hints, aligned with policy predicates.
|
||||
4. Publish contribution guidelines for customers to submit launcher patterns, keeping deterministic ordering and tests.
|
||||
- **Policy considerations**: Ensure policy predicates (e.g., `entrytrace.resolution`) include confidence metadata; lattice logic should treat unresolved entrypoints with configurable severity.
|
||||
- **Next actions**: open backlog item for heuristic upkeep and docs task for CLI/policy explain guidance.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Shell AST parsing | Dockerfile ENTRYPOINT/CMD, shell scripts | StellaOps.Scanner.EntryTrace | Builds command graph with confidence scores; merged into usage SBOM to mark runtime components. |
|
||||
| Wrapper catalogue resolution | Known launchers (npm, yarn, poetry, bundle exec, supervisor) | EntryTrace.WrapperCatalog | Resolves wrappers to underlying binaries; merges with language analyzers via UsageHints. |
|
||||
| Fallback heuristics | History scripts, init configs, service manifests | EntryTrace heuristic expansions | Flags unresolved entrypoints with reasons; Policy Engine consumes to warn/fail. |
|
||||
| Competitor baseline | — | Trivy/Grype/Snyk | No runtime resolution; StellaOps maintains differentiated capability. |
|
||||
|
||||
## DSSE/Rekor operator enablement (Trivy, Grype, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 4 | Regulated tenants require auditable attestations and Rekor proofs for compliance handoffs. |
|
||||
| Competitive risk | 3 | Trivy and Grype export SBOMs but lack DSSE/Rekor workflows; Snyk relies on SaaS attestations. |
|
||||
| Engineering effort | 2 | Capabilities exist; need enablement guides, default policies, and operator tooling. |
|
||||
| Policy/config impact | 4 | Policies must ensure attestation upload/log and enforce Rekor verifiability by tenant. |
|
||||
| Offline/air-gap impact | 2 | DSSE/Rekor flows already support offline bundles; need better documentation and guardrails. |
|
||||
|
||||
- **Competitor capability**: Trivy emits SBOMs and Cosign signatures but Rekor usage is manual; Grype consumes Syft SBOMs without attestations; Snyk Container signs via SaaS only.
|
||||
- **StellaOps gap**: Signing pipeline exists (Signer → Attestor → Rekor v2) yet operators need prescriptive runbooks, policy defaults, and Export Center alignment.
|
||||
- **Proposed plan**:
|
||||
1. Publish DSSE/Rekor operator guide detailing enablement, policy toggles, and verification CLI workflows.
|
||||
2. Extend Export Center profiles with attestation policy checks and Rekor proof bundling by default.
|
||||
3. Surface Rekor health metrics in Scanner.WebService and Notify to escalate failed submissions.
|
||||
- **Policy considerations**: Provide policy predicates for attestation presence, Rekor inclusion, and proof expiry to enforce promotion gates.
|
||||
- **Next actions**: Track via DOCS-SCANNER-BENCH-62-015 and SCANNER-ENG-0015 for playbook plus tooling updates.
|
||||
|
||||
### Implementation details
|
||||
- **StellaOps**:
|
||||
- `StellaOps.Signer` generates DSSE envelopes for SBOMs/reports using PoE-scoped keys and forwards them to `StellaOps.Attestor`, which handles Rekor v2 submissions with retries and proof caching.
|
||||
- Export Center profiles bundle DSSE payloads, Rekor inclusion proofs, and any external attestations into offline-ready archives; CLI and Policy Engine verify proofs before release.
|
||||
- Notify + Scanner.WebService emit attestation health telemetry so operators can quickly spot and remediate failed Rekor submissions.
|
||||
- **Trivy / Grype / Snyk**:
|
||||
- Trivy supports optional Cosign signing but leaves Rekor submission manual; proofs are not bundled with scanner outputs.
|
||||
- Grype leans on Syft for SBOM export and does not sign outputs.
|
||||
- Snyk Container/Snyk CLI rely on SaaS-managed signing and do not expose DSSE workflows or offline proof packaging.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| SBOM emission | CycloneDX/SPDX payloads per scan | Scanner emit pipelines | Generates inventory/usage BOMs stored with CAS hashes for attestation. |
|
||||
| DSSE signing | DSSE bundles, signing keys | StellaOps.Signer + StellaOps.Attestor | Signs SBOM/report metadata, forwards to Rekor v2, records proof identifiers. |
|
||||
| Rekor proof packaging | Rekor inclusion proofs, bundle metadata | Export Center attestation packager | Bundles proofs into Offline Kit/export artifacts; Policy verifies before release. |
|
||||
| Policy enforcement | Attestation & proof evidence | Policy Engine, Scheduler gates | Policies require successful DSSE/Rekor entries before promotion; Scheduler blocks exports lacking proofs. |
|
||||
| Competitor approach | CLI or SaaS-managed signing | Trivy Cosign integration, Snyk SaaS, Grype none | Operators must integrate manually; no default policy enforcement. |
|
||||
|
||||
## Ruby analyzer parity (Trivy, Grype, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 4 | Rails and Sidekiq users expect first-party support with deterministic outputs. |
|
||||
| Competitive risk | 4 | Trivy ships bundler/gemspec analyzers; Snyk offers SaaS rubygems scanning; Grype mirrors Syft data. |
|
||||
| Engineering effort | 5 | Full analyzer stack (lockfile, runtime edges, capability signals) remains to be built. |
|
||||
| Policy/config impact | 4 | Requires policy predicates for bundler groups, autoload resolution, and capability flags. |
|
||||
| Offline/air-gap impact | 3 | Analyzer must ship with Offline Kit assets (fingerprints, autoload maps). |
|
||||
|
||||
- **Competitor capability**: Trivy parses bundler and gemspec data (pkg/fanal/analyzer/language/ruby); Grype relies on Syft ruby catalogers; Snyk CLI delegates to rubygems plugin hitting SaaS.
|
||||
- **StellaOps gap**: No Ruby analyzer in production; only backlog tasks exist.
|
||||
- **Proposed plan**:
|
||||
1. Execute SCANNER-ANALYZERS-RUBY-28-001..012 to deliver lockfile parsing, autoload graphs, capability mapping, and observation outputs.
|
||||
2. Wire CLI () and Offline Kit packaging once analyzer stabilises.
|
||||
3. Provide policy templates covering bundler groups, native extension handling, and dynamic require warnings.
|
||||
- **Policy considerations**: Policy Engine must treat declared groups versus runtime usage distinctly and allow waivers for development/test groups.
|
||||
- **Next actions**: Coordinate via SCANNER-ENG-0009 and DOCS-SCANNER-BENCH-62-009 for documentation and rollout.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Bundler lock parsing | Gemfile, Gemfile.lock, vendor/bundle specs | Trivy bundler analyzer; planned StellaOps Ruby lock collector | Emits package graph with group metadata; merges with installed gems once analyzer ships. |
|
||||
| Gemspec inspection | *.gemspec records, cached specs | Trivy gemspec analyzer; Syft gemspec cataloger | Provides metadata for packaged gems; merges for vendored dependencies. |
|
||||
| Runtime require graph | require/require_relative, autoload hints | Planned StellaOps Ruby require analyzer | Links runtime usage to packages; Policy uses edges for explain traces. |
|
||||
| Capability signals | exec, net/http, YAML load, Sidekiq configs | Planned StellaOps Ruby capability analyzer | Produces policy evidence for dangerous patterns and job schedulers. |
|
||||
|
||||
## PHP analyzer parity (Trivy, Grype, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 4 | Magento, WordPress, Laravel tenants request deterministic composer coverage. |
|
||||
| Competitive risk | 4 | Trivy composer analyzer handles lock/json; Snyk PHP plugin uploads manifests to SaaS; Grype relies on Syft composer data. |
|
||||
| Engineering effort | 5 | Requires composer parsing, include graph, framework detectors, PHAR support. |
|
||||
| Policy/config impact | 4 | Policies must recognise autoload mappings, dangerous functions, extension requirements. |
|
||||
| Offline/air-gap impact | 3 | Analyzer assets must ship with Offline Kit (PHAR readers, fingerprints). |
|
||||
|
||||
- **Competitor capability**: Trivy composer analyzer (pkg/fanal/analyzer/language/php/composer) walks composer.lock and composer.json; Snyk CLI defers to snyk-php-plugin; Grype inherits Syft composer cataloger.
|
||||
- **StellaOps gap**: No PHP analyzer yet; tasks scoped but unimplemented.
|
||||
- **Proposed plan**:
|
||||
1. Deliver SCANNER-ANALYZERS-PHP-27-001..012 covering composer parsing, include graph, PHAR handling, capability analysis.
|
||||
2. Integrate extension detection with Surface.Validation and policy templates for required extensions.
|
||||
3. Provide CLI commands () and Offline Kit documentation.
|
||||
- **Policy considerations**: Configure policies for autoload coverage, dangerous constructs, upload limits, and extension presence.
|
||||
- **Next actions**: SCANNER-ENG-0010 and DOCS-SCANNER-BENCH-62-010 own design and documentation deliverables.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Composer lock parsing | composer.lock, composer.json | Trivy composer analyzer; planned StellaOps Composer collector | Generates package graph with direct versus transitive dependency tagging. |
|
||||
| Autoload resolution | psr-0/psr-4/classmap/files entries | Planned StellaOps PHP autoload analyzer | Builds module graph; merges with capability scanner to highlight runtime usage. |
|
||||
| Capability detection | exec, curl, unserialize, stream wrappers | Planned StellaOps PHP capability analyzer | Records evidence with file/line hashes; policy consumes for risk scoring. |
|
||||
| PHAR inspection | .phar archives, stub metadata | Planned StellaOps PHAR inspector | Expands embedded vendor trees; merges with package inventory. |
|
||||
|
||||
## Deno analyzer outlook (Trivy, Grype, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 2 | Limited but growing demand from edge/runtime teams adopting Deno. |
|
||||
| Competitive risk | 2 | Trivy, Grype, and Snyk lack dedicated Deno analyzers; coverage relies on generic JavaScript workflows. |
|
||||
| Engineering effort | 3 | Requires lockfile parser, import graph resolution, and permission model mapping. |
|
||||
| Policy/config impact | 3 | Policies must treat Deno permissions (net/fs/run) and URL-based modules. |
|
||||
| Offline/air-gap impact | 3 | Need cached registry mirrors or import map handling for air-gapped runs. |
|
||||
|
||||
- **Competitor capability**: Current tooling leans on npm/pnpm analyzers; no first-party Deno parser is shipped in Trivy, Grype, or Snyk.
|
||||
- **StellaOps gap**: No analyzer today; opportunity to differentiate with deterministic import resolution and permission mapping.
|
||||
- **Proposed plan**:
|
||||
1. Scope parsing for deno.lock and import maps with content-addressed module fetching.
|
||||
2. Map permission declarations () into policy evidence.
|
||||
3. Provide Offline Kit guidance for cached module registries and pinned URLs.
|
||||
- **Policy considerations**: Introduce policy predicates for Deno permission sets and remote module domains.
|
||||
- **Next actions**: SCANNER-ENG-0011 and DOCS-SCANNER-BENCH-62-011 to draft design spike and documentation.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Lockfile analysis (planned) | deno.lock, import maps | Planned StellaOps Deno collector | Produces module graph keyed by URL; merges with cached artifacts. |
|
||||
| Permission audit | CLI flags, configuration files | Planned Deno policy analyzer | Records required permissions for policy gating. |
|
||||
| Competitor fallback | Manifest-based npm/pnpm scans | Trivy npm analyzer; Snyk node plugins | Provides partial coverage; lacks Deno permissions and remote module mapping. |
|
||||
|
||||
## Dart analyzer roadmap (Trivy, Grype, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 2 | Dart/Flutter containers are niche but emerging in regulated workloads. |
|
||||
| Competitive risk | 3 | Trivy parses pubspec lockfiles; Snyk references SaaS plugin; Grype lacks native support. |
|
||||
| Engineering effort | 4 | Requires pubspec.lock parser, AOT snapshot fingerprinting, and runtime usage mapping. |
|
||||
| Policy/config impact | 3 | Policies must recognise build modes (debug/release) and AOT binaries. |
|
||||
| Offline/air-gap impact | 3 | Need mirrored pub registries and snapshot tooling packaged offline. |
|
||||
|
||||
- **Competitor capability**: Trivy Dart analyzer (pkg/fanal/analyzer/language/dart/pub) parses pubspec.lock; Snyk delegates to SaaS; Grype is absent.
|
||||
- **StellaOps gap**: No Dart analyzer or policy templates today.
|
||||
- **Proposed plan**:
|
||||
1. Implement pubspec.lock parser with dependency graph and hosted path resolution.
|
||||
2. Fingerprint Dart AOT snapshots to tie binaries back to packages.
|
||||
3. Emit capabilities (platform channels, native plugins) for policy gating.
|
||||
- **Policy considerations**: Distinguish debug versus release builds; allow tenants to require AOT parity.
|
||||
- **Next actions**: SCANNER-ENG-0012 and DOCS-SCANNER-BENCH-62-012 handle design and doc updates.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Lockfile parsing | pubspec.lock, pubspec.yaml | Trivy Dart analyzer; planned StellaOps Dart collector | Builds dependency graph with hosted path info; merges with runtime fingerprints. |
|
||||
| Snapshot fingerprinting | AOT snapshots, dill files | Planned Dart snapshot analyzer | Maps binaries to packages and versions; flagged for policy when unmatched. |
|
||||
| Capability mapping | Flutter platform channels, plugin manifests | Planned Dart capability analyzer | Records platform usage for policy weighting. |
|
||||
|
||||
## Swift analyzer assessment (Trivy, Grype, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 3 | iOS/macOS teams expect Package.resolved support once macOS scanning lands. |
|
||||
| Competitive risk | 4 | Trivy supports SwiftPM and CocoaPods; Snyk ships swift plugin; Grype lacks native Swift analyzers. |
|
||||
| Engineering effort | 4 | Requires SwiftPM parsing, xcframework metadata, and runtime usage heuristics. |
|
||||
| Policy/config impact | 4 | Policies must check binary signature, platform targets, and dynamic library usage. |
|
||||
| Offline/air-gap impact | 3 | Need mirrored Swift package indexes for air-gapped runs. |
|
||||
|
||||
- **Competitor capability**: Trivy swift analyzers (pkg/fanal/analyzer/language/swift) parse Package.resolved and CocoaPods; Snyk swift plugin relies on SaaS.
|
||||
- **StellaOps gap**: No Swift analyzer yet; Windows/macOS coverage pending.
|
||||
- **Proposed plan**:
|
||||
1. Design SwiftPM parser and binary metadata collector under Swift analyzer guild.
|
||||
2. Plan signature validation and entitlements capture for macOS targets.
|
||||
3. Coordinate with Offline Kit to mirror Swift registries and xcframework assets.
|
||||
- **Policy considerations**: Provide predicates for platform targets, entitlements, and signing requirements.
|
||||
- **Next actions**: SCANNER-ENG-0013 and DOCS-SCANNER-BENCH-62-013 drive design and documentation tasks.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| SwiftPM parsing | Package.swift, Package.resolved | Trivy swift analyzer; planned StellaOps Swift collector | Produces dependency graph with target info; merges into SBOM inventory. |
|
||||
| CocoaPods integration | Podfile.lock, Pods directory | Trivy CocoaPods analyzer; planned StellaOps CocoaPods collector | Maps pods to app targets; merges with SwiftPM data. |
|
||||
| Binary metadata | xcframeworks, Mach-O signatures | Planned Swift binary analyzer | Captures signing, architectures, and entitlements; fed into policy engine. |
|
||||
|
||||
## Kubernetes/VM target coverage alignment (Trivy, Snyk)
|
||||
### Scorecard
|
||||
| Dimension | Score (1-5) | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| Customer demand | 4 | Platform teams expect coverage for live clusters, VMs, and admission controls. |
|
||||
| Competitive risk | 3 | Trivy Operator and Snyk monitor clusters but lack deterministic attestations; Grype stays image-focused. |
|
||||
| Engineering effort | 3 | Needs coordination between Scanner, Zastava, and runtime posture services. |
|
||||
| Policy/config impact | 4 | Policies must combine runtime posture data with scan evidence. |
|
||||
| Offline/air-gap impact | 3 | Requires offline posture bundles and admission controller configuration guidance. |
|
||||
|
||||
- **Competitor capability**: Trivy Operator scans clusters via live API calls; Snyk relies on SaaS; Grype covers images only.
|
||||
- **StellaOps gap**: Scanner handles images/filesystems; runtime enforcement lives in Zastava and needs coordinated roadmap.
|
||||
- **Proposed plan**:
|
||||
1. Produce joint roadmap clarifying Scanner versus Zastava responsibilities for clusters and VMs.
|
||||
2. Document how runtime posture feeds into Policy Engine and Export Center outputs.
|
||||
3. Provide Offline Kit assets for Zastava admission policies and scheduler hooks.
|
||||
- **Policy considerations**: Expand policy predicates to ingest runtime posture signals (signed images, SBOM availability, policy verdicts).
|
||||
- **Next actions**: SCANNER-ENG-0014 and DOCS-SCANNER-BENCH-62-014 deliver roadmap and documentation.
|
||||
|
||||
### Detection techniques
|
||||
| Technique | Artifacts | Analyzer / Module | Merge strategy |
|
||||
|-----------|-----------|-------------------|----------------|
|
||||
| Image/file scan | Container images, filesystem snapshots | StellaOps.Scanner.Worker | Provides deterministic inventory and usage data for images. |
|
||||
| Runtime posture (planned) | Admission events, sensor telemetry | Zastava.Observer and Webhook | Supplies runtime evidence (signed images, drift) merged into policy overlays. |
|
||||
| Cluster drift detection | Scheduler and Vuln Explorer events | Scheduler + Policy Engine | Detects advisory/VEX deltas and schedules analysis-only runs. |
|
||||
| Competitor workflow | Live API queries and SaaS services | Trivy Operator; Snyk Kubernetes integration | Offers visibility but lacks attestations and offline parity. |
|
||||
33
docs/benchmarks/scanner/windows-macos-demand.md
Normal file
33
docs/benchmarks/scanner/windows-macos-demand.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Windows / macOS Analyzer Demand Capture
|
||||
|
||||
## Current competitive posture
|
||||
- **Trivy** coverage tables enumerate Linux family distributions only (Alpine, Wolfi, Chainguard, Debian/Ubuntu, RHEL/Alma/Rocky, SUSE, Photon, Amazon, Bottlerocket) with no mention of Windows or macOS package managers (source: /tmp/trivy-docs/docs/docs/coverage/os/index.md).
|
||||
- **Grype** matchers target Linux ecosystems via Syft catalogers (APK, DPKG/APT, RPM, Portage, Bitnami) with no coverage for Windows Installer, MSI, Chocolatey, or macOS Homebrew/App bundles (source: /tmp/grype-data/grype/matcher/{apk,dpkg,rpm}/matcher.go).
|
||||
- **Snyk CLI** focuses on container, open source, IaC, and code scanning routed through the SaaS service; CLI documentation does not advertise Windows/macOS package coverage beyond container images (source: /tmp/snyk-cli/README.md).
|
||||
|
||||
## Signals to gather
|
||||
1. **Customer interviews** – ask regulated customers deploying Windows Server or Windows container workloads which artifacts require SBOM + VEX and whether current StellaOps scope (Linux images) blocks adoption.
|
||||
2. **Sales & SE feedback loop** – capture any RFP items referencing Windows/macOS scanning and log them in the Scanner guild tracker (SCANNER-ANALYZERS-OS-*).
|
||||
3. **Support telemetry** – review ticket tags for “windows”, “macos”, “dotnet framework” to quantify inbound demand.
|
||||
4. **Community landscape** – monitor Trivy/Grype/Snyk release notes for Windows/macOS announcements; update this note and the feature matrix when competitors change posture.
|
||||
5. **Interview discipline** – use the structured questionnaire in `windows-macos-interview-template.md` to ensure consistent scoring and capture follow-up actions.
|
||||
|
||||
## Signals log — macOS
|
||||
| Date (YYYY-MM-DD) | Source / Account | Use case | Demand strength (1-5) | Notes / follow-up |
|
||||
|-------------------|------------------|----------|------------------------|-------------------|
|
||||
| 2025-11-03 | Northwind Health Services (NA) | macOS CI runners require notarization evidence for release sign-off | 4 | Demo deterministic bundle inspection w/ Product on 2025-11-10; capture entitlements policy requirements. |
|
||||
|
||||
## Signals log — Windows
|
||||
| Date (YYYY-MM-DD) | Source / Account | Use case | Demand strength (1-5) | Notes / follow-up |
|
||||
|-------------------|------------------|----------|------------------------|-------------------|
|
||||
| 2025-11-03 | FinSecure Corp (NA) | Windows Server 2019 images need MSI/WinSxS SBOM + signed driver attestations for PCI audit | 5 | Blocking go-live; Security guild to confirm Authenticode posture (POLICY-READINESS-0002) by 2025-11-07. |
|
||||
|
||||
## Next actions
|
||||
- Coordinate with Product Marketing to add Windows/macOS discovery prompts into upcoming customer advisory sessions (target: Sprint 132 intake).
|
||||
- Instrument the scanner roadmap intake form with explicit checkboxes for Windows/macOS package ecosystems.
|
||||
- If three or more qualified customers flag Windows/macOS coverage as a blocking requirement, open a design spike under the Scanner Analyzer Guild with scope/time estimates and Offline Kit considerations.
|
||||
- Keep the macOS deep dive (`docs/benchmarks/scanner/deep-dives/macos.md`) in sync with demand findings so engineering can move from design sketch to formal backlog when thresholds are met.
|
||||
- Update the Windows deep dive (`docs/benchmarks/scanner/deep-dives/windows.md`) and associated design briefs (`docs/modules/scanner/design/windows-analyzer.md`) as new signals arrive.
|
||||
- Refresh API dashboards (`docs/api/scanner/windows-macos-summary.md`, `docs/api/scanner/windows-coverage.md`) after each update to keep Product and Field teams aligned.
|
||||
- Drive POLICY-READINESS-0002 Authenticode/feed decision by 2025-11-07 (FinSecure PCI blocker); log outcome in dashboards and design briefs.
|
||||
- Prepare POLICY-READINESS-0001 workshop aligned with Northwind demo on 2025-11-10, updating policy briefs with masking/telemetry decisions.
|
||||
50
docs/benchmarks/scanner/windows-macos-interview-template.md
Normal file
50
docs/benchmarks/scanner/windows-macos-interview-template.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Windows / macOS Analyzer Demand — Interview Template
|
||||
|
||||
Use this template during customer interviews, SE discovery calls, or product advisory meetings. Copy the table into your meeting notes and fill in the responses. Summaries should be pushed back into `windows-macos-demand.md`.
|
||||
|
||||
## Interview metadata
|
||||
| Field | Notes |
|
||||
| --- | --- |
|
||||
| Date | `YYYY-MM-DD` |
|
||||
| Interviewer(s) | |
|
||||
| Customer / Account | |
|
||||
| Participant roles | (e.g., platform lead, security architect) |
|
||||
| Workload context | (container images, VMs, desktop fleets, CI pipelines, etc.) |
|
||||
|
||||
## Current state
|
||||
1. **Operating systems in scope**
|
||||
- Which Windows or macOS versions/images are mission critical?
|
||||
- Container vs VM vs bare-metal distribution?
|
||||
2. **Existing tooling**
|
||||
- What scanners or inventory tools are used today (e.g., SCCM, Tanium, Trivy, Snyk, custom scripts)?
|
||||
- Pain points / gaps they experience (offline support, provenance, coverage, explainability).
|
||||
3. **Regulatory / compliance drivers**
|
||||
- Any specific frameworks (PCI, FedRAMP, DISA, internal policies) mandating Windows/macOS SBOM or attestation?
|
||||
|
||||
## Desired capabilities (score 1–5 per feature)
|
||||
| Capability | Score | Notes |
|
||||
| --- | --- | --- |
|
||||
| MSI / WinSxS package inventory | | |
|
||||
| Chocolatey / third-party feed tracking | | |
|
||||
| macOS Homebrew / pkgutil receipts | | |
|
||||
| `.app` bundle inspection (signing, entitlements) | | |
|
||||
| Driver / service posture | | |
|
||||
| Authenticode / notarization verification | | |
|
||||
| Offline/air-gap parity | | |
|
||||
| Policy integration (e.g., block unsigned driver) | | |
|
||||
|
||||
## Operational requirements
|
||||
- **Offline expectations**: Do they require artefact mirroring? Which feeds?
|
||||
- **Performance**: Time budget for scans? Incremental vs full?
|
||||
- **Evidence formats**: Preferred SBOM types, attestation needs, API endpoints.
|
||||
- **Secrets / credentials**: Any constraints for registry/hive exports or feed mirrors?
|
||||
|
||||
## Success metrics
|
||||
- How will the customer judge success? (e.g., number of workloads covered, audit findings reduced, ability to prove provenance).
|
||||
- Timeline expectations for pilot vs GA?
|
||||
|
||||
## Follow-up actions
|
||||
- What next steps were promised (POC, roadmap update, integration with other guilds)?
|
||||
- Owners + due dates.
|
||||
|
||||
> After the interview: convert highlights into a concise row in `windows-macos-demand.md` and, if needed, create Jira/backlog items for SCANNER-ENG-0020..0027 or DOCS-SCANNER-BENCH-62-016 with the captured context.
|
||||
@@ -1,220 +1,220 @@
|
||||
# Vexer Connector Packaging Guide
|
||||
|
||||
> **Audience:** teams implementing new Vexer provider plug‑ins (CSAF feeds,
|
||||
> OpenVEX attestations, etc.)
|
||||
> **Prerequisites:** read `docs/modules/vexer/architecture.md` and the module
|
||||
> `AGENTS.md` in `src/Excititor/__Libraries/StellaOps.Excititor.Connectors.Abstractions/`.
|
||||
|
||||
The Vexer connector SDK gives you:
|
||||
|
||||
- `VexConnectorBase` – deterministic logging, SHA‑256 helpers, time provider.
|
||||
- `VexConnectorOptionsBinder` – strongly typed YAML/JSON configuration binding.
|
||||
- `IVexConnectorOptionsValidator<T>` – custom validation hooks (offline defaults, auth invariants).
|
||||
- `VexConnectorDescriptor` & metadata helpers for consistent telemetry.
|
||||
|
||||
This guide explains how to package a connector so the Vexer Worker/WebService
|
||||
can load it via the plugin host.
|
||||
|
||||
---
|
||||
|
||||
## 1. Project layout
|
||||
|
||||
Start from the template under
|
||||
`docs/dev/templates/vexer-connector/`. It contains:
|
||||
|
||||
```
|
||||
Vexer.MyConnector/
|
||||
├── src/
|
||||
│ ├── Vexer.MyConnector.csproj
|
||||
│ ├── MyConnectorOptions.cs
|
||||
│ ├── MyConnector.cs
|
||||
│ └── MyConnectorPlugin.cs
|
||||
└── manifest/
|
||||
└── connector.manifest.yaml
|
||||
```
|
||||
|
||||
Key points:
|
||||
|
||||
- Target `net10.0`, enable `TreatWarningsAsErrors`, reference the
|
||||
`StellaOps.Vexer.Connectors.Abstractions` project (or NuGet once published).
|
||||
- Keep project ID prefix `StellaOps.Vexer.Connectors.<Provider>` so the
|
||||
plugin loader can discover it with the default search pattern.
|
||||
|
||||
### 1.1 csproj snippet
|
||||
|
||||
```xml
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\StellaOps.Vexer.Connectors.Abstractions\StellaOps.Vexer.Connectors.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
Adjust the `ProjectReference` for your checkout (or switch to a NuGet package
|
||||
once published).
|
||||
|
||||
---
|
||||
|
||||
## 2. Implement the connector
|
||||
|
||||
1. **Options model** – create an options POCO with data-annotation attributes.
|
||||
Bind it via `VexConnectorOptionsBinder.Bind<TOptions>` in your connector
|
||||
constructor or `ValidateAsync`.
|
||||
2. **Validator** – implement `IVexConnectorOptionsValidator<TOptions>` to add
|
||||
complex checks (e.g., ensure both `clientId` and `clientSecret` are present).
|
||||
3. **Connector** – inherit from `VexConnectorBase`. Implement:
|
||||
- `ValidateAsync` – run binder/validators, log configuration summary.
|
||||
- `FetchAsync` – stream raw documents to `context.RawSink`.
|
||||
- `NormalizeAsync` – convert raw documents into `VexClaimBatch` via
|
||||
format-specific normalizers (`context.Normalizers`).
|
||||
4. **Plugin adapter** – expose the connector via a plugin entry point so the
|
||||
host can instantiate it.
|
||||
|
||||
### 2.1 Options binding example
|
||||
|
||||
```csharp
|
||||
public sealed class MyConnectorOptions
|
||||
{
|
||||
[Required]
|
||||
[Url]
|
||||
public string CatalogUri { get; set; } = default!;
|
||||
|
||||
[Required]
|
||||
public string ApiKey { get; set; } = default!;
|
||||
|
||||
[Range(1, 64)]
|
||||
public int MaxParallelRequests { get; set; } = 4;
|
||||
}
|
||||
|
||||
public sealed class MyConnectorOptionsValidator : IVexConnectorOptionsValidator<MyConnectorOptions>
|
||||
{
|
||||
public void Validate(VexConnectorDescriptor descriptor, MyConnectorOptions options, IList<string> errors)
|
||||
{
|
||||
if (!options.CatalogUri.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
errors.Add("CatalogUri must use HTTPS.");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Bind inside the connector:
|
||||
|
||||
```csharp
|
||||
private readonly MyConnectorOptions _options;
|
||||
|
||||
public MyConnector(VexConnectorDescriptor descriptor, ILogger<MyConnector> logger, TimeProvider timeProvider)
|
||||
: base(descriptor, logger, timeProvider)
|
||||
{
|
||||
// `settings` comes from the orchestrator; validators registered via DI.
|
||||
_options = VexConnectorOptionsBinder.Bind<MyConnectorOptions>(
|
||||
descriptor,
|
||||
VexConnectorSettings.Empty,
|
||||
validators: new[] { new MyConnectorOptionsValidator() });
|
||||
}
|
||||
```
|
||||
|
||||
Replace `VexConnectorSettings.Empty` with the actual settings from context
|
||||
inside `ValidateAsync`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Plugin adapter & manifest
|
||||
|
||||
Create a simple plugin class that implements
|
||||
`StellaOps.Plugin.IConnectorPlugin`. The Worker/WebService plugin host uses
|
||||
this contract today.
|
||||
|
||||
```csharp
|
||||
public sealed class MyConnectorPlugin : IConnectorPlugin
|
||||
{
|
||||
private static readonly VexConnectorDescriptor Descriptor =
|
||||
new("vexer:my-provider", VexProviderKind.Vendor, "My Provider VEX");
|
||||
|
||||
public string Name => Descriptor.DisplayName;
|
||||
|
||||
public bool IsAvailable(IServiceProvider services) => true; // inject feature flags if needed
|
||||
|
||||
public IFeedConnector Create(IServiceProvider services)
|
||||
{
|
||||
var logger = services.GetRequiredService<ILogger<MyConnector>>();
|
||||
var timeProvider = services.GetRequiredService<TimeProvider>();
|
||||
return new MyConnector(Descriptor, logger, timeProvider);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:** the Vexer Worker currently instantiates connectors through the
|
||||
> shared `IConnectorPlugin` contract. Once a dedicated Vexer plugin interface
|
||||
> lands you simply swap the base interface; the descriptor/connector code
|
||||
> remains unchanged.
|
||||
|
||||
Provide a manifest describing the assembly for operational tooling:
|
||||
|
||||
```yaml
|
||||
# manifest/connector.manifest.yaml
|
||||
id: vexer-my-provider
|
||||
assembly: StellaOps.Vexer.Connectors.MyProvider.dll
|
||||
entryPoint: StellaOps.Vexer.Connectors.MyProvider.MyConnectorPlugin
|
||||
description: >
|
||||
Official VEX feed for ExampleCorp products (CSAF JSON, daily updates).
|
||||
tags:
|
||||
- vexer
|
||||
- csaf
|
||||
- vendor
|
||||
```
|
||||
|
||||
Store manifests under `/opt/stella/vexer/plugins/<connector>/manifest/` in
|
||||
production so the deployment tooling can inventory and verify plug‑ins.
|
||||
|
||||
---
|
||||
|
||||
## 4. Packaging workflow
|
||||
|
||||
1. `dotnet publish -c Release` → copy the published DLLs to
|
||||
`/opt/stella/vexer/plugins/<Provider>/`.
|
||||
2. Place `connector.manifest.yaml` next to the binaries.
|
||||
3. Restart the Vexer Worker or WebService (hot reload not supported yet).
|
||||
4. Verify logs: `VEX-ConnectorLoader` should list the connector descriptor.
|
||||
|
||||
### 4.1 Offline kits
|
||||
|
||||
- Add the connector folder (binaries + manifest) to the Offline Kit bundle.
|
||||
- Include a `settings.sample.yaml` demonstrating offline-friendly defaults.
|
||||
- Document any external dependencies (e.g., SHA mirrors) in the manifest `notes`
|
||||
field.
|
||||
|
||||
---
|
||||
|
||||
## 5. Testing checklist
|
||||
|
||||
- Unit tests around options binding & validators.
|
||||
- Integration tests (future `StellaOps.Vexer.Connectors.Abstractions.Tests`)
|
||||
verifying deterministic logging scopes:
|
||||
`logger.BeginScope` should produce `vex.connector.id`, `vex.connector.kind`,
|
||||
and `vex.connector.operation`.
|
||||
- Deterministic SHA tests: repeated `CreateRawDocument` calls with identical
|
||||
content must return the same digest.
|
||||
|
||||
---
|
||||
|
||||
## 6. Reference template
|
||||
|
||||
See `docs/dev/templates/vexer-connector/` for the full quick‑start including:
|
||||
|
||||
- Sample options class + validator.
|
||||
- Connector implementation inheriting from `VexConnectorBase`.
|
||||
- Plugin adapter + manifest.
|
||||
|
||||
Copy the directory, rename namespaces/IDs, then iterate on provider-specific
|
||||
logic.
|
||||
|
||||
---
|
||||
|
||||
*Last updated: 2025-10-17*
|
||||
# Excitor Connector Packaging Guide
|
||||
|
||||
> **Audience:** teams implementing new Excitor provider plug‑ins (CSAF feeds,
|
||||
> OpenVEX attestations, etc.)
|
||||
> **Prerequisites:** read `docs/modules/excitor/architecture.md` and the module
|
||||
> `AGENTS.md` in `src/Excititor/__Libraries/StellaOps.Excititor.Connectors.Abstractions/`.
|
||||
|
||||
The Excitor connector SDK gives you:
|
||||
|
||||
- `VexConnectorBase` – deterministic logging, SHA‑256 helpers, time provider.
|
||||
- `VexConnectorOptionsBinder` – strongly typed YAML/JSON configuration binding.
|
||||
- `IVexConnectorOptionsValidator<T>` – custom validation hooks (offline defaults, auth invariants).
|
||||
- `VexConnectorDescriptor` & metadata helpers for consistent telemetry.
|
||||
|
||||
This guide explains how to package a connector so the Excitor Worker/WebService
|
||||
can load it via the plugin host.
|
||||
|
||||
---
|
||||
|
||||
## 1. Project layout
|
||||
|
||||
Start from the template under
|
||||
`docs/dev/templates/excitor-connector/`. It contains:
|
||||
|
||||
```
|
||||
Excitor.MyConnector/
|
||||
├── src/
|
||||
│ ├── Excitor.MyConnector.csproj
|
||||
│ ├── MyConnectorOptions.cs
|
||||
│ ├── MyConnector.cs
|
||||
│ └── MyConnectorPlugin.cs
|
||||
└── manifest/
|
||||
└── connector.manifest.yaml
|
||||
```
|
||||
|
||||
Key points:
|
||||
|
||||
- Target `net10.0`, enable `TreatWarningsAsErrors`, reference the
|
||||
`StellaOps.Excitor.Connectors.Abstractions` project (or NuGet once published).
|
||||
- Keep project ID prefix `StellaOps.Excitor.Connectors.<Provider>` so the
|
||||
plugin loader can discover it with the default search pattern.
|
||||
|
||||
### 1.1 csproj snippet
|
||||
|
||||
```xml
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\StellaOps.Excitor.Connectors.Abstractions\StellaOps.Excitor.Connectors.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
Adjust the `ProjectReference` for your checkout (or switch to a NuGet package
|
||||
once published).
|
||||
|
||||
---
|
||||
|
||||
## 2. Implement the connector
|
||||
|
||||
1. **Options model** – create an options POCO with data-annotation attributes.
|
||||
Bind it via `VexConnectorOptionsBinder.Bind<TOptions>` in your connector
|
||||
constructor or `ValidateAsync`.
|
||||
2. **Validator** – implement `IVexConnectorOptionsValidator<TOptions>` to add
|
||||
complex checks (e.g., ensure both `clientId` and `clientSecret` are present).
|
||||
3. **Connector** – inherit from `VexConnectorBase`. Implement:
|
||||
- `ValidateAsync` – run binder/validators, log configuration summary.
|
||||
- `FetchAsync` – stream raw documents to `context.RawSink`.
|
||||
- `NormalizeAsync` – convert raw documents into `VexClaimBatch` via
|
||||
format-specific normalizers (`context.Normalizers`).
|
||||
4. **Plugin adapter** – expose the connector via a plugin entry point so the
|
||||
host can instantiate it.
|
||||
|
||||
### 2.1 Options binding example
|
||||
|
||||
```csharp
|
||||
public sealed class MyConnectorOptions
|
||||
{
|
||||
[Required]
|
||||
[Url]
|
||||
public string CatalogUri { get; set; } = default!;
|
||||
|
||||
[Required]
|
||||
public string ApiKey { get; set; } = default!;
|
||||
|
||||
[Range(1, 64)]
|
||||
public int MaxParallelRequests { get; set; } = 4;
|
||||
}
|
||||
|
||||
public sealed class MyConnectorOptionsValidator : IVexConnectorOptionsValidator<MyConnectorOptions>
|
||||
{
|
||||
public void Validate(VexConnectorDescriptor descriptor, MyConnectorOptions options, IList<string> errors)
|
||||
{
|
||||
if (!options.CatalogUri.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
errors.Add("CatalogUri must use HTTPS.");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Bind inside the connector:
|
||||
|
||||
```csharp
|
||||
private readonly MyConnectorOptions _options;
|
||||
|
||||
public MyConnector(VexConnectorDescriptor descriptor, ILogger<MyConnector> logger, TimeProvider timeProvider)
|
||||
: base(descriptor, logger, timeProvider)
|
||||
{
|
||||
// `settings` comes from the orchestrator; validators registered via DI.
|
||||
_options = VexConnectorOptionsBinder.Bind<MyConnectorOptions>(
|
||||
descriptor,
|
||||
VexConnectorSettings.Empty,
|
||||
validators: new[] { new MyConnectorOptionsValidator() });
|
||||
}
|
||||
```
|
||||
|
||||
Replace `VexConnectorSettings.Empty` with the actual settings from context
|
||||
inside `ValidateAsync`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Plugin adapter & manifest
|
||||
|
||||
Create a simple plugin class that implements
|
||||
`StellaOps.Plugin.IConnectorPlugin`. The Worker/WebService plugin host uses
|
||||
this contract today.
|
||||
|
||||
```csharp
|
||||
public sealed class MyConnectorPlugin : IConnectorPlugin
|
||||
{
|
||||
private static readonly VexConnectorDescriptor Descriptor =
|
||||
new("excitor:my-provider", VexProviderKind.Vendor, "My Provider VEX");
|
||||
|
||||
public string Name => Descriptor.DisplayName;
|
||||
|
||||
public bool IsAvailable(IServiceProvider services) => true; // inject feature flags if needed
|
||||
|
||||
public IFeedConnector Create(IServiceProvider services)
|
||||
{
|
||||
var logger = services.GetRequiredService<ILogger<MyConnector>>();
|
||||
var timeProvider = services.GetRequiredService<TimeProvider>();
|
||||
return new MyConnector(Descriptor, logger, timeProvider);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:** the Excitor Worker currently instantiates connectors through the
|
||||
> shared `IConnectorPlugin` contract. Once a dedicated Excitor plugin interface
|
||||
> lands you simply swap the base interface; the descriptor/connector code
|
||||
> remains unchanged.
|
||||
|
||||
Provide a manifest describing the assembly for operational tooling:
|
||||
|
||||
```yaml
|
||||
# manifest/connector.manifest.yaml
|
||||
id: excitor-my-provider
|
||||
assembly: StellaOps.Excitor.Connectors.MyProvider.dll
|
||||
entryPoint: StellaOps.Excitor.Connectors.MyProvider.MyConnectorPlugin
|
||||
description: >
|
||||
Official VEX feed for ExampleCorp products (CSAF JSON, daily updates).
|
||||
tags:
|
||||
- excitor
|
||||
- csaf
|
||||
- vendor
|
||||
```
|
||||
|
||||
Store manifests under `/opt/stella/excitor/plugins/<connector>/manifest/` in
|
||||
production so the deployment tooling can inventory and verify plug‑ins.
|
||||
|
||||
---
|
||||
|
||||
## 4. Packaging workflow
|
||||
|
||||
1. `dotnet publish -c Release` → copy the published DLLs to
|
||||
`/opt/stella/excitor/plugins/<Provider>/`.
|
||||
2. Place `connector.manifest.yaml` next to the binaries.
|
||||
3. Restart the Excitor Worker or WebService (hot reload not supported yet).
|
||||
4. Verify logs: `VEX-ConnectorLoader` should list the connector descriptor.
|
||||
|
||||
### 4.1 Offline kits
|
||||
|
||||
- Add the connector folder (binaries + manifest) to the Offline Kit bundle.
|
||||
- Include a `settings.sample.yaml` demonstrating offline-friendly defaults.
|
||||
- Document any external dependencies (e.g., SHA mirrors) in the manifest `notes`
|
||||
field.
|
||||
|
||||
---
|
||||
|
||||
## 5. Testing checklist
|
||||
|
||||
- Unit tests around options binding & validators.
|
||||
- Integration tests (future `StellaOps.Excitor.Connectors.Abstractions.Tests`)
|
||||
verifying deterministic logging scopes:
|
||||
`logger.BeginScope` should produce `vex.connector.id`, `vex.connector.kind`,
|
||||
and `vex.connector.operation`.
|
||||
- Deterministic SHA tests: repeated `CreateRawDocument` calls with identical
|
||||
content must return the same digest.
|
||||
|
||||
---
|
||||
|
||||
## 6. Reference template
|
||||
|
||||
See `docs/dev/templates/excitor-connector/` for the full quick‑start including:
|
||||
|
||||
- Sample options class + validator.
|
||||
- Connector implementation inheriting from `VexConnectorBase`.
|
||||
- Plugin adapter + manifest.
|
||||
|
||||
Copy the directory, rename namespaces/IDs, then iterate on provider-specific
|
||||
logic.
|
||||
|
||||
---
|
||||
|
||||
*Last updated: 2025-10-17*
|
||||
@@ -0,0 +1,8 @@
|
||||
id: excitor-my-provider
|
||||
assembly: StellaOps.Excitor.Connectors.MyProvider.dll
|
||||
entryPoint: StellaOps.Excitor.Connectors.MyProvider.MyConnectorPlugin
|
||||
description: |
|
||||
Example connector template. Replace metadata before shipping.
|
||||
tags:
|
||||
- excitor
|
||||
- template
|
||||
@@ -7,6 +7,6 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Adjust the relative path when copying this template into a repo -->
|
||||
<ProjectReference Include="..\..\..\..\src\StellaOps.Vexer.Connectors.Abstractions\StellaOps.Vexer.Connectors.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\src\StellaOps.Excitor.Connectors.Abstractions\StellaOps.Excitor.Connectors.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -2,10 +2,10 @@ using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Vexer.Connectors.Abstractions;
|
||||
using StellaOps.Vexer.Core;
|
||||
using StellaOps.Excitor.Connectors.Abstractions;
|
||||
using StellaOps.Excitor.Core;
|
||||
|
||||
namespace StellaOps.Vexer.Connectors.MyProvider;
|
||||
namespace StellaOps.Excitor.Connectors.MyProvider;
|
||||
|
||||
public sealed class MyConnector : VexConnectorBase
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace StellaOps.Vexer.Connectors.MyProvider;
|
||||
namespace StellaOps.Excitor.Connectors.MyProvider;
|
||||
|
||||
public sealed class MyConnectorOptions
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using StellaOps.Vexer.Connectors.Abstractions;
|
||||
using StellaOps.Excitor.Connectors.Abstractions;
|
||||
|
||||
namespace StellaOps.Vexer.Connectors.MyProvider;
|
||||
namespace StellaOps.Excitor.Connectors.MyProvider;
|
||||
|
||||
public sealed class MyConnectorOptionsValidator : IVexConnectorOptionsValidator<MyConnectorOptions>
|
||||
{
|
||||
@@ -1,15 +1,15 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Plugin;
|
||||
using StellaOps.Vexer.Connectors.Abstractions;
|
||||
using StellaOps.Vexer.Core;
|
||||
using StellaOps.Excitor.Connectors.Abstractions;
|
||||
using StellaOps.Excitor.Core;
|
||||
|
||||
namespace StellaOps.Vexer.Connectors.MyProvider;
|
||||
namespace StellaOps.Excitor.Connectors.MyProvider;
|
||||
|
||||
public sealed class MyConnectorPlugin : IConnectorPlugin
|
||||
{
|
||||
private static readonly VexConnectorDescriptor Descriptor = new(
|
||||
id: "vexer:my-provider",
|
||||
id: "excitor:my-provider",
|
||||
kind: VexProviderKind.Vendor,
|
||||
displayName: "My Provider VEX");
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
id: vexer-my-provider
|
||||
assembly: StellaOps.Vexer.Connectors.MyProvider.dll
|
||||
entryPoint: StellaOps.Vexer.Connectors.MyProvider.MyConnectorPlugin
|
||||
description: |
|
||||
Example connector template. Replace metadata before shipping.
|
||||
tags:
|
||||
- vexer
|
||||
- template
|
||||
@@ -14,6 +14,13 @@ Follow the sprint files below in order. Update task status in both `SPRINTS` and
|
||||
- [Ops & Offline](./SPRINT_190_ops_offline.md)
|
||||
- [Documentation & Process](./SPRINT_200_documentation_process.md)
|
||||
|
||||
> 2025-11-03: AIRGAP-POL-57-002 confirmed DOING (AirGap Policy Guild, Task Runner Guild) – continuing Task Runner sealed-mode egress validation and test sweep.
|
||||
> 2025-11-03: AIRGAP-POL-57-002 marked DONE (AirGap Policy Guild, Task Runner Guild) – worker now injects `IEgressPolicy`, filesystem dispatcher enforces sealed-mode egress, planner grants normalized, sealed-mode dispatcher test added; follow-up queued to lift remaining dispatchers/executors onto the shared policy before sealing the full worker loop.
|
||||
> 2025-11-03: MERGE-LNM-21-001 moved to DOING (BE-Merge, Architecture Guild) – drafting `no-merge` migration playbook outline and capturing rollout/backfill checkpoints.
|
||||
> 2025-11-03: MERGE-LNM-21-001 marked DONE – published `docs/migration/no-merge.md` with rollout, backfill, validation, and rollback guidance for the LNM cutover.
|
||||
> 2025-11-03: MERGE-LNM-21-002 moved to DOING (BE-Merge) – auditing `AdvisoryMergeService` call sites to scope removal and analyzer enforcement.
|
||||
> 2025-11-03: DOCS-LNM-22-008 moved to DOING (Docs Guild, DevOps Guild) – aligning migration playbook structure and readiness checklist.
|
||||
> 2025-11-03: DOCS-LNM-22-008 marked DONE – `/docs/migration/no-merge.md` published for DevOps/Export Center planning with checklist for cutover readiness.
|
||||
> 2025-11-01: SCANNER-ANALYZERS-LANG-10-308R marked DONE (Language Analyzer Guild) – heuristics fixtures, benchmarks, and coverage comparison published.
|
||||
> 2025-11-01: SCANNER-ANALYZERS-LANG-10-309R marked DONE (Language Analyzer Guild) – Rust analyzer packaged with offline kit smoke tests and docs.
|
||||
> 2025-11-01: ENTRYTRACE-SURFACE-01 moved to DOING (EntryTrace Guild) – wiring Surface.Validation and Surface.FS reuse ahead of EntryTrace runs.
|
||||
@@ -38,6 +45,7 @@ Follow the sprint files below in order. Update task status in both `SPRINTS` and
|
||||
> 2025-11-02: SURFACE-FS-02 moved to DOING (Surface FS Guild) – building core abstractions and deterministic serializers.
|
||||
> 2025-11-02: SURFACE-SECRETS-01 moved to DOING (Surface Secrets Guild) – updating secrets design for provider matrix.
|
||||
> 2025-11-02: SURFACE-SECRETS-02 moved to DOING (Surface Secrets Guild) – implementing base providers + tests.
|
||||
> 2025-11-02: AUTH-POLICY-27-002 marked DONE (Authority Core & Security Guild) – interactive-only policy publish/promote scopes delivered with metadata, fresh-auth enforcement, and audit/docs updates.
|
||||
> 2025-11-02: SCANNER-ENTRYTRACE-18-506 moved to DOING (EntryTrace Guild, Scanner WebService Guild) – surfacing EntryTrace results via WebService/CLI with confidence metadata.
|
||||
> 2025-11-02: ATTESTOR-74-001 marked DONE (Attestor Service Guild) – witness client integration, repository schema, and verification/reporting updates landed with tests.
|
||||
> 2025-11-02: AUTH-OAS-63-001 moved to DOING (Authority Core & Security Guild, API Governance Guild) – verifying legacy `/oauth/*` deprecation signalling and notifications ahead of sunset.
|
||||
@@ -51,6 +59,8 @@ Follow the sprint files below in order. Update task status in both `SPRINTS` and
|
||||
> 2025-11-02: AUTH-ORCH-34-001 marked DONE (Authority Core & Security Guild) – `orch:backfill` scope enforced with reason/ticket metadata, Authority + CLI updated, docs/config refreshed for Orchestrator admins.
|
||||
> 2025-11-02: AUTH-PACKS-41-001 moved to DOING (Authority Core & Security Guild) – defining packs scope catalogue, issuer templates, and offline defaults.
|
||||
> 2025-11-02: AUTH-PACKS-41-001 added shared OpenSSL 1.1 test libs so Authority & Signals Mongo2Go suites run on OpenSSL 3.
|
||||
> 2025-11-02: AUTH-NOTIFY-42-001 moved to DOING (Authority Core & Security Guild) – investigating `/notify/ack-tokens/rotate` 500 responses when key metadata missing.
|
||||
> 2025-11-02: AUTH-NOTIFY-42-001 marked DONE (Authority Core & Security Guild) – bootstrap rotate defaults fixed, `StellaOpsBearer` test alias added, and notify ack rotation regression passes.
|
||||
> 2025-11-02: ENTRYTRACE-SURFACE-02 moved to DOING (EntryTrace Guild) – replacing direct env/secret access with Surface.Secrets provider for EntryTrace runs.
|
||||
> 2025-11-02: ENTRYTRACE-SURFACE-01 marked DONE (EntryTrace Guild) – Surface.Validation + Surface.FS cache now drive EntryTrace reuse with regression tests.
|
||||
> 2025-11-02: ENTRYTRACE-SURFACE-02 marked DONE (EntryTrace Guild) – EntryTrace environment placeholders resolved via Surface.Secrets with updated docs/tests.
|
||||
@@ -63,3 +73,43 @@ Follow the sprint files below in order. Update task status in both `SPRINTS` and
|
||||
> 2025-11-02: CONCELIER-WEB-OAS-61-001 marked DONE (Concelier WebService Guild) – discovery endpoint now serves signed OpenAPI 3.1 document with ETag support.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-001 moved to DOING (Docs Guild, Scanner Guild) – refreshing Trivy/Grype/Snyk comparison docs and ecosystem matrix with source-linked coverage.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-001 marked DONE (Docs Guild, Scanner Guild) – matrix updated with Windows/macOS coverage row and secret detection techniques; deep dives cite Trivy/Grype/Snyk sources.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-003 added (Docs Guild, Product Guild) – recording Python lockfile/editable-install demand signals for policy guidance follow-up.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-004 added (Docs Guild, Java Analyzer Guild) – documenting Java lockfile ingestion plan and policy templates.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-005 added (Docs Guild, Go Analyzer Guild) – documenting Go stripped-binary fallback enrichment guidance.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-006 added (Docs Guild, Rust Analyzer Guild) – documenting Rust fingerprint enrichment guidance.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-007 added (Docs Guild, Security Guild) – documenting secret leak detection guidance.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-008 added (Docs Guild, EntryTrace Guild) – documenting EntryTrace heuristic maintenance guidance.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-009 added (Docs Guild, Ruby Analyzer Guild) – deepening Ruby gap analysis with detection tables; status set to DOING.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-010 added (Docs Guild, PHP Analyzer Guild) – documenting PHP analyzer parity gaps; status set to DOING.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-011 added (Docs Guild, Language Analyzer Guild) – capturing Deno runtime gap analysis; status set to DOING.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-012 added (Docs Guild, Language Analyzer Guild) – expanding Dart ecosystem comparison; status set to DOING.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-013 added (Docs Guild, Swift Analyzer Guild) – expanding Swift coverage analysis; status set to DOING.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-014 added (Docs Guild, Runtime Guild) – detailing Kubernetes/VM coverage plan; status set to DOING.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-015 added (Docs Guild, Export Center Guild) – outlining DSSE/Rekor operator enablement guidance; status set to DOING.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-009 marked DONE (Docs Guild, Ruby Analyzer Guild) – Ruby gap section delivered with detection tables and backlog links.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-010 marked DONE (Docs Guild, PHP Analyzer Guild) – PHP gap analysis updated with implementation notes.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-011 marked DONE (Docs Guild, Language Analyzer Guild) – Deno plan documented with detection technique table.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-012 marked DONE (Docs Guild, Language Analyzer Guild) – Dart coverage section fleshed out with detection strategies.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-013 marked DONE (Docs Guild, Swift Analyzer Guild) – Swift analyzer roadmap captured with policy hooks.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-014 marked DONE (Docs Guild, Runtime Guild) – Kubernetes/VM alignment section published.
|
||||
> 2025-11-02: DOCS-SCANNER-BENCH-62-015 marked DONE (Docs Guild, Export Center Guild) – DSSE/Rekor enablement guidance appended to gap doc.
|
||||
> 2025-11-02: SCANNER-ENG-0009 moved to DOING (Ruby Analyzer Guild) – drafting Ruby analyzer parity design package.
|
||||
> 2025-11-02: SCANNER-ENG-0016 added (Ruby Analyzer Guild) – implementing Ruby lock collector & vendor cache ingestion.
|
||||
> 2025-11-02: SCANNER-ENG-0016 moved to DOING (Ruby Analyzer Guild) – lockfile parser skeleton committed with initial Gemfile.lock parsing.
|
||||
> 2025-11-02: SCANNER-ENG-0017 added (Ruby Analyzer Guild) – building runtime require/autoload graph builder.
|
||||
> 2025-11-02: SCANNER-ENG-0018 added (Ruby Analyzer Guild) – emitting Ruby capability and framework signals.
|
||||
> 2025-11-02: SCANNER-ENG-0019 added (Ruby Analyzer Guild, CLI Guild) – delivering Ruby CLI verbs and Offline Kit packaging.
|
||||
> 2025-11-02: SCANNER-LIC-0001 added (Scanner Guild, Legal Guild) – vetting tree-sitter Ruby licensing/offline packaging.
|
||||
> 2025-11-02: SCANNER-LIC-0001 moved to DOING (Scanner Guild, Legal Guild) – SPDX review in progress.
|
||||
> 2025-11-02: SCANNER-POLICY-0001 added (Policy Guild, Ruby Analyzer Guild) – defining Ruby capability predicates in Policy Engine.
|
||||
> 2025-11-02: SCANNER-CLI-0001 added (CLI Guild, Ruby Analyzer Guild) – coordinating CLI UX/docs for Ruby verbs.
|
||||
> 2025-11-02: AIAI-31-011 moved to DOING (Advisory AI Guild) – implementing Excititor VEX document provider.
|
||||
> 2025-11-02: AIAI-31-011 marked DONE (Advisory AI Guild) – Excititor VEX provider + OpenVEX chunking shipped with tests.
|
||||
> 2025-11-02: AIAI-31-002 moved to DOING (Advisory AI Guild, SBOM Service Guild) – building SBOM context retriever for timelines/paths/blast radius.
|
||||
> 2025-11-02: AIAI-31-002 progressing – SBOM context models/tests landed; awaiting SBOM guild client hookup.
|
||||
|
||||
> 2025-11-02: AIAI-31-003 moved to DOING – kicking off deterministic tooling (comparators, dependency lookup). First drop covers semver range evaluator + RPM EVR comparator.
|
||||
|
||||
> 2025-11-02: AIAI-31-004 moved to DOING – starting deterministic orchestration pipeline (summary/conflict/remediation flow).
|
||||
|
||||
> 2025-11-02: ISSUER-30-006 moved to DOING (Issuer Directory Guild, DevOps Guild) – deployment manifests, backup/restore, secret handling, and offline kit docs in progress.
|
||||
|
||||
@@ -24,7 +24,7 @@ This file describe implementation of Stella Ops (docs/README.md). Implementation
|
||||
| Sprint 8 | Plugin Infrastructure | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-20) | Authority Core, Plugin Platform Guild | AUTH-PLUGIN-COORD-08-002 | Coordinate scoped-service adoption for Authority plug-in registrars<br>Workshop notes and follow-up backlog captured 2025-10-20 in `docs/dev/authority-plugin-di-coordination.md`. |
|
||||
| Sprint 9 | Scanner Core Foundations | src/Scanner/StellaOps.Scanner.WebService/TASKS.md | DONE (2025-10-19) | Team Scanner WebService | SCANNER-WEB-09-103 | Progress streaming (SSE/JSONL) with correlation IDs and ISO-8601 UTC timestamps, documented in API reference. |
|
||||
| Sprint 9 | Scanner Core Foundations | src/Scanner/StellaOps.Scanner.WebService/TASKS.md | DONE (2025-10-19) | Team Scanner WebService | SCANNER-POLICY-09-105 | Policy snapshot loader + schema + OpenAPI (YAML ignore rules, VEX include/exclude, vendor precedence). |
|
||||
| Sprint 9 | Scanner Core Foundations | src/Scanner/StellaOps.Scanner.WebService/TASKS.md | DONE (2025-10-19) | Team Scanner WebService | SCANNER-POLICY-09-106 | `/reports` verdict assembly (Feedser+Vexer+Policy) + signed response envelope. |
|
||||
| Sprint 9 | Scanner Core Foundations | src/Scanner/StellaOps.Scanner.WebService/TASKS.md | DONE (2025-10-19) | Team Scanner WebService | SCANNER-POLICY-09-106 | `/reports` verdict assembly (Conselier+Excitor+Policy) + signed response envelope. |
|
||||
| Sprint 9 | Scanner Core Foundations | src/Scanner/StellaOps.Scanner.WebService/TASKS.md | DONE (2025-10-19) | Team Scanner WebService | SCANNER-POLICY-09-107 | Expose score inputs, config version, and quiet provenance in `/reports` JSON and signed payload. |
|
||||
| Sprint 9 | DevOps Foundations | ops/devops/TASKS.md | DONE (2025-10-21) | DevOps Guild, Scanner WebService Guild | DEVOPS-SCANNER-09-204 | Surface `SCANNER__EVENTS__*` env config across Compose/Helm and document overrides. |
|
||||
| Sprint 9 | DevOps Foundations | ops/devops/TASKS.md | DONE (2025-10-21) | DevOps Guild, Notify Guild | DEVOPS-SCANNER-09-205 | Notify smoke job validates Redis stream + Notify deliveries after staging deploys. |
|
||||
|
||||
@@ -20,7 +20,7 @@ This file describe implementation of Stella Ops (docs/README.md). Implementation
|
||||
| Sprint 12 | Runtime Guardrails | src/Zastava/StellaOps.Zastava.Webhook/TASKS.md | DONE (2025-10-24) | Zastava Webhook Guild | ZASTAVA-WEBHOOK-12-103 | Caching, fail-open/closed toggles, metrics/logging for admission decisions. |
|
||||
| Sprint 12 | Runtime Guardrails | src/Zastava/StellaOps.Zastava.Webhook/TASKS.md | DONE (2025-10-24) | Zastava Webhook Guild | ZASTAVA-WEBHOOK-12-104 | Wire `/admission` endpoint to runtime policy client and emit allow/deny envelopes. |
|
||||
| Sprint 12 | Runtime Guardrails | src/Scanner/StellaOps.Scanner.WebService/TASKS.md | DONE (2025-10-24) | Scanner WebService Guild | SCANNER-RUNTIME-12-302 | `/policy/runtime` endpoint joining SBOM baseline + policy verdict, returning admission guidance. |
|
||||
| Sprint 12 | Runtime Guardrails | src/Scanner/StellaOps.Scanner.WebService/TASKS.md | DONE (2025-10-24) | Scanner WebService Guild | SCANNER-RUNTIME-12-303 | Align `/policy/runtime` verdicts with canonical policy evaluation (Feedser/Vexer). |
|
||||
| Sprint 12 | Runtime Guardrails | src/Scanner/StellaOps.Scanner.WebService/TASKS.md | DONE (2025-10-24) | Scanner WebService Guild | SCANNER-RUNTIME-12-303 | Align `/policy/runtime` verdicts with canonical policy evaluation (Conselier/Excitor). |
|
||||
| Sprint 12 | Runtime Guardrails | src/Scanner/StellaOps.Scanner.WebService/TASKS.md | DONE (2025-10-24) | Scanner WebService Guild | SCANNER-RUNTIME-12-304 | Integrate attestation verification into runtime policy metadata. |
|
||||
| Sprint 12 | Runtime Guardrails | src/Scanner/StellaOps.Scanner.WebService/TASKS.md | DONE (2025-10-24) | Scanner WebService Guild | SCANNER-RUNTIME-12-305 | Deliver shared fixtures + e2e validation with Zastava/CLI teams. |
|
||||
| Sprint 13 | UX & CLI Experience | src/UI/StellaOps.UI/TASKS.md | DONE (2025-10-23) | UI Guild | UI-AUTH-13-001 | Integrate Authority OIDC + DPoP flows with session management. |
|
||||
|
||||
@@ -1,84 +1,84 @@
|
||||
This file describe implementation of Stella Ops (docs/README.md). Implementation must respect rules from AGENTS.md (read if you have not).
|
||||
|
||||
| Sprint | Theme | Tasks File Path | Status | Type of Specialist | Task ID | Task Description |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| Sprint 13 | Platform Reliability | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-NUGET-13-002 | Ensure all solutions/projects prioritize `local-nuget` before public feeds and add restore-order validation. |
|
||||
| Sprint 13 | Platform Reliability | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild, Platform Leads | DEVOPS-NUGET-13-003 | Upgrade `Microsoft.*` dependencies pinned to 8.* to their latest .NET 10 (or 9.x) releases and refresh guidance. |
|
||||
| Sprint 14 | Release & Offline Ops | ops/deployment/TASKS.md | DONE (2025-10-26) | Deployment Guild | DEVOPS-OPS-14-003 | Deployment/update/rollback automation and channel management documentation. |
|
||||
| Sprint 14 | Release & Offline Ops | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-REL-14-001 | Deterministic build/release pipeline with SBOM/provenance, signing, and manifest generation. |
|
||||
| Sprint 14 | Release & Offline Ops | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild, Scanner Guild | DEVOPS-REL-14-004 | Extend release/offline smoke jobs to cover Python analyzer plug-ins (warm/cold, determinism, signing). |
|
||||
| Sprint 14 | Release & Offline Ops | ops/licensing/TASKS.md | DONE (2025-10-26) | Licensing Guild | DEVOPS-LIC-14-004 | Registry token service tied to Authority, plan gating, revocation handling, monitoring. |
|
||||
| Sprint 14 | Release & Offline Ops | ops/offline-kit/TASKS.md | DONE (2025-10-26) | Offline Kit Guild | DEVOPS-OFFLINE-14-002 | Offline kit packaging workflow with integrity verification and documentation. |
|
||||
| Sprint 15 | Benchmarks | src/Bench/StellaOps.Bench/TASKS.md | DONE (2025-10-26) | Bench Guild, Notify Team | BENCH-NOTIFY-15-001 | Notify dispatch throughput bench with results CSV. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/TASKS.md | DONE (2025-10-19) | Scheduler Models Guild | SCHED-MODELS-16-101 | Define Scheduler DTOs & validation. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/TASKS.md | DONE (2025-10-19) | Scheduler Models Guild | SCHED-MODELS-16-102 | Publish schema docs/sample payloads. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.Storage.Mongo/TASKS.md | DONE (2025-10-19) | Scheduler Storage Guild | SCHED-STORAGE-16-201 | Mongo schemas/indexes for Scheduler state. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.Storage.Mongo/TASKS.md | DONE (2025-10-26) | Scheduler Storage Guild | SCHED-STORAGE-16-202 | Repositories with tenant scoping, TTL, causal consistency. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.Storage.Mongo/TASKS.md | DONE (2025-10-26) | Scheduler Storage Guild | SCHED-STORAGE-16-203 | Audit/run stats materialization for UI. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.ImpactIndex/TASKS.md | DONE (2025-10-26) | Scheduler ImpactIndex Guild | SCHED-IMPACT-16-302 | Query APIs for ResolveByPurls/ResolveByVulns/ResolveAll. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.ImpactIndex/TASKS.md | DONE (2025-10-26) | Scheduler ImpactIndex Guild | SCHED-IMPACT-16-301 | Ingest BOM-Index into roaring bitmap store. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-26) | Scheduler WebService Guild | SCHED-WEB-16-102 | Schedules CRUD (cron validation, pause/resume, audit). |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-26) | Scheduler WebService Guild | SCHED-WEB-16-103 | Runs API (list/detail/cancel) + impact previews. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-27) | Scheduler WebService Guild | SCHED-WEB-16-104 | Feedser/Vexer webhook handlers with security enforcement. |
|
||||
| Sprint 17 | Symbol Intelligence & Forensics | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-RUNTIME-17-004 | Document build-id workflows for SBOMs, runtime events, and debug-store usage. |
|
||||
| Sprint 17 | Symbol Intelligence & Forensics | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-REL-17-002 | Ship stripped debug artifacts organised by build-id within release/offline kits. |
|
||||
| Sprint 17 | Symbol Intelligence & Forensics | ops/offline-kit/TASKS.md | DONE (2025-10-26) | Offline Kit Guild, DevOps Guild | DEVOPS-OFFLINE-17-003 | Mirror release debug-store artefacts into Offline Kit packaging and document validation. |
|
||||
| Sprint 17 | Symbol Intelligence & Forensics | src/Scanner/__Libraries/StellaOps.Scanner.Emit/TASKS.md | DONE (2025-10-26) | Emit Guild | SCANNER-EMIT-17-701 | Record GNU build-id for ELF components and surface it in SBOM/diff outputs. |
|
||||
| Sprint 18 | Launch Readiness | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-LAUNCH-18-001 | Production launch cutover rehearsal and runbook publication. |
|
||||
| Sprint 18 | Launch Readiness | ops/offline-kit/TASKS.md | DONE (2025-10-26) | Offline Kit Guild, Scanner Guild | DEVOPS-OFFLINE-18-005 | Rebuild Offline Kit with Python analyzer artefacts and refreshed manifest/signature pair. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-AOC-19-001 | Publish aggregation-only contract reference documentation. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Architecture Guild | DOCS-AOC-19-002 | Update architecture overview with AOC boundary diagrams. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Policy Guild | DOCS-AOC-19-003 | Refresh policy engine doc with raw ingestion constraints. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, UI Guild | DOCS-AOC-19-004 | Document console AOC dashboard and drill-down flow. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, CLI Guild | DOCS-AOC-19-005 | Document CLI AOC commands and exit codes. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Observability Guild | DOCS-AOC-19-006 | Document new AOC metrics, traces, and logs. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Authority Core | DOCS-AOC-19-007 | Document new Authority scopes and tenancy enforcement. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, DevOps Guild | DOCS-AOC-19-008 | Update deployment guide with validator enablement and verify user guidance. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core & Security Guild | AUTH-AOC-19-001 | Introduce new ingestion/auth scopes across Authority. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-POLICY-20-001 | Publish `/docs/policy/overview.md` with compliance checklist. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-POLICY-20-002 | Document DSL grammar + examples in `/docs/policy/dsl.md`. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Authority Core | DOCS-POLICY-20-003 | Write `/docs/policy/lifecycle.md` covering workflow + roles. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Scheduler Guild | DOCS-POLICY-20-004 | Document policy run modes + cursors in `/docs/policy/runs.md`. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Platform Guild | DOCS-POLICY-20-005 | Produce `/docs/api/policy.md` with endpoint schemas + errors. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, CLI Guild | DOCS-POLICY-20-006 | Author `/docs/modules/cli/guides/policy.md` with commands, exit codes, JSON output. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, UI Guild | DOCS-POLICY-20-007 | Create `/docs/ui/policy-editor.md` covering editor, simulation, approvals. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Architecture Guild | DOCS-POLICY-20-008 | Publish `/docs/modules/policy/architecture.md` with sequence diagrams. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Observability Guild | DOCS-POLICY-20-009 | Document metrics/traces/logs in `/docs/observability/policy.md`. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Security Guild | DOCS-POLICY-20-010 | Publish `/docs/security/policy-governance.md` for scopes + approvals. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Policy Guild | DOCS-POLICY-20-011 | Add example policies under `/docs/examples/policies/` with commentary. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Support Guild | DOCS-POLICY-20-012 | Draft `/docs/faq/policy-faq.md` covering conflicts, determinism, pitfalls. |
|
||||
| Sprint 20 | Policy Engine v2 | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-POLICY-20-001 | Add DSL lint + compile checks to CI pipelines. |
|
||||
| Sprint 20 | Policy Engine v2 | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild, QA Guild | DEVOPS-POLICY-20-003 | Add determinism CI job diffing repeated policy runs. |
|
||||
| Sprint 20 | Policy Engine v2 | samples/TASKS.md | DONE (2025-10-26) | Samples Guild, Policy Guild | SAMPLES-POLICY-20-001 | Commit baseline/serverless/internal-only policy samples + fixtures. |
|
||||
| Sprint 20 | Policy Engine v2 | samples/TASKS.md | DONE (2025-10-26) | Samples Guild, UI Guild | SAMPLES-POLICY-20-002 | Produce simulation diff fixtures for UI/CLI tests. |
|
||||
| Sprint 20 | Policy Engine v2 | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core & Security Guild | AUTH-POLICY-20-001 | Add new policy scopes (`policy:*`, `findings:read`, `effective:write`). |
|
||||
| Sprint 20 | Policy Engine v2 | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core & Security Guild | AUTH-POLICY-20-002 | Enforce Policy Engine service identity and scope checks at gateway. |
|
||||
| Sprint 20 | Policy Engine v2 | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core & Docs Guild | AUTH-POLICY-20-003 | Update Authority docs/config samples for policy scopes + workflows. |
|
||||
| Sprint 20 | Policy Engine v2 | src/Bench/StellaOps.Bench/TASKS.md | DONE (2025-10-26) | Bench Guild, Policy Guild | BENCH-POLICY-20-001 | Create policy evaluation benchmark suite + baseline metrics. |
|
||||
| Sprint 20 | Policy Engine v2 | src/Policy/StellaOps.Policy.Engine/TASKS.md | DONE (2025-10-26) | Policy Guild, Platform Guild | POLICY-ENGINE-20-000 | Spin up new Policy Engine service host with DI bootstrap and Authority wiring. |
|
||||
| Sprint 20 | Policy Engine v2 | src/Policy/StellaOps.Policy.Engine/TASKS.md | DONE (2025-10-26) | Policy Guild | POLICY-ENGINE-20-001 | Deliver `stella-dsl@1` parser + IR compiler with diagnostics and checksums. |
|
||||
| Sprint 20 | Policy Engine v2 | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/TASKS.md | DONE (2025-10-26) | Scheduler Models Guild | SCHED-MODELS-20-001 | Define policy run/diff DTOs + validation helpers. |
|
||||
| Sprint 21 | Graph Explorer v1 | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core Guild | AUTH-GRAPH-21-001 | Introduce graph scopes (`graph:*`) with configuration binding and defaults. |
|
||||
| Sprint 21 | Graph Explorer v1 | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core Guild | AUTH-GRAPH-21-002 | Enforce graph scopes/identities at gateway with tenant propagation. |
|
||||
| Sprint 21 | Graph Explorer v1 | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core & Docs Guild | AUTH-GRAPH-21-003 | Update security docs/config samples for graph access and least privilege. |
|
||||
| Sprint 21 | Graph Explorer v1 | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/TASKS.md | DONE (2025-10-26) | Scheduler Models Guild | SCHED-MODELS-21-001 | Define job DTOs for graph builds/overlay refresh (`GraphBuildJob`, `GraphOverlayJob`) with deterministic serialization and status enums; document in `src/Scheduler/__Libraries/StellaOps.Scheduler.Models/docs/SCHED-MODELS-21-001-GRAPH-JOBS.md`. |
|
||||
| Sprint 21 | Graph Explorer v1 | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/TASKS.md | DONE (2025-10-26) | Scheduler Models Guild | SCHED-MODELS-21-002 | Publish schema docs/sample payloads for graph job lifecycle. |
|
||||
| Sprint 22 | Link-Not-Merge v1 | src/Bench/StellaOps.Bench/TASKS.md | DONE (2025-10-26) | Bench Guild | BENCH-LNM-22-001 | Benchmark advisory observation ingest/correlation throughput. |
|
||||
| Sprint 22 | Link-Not-Merge v1 | src/Bench/StellaOps.Bench/TASKS.md | DONE (2025-10-26) | Bench Guild | BENCH-LNM-22-002 | Benchmark VEX ingest/correlation latency and event emission. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-001 | Publish `/docs/ui/console-overview.md` (IA, tenant model, filters, AOC alignment). |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-002 | Author `/docs/ui/navigation.md` with route map, filters, keyboard shortcuts, deep links. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-003 | Document `/docs/ui/sbom-explorer.md` covering catalog, graph, overlays, exports. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-004 | Produce `/docs/ui/advisories-and-vex.md` detailing aggregation-not-merge UX. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-005 | Write `/docs/ui/findings.md` with filters, explain, exports, CLI parity notes. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-006 | Publish `/docs/ui/policies.md` (editor, simulation, approvals, RBAC). |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-007 | Document `/docs/ui/runs.md` with SSE monitoring, diff, retries, evidence downloads. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-008 | Draft `/docs/ui/admin.md` covering tenants, roles, tokens, integrations, fresh-auth. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-27) | Docs Guild | DOCS-CONSOLE-23-009 | Publish `/docs/ui/downloads.md` aligning manifest with commands and offline flow. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-27) | Docs Guild, Deployment Guild, Console Guild | DOCS-CONSOLE-23-010 | Write `/docs/deploy/console.md` (Helm, ingress, TLS, env vars, health checks). |
|
||||
| Sprint 28 | Graph Explorer | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-26) | Scheduler WebService Guild | SCHED-WEB-21-001 | Provide graph build/overlay job APIs; see `docs/SCHED-WEB-21-001-GRAPH-APIS.md`. |
|
||||
| Sprint 28 | Graph Explorer | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-26) | Scheduler WebService Guild | SCHED-WEB-21-002 | Provide overlay lag metrics endpoint/webhook; see `docs/SCHED-WEB-21-001-GRAPH-APIS.md`. |
|
||||
| Sprint 28 | Graph Explorer | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-26) | Scheduler WebService Guild, Authority Core Guild | SCHED-WEB-21-003 | Replace header auth with Authority scopes using `StellaOpsScopes`; dev fallback only when `Scheduler:Authority:Enabled=false`. |
|
||||
| Sprint 50 | Observability & Forensics Phase 1 – Baseline Telemetry | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-OBS-50-001 | Deploy default OpenTelemetry collector manifests with secure OTLP pipeline. |
|
||||
| Sprint 50 | Observability & Forensics Phase 1 – Baseline Telemetry | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-OBS-50-003 | Package telemetry stack configs for offline/air-gapped installs with signatures. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-27) | Scheduler WebService Guild | SCHED-WEB-16-101 | Minimal API host with Authority enforcement. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.Worker/TASKS.md | DONE (2025-10-27) | Scheduler Worker Guild | SCHED-WORKER-16-202 | ImpactIndex targeting and shard planning. |
|
||||
This file describe implementation of Stella Ops (docs/README.md). Implementation must respect rules from AGENTS.md (read if you have not).
|
||||
|
||||
| Sprint | Theme | Tasks File Path | Status | Type of Specialist | Task ID | Task Description |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| Sprint 13 | Platform Reliability | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-NUGET-13-002 | Ensure all solutions/projects prioritize `local-nuget` before public feeds and add restore-order validation. |
|
||||
| Sprint 13 | Platform Reliability | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild, Platform Leads | DEVOPS-NUGET-13-003 | Upgrade `Microsoft.*` dependencies pinned to 8.* to their latest .NET 10 (or 9.x) releases and refresh guidance. |
|
||||
| Sprint 14 | Release & Offline Ops | ops/deployment/TASKS.md | DONE (2025-10-26) | Deployment Guild | DEVOPS-OPS-14-003 | Deployment/update/rollback automation and channel management documentation. |
|
||||
| Sprint 14 | Release & Offline Ops | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-REL-14-001 | Deterministic build/release pipeline with SBOM/provenance, signing, and manifest generation. |
|
||||
| Sprint 14 | Release & Offline Ops | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild, Scanner Guild | DEVOPS-REL-14-004 | Extend release/offline smoke jobs to cover Python analyzer plug-ins (warm/cold, determinism, signing). |
|
||||
| Sprint 14 | Release & Offline Ops | ops/licensing/TASKS.md | DONE (2025-10-26) | Licensing Guild | DEVOPS-LIC-14-004 | Registry token service tied to Authority, plan gating, revocation handling, monitoring. |
|
||||
| Sprint 14 | Release & Offline Ops | ops/offline-kit/TASKS.md | DONE (2025-10-26) | Offline Kit Guild | DEVOPS-OFFLINE-14-002 | Offline kit packaging workflow with integrity verification and documentation. |
|
||||
| Sprint 15 | Benchmarks | src/Bench/StellaOps.Bench/TASKS.md | DONE (2025-10-26) | Bench Guild, Notify Team | BENCH-NOTIFY-15-001 | Notify dispatch throughput bench with results CSV. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/TASKS.md | DONE (2025-10-19) | Scheduler Models Guild | SCHED-MODELS-16-101 | Define Scheduler DTOs & validation. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/TASKS.md | DONE (2025-10-19) | Scheduler Models Guild | SCHED-MODELS-16-102 | Publish schema docs/sample payloads. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.Storage.Mongo/TASKS.md | DONE (2025-10-19) | Scheduler Storage Guild | SCHED-STORAGE-16-201 | Mongo schemas/indexes for Scheduler state. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.Storage.Mongo/TASKS.md | DONE (2025-10-26) | Scheduler Storage Guild | SCHED-STORAGE-16-202 | Repositories with tenant scoping, TTL, causal consistency. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.Storage.Mongo/TASKS.md | DONE (2025-10-26) | Scheduler Storage Guild | SCHED-STORAGE-16-203 | Audit/run stats materialization for UI. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.ImpactIndex/TASKS.md | DONE (2025-10-26) | Scheduler ImpactIndex Guild | SCHED-IMPACT-16-302 | Query APIs for ResolveByPurls/ResolveByVulns/ResolveAll. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.ImpactIndex/TASKS.md | DONE (2025-10-26) | Scheduler ImpactIndex Guild | SCHED-IMPACT-16-301 | Ingest BOM-Index into roaring bitmap store. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-26) | Scheduler WebService Guild | SCHED-WEB-16-102 | Schedules CRUD (cron validation, pause/resume, audit). |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-26) | Scheduler WebService Guild | SCHED-WEB-16-103 | Runs API (list/detail/cancel) + impact previews. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-27) | Scheduler WebService Guild | SCHED-WEB-16-104 | Conselier/Excitor webhook handlers with security enforcement. |
|
||||
| Sprint 17 | Symbol Intelligence & Forensics | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-RUNTIME-17-004 | Document build-id workflows for SBOMs, runtime events, and debug-store usage. |
|
||||
| Sprint 17 | Symbol Intelligence & Forensics | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-REL-17-002 | Ship stripped debug artifacts organised by build-id within release/offline kits. |
|
||||
| Sprint 17 | Symbol Intelligence & Forensics | ops/offline-kit/TASKS.md | DONE (2025-10-26) | Offline Kit Guild, DevOps Guild | DEVOPS-OFFLINE-17-003 | Mirror release debug-store artefacts into Offline Kit packaging and document validation. |
|
||||
| Sprint 17 | Symbol Intelligence & Forensics | src/Scanner/__Libraries/StellaOps.Scanner.Emit/TASKS.md | DONE (2025-10-26) | Emit Guild | SCANNER-EMIT-17-701 | Record GNU build-id for ELF components and surface it in SBOM/diff outputs. |
|
||||
| Sprint 18 | Launch Readiness | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-LAUNCH-18-001 | Production launch cutover rehearsal and runbook publication. |
|
||||
| Sprint 18 | Launch Readiness | ops/offline-kit/TASKS.md | DONE (2025-10-26) | Offline Kit Guild, Scanner Guild | DEVOPS-OFFLINE-18-005 | Rebuild Offline Kit with Python analyzer artefacts and refreshed manifest/signature pair. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-AOC-19-001 | Publish aggregation-only contract reference documentation. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Architecture Guild | DOCS-AOC-19-002 | Update architecture overview with AOC boundary diagrams. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Policy Guild | DOCS-AOC-19-003 | Refresh policy engine doc with raw ingestion constraints. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, UI Guild | DOCS-AOC-19-004 | Document console AOC dashboard and drill-down flow. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, CLI Guild | DOCS-AOC-19-005 | Document CLI AOC commands and exit codes. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Observability Guild | DOCS-AOC-19-006 | Document new AOC metrics, traces, and logs. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Authority Core | DOCS-AOC-19-007 | Document new Authority scopes and tenancy enforcement. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, DevOps Guild | DOCS-AOC-19-008 | Update deployment guide with validator enablement and verify user guidance. |
|
||||
| Sprint 19 | Aggregation-Only Contract Enforcement | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core & Security Guild | AUTH-AOC-19-001 | Introduce new ingestion/auth scopes across Authority. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-POLICY-20-001 | Publish `/docs/policy/overview.md` with compliance checklist. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-POLICY-20-002 | Document DSL grammar + examples in `/docs/policy/dsl.md`. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Authority Core | DOCS-POLICY-20-003 | Write `/docs/policy/lifecycle.md` covering workflow + roles. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Scheduler Guild | DOCS-POLICY-20-004 | Document policy run modes + cursors in `/docs/policy/runs.md`. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Platform Guild | DOCS-POLICY-20-005 | Produce `/docs/api/policy.md` with endpoint schemas + errors. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, CLI Guild | DOCS-POLICY-20-006 | Author `/docs/modules/cli/guides/policy.md` with commands, exit codes, JSON output. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, UI Guild | DOCS-POLICY-20-007 | Create `/docs/ui/policy-editor.md` covering editor, simulation, approvals. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Architecture Guild | DOCS-POLICY-20-008 | Publish `/docs/modules/policy/architecture.md` with sequence diagrams. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Observability Guild | DOCS-POLICY-20-009 | Document metrics/traces/logs in `/docs/observability/policy.md`. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Security Guild | DOCS-POLICY-20-010 | Publish `/docs/security/policy-governance.md` for scopes + approvals. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Policy Guild | DOCS-POLICY-20-011 | Add example policies under `/docs/examples/policies/` with commentary. |
|
||||
| Sprint 20 | Policy Engine v2 | docs/TASKS.md | DONE (2025-10-26) | Docs Guild, Support Guild | DOCS-POLICY-20-012 | Draft `/docs/faq/policy-faq.md` covering conflicts, determinism, pitfalls. |
|
||||
| Sprint 20 | Policy Engine v2 | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-POLICY-20-001 | Add DSL lint + compile checks to CI pipelines. |
|
||||
| Sprint 20 | Policy Engine v2 | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild, QA Guild | DEVOPS-POLICY-20-003 | Add determinism CI job diffing repeated policy runs. |
|
||||
| Sprint 20 | Policy Engine v2 | samples/TASKS.md | DONE (2025-10-26) | Samples Guild, Policy Guild | SAMPLES-POLICY-20-001 | Commit baseline/serverless/internal-only policy samples + fixtures. |
|
||||
| Sprint 20 | Policy Engine v2 | samples/TASKS.md | DONE (2025-10-26) | Samples Guild, UI Guild | SAMPLES-POLICY-20-002 | Produce simulation diff fixtures for UI/CLI tests. |
|
||||
| Sprint 20 | Policy Engine v2 | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core & Security Guild | AUTH-POLICY-20-001 | Add new policy scopes (`policy:*`, `findings:read`, `effective:write`). |
|
||||
| Sprint 20 | Policy Engine v2 | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core & Security Guild | AUTH-POLICY-20-002 | Enforce Policy Engine service identity and scope checks at gateway. |
|
||||
| Sprint 20 | Policy Engine v2 | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core & Docs Guild | AUTH-POLICY-20-003 | Update Authority docs/config samples for policy scopes + workflows. |
|
||||
| Sprint 20 | Policy Engine v2 | src/Bench/StellaOps.Bench/TASKS.md | DONE (2025-10-26) | Bench Guild, Policy Guild | BENCH-POLICY-20-001 | Create policy evaluation benchmark suite + baseline metrics. |
|
||||
| Sprint 20 | Policy Engine v2 | src/Policy/StellaOps.Policy.Engine/TASKS.md | DONE (2025-10-26) | Policy Guild, Platform Guild | POLICY-ENGINE-20-000 | Spin up new Policy Engine service host with DI bootstrap and Authority wiring. |
|
||||
| Sprint 20 | Policy Engine v2 | src/Policy/StellaOps.Policy.Engine/TASKS.md | DONE (2025-10-26) | Policy Guild | POLICY-ENGINE-20-001 | Deliver `stella-dsl@1` parser + IR compiler with diagnostics and checksums. |
|
||||
| Sprint 20 | Policy Engine v2 | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/TASKS.md | DONE (2025-10-26) | Scheduler Models Guild | SCHED-MODELS-20-001 | Define policy run/diff DTOs + validation helpers. |
|
||||
| Sprint 21 | Graph Explorer v1 | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core Guild | AUTH-GRAPH-21-001 | Introduce graph scopes (`graph:*`) with configuration binding and defaults. |
|
||||
| Sprint 21 | Graph Explorer v1 | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core Guild | AUTH-GRAPH-21-002 | Enforce graph scopes/identities at gateway with tenant propagation. |
|
||||
| Sprint 21 | Graph Explorer v1 | src/Authority/StellaOps.Authority/TASKS.md | DONE (2025-10-26) | Authority Core & Docs Guild | AUTH-GRAPH-21-003 | Update security docs/config samples for graph access and least privilege. |
|
||||
| Sprint 21 | Graph Explorer v1 | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/TASKS.md | DONE (2025-10-26) | Scheduler Models Guild | SCHED-MODELS-21-001 | Define job DTOs for graph builds/overlay refresh (`GraphBuildJob`, `GraphOverlayJob`) with deterministic serialization and status enums; document in `src/Scheduler/__Libraries/StellaOps.Scheduler.Models/docs/SCHED-MODELS-21-001-GRAPH-JOBS.md`. |
|
||||
| Sprint 21 | Graph Explorer v1 | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/TASKS.md | DONE (2025-10-26) | Scheduler Models Guild | SCHED-MODELS-21-002 | Publish schema docs/sample payloads for graph job lifecycle. |
|
||||
| Sprint 22 | Link-Not-Merge v1 | src/Bench/StellaOps.Bench/TASKS.md | DONE (2025-10-26) | Bench Guild | BENCH-LNM-22-001 | Benchmark advisory observation ingest/correlation throughput. |
|
||||
| Sprint 22 | Link-Not-Merge v1 | src/Bench/StellaOps.Bench/TASKS.md | DONE (2025-10-26) | Bench Guild | BENCH-LNM-22-002 | Benchmark VEX ingest/correlation latency and event emission. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-001 | Publish `/docs/ui/console-overview.md` (IA, tenant model, filters, AOC alignment). |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-002 | Author `/docs/ui/navigation.md` with route map, filters, keyboard shortcuts, deep links. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-003 | Document `/docs/ui/sbom-explorer.md` covering catalog, graph, overlays, exports. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-004 | Produce `/docs/ui/advisories-and-vex.md` detailing aggregation-not-merge UX. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-005 | Write `/docs/ui/findings.md` with filters, explain, exports, CLI parity notes. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-006 | Publish `/docs/ui/policies.md` (editor, simulation, approvals, RBAC). |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-007 | Document `/docs/ui/runs.md` with SSE monitoring, diff, retries, evidence downloads. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-26) | Docs Guild | DOCS-CONSOLE-23-008 | Draft `/docs/ui/admin.md` covering tenants, roles, tokens, integrations, fresh-auth. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-27) | Docs Guild | DOCS-CONSOLE-23-009 | Publish `/docs/ui/downloads.md` aligning manifest with commands and offline flow. |
|
||||
| Sprint 23 | StellaOps Console | docs/TASKS.md | DONE (2025-10-27) | Docs Guild, Deployment Guild, Console Guild | DOCS-CONSOLE-23-010 | Write `/docs/deploy/console.md` (Helm, ingress, TLS, env vars, health checks). |
|
||||
| Sprint 28 | Graph Explorer | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-26) | Scheduler WebService Guild | SCHED-WEB-21-001 | Provide graph build/overlay job APIs; see `docs/SCHED-WEB-21-001-GRAPH-APIS.md`. |
|
||||
| Sprint 28 | Graph Explorer | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-26) | Scheduler WebService Guild | SCHED-WEB-21-002 | Provide overlay lag metrics endpoint/webhook; see `docs/SCHED-WEB-21-001-GRAPH-APIS.md`. |
|
||||
| Sprint 28 | Graph Explorer | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-26) | Scheduler WebService Guild, Authority Core Guild | SCHED-WEB-21-003 | Replace header auth with Authority scopes using `StellaOpsScopes`; dev fallback only when `Scheduler:Authority:Enabled=false`. |
|
||||
| Sprint 50 | Observability & Forensics Phase 1 – Baseline Telemetry | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-OBS-50-001 | Deploy default OpenTelemetry collector manifests with secure OTLP pipeline. |
|
||||
| Sprint 50 | Observability & Forensics Phase 1 – Baseline Telemetry | ops/devops/TASKS.md | DONE (2025-10-26) | DevOps Guild | DEVOPS-OBS-50-003 | Package telemetry stack configs for offline/air-gapped installs with signatures. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/StellaOps.Scheduler.WebService/TASKS.md | DONE (2025-10-27) | Scheduler WebService Guild | SCHED-WEB-16-101 | Minimal API host with Authority enforcement. |
|
||||
| Sprint 16 | Scheduler Intelligence | src/Scheduler/__Libraries/StellaOps.Scheduler.Worker/TASKS.md | DONE (2025-10-27) | Scheduler Worker Guild | SCHED-WORKER-16-202 | ImpactIndex targeting and shard planning. |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,6 +52,8 @@ AUTH-NOTIFY-38-001 | DONE (2025-11-01) | Define `Notify.Viewer`, `Notify.Operato
|
||||
> 2025-11-01: AUTH-NOTIFY-38-001 completed—Notify scope catalog, discovery metadata, docs, configuration samples, and service tests updated for new roles.
|
||||
AUTH-NOTIFY-40-001 | DONE (2025-11-02) | Implement signed ack token key rotation, webhook allowlists, admin-only escalation settings, and audit logging of ack actions. Dependencies: AUTH-NOTIFY-38-001, WEB-NOTIFY-40-001. | Authority Core & Security Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
> 2025-11-02: `/notify/ack-tokens/rotate` (notify.admin) now rotates DSSE keys with audit coverage and integration tests. Webhook allowlist + escalation scope enforcement verified.
|
||||
AUTH-NOTIFY-42-001 | DONE (2025-11-02) | Investigate ack token rotation 500 errors (test Rotate_ReturnsBadRequest_WhenKeyIdMissing_AndAuditsFailure still failing). Capture logs, identify root cause, and patch handler. Dependencies: AUTH-NOTIFY-40-001. | Authority Core & Security Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
> 2025-11-02: Added `StellaOpsBearer` mapping to test harness, fixed bootstrap rotate handler defaults, and reran targeted notify ack rotation test (now returning BadRequest instead of 500).
|
||||
AUTH-OAS-62-001 | DONE (2025-11-02) | Provide SDK helpers for OAuth2/PAT flows, tenancy override header; add integration tests. Dependencies: AUTH-OAS-61-001, SDKGEN-63-001. | Authority Core & Security Guild, SDK Generator Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
> 2025-11-02: Added HttpClient auth helper (OAuth2 + PAT) with tenant header support, plus coverage in `StellaOps.Auth.Client.Tests`.
|
||||
AUTH-OAS-63-001 | DONE (2025-11-02) | Emit deprecation headers and notifications for legacy auth endpoints. Dependencies: AUTH-OAS-62-001, APIGOV-63-001. | Authority Core & Security Guild, API Governance Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
@@ -77,11 +79,15 @@ Task ID | State | Task description | Owners (Source)
|
||||
--- | --- | --- | ---
|
||||
AUTH-POLICY-23-002 | BLOCKED (2025-10-29) | Implement optional two-person rule for activation: require two distinct `policy:activate` approvals when configured; emit audit logs. Dependencies: AUTH-POLICY-23-001. | Authority Core & Security Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
AUTH-POLICY-23-003 | BLOCKED (2025-10-29) | Update documentation and sample configs for policy roles, approval workflow, and signing requirements. Dependencies: AUTH-POLICY-23-001. | Authority Core & Docs Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
AUTH-POLICY-27-002 | TODO | Provide attestation signing service bindings (OIDC token exchange, cosign integration) and enforce publish/promote scope checks, fresh-auth requirements, and audit logging. Dependencies: AUTH-POLICY-27-001, REGISTRY-API-27-007. | Authority Core & Security Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
AUTH-POLICY-27-003 | TODO | Update Authority configuration/docs for Policy Studio roles, signing policies, approval workflows, and CLI integration; include compliance checklist. Dependencies: AUTH-POLICY-27-001, AUTH-POLICY-27-002. | Authority Core & Docs Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
AUTH-TEN-49-001 | TODO | Implement service accounts & delegation tokens (`act` chain), per-tenant quotas, audit stream of auth decisions, and revocation APIs. Dependencies: AUTH-TEN-47-001. | Authority Core & Security Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
AUTH-VULN-29-001 | TODO | Define Vuln Explorer scopes/roles (`vuln:view`, `vuln:investigate`, `vuln:operate`, `vuln:audit`) with ABAC attributes (env, owner, business_tier) and update discovery metadata/offline kit defaults. Dependencies: AUTH-POLICY-27-001. | Authority Core & Security Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
AUTH-VULN-29-002 | TODO | Enforce CSRF/anti-forgery tokens for workflow actions, sign attachment tokens, and record audit logs with ledger event hashes. Dependencies: AUTH-VULN-29-001, LEDGER-29-002. | Authority Core & Security Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
AUTH-POLICY-27-002 | DONE (2025-11-02) | Provide attestation signing service bindings (OIDC token exchange, cosign integration) and enforce publish/promote scope checks, fresh-auth requirements, and audit logging. Dependencies: AUTH-POLICY-27-001, REGISTRY-API-27-007. | Authority Core & Security Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
> 2025-11-02: Added interactive-only `policy:publish`/`policy:promote` scopes with metadata requirements (`policy_reason`, `policy_ticket`, `policy_digest`), fresh-auth validation, audit enrichment, and updated config/docs for operators.
|
||||
AUTH-POLICY-27-003 | DOING (2025-11-02) | Update Authority configuration/docs for Policy Studio roles, signing policies, approval workflows, and CLI integration; include compliance checklist. Dependencies: AUTH-POLICY-27-001, AUTH-POLICY-27-002. | Authority Core & Docs Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
AUTH-TEN-49-001 | DOING (2025-11-02) | Implement service accounts & delegation tokens (`act` chain), per-tenant quotas, audit stream of auth decisions, and revocation APIs. Dependencies: AUTH-TEN-47-001. | Authority Core & Security Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
> 2025-11-02: Service account store + configuration wired, delegation quotas enforced, token persistence extended with `serviceAccountId`/`tokenKind`/`actorChain`, docs & samples refreshed, and new tests cover delegated issuance/persistence.
|
||||
> 2025-11-02: Updated bootstrap test fixtures to use AuthorityDelegation seed types and verified `/internal/service-accounts` endpoints respond as expected via targeted Authority tests.
|
||||
> 2025-11-02: Documented bootstrap admin API usage (`/internal/service-accounts/**`) and clarified that repeated seeding preserves Mongo `_id`/`createdAt` values to avoid immutable field errors.
|
||||
AUTH-VULN-29-001 | DONE (2025-11-03) | Define Vuln Explorer scopes/roles (`vuln:view`, `vuln:investigate`, `vuln:operate`, `vuln:audit`) with ABAC attributes (env, owner, business_tier) and update discovery metadata/offline kit defaults. Dependencies: AUTH-POLICY-27-001. | Authority Core & Security Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
AUTH-VULN-29-002 | DOING (2025-11-03) | Enforce CSRF/anti-forgery tokens for workflow actions, sign attachment tokens, and record audit logs with ledger event hashes. Dependencies: AUTH-VULN-29-001, LEDGER-29-002. | Authority Core & Security Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
AUTH-VULN-29-003 | TODO | Update security docs/config samples for Vuln Explorer roles, ABAC policies, attachment signing, and ledger verification guidance. Dependencies: AUTH-VULN-29-001..002. | Authority Core & Docs Guild (src/Authority/StellaOps.Authority/TASKS.md)
|
||||
PLG4-6.CAPABILITIES | BLOCKED (2025-10-12) | Finalise capability metadata exposure, config validation, and developer guide updates; remaining action is Docs polish/diagram export. | BE-Auth Plugin, Docs Guild (src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Standard/TASKS.md)
|
||||
PLG6.DIAGRAM | TODO | Export final sequence/component diagrams for the developer guide and add offline-friendly assets under `docs/assets/authority`. | Docs Guild (src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Standard/TASKS.md)
|
||||
@@ -98,9 +104,9 @@ Task ID | State | Task description | Owners (Source)
|
||||
ISSUER-30-001 | DONE (2025-11-01) | Implement issuer CRUD API with RBAC, audit logging, and tenant scoping; seed CSAF publisher metadata. | Issuer Directory Guild (src/IssuerDirectory/StellaOps.IssuerDirectory/TASKS.md)
|
||||
ISSUER-30-002 | DONE (2025-11-01) | Implement key management endpoints (add/rotate/revoke keys), enforce expiry, validate formats (Ed25519, X.509, DSSE). Dependencies: ISSUER-30-001. | Issuer Directory Guild, Security Guild (src/IssuerDirectory/StellaOps.IssuerDirectory/TASKS.md)
|
||||
ISSUER-30-003 | DOING | Provide trust weight APIs and tenant overrides with validation (+/- bounds) and audit trails. Dependencies: ISSUER-30-001. | Issuer Directory Guild, Policy Guild (src/IssuerDirectory/StellaOps.IssuerDirectory/TASKS.md)
|
||||
ISSUER-30-004 | DONE (2025-11-01) | Integrate with VEX Lens and Excitator signature verification (client SDK, caching, retries). Dependencies: ISSUER-30-001..003. | Issuer Directory Guild, VEX Lens Guild (src/IssuerDirectory/StellaOps.IssuerDirectory/TASKS.md)
|
||||
ISSUER-30-004 | DONE (2025-11-01) | Integrate with VEX Lens and Excitor signature verification (client SDK, caching, retries). Dependencies: ISSUER-30-001..003. | Issuer Directory Guild, VEX Lens Guild (src/IssuerDirectory/StellaOps.IssuerDirectory/TASKS.md)
|
||||
ISSUER-30-005 | DONE (2025-11-01) | Instrument metrics/logs (issuer changes, key rotation, verification failures) and dashboards/alerts. Dependencies: ISSUER-30-001..004. | Issuer Directory Guild, Observability Guild (src/IssuerDirectory/StellaOps.IssuerDirectory/TASKS.md)
|
||||
ISSUER-30-006 | TODO | Provide deployment manifests, backup/restore, secure secret storage, and offline kit instructions. Dependencies: ISSUER-30-001..005. | Issuer Directory Guild, DevOps Guild (src/IssuerDirectory/StellaOps.IssuerDirectory/TASKS.md)
|
||||
ISSUER-30-006 | DONE (2025-11-02) | Provide deployment manifests, backup/restore, secure secret storage, and offline kit instructions. Dependencies: ISSUER-30-001..005. | Issuer Directory Guild, DevOps Guild (src/IssuerDirectory/StellaOps.IssuerDirectory/TASKS.md)
|
||||
|
||||
|
||||
[Identity & Signing] 100.D) __Libraries
|
||||
|
||||
@@ -5,17 +5,30 @@ Depends on: Sprint 100.A - Attestor
|
||||
Summary: Ingestion & Evidence focus on AdvisoryAI.
|
||||
Task ID | State | Task description | Owners (Source)
|
||||
--- | --- | --- | ---
|
||||
AIAI-31-001 | DOING (2025-11-02) | Implement structured and vector retrievers for advisories/VEX with paragraph anchors and citation metadata. Dependencies: CONCELIER-VULN-29-001, EXCITITOR-VULN-29-001. | Advisory AI Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-002 | TODO | Build SBOM context retriever (purl version timelines, dependency paths, env flags, blast radius estimator). Dependencies: SBOM-VULN-29-001. | Advisory AI Guild, SBOM Service Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-003 | TODO | Implement deterministic toolset (version comparators, range checks, dependency analysis, policy lookup) exposed via orchestrator. Dependencies: AIAI-31-001..002. | Advisory AI Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-004 | TODO | Build orchestration pipeline for Summary/Conflict/Remediation tasks (prompt templates, tool calls, token budgets, caching). Dependencies: AIAI-31-001..003, AUTH-VULN-29-001. | Advisory AI Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-001 | DONE (2025-11-02) | Implement structured and vector retrievers for advisories/VEX with paragraph anchors and citation metadata. Dependencies: CONCELIER-VULN-29-001, EXCITITOR-VULN-29-001. | Advisory AI Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-002 | DOING | Build SBOM context retriever (purl version timelines, dependency paths, env flags, blast radius estimator). Dependencies: SBOM-VULN-29-001. | Advisory AI Guild, SBOM Service Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-003 | DOING | Implement deterministic toolset (version comparators, range checks, dependency analysis, policy lookup) exposed via orchestrator. Dependencies: AIAI-31-001..002. | Advisory AI Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-004 | DOING | Build orchestration pipeline for Summary/Conflict/Remediation tasks (prompt templates, tool calls, token budgets, caching). Dependencies: AIAI-31-001..003, AUTH-VULN-29-001. | Advisory AI Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-004A | TODO | Wire orchestrator into WebService/Worker, expose API + queue contract, emit metrics, stub cache. Dependencies: AIAI-31-004, AIAI-31-002. | Advisory AI Guild, Platform Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-004B | TODO | Implement prompt assembler, guardrails, cache persistence, DSSE provenance, golden outputs. Dependencies: AIAI-31-004A, DOCS-AIAI-31-003, AUTH-AIAI-31-004. | Advisory AI Guild, Security Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-004C | TODO | Deliver CLI `stella advise run` command, renderer, docs, CLI golden tests. Dependencies: AIAI-31-004B, CLI-AIAI-31-003. | Advisory AI Guild, CLI Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-005 | TODO | Implement guardrails (redaction, injection defense, output validation, citation enforcement) and fail-safe handling. Dependencies: AIAI-31-004. | Advisory AI Guild, Security Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-006 | TODO | Expose REST API endpoints (`/advisory/ai/*`) with RBAC, rate limits, OpenAPI schemas, and batching support. Dependencies: AIAI-31-004..005. | Advisory AI Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-007 | TODO | Instrument metrics (`advisory_ai_latency`, `guardrail_blocks`, `validation_failures`, `citation_coverage`), logs, and traces; publish dashboards/alerts. Dependencies: AIAI-31-004..006. | Advisory AI Guild, Observability Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-008 | TODO | Package inference on-prem container, remote inference toggle, Helm/Compose manifests, scaling guidance, offline kit instructions. Dependencies: AIAI-31-006..007. | Advisory AI Guild, DevOps Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-010 | DONE (2025-11-02) | Implement Concelier advisory raw document provider mapping CSAF/OSV payloads into structured chunks for retrieval. Dependencies: CONCELIER-VULN-29-001, EXCITITOR-VULN-29-001. | Advisory AI Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-011 | DONE (2025-11-02) | Implement Excititor VEX document provider to surface structured VEX statements for retrieval. Dependencies: EXCITITOR-LNM-21-201, EXCITITOR-CORE-AOC-19-002. | Advisory AI Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
AIAI-31-009 | TODO | Develop unit/golden/property/perf tests, injection harness, and regression suite; ensure determinism with seeded caches. Dependencies: AIAI-31-001..006. | Advisory AI Guild, QA Guild (src/AdvisoryAI/StellaOps.AdvisoryAI/TASKS.md)
|
||||
|
||||
|
||||
|
||||
> 2025-11-02: AIAI-31-004 kicked off orchestration pipeline design – establishing deterministic task sequence (summary/conflict/remediation) and cache key strategy.
|
||||
> 2025-11-02: AIAI-31-004 orchestration prerequisites documented in docs/modules/advisory-ai/orchestration-pipeline.md (tasks 004A/004B/004C).
|
||||
> 2025-11-02: AIAI-31-003 moved to DOING – beginning deterministic tooling (comparators, dependency analysis) while awaiting SBOM context client. Semantic & EVR comparators shipped; toolset interface published for orchestrator adoption.
|
||||
> 2025-11-02: Structured + vector retrievers landed with deterministic CSAF/OSV/Markdown chunkers, deterministic hash embeddings, and unit coverage for sample advisories.
|
||||
> 2025-11-02: SBOM context request/result models finalized; retriever tests now validate environment-flag toggles and dependency-path dedupe. SBOM guild to wire real context service client.
|
||||
|
||||
|
||||
[Ingestion & Evidence] 110.B) Concelier.I
|
||||
Depends on: Sprint 100.A - Attestor
|
||||
Summary: Ingestion & Evidence focus on Concelier (phase I).
|
||||
@@ -145,7 +158,7 @@ FEEDMERGE-COORD-02-902 ICS-CISA version comparison support | BE-Merge, Models |
|
||||
FEEDMERGE-COORD-02-903 KISA firmware scheme review | BE-Merge, Models | **TODO (due 2025-10-24)** – Pair with KISA team on proposed firmware comparison helper (`kisa.build` or variant), ensure observation mapper alignment, and open Models ticket only if a new comparator is required. Log the final helper signature and observation coverage metrics in coordination docs + tracker files. Dependencies: FEEDMERGE-COORD-02-902. | FEEDMERGE-COORD-02-900 (src/Concelier/__Libraries/StellaOps.Concelier.Merge/TASKS.md)
|
||||
Fixture validation sweep | QA | **DOING (2025-10-19)** – Prereqs confirmed none; continuing RHSA fixture regeneration and diff review alongside mapper provenance updates.<br>2025-10-29: Added `scripts/update-redhat-fixtures.sh` to regenerate golden snapshots with `UPDATE_GOLDENS=1`; run it before reviews to capture CSAF contract deltas. | None (src/Concelier/__Libraries/StellaOps.Concelier.Connector.Distro.RedHat/TASKS.md)
|
||||
Link-Not-Merge version provenance coordination | BE-Merge | **DOING** – Coordinate remaining connectors (`Acsc`, `Cccs`, `CertBund`, `CertCc`, `Cve`, `Ghsa`, `Ics.Cisa`, `Kisa`, `Ru.Bdu`, `Ru.Nkcki`, `Vndr.Apple`, `Vndr.Cisco`, `Vndr.Msrc`) so they emit `advisory_observations.affected.versions[]` entries with provenance tags and deterministic comparison keys. Track rollout status in `docs/dev/normalized-rule-recipes.md` (now updated for Link-Not-Merge) and retire the legacy merge counters as coverage transitions to linkset validation metrics.<br>2025-10-29: Added new guidance in the doc for recording observation version metadata and logging gaps via `LinksetVersionCoverage` warnings to replace prior `concelier.merge.normalized_rules*` alerts. Dependencies: CONCELIER-LNM-21-203. | CONCELIER-LNM-21-001 (src/Concelier/__Libraries/StellaOps.Concelier.Merge/TASKS.md)
|
||||
MERGE-LNM-21-001 Migration plan authoring | BE-Merge, Architecture Guild | Draft `no-merge` migration playbook, documenting backfill strategy, feature flag rollout, and rollback steps for legacy merge pipeline deprecation. | CONCELIER-LNM-21-101 (src/Concelier/__Libraries/StellaOps.Concelier.Merge/TASKS.md)
|
||||
MERGE-LNM-21-001 | DONE (2025-11-03) | Draft `no-merge` migration playbook, documenting backfill strategy, feature flag rollout, and rollback steps for legacy merge pipeline deprecation.<br>2025-11-03: Authored `docs/migration/no-merge.md` covering rollout phases, backfill/validation checklists, and rollback guidance; shared artefact owners. | BE-Merge, Architecture Guild (src/Concelier/__Libraries/StellaOps.Concelier.Merge/TASKS.md)
|
||||
|
||||
|
||||
[Ingestion & Evidence] 110.B) Concelier.VII
|
||||
@@ -153,7 +166,7 @@ Depends on: Sprint 110.B - Concelier.VI
|
||||
Summary: Ingestion & Evidence focus on Concelier (phase VII).
|
||||
Task ID | State | Task description | Owners (Source)
|
||||
--- | --- | --- | ---
|
||||
MERGE-LNM-21-002 Merge service deprecation | BE-Merge | Refactor or retire `AdvisoryMergeService` and related pipelines, ensuring callers transition to observation/linkset APIs; add compile-time analyzer preventing merge service usage. Dependencies: MERGE-LNM-21-001. | MERGE-LNM-21-001 (src/Concelier/__Libraries/StellaOps.Concelier.Merge/TASKS.md)
|
||||
MERGE-LNM-21-002 | DOING (2025-11-03) | Refactor or retire `AdvisoryMergeService` and related pipelines, ensuring callers transition to observation/linkset APIs; add compile-time analyzer preventing merge service usage.<br>2025-11-03: Began dependency audit and call-site inventory ahead of deprecation plan; cataloging service registrations/tests referencing merge APIs. | BE-Merge (src/Concelier/__Libraries/StellaOps.Concelier.Merge/TASKS.md)
|
||||
MERGE-LNM-21-003 Determinism/test updates | QA Guild, BE-Merge | Replace merge determinism suites with observation/linkset regression tests verifying no data mutation and conflicts remain visible. Dependencies: MERGE-LNM-21-002. | MERGE-LNM-21-002 (src/Concelier/__Libraries/StellaOps.Concelier.Merge/TASKS.md)
|
||||
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ Depends on: Sprint 110.A - AdvisoryAI
|
||||
Summary: Policy & Reasoning focus on AirGap).
|
||||
Task ID | State | Task description | Owners (Source)
|
||||
--- | --- | --- | ---
|
||||
AIRGAP-POL-56-001 | TODO | Implement `StellaOps.AirGap.Policy` package exposing `EgressPolicy` facade with sealed/unsealed branches and remediation-friendly errors. | AirGap Policy Guild (src/AirGap/StellaOps.AirGap.Policy/TASKS.md)
|
||||
AIRGAP-POL-56-002 | TODO | Create Roslyn analyzer/code fix warning on raw `HttpClient` usage outside approved wrappers; add CI integration. Dependencies: AIRGAP-POL-56-001. | AirGap Policy Guild, DevEx Guild (src/AirGap/StellaOps.AirGap.Policy/TASKS.md)
|
||||
AIRGAP-POL-57-001 | TODO | Update core web services (Web, Exporter, Policy, Findings, Authority) to use `EgressPolicy`; ensure configuration wiring for sealed mode. Dependencies: AIRGAP-POL-56-002. | AirGap Policy Guild, BE-Base Platform Guild (src/AirGap/StellaOps.AirGap.Policy/TASKS.md)
|
||||
AIRGAP-POL-57-002 | TODO | Implement Task Runner job plan validator rejecting network steps unless marked internal allow-list. Dependencies: AIRGAP-POL-57-001. | AirGap Policy Guild, Task Runner Guild (src/AirGap/StellaOps.AirGap.Policy/TASKS.md)
|
||||
AIRGAP-POL-56-001 | DONE | Implement `StellaOps.AirGap.Policy` package exposing `EgressPolicy` facade with sealed/unsealed branches and remediation-friendly errors. | AirGap Policy Guild (src/AirGap/StellaOps.AirGap.Policy/TASKS.md)
|
||||
AIRGAP-POL-56-002 | DONE | Create Roslyn analyzer/code fix warning on raw `HttpClient` usage outside approved wrappers; add CI integration. Dependencies: AIRGAP-POL-56-001. | AirGap Policy Guild, DevEx Guild (src/AirGap/StellaOps.AirGap.Policy/TASKS.md)
|
||||
AIRGAP-POL-57-001 | DONE (2025-11-03) | Update core web services (Web, Exporter, Policy, Findings, Authority) to use `EgressPolicy`; ensure configuration wiring for sealed mode. Dependencies: AIRGAP-POL-56-002. | AirGap Policy Guild, BE-Base Platform Guild (src/AirGap/StellaOps.AirGap.Policy/TASKS.md)
|
||||
AIRGAP-POL-57-002 | DONE (2025-11-03) | Implement Task Runner job plan validator rejecting network steps unless marked internal allow-list.<br>2025-11-03: Worker wiring pulls `IEgressPolicy`, filesystem dispatcher enforces sealed-mode egress, dispatcher test + grant normalization landed, package versions aligned to rc.2.<br>Next: ensure other dispatchers/executors reuse the injected policy before enabling sealed-mode runs in worker service. Dependencies: AIRGAP-POL-57-001. | AirGap Policy Guild, Task Runner Guild (src/AirGap/StellaOps.AirGap.Policy/TASKS.md)
|
||||
AIRGAP-POL-58-001 | TODO | Ensure Observability exporters only target local endpoints in sealed mode; disable remote sinks with warning. Dependencies: AIRGAP-POL-57-002. | AirGap Policy Guild, Observability Guild (src/AirGap/StellaOps.AirGap.Policy/TASKS.md)
|
||||
AIRGAP-POL-58-002 | TODO | Add CLI sealed-mode guard that refuses commands needing egress and surfaces remediation. Dependencies: AIRGAP-POL-58-001. | AirGap Policy Guild, CLI Guild (src/AirGap/StellaOps.AirGap.Policy/TASKS.md)
|
||||
|
||||
@@ -226,7 +226,7 @@ Task ID | State | Task description | Owners (Source)
|
||||
RISK-ENGINE-66-001 | TODO | Scaffold scoring service (job queue, worker loop, provider registry) with deterministic execution harness. | Risk Engine Guild (src/RiskEngine/StellaOps.RiskEngine/TASKS.md)
|
||||
RISK-ENGINE-66-002 | TODO | Implement default transforms (linear, minmax, logistic, piecewise), clamping, gating, and contribution calculator. Dependencies: RISK-ENGINE-66-001. | Risk Engine Guild (src/RiskEngine/StellaOps.RiskEngine/TASKS.md)
|
||||
RISK-ENGINE-67-001 | TODO | Integrate CVSS and KEV providers pulling data from Conseiller; implement reducers (`max`, `any`, `consensus`). Dependencies: RISK-ENGINE-66-002. | Risk Engine Guild, Concelier Guild (src/RiskEngine/StellaOps.RiskEngine/TASKS.md)
|
||||
RISK-ENGINE-67-002 | TODO | Integrate VEX gate provider and ensure gating short-circuits scoring as configured. Dependencies: RISK-ENGINE-67-001. | Risk Engine Guild, Excitator Guild (src/RiskEngine/StellaOps.RiskEngine/TASKS.md)
|
||||
RISK-ENGINE-67-002 | TODO | Integrate VEX gate provider and ensure gating short-circuits scoring as configured. Dependencies: RISK-ENGINE-67-001. | Risk Engine Guild, Excitor Guild (src/RiskEngine/StellaOps.RiskEngine/TASKS.md)
|
||||
RISK-ENGINE-67-003 | TODO | Add fix availability, asset criticality, and internet exposure providers with caching + TTL enforcement. Dependencies: RISK-ENGINE-67-002. | Risk Engine Guild, Policy Engine Guild (src/RiskEngine/StellaOps.RiskEngine/TASKS.md)
|
||||
RISK-ENGINE-68-001 | TODO | Persist scoring results + explanation pointers to Findings Ledger; handle incremental updates via input hash. Dependencies: RISK-ENGINE-67-003. | Risk Engine Guild, Findings Ledger Guild (src/RiskEngine/StellaOps.RiskEngine/TASKS.md)
|
||||
RISK-ENGINE-68-002 | TODO | Expose APIs (`/risk/jobs`, `/risk/results`, `/risk/results/{id}/explanation`); include pagination, filtering, error codes. Dependencies: RISK-ENGINE-68-001. | Risk Engine Guild, API Guild (src/RiskEngine/StellaOps.RiskEngine/TASKS.md)
|
||||
|
||||
@@ -134,19 +134,27 @@ Summary: Scanner & Surface focus on Scanner (phase VII).
|
||||
Task ID | State | Task description | Owners (Source)
|
||||
--- | --- | --- | ---
|
||||
SCANNER-ENTRYTRACE-18-504 | TODO | Emit EntryTrace AOC NDJSON (`entrytrace.entry/node/edge/target/warning/capability`) and wire CLI/service streaming outputs. Dependencies: SCANNER-ENTRYTRACE-18-503. | EntryTrace Guild (src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace/TASKS.md)
|
||||
SCANNER-ENV-01 | TODO | Replace ad-hoc environment reads with `StellaOps.Scanner.Surface.Env` helpers for cache roots and CAS endpoints. | Scanner Worker Guild (src/Scanner/StellaOps.Scanner.Worker/TASKS.md)
|
||||
SCANNER-ENV-02 | TODO | Wire Surface.Env helpers into WebService hosting (cache roots, feature flags) and document configuration. Dependencies: SCANNER-ENV-01. | Scanner WebService Guild, Ops Guild (src/Scanner/StellaOps.Scanner.WebService/TASKS.md)
|
||||
SCANNER-ENV-01 | DOING (2025-11-02) | Replace ad-hoc environment reads with `StellaOps.Scanner.Surface.Env` helpers for cache roots and CAS endpoints.<br>2025-11-02: Env helper wiring drafted for Worker startup; initial tests validate cache root resolution. | Scanner Worker Guild (src/Scanner/StellaOps.Scanner.Worker/TASKS.md)
|
||||
SCANNER-ENV-02 | DOING (2025-11-02) | Wire Surface.Env helpers into WebService hosting (cache roots, feature flags) and document configuration. Dependencies: SCANNER-ENV-01.<br>2025-11-02: WebService bootstrap now consumes Surface.Env helpers for cache roots and feature flag toggles; configuration doc draft pending. | Scanner WebService Guild, Ops Guild (src/Scanner/StellaOps.Scanner.WebService/TASKS.md)
|
||||
SCANNER-ENV-03 | TODO | Adopt Surface.Env helpers for plugin configuration (cache roots, CAS endpoints, feature toggles). Dependencies: SCANNER-ENV-02. | BuildX Plugin Guild (src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin/TASKS.md)
|
||||
SCANNER-EVENTS-16-301 | BLOCKED (2025-10-26) | Emit orchestrator-compatible envelopes (`scanner.event.*`) and update integration tests to verify Notifier ingestion (no Redis queue coupling). | Scanner WebService Guild (src/Scanner/StellaOps.Scanner.WebService/TASKS.md)
|
||||
SCANNER-EVENTS-16-302 | DOING (2025-10-26) | Extend orchestrator event links (report/policy/attestation) once endpoints are finalised across gateway + console. Dependencies: SCANNER-EVENTS-16-301. | Scanner WebService Guild (src/Scanner/StellaOps.Scanner.WebService/TASKS.md)
|
||||
SCANNER-GRAPH-21-001 | TODO | Provide webhook/REST endpoint for Cartographer to request policy overlays and runtime evidence for graph nodes, ensuring determinism and tenant scoping. | Scanner WebService Guild, Cartographer Guild (src/Scanner/StellaOps.Scanner.WebService/TASKS.md)
|
||||
SCANNER-LNM-21-001 | TODO | Update `/reports` and `/policy/runtime` payloads to consume advisory/vex linksets, exposing source severity arrays and conflict summaries alongside effective verdicts. | Scanner WebService Guild, Policy Guild (src/Scanner/StellaOps.Scanner.WebService/TASKS.md)
|
||||
SCANNER-LNM-21-002 | TODO | Add evidence endpoint for Console to fetch linkset summaries with policy overlay for a component/SBOM, including AOC references. Dependencies: SCANNER-LNM-21-001. | Scanner WebService Guild, UI Guild (src/Scanner/StellaOps.Scanner.WebService/TASKS.md)
|
||||
SCANNER-SECRETS-01 | TODO | Adopt `StellaOps.Scanner.Surface.Secrets` for registry/CAS credentials during scan execution. | Scanner Worker Guild, Security Guild (src/Scanner/StellaOps.Scanner.Worker/TASKS.md)
|
||||
SCANNER-SECRETS-02 | TODO | Replace ad-hoc secret wiring with Surface.Secrets for report/export operations (registry and CAS tokens). Dependencies: SCANNER-SECRETS-01. | Scanner WebService Guild, Security Guild (src/Scanner/StellaOps.Scanner.WebService/TASKS.md)
|
||||
SCANNER-SECRETS-01 | DOING (2025-11-02) | Adopt `StellaOps.Scanner.Surface.Secrets` for registry/CAS credentials during scan execution.<br>2025-11-02: Worker integration tests added for CAS token retrieval via Surface.Secrets abstraction; refactor under review. | Scanner Worker Guild, Security Guild (src/Scanner/StellaOps.Scanner.Worker/TASKS.md)
|
||||
SCANNER-SECRETS-02 | DOING (2025-11-02) | Replace ad-hoc secret wiring with Surface.Secrets for report/export operations (registry and CAS tokens). Dependencies: SCANNER-SECRETS-01.<br>2025-11-02: WebService export path now resolves registry credentials via Surface.Secrets stub; CI pipeline hook in progress. | Scanner WebService Guild, Security Guild (src/Scanner/StellaOps.Scanner.WebService/TASKS.md)
|
||||
SCANNER-SECRETS-03 | TODO | Use Surface.Secrets to retrieve registry credentials when interacting with CAS/referrers. Dependencies: SCANNER-SECRETS-02. | BuildX Plugin Guild, Security Guild (src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin/TASKS.md)
|
||||
SCANNER-SURFACE-01 | TODO | Persist Surface.FS manifests after analyzer stages, including layer CAS metadata and EntryTrace fragments. | Scanner Worker Guild (src/Scanner/StellaOps.Scanner.Worker/TASKS.md)
|
||||
SCANNER-SURFACE-02 | TODO | Publish Surface.FS pointers (CAS URIs, manifests) via scan/report APIs and update attestation metadata. Dependencies: SCANNER-SURFACE-01. | Scanner WebService Guild (src/Scanner/StellaOps.Scanner.WebService/TASKS.md)
|
||||
SCANNER-ENG-0020 | TODO | Implement Homebrew collector & fragment mapper per `design/macos-analyzer.md` §3.1. | Scanner Guild (docs/modules/scanner/TASKS.md)
|
||||
SCANNER-ENG-0021 | TODO | Implement pkgutil receipt collector per `design/macos-analyzer.md` §3.2. | Scanner Guild (docs/modules/scanner/TASKS.md)
|
||||
SCANNER-ENG-0022 | TODO | Implement macOS bundle inspector & capability overlays per `design/macos-analyzer.md` §3.3. | Scanner Guild, Policy Guild (docs/modules/scanner/TASKS.md)
|
||||
SCANNER-ENG-0023 | TODO | Deliver macOS policy/offline integration per `design/macos-analyzer.md` §5–6. | Scanner Guild, Offline Kit Guild, Policy Guild (docs/modules/scanner/TASKS.md)
|
||||
SCANNER-ENG-0024 | TODO | Implement Windows MSI collector per `design/windows-analyzer.md` §3.1. | Scanner Guild (docs/modules/scanner/TASKS.md)
|
||||
SCANNER-ENG-0025 | TODO | Implement WinSxS manifest collector per `design/windows-analyzer.md` §3.2. | Scanner Guild (docs/modules/scanner/TASKS.md)
|
||||
SCANNER-ENG-0026 | TODO | Implement Windows Chocolatey & registry collectors per `design/windows-analyzer.md` §3.3–3.4. | Scanner Guild (docs/modules/scanner/TASKS.md)
|
||||
SCANNER-ENG-0027 | TODO | Deliver Windows policy/offline integration per `design/windows-analyzer.md` §5–6. | Scanner Guild, Policy Guild, Offline Kit Guild (docs/modules/scanner/TASKS.md)
|
||||
SCANNER-SURFACE-01 | DOING (2025-11-02) | Persist Surface.FS manifests after analyzer stages, including layer CAS metadata and EntryTrace fragments.<br>2025-11-02: Worker pipeline emitting draft Surface.FS manifests for sample scans; determinism checks running. | Scanner Worker Guild (src/Scanner/StellaOps.Scanner.Worker/TASKS.md)
|
||||
SCANNER-SURFACE-02 | DOING (2025-11-02) | Publish Surface.FS pointers (CAS URIs, manifests) via scan/report APIs and update attestation metadata. Dependencies: SCANNER-SURFACE-01.<br>2025-11-02: WebService responses now include preview CAS URIs; attestation metadata updates staged for review. | Scanner WebService Guild (src/Scanner/StellaOps.Scanner.WebService/TASKS.md)
|
||||
SCANNER-SURFACE-03 | TODO | Push layer manifests and entry fragments into Surface.FS during build-time SBOM generation. Dependencies: SCANNER-SURFACE-02. | BuildX Plugin Guild (src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin/TASKS.md)
|
||||
|
||||
[Scanner & Surface] 130.A) Scanner.VIII
|
||||
|
||||
@@ -5,6 +5,7 @@ Depends on: Sprint 150.A - Orchestrator
|
||||
Summary: Notifications & Telemetry focus on Notifier (phase I).
|
||||
Task ID | State | Task description | Owners (Source)
|
||||
--- | --- | --- | ---
|
||||
NOTIFY-DOC-70-001 | DONE | Record architecture decision to keep `src/Notify` (shared libraries) and `src/Notifier` (host runtime) separate; capture rationale in notifications docs. Notes added 2025-11-02. | Notifications Service Guild (src/Notifier/StellaOps.Notifier/TASKS.md)
|
||||
NOTIFY-AIRGAP-56-001 | TODO | Disable external webhook targets in sealed mode, default to enclave-safe channels (SMTP relay, syslog, file sink), and surface remediation guidance. | Notifications Service Guild (src/Notifier/StellaOps.Notifier/TASKS.md)
|
||||
NOTIFY-AIRGAP-56-002 | TODO | Provide local notifier configurations bundled within Bootstrap Pack with deterministic secrets handling. Dependencies: NOTIFY-AIRGAP-56-001. | Notifications Service Guild, DevOps Guild (src/Notifier/StellaOps.Notifier/TASKS.md)
|
||||
NOTIFY-AIRGAP-57-001 | TODO | Send staleness drift and bundle import notifications with remediation steps. Dependencies: NOTIFY-AIRGAP-56-002. | Notifications Service Guild, AirGap Time Guild (src/Notifier/StellaOps.Notifier/TASKS.md)
|
||||
|
||||
@@ -136,9 +136,9 @@ DEVOPS-VEX-30-001 | TODO | Provision CI, load tests, dashboards, alerts for VEX
|
||||
DEVOPS-VULN-29-001 | TODO | Provision CI jobs for ledger projector (replay, determinism), set up backups, monitor Merkle anchoring, and automate verification. | DevOps Guild, Findings Ledger Guild (ops/devops/TASKS.md)
|
||||
DEVOPS-VULN-29-002 | TODO | Configure load/perf tests (5M findings/tenant), query budget enforcement, API SLO dashboards, and alerts for `vuln_list_latency` and `projection_lag`. Dependencies: DEVOPS-VULN-29-001. | DevOps Guild, Vuln Explorer API Guild (ops/devops/TASKS.md)
|
||||
DEVOPS-VULN-29-003 | TODO | Instrument analytics pipeline for Vuln Explorer (telemetry ingestion, query hashes), ensure compliance with privacy/PII guardrails, and update observability docs. Dependencies: DEVOPS-VULN-29-002. | DevOps Guild, Console Guild (ops/devops/TASKS.md)
|
||||
DOCKER-44-001 | TODO | Author multi-stage Dockerfiles for all core services (API, Console, Orchestrator, Task Runner, Conseiller, Excitator, Policy, Notify, Export, AI) with non-root users, read-only file systems, and health scripts. | DevOps Guild, Service Owners (ops/devops/TASKS.md)
|
||||
DOCKER-44-001 | TODO | Author multi-stage Dockerfiles for all core services (API, Console, Orchestrator, Task Runner, Conseiller, Excitor, Policy, Notify, Export, AI) with non-root users, read-only file systems, and health scripts. | DevOps Guild, Service Owners (ops/devops/TASKS.md)
|
||||
DOCKER-44-002 | TODO | Generate SBOMs and cosign attestations for each image and integrate verification into CI. Dependencies: DOCKER-44-001. | DevOps Guild (ops/devops/TASKS.md)
|
||||
DOCKER-44-003 | TODO | Implement `/health/liveness`, `/health/readiness`, `/version`, `/metrics`, and ensure capability endpoint returns `merge=false` for Conseiller/Excitator. Dependencies: DOCKER-44-002. | DevOps Guild (ops/devops/TASKS.md)
|
||||
DOCKER-44-003 | TODO | Implement `/health/liveness`, `/health/readiness`, `/version`, `/metrics`, and ensure capability endpoint returns `merge=false` for Conseiller/Excitor. Dependencies: DOCKER-44-002. | DevOps Guild (ops/devops/TASKS.md)
|
||||
OPS-ENV-01 | TODO | Update deployment manifests (Helm/Compose) and configuration docs to include Surface.Env variables for Scanner and Zastava services. | DevOps Guild, Scanner Guild (ops/devops/TASKS.md)
|
||||
OPS-SECRETS-01 | TODO | Define secret provisioning workflow (Kubernetes, Compose, Offline Kit) for Surface.Secrets references and update runbooks. | DevOps Guild, Security Guild (ops/devops/TASKS.md)
|
||||
OPS-SECRETS-02 | TODO | Embed Surface.Secrets material (encrypted bundles, manifests) into offline kit packaging scripts. Dependencies: OPS-SECRETS-01. | DevOps Guild, Offline Kit Guild (ops/devops/TASKS.md)
|
||||
|
||||
@@ -103,7 +103,8 @@ DOCS-LNM-22-003 | BLOCKED (2025-10-27) | Update `/docs/api/advisories.md` and `/
|
||||
DOCS-LNM-22-004 | TODO | Create `/docs/policy/effective-severity.md` detailing severity selection strategies from multiple sources. Dependencies: DOCS-LNM-22-003. | Docs Guild, Policy Guild (docs/TASKS.md)
|
||||
DOCS-LNM-22-005 | BLOCKED (2025-10-27) | Document `/docs/ui/evidence-panel.md` with screenshots, conflict badges, accessibility guidance. Dependencies: DOCS-LNM-22-004. | Docs Guild, UI Guild (docs/TASKS.md)
|
||||
DOCS-LNM-22-007 | TODO | Publish `/docs/observability/aggregation.md` with metrics/traces/logs/SLOs. Dependencies: DOCS-LNM-22-005. | Docs Guild, Observability Guild (docs/TASKS.md)
|
||||
DOCS-LNM-22-008 | TODO | Write `/docs/migration/no-merge.md` describing migration plan, backfill steps, rollback, feature flags. Dependencies: DOCS-LNM-22-007. | Docs Guild, DevOps Guild (docs/TASKS.md)
|
||||
DOCS-LNM-22-008 | DONE (2025-11-03) | Write `/docs/migration/no-merge.md` describing migration plan, backfill steps, rollback, feature flags. Dependencies: DOCS-LNM-22-007. | Docs Guild, DevOps Guild (docs/TASKS.md)
|
||||
> 2025-11-03: Drafted and published `docs/migration/no-merge.md` covering rollout phases, backfill/validation workflow, rollback plan, and readiness checklist.
|
||||
DOCS-NOTIFY-40-001 | TODO | Publish `/docs/notifications/channels.md`, `/docs/notifications/escalations.md`, `/docs/notifications/api.md`, `/docs/operations/notifier-runbook.md`, `/docs/security/notifications-hardening.md`; each ends with imposed rule line. | Docs Guild, Security Guild (docs/TASKS.md)
|
||||
DOCS-OAS-61-001 | TODO | Publish `/docs/api/overview.md` covering auth, tenancy, pagination, idempotency, rate limits with banner. | Docs Guild, API Contracts Guild (docs/TASKS.md)
|
||||
DOCS-OAS-61-002 | TODO | Author `/docs/api/conventions.md` capturing naming, errors, filters, sorting, examples. Dependencies: DOCS-OAS-61-001. | Docs Guild, API Governance Guild (docs/TASKS.md)
|
||||
@@ -206,6 +207,14 @@ Task ID | State | Task description | Owners (Source)
|
||||
DOCS-SIG-26-008 | TODO | Write `/docs/migration/enable-reachability.md` guiding rollout, fallbacks, monitoring. Dependencies: DOCS-SIG-26-007. | Docs Guild, DevOps Guild (docs/TASKS.md)
|
||||
DOCS-SURFACE-01 | TODO | Create `/docs/modules/scanner/scanner-engine.md` covering Surface.FS/Env/Secrets workflow between Scanner, Zastava, Scheduler, and Ops. | Docs Guild, Scanner Guild, Zastava Guild (docs/TASKS.md)
|
||||
DOCS-SCANNER-BENCH-62-001 | DONE (2025-11-02) | Refresh scanner comparison docs (Trivy/Grype/Snyk) and keep ecosystem matrix aligned with source implementations. | Docs Guild, Scanner Guild (docs/TASKS.md)
|
||||
DOCS-SCANNER-BENCH-62-002 | TODO | Capture customer demand for Windows/macOS analyzer coverage and document outcomes. | Docs Guild, Product Guild (docs/TASKS.md)
|
||||
DOCS-SCANNER-BENCH-62-003 | TODO | Capture Python lockfile/editable install requirements and document policy guidance. | Docs Guild, Product Guild (docs/TASKS.md)
|
||||
DOCS-SCANNER-BENCH-62-004 | TODO | Document Java lockfile ingestion guidance and policy templates. | Docs Guild, Java Analyzer Guild (docs/TASKS.md)
|
||||
DOCS-SCANNER-BENCH-62-005 | TODO | Document Go stripped-binary fallback enrichment guidance once implementation lands. | Docs Guild, Go Analyzer Guild (docs/TASKS.md)
|
||||
DOCS-SCANNER-BENCH-62-006 | TODO | Document Rust fingerprint enrichment guidance and policy examples. | Docs Guild, Rust Analyzer Guild (docs/TASKS.md)
|
||||
DOCS-SCANNER-BENCH-62-007 | DOING (2025-11-02) | Produce secret leak detection documentation (rules, policy templates). | Docs Guild, Security Guild (docs/TASKS.md)
|
||||
DOCS-SCANNER-BENCH-62-008 | TODO | Publish EntryTrace explain/heuristic maintenance guide. | Docs Guild, EntryTrace Guild (docs/TASKS.md)
|
||||
DOCS-SCANNER-BENCH-62-009 | TODO | Produce SAST integration documentation (connector framework, policy templates). | Docs Guild, Policy Guild (docs/TASKS.md)
|
||||
DOCS-TEN-47-001 | TODO | Publish `/docs/security/tenancy-overview.md` and `/docs/security/scopes-and-roles.md` outlining scope grammar, tenant model, imposed rule reminder. | Docs Guild, Authority Core (docs/TASKS.md)
|
||||
DOCS-TEN-48-001 | TODO | Publish `/docs/operations/multi-tenancy.md`, `/docs/operations/rls-and-data-isolation.md`, `/docs/console/admin-tenants.md`. Dependencies: DOCS-TEN-47-001. | Docs Guild, Platform Ops (docs/TASKS.md)
|
||||
DOCS-TEN-49-001 | TODO | Publish `/docs/modules/cli/guides/authentication.md`, `/docs/api/authentication.md`, `/docs/policy/examples/abac-overlays.md`, update `/docs/install/configuration-reference.md` with new env vars, all ending with imposed rule line. Dependencies: DOCS-TEN-48-001. | Docs & DevEx Guilds (docs/TASKS.md)
|
||||
|
||||
141
docs/migration/no-merge.md
Normal file
141
docs/migration/no-merge.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# No-Merge Migration Playbook
|
||||
|
||||
_Last updated: 2025-11-03_
|
||||
|
||||
This playbook guides the full retirement of the legacy Merge service (`AdvisoryMergeService`) in favour of Link-Not-Merge (LNM) observations plus linksets. It is written for the BE-Merge, Architecture, DevOps, and Docs guilds coordinating Sprint 110 (Ingestion & Evidence) deliverables, and it feeds CONCELIER-LNM-21-101 / MERGE-LNM-21-001 and downstream DOCS-LNM-22-008.
|
||||
|
||||
## 0. Scope & objectives
|
||||
|
||||
- **Primary goal:** cut over all advisory pipelines to Link-Not-Merge with no residual dependencies on `AdvisoryMergeService`.
|
||||
- **Secondary goals:** maintain deterministic evidence, zero data loss, and reversible deployment across online and offline tenants.
|
||||
- **Success criteria:**
|
||||
- All connectors emit observation `affected.versions[]` with provenance and pass LNM guardrails.
|
||||
- Linkset dashboards show zero `missing_version_entries_total` and no `Normalized version rules missing…` warnings.
|
||||
- Policy, Export Center, and CLI consumers operate solely on observations/linksets.
|
||||
- Rollback playbook validated and rehearsed in staging.
|
||||
|
||||
## 1. Prerequisites checklist
|
||||
|
||||
| Item | Owner | Notes |
|
||||
| --- | --- | --- |
|
||||
| Normalized version ranges emitted for all Sprint 110 connectors (`Acsc`, `Cccs`, `CertBund`, `CertCc`, `Cve`, `Ghsa`, `Ics.Cisa`, `Kisa`, `Ru.Bdu`, `Ru.Nkcki`, `Vndr.Apple`, `Vndr.Cisco`, `Vndr.Msrc`). | Connector guilds | Follow `docs/dev/normalized-rule-recipes.md`; update fixtures with `UPDATE_*_FIXTURES=1`. |
|
||||
| Metrics dashboards (`LinksetVersionCoverage`, `Normalized version rules missing`) available in Grafana/CI snapshots. | Observability guild | Publish baseline before shadow rollout. |
|
||||
| Concelier WebService exposes `linkset` and `observation` read APIs for policy/CLI consumers. | BE-Merge / Platform | Confirm contract parity with Merge outputs. |
|
||||
| Export Center / Offline Kit aware of new manifests. | Export Center guild | Provide beta bundle for QA verification. |
|
||||
| Docs guild aligned on public migration messaging. | Docs guild | Update `docs/dev`, `docs/modules/concelier`, and release notes once cutover date is locked. |
|
||||
|
||||
Do not proceed to Phase 1 until all prerequisites are checked or explicitly waived by Architecture guild.
|
||||
|
||||
## 2. Feature flag & configuration plan
|
||||
|
||||
| Toggle | Default | Purpose | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| `concelier:features:noMergeEnabled` | `false` | Master switch to disable legacy Merge job scheduling/execution. | Applies to WebService + Worker; gate `AdvisoryMergeService` DI registration. |
|
||||
| `concelier:features:lnmShadowWrites` | `true` | Enables dual-write of linksets while Merge remains active. | Keep enabled throughout Phase 0–1 to validate parity. |
|
||||
| `concelier:jobs:merge:allowlist` | `[]` | Explicit allowlist for Merge jobs when noMergeEnabled is `false`. | Set to empty during Phase 2+ to prevent accidental restarts. |
|
||||
| `policy:overlays:requireLinksetEvidence` | `false` | Policy engine safety net to require linkset-backed findings. | Flip to `true` only after cutover (Phase 2). |
|
||||
|
||||
> **Configuration hygiene:** Document the toggle values per environment in `ops/devops/configuration/staging.md` and `ops/devops/configuration/production.md`. Air-gapped customers receive defaults through the Offline Kit release notes.
|
||||
|
||||
## 3. Rollout phases
|
||||
|
||||
| Phase | Goal | Duration | Key actions |
|
||||
| --- | --- | --- | --- |
|
||||
| **0 – Preparation** | Ensure readiness | 2–3 days | Finalise prerequisites, snapshot Merge metrics, dry-run backfill scripts in dev. |
|
||||
| **1 – Shadow / Dual Write** | Validate parity | 5–7 days | Enable `lnmShadowWrites`, keep Merge primary. Compare linkset vs merged outputs using `stella concelier diff-merge --snapshot <date>`; fix discrepancies. |
|
||||
| **2 – Cutover** | Switch to LNM | 1 day (per env) | Enable `noMergeEnabled`, disable Merge job schedules, update Policy/Export configs, run post-cutover smoke tests. |
|
||||
| **3 – Harden** | Decommission Merge | 2–3 days | Remove Merge background services, delete `merge_event` retention jobs, clean dashboards, notify operators. |
|
||||
|
||||
### 3.1 Environment sequencing
|
||||
|
||||
1. **Dev/Test clusters:** Validate all automation. Run full regression suite (`dotnet test src/Concelier/...`).
|
||||
2. **Staging:** Execute complete backfill (see §4) and collect 24 h of telemetry before sign-off.
|
||||
3. **Production:** Perform cutover during low-ingest window; communicate via Slack/email + status page two days in advance.
|
||||
4. **Offline kit:** Package new Observer snapshots with LNM-only data; ensure instructions cover flag toggles for air-gapped deployments.
|
||||
|
||||
### 3.2 Smoke test matrix
|
||||
|
||||
- `stella concelier status --include linkset` returns healthy and shows zero Merge workers.
|
||||
- `stella policy evaluate` against sample tenants produces identical findings pre/post cutover.
|
||||
- Export Center bundle diff shows only expected metadata changes (manifest ID, timestamps).
|
||||
- Grafana dashboards: `linkset_insert_duration_ms` steady, `merge.identity.conflicts` flatlined.
|
||||
|
||||
## 4. Backfill strategy
|
||||
|
||||
1. **Freeze Merge writes:** Pause Merge job scheduler (`MergeJobScheduler.PauseAsync`) to prevent new merge events while snapshots are taken.
|
||||
2. **Generate linkset baseline:** Run `dotnet run --project src/Concelier/StellaOps.Concelier.WebService -- linkset backfill --from 2024-01-01` (or equivalent CLI job) to rebuild linksets from `advisory_raw`. Capture job output artefacts and attach to the sprint issue.
|
||||
3. **Validate parity:** Use the internal diff tool (`tools/concelier/compare-linkset-merge.ps1`) to compare sample advisories. Any diffs must be triaged before production cutover.
|
||||
4. **Publish evidence:** For air-gapped tenants, create a one-off Offline Kit slice (`export profile linkset-backfill`) and push to staging mirror.
|
||||
5. **Tag snapshot:** Record Mongo `oplog` timestamp and S3/object storage manifests in `ops/devops/runbooks/concelier/no-merge.md` (new section) so rollback knows the safe point.
|
||||
|
||||
> **Determinism:** rerunning the backfill with identical inputs must produce byte-identical linkset documents. Use the `--verify-determinism` flag where available and archive the checksum report under `artifacts/lnm-backfill/<date>/`.
|
||||
|
||||
## 5. Validation gates
|
||||
|
||||
- **Metrics:** `linkset_insert_duration_ms`, `linkset_documents_total`, `normalized_version_rules_missing`, `merge.identity.conflicts`.
|
||||
- Gate: `normalized_version_rules_missing == 0` for 48 h before enabling `noMergeEnabled`.
|
||||
- **Logs:** Ensure no occurrences of `Fallbacking to merge service` after cutover.
|
||||
- **Change streams:** Policy and Scheduler should observe only `advisory.linkset.updated` events; monitor for stragglers referencing merge IDs.
|
||||
- **QA:** Golden tests in `StellaOps.Concelier.Merge.Tests` updated to assert absence of merge outputs, plus integration tests verifying LNM-only exports.
|
||||
|
||||
Capture validation evidence in the sprint journal (attach Grafana screenshots + CLI output).
|
||||
|
||||
## 6. Rollback plan
|
||||
|
||||
1. **Toggle sequence:**
|
||||
- Set `concelier:features:noMergeEnabled=false`.
|
||||
- Re-enable Merge job schedules (`concelier:jobs:merge:allowlist=["merge:default"]`).
|
||||
- Disable `policy:overlays:requireLinksetEvidence`.
|
||||
2. **Data considerations:**
|
||||
- Linkset writes continue, so no data is lost; ensure Policy consumers ignore linkset-only fields during rollback window.
|
||||
- If Merge pipeline was fully removed (Phase 3 complete), redeploy the Merge service container image from the `rollback` tag published before cutover.
|
||||
3. **Verification:**
|
||||
- Run `stella concelier status` to confirm Merge workers active.
|
||||
- Monitor `merge.identity.conflicts` for spikes; if present, roll forward and re-open incident with Architecture guild.
|
||||
4. **Communication:**
|
||||
- Post incident note in #release-infra and customer status page.
|
||||
- Log rollback reason, window, and configs in `ops/devops/incidents/<yyyy-mm-dd>-no-merge.md`.
|
||||
|
||||
Rollback window should not exceed 4 hours; beyond that, plan to roll forward with a hotfix rather than reintroducing Merge.
|
||||
|
||||
## 7. Documentation & communications
|
||||
|
||||
- Update `docs/modules/concelier/architecture.md` appendix to mark Merge deprecated and link back to this playbook.
|
||||
- Coordinate with Docs guild to publish operator-facing guidance (`docs/releases/2025-q4.md`) and update CLI help text.
|
||||
- Notify product/CS teams with a short FAQ covering timelines, customer impact, and steps for self-hosted installations.
|
||||
|
||||
## 8. Responsibilities matrix
|
||||
|
||||
| Area | Lead guild(s) | Supporting |
|
||||
| --- | --- | --- |
|
||||
| Feature flags & config | BE-Merge | DevOps |
|
||||
| Backfill scripting | BE-Merge | Tools |
|
||||
| Observability dashboards | Observability | QA |
|
||||
| Offline kit packaging | Export Center | AirGap |
|
||||
| Customer comms | Docs | Product, Support |
|
||||
|
||||
## 9. Deliverables & artefacts
|
||||
|
||||
- Config diff per environment (stored in GitOps repo).
|
||||
- Backfill checksum report (`artifacts/lnm-backfill/<date>/checksums.json`).
|
||||
- Grafana export (PDF) showing validation metrics.
|
||||
- QA test run attesting to LNM-only regressions passing.
|
||||
- Updated runbook entry in `ops/devops/runbooks/concelier/`.
|
||||
|
||||
---
|
||||
|
||||
## 10. Migration readiness checklist
|
||||
|
||||
| Item | Primary owner | Status notes |
|
||||
| --- | --- | --- |
|
||||
| Capture Linkset coverage baselines (`version_entries_total`, `missing_version_entries_total`) and archive Grafana export. | Observability Guild | [ ] Pending |
|
||||
| Stage and verify linkset backfill using `linkset backfill` job; store checksum report under `artifacts/lnm-backfill/<date>/`. | BE-Merge, DevOps Guild | [ ] Pending |
|
||||
| Confirm feature flags per environment (`noMergeEnabled`, `lnmShadowWrites`, `policy:overlays:requireLinksetEvidence`) match Phase 0–3 plan. | DevOps Guild | [ ] Pending |
|
||||
| Publish operator comms (status page, Slack/email) with cutover + rollback windows. | Docs Guild, Product | [ ] Pending |
|
||||
| Execute rollback rehearsal in staging and log results in `ops/devops/incidents/<date>-no-merge.md`. | DevOps Guild, Architecture Guild | [ ] Pending |
|
||||
|
||||
> Update the checklist as each item completes; completion of every row is required before moving to Phase 2 (Cutover).
|
||||
|
||||
---
|
||||
|
||||
With this playbook completed, proceed to MERGE-LNM-21-002 to remove the Merge service code paths and enforce compile-time analyzers that block new merge dependencies.
|
||||
@@ -1,100 +1,115 @@
|
||||
# Advisory AI architecture
|
||||
|
||||
> Captures the retrieval, guardrail, and inference packaging requirements defined in the Advisory AI implementation plan and related module guides.
|
||||
|
||||
## 1) Goals
|
||||
|
||||
- Summarise advisories/VEX evidence into operator-ready briefs with citations.
|
||||
- Explain conflicting statements with provenance and trust weights (using VEX Lens & Excititor data).
|
||||
- Suggest remediation plans aligned with Offline Kit deployment models and scheduler follow-ups.
|
||||
- Operate deterministically where possible; cache generated artefacts with digests for audit.
|
||||
|
||||
## 2) Pipeline overview
|
||||
|
||||
```
|
||||
+---------------------+
|
||||
Concelier/VEX Lens | Evidence Retriever |
|
||||
Policy Engine ----> | (vector + keyword) | ---> Context Pack (JSON)
|
||||
Zastava runtime +---------------------+
|
||||
|
|
||||
v
|
||||
+-------------+
|
||||
| Prompt |
|
||||
| Assembler |
|
||||
+-------------+
|
||||
|
|
||||
v
|
||||
+-------------+
|
||||
| Guarded LLM |
|
||||
| (local/host)|
|
||||
+-------------+
|
||||
|
|
||||
v
|
||||
+-----------------+
|
||||
| Citation & |
|
||||
| Validation |
|
||||
+-----------------+
|
||||
|
|
||||
v
|
||||
+----------------+
|
||||
| Output cache |
|
||||
| (hash, bundle) |
|
||||
+----------------+
|
||||
```
|
||||
|
||||
## 3) Retrieval & context
|
||||
|
||||
- Hybrid search: vector embeddings (SBERT-compatible) + keyword filters for advisory IDs, PURLs, CVEs.
|
||||
- Context packs include:
|
||||
- Advisory raw excerpts with highlighted sections and source URLs.
|
||||
- VEX statements (normalized tuples + trust metadata).
|
||||
- Policy explain traces for the affected finding.
|
||||
- Runtime/impact hints from Zastava (exposure, entrypoints).
|
||||
- Export-ready remediation data (fixed versions, patches).
|
||||
|
||||
All context references include `content_hash` and `source_id` enabling verifiable citations.
|
||||
|
||||
## 4) Guardrails
|
||||
|
||||
- Prompt templates enforce structure: summary, conflicts, remediation, references.
|
||||
- Response validator ensures:
|
||||
- No hallucinated advisories (every fact must map to input context).
|
||||
- Citations follow `[n]` indexing referencing actual sources.
|
||||
- Remediation suggestions only cite policy-approved sources (fixed versions, vendor hotfixes).
|
||||
- Moderation/PII filters prevent leaking secrets; responses failing validation are rejected and logged.
|
||||
|
||||
## 5) Output persistence
|
||||
|
||||
- Cached artefacts stored in `advisory_ai_outputs` with fields:
|
||||
- `output_hash` (sha256 of JSON response).
|
||||
- `input_digest` (hash of context pack).
|
||||
- `summary`, `conflicts`, `remediation`, `citations`.
|
||||
- `generated_at`, `model_id`, `profile` (Sovereign/FIPS etc.).
|
||||
- `signatures` (optional DSSE if run in deterministic mode).
|
||||
- Offline bundle format contains `summary.md`, `citations.json`, `context_manifest.json`, `signatures/`.
|
||||
|
||||
## 6) Profiles & sovereignty
|
||||
|
||||
- **Profiles:** `default`, `fips-local` (FIPS-compliant local model), `gost-local`, `cloud-openai` (optional, disabled by default). Each profile defines allowed models, key management, and telemetry endpoints.
|
||||
- **CryptoProfile/RootPack integration:** generated artefacts can be signed using configured CryptoProfile to satisfy procurement/trust requirements.
|
||||
|
||||
## 7) APIs
|
||||
|
||||
- `POST /v1/advisory-ai/summaries` — generate (or retrieve cached) summary for `{advisoryKey, artifactId, policyVersion}`.
|
||||
- `POST /v1/advisory-ai/conflicts` — explain conflicting VEX statements with trust ranking.
|
||||
- `POST /v1/advisory-ai/remediation` — fetch remediation plan with target fix versions, prerequisites, verification steps.
|
||||
- `GET /v1/advisory-ai/outputs/{hash}` — retrieve cached artefact (used by CLI/Console/Export Center).
|
||||
|
||||
All endpoints accept `profile` parameter (default `fips-local`) and return `output_hash`, `input_digest`, and `citations` for verification.
|
||||
|
||||
## 8) Observability
|
||||
|
||||
- Metrics: `advisory_ai_requests_total{profile,type}`, `advisory_ai_latency_seconds`, `advisory_ai_validation_failures_total`.
|
||||
- Logs: include `output_hash`, `input_digest`, `profile`, `model_id`, `tenant`, `artifacts`. Sensitive context is not logged.
|
||||
- Traces: spans for retrieval, prompt assembly, model inference, validation, cache write.
|
||||
|
||||
## 9) Operational controls
|
||||
|
||||
- Feature flags per tenant (`ai.summary.enabled`, `ai.remediation.enabled`).
|
||||
- Rate limits (per tenant, per profile) enforced by Orchestrator to prevent runaway usage.
|
||||
- Offline/air-gapped deployments run local models packaged with Offline Kit; model weights validated via manifest digests.
|
||||
# Advisory AI architecture
|
||||
|
||||
> Captures the retrieval, guardrail, and inference packaging requirements defined in the Advisory AI implementation plan and related module guides.
|
||||
|
||||
## 1) Goals
|
||||
|
||||
- Summarise advisories/VEX evidence into operator-ready briefs with citations.
|
||||
- Explain conflicting statements with provenance and trust weights (using VEX Lens & Excititor data).
|
||||
- Suggest remediation plans aligned with Offline Kit deployment models and scheduler follow-ups.
|
||||
- Operate deterministically where possible; cache generated artefacts with digests for audit.
|
||||
|
||||
## 2) Pipeline overview
|
||||
|
||||
```
|
||||
+---------------------+
|
||||
Concelier/VEX Lens | Evidence Retriever |
|
||||
Policy Engine ----> | (vector + keyword) | ---> Context Pack (JSON)
|
||||
Zastava runtime +---------------------+
|
||||
|
|
||||
v
|
||||
+-------------+
|
||||
| Prompt |
|
||||
| Assembler |
|
||||
+-------------+
|
||||
|
|
||||
v
|
||||
+-------------+
|
||||
| Guarded LLM |
|
||||
| (local/host)|
|
||||
+-------------+
|
||||
|
|
||||
v
|
||||
+-----------------+
|
||||
| Citation & |
|
||||
| Validation |
|
||||
+-----------------+
|
||||
|
|
||||
v
|
||||
+----------------+
|
||||
| Output cache |
|
||||
| (hash, bundle) |
|
||||
+----------------+
|
||||
```
|
||||
|
||||
## 3) Retrieval & context
|
||||
|
||||
- Hybrid search: vector embeddings (SBERT-compatible) + keyword filters for advisory IDs, PURLs, CVEs.
|
||||
- Context packs include:
|
||||
- Advisory raw excerpts with highlighted sections and source URLs.
|
||||
- VEX statements (normalized tuples + trust metadata).
|
||||
- Policy explain traces for the affected finding.
|
||||
- Runtime/impact hints from Zastava (exposure, entrypoints).
|
||||
- Export-ready remediation data (fixed versions, patches).
|
||||
- **SBOM context retriever** (AIAI-31-002) hydrates:
|
||||
- Version timelines (first/last observed, status, fix availability).
|
||||
- Dependency paths (runtime vs build/test, deduped by coordinate chain).
|
||||
- Tenant environment flags (prod/stage toggles) with optional blast radius summary.
|
||||
- Service-side clamps: max 500 timeline entries, 200 dependency paths, with client-provided toggles for env/blast data.
|
||||
|
||||
Retriever requests and results are trimmed/normalized before hashing; metadata (counts, provenance keys) is returned for downstream guardrails. Unit coverage ensures deterministic ordering and flag handling.
|
||||
|
||||
All context references include `content_hash` and `source_id` enabling verifiable citations.
|
||||
|
||||
## 4) Guardrails
|
||||
|
||||
- Prompt templates enforce structure: summary, conflicts, remediation, references.
|
||||
- Response validator ensures:
|
||||
- No hallucinated advisories (every fact must map to input context).
|
||||
- Citations follow `[n]` indexing referencing actual sources.
|
||||
- Remediation suggestions only cite policy-approved sources (fixed versions, vendor hotfixes).
|
||||
- Moderation/PII filters prevent leaking secrets; responses failing validation are rejected and logged.
|
||||
|
||||
## 5) Deterministic tooling
|
||||
|
||||
- **Version comparators** — offline semantic version + RPM EVR parsers with range evaluators. Supports chained constraints (`>=`, `<=`, `!=`) used by remediation advice and blast radius calcs.
|
||||
- Registered via `AddAdvisoryDeterministicToolset` for reuse across orchestrator, CLI, and services.
|
||||
- **Orchestration pipeline** — see `orchestration-pipeline.md` for prerequisites, task breakdown, and cross-guild responsibilities before wiring the execution flows.
|
||||
- **Planned extensions** — NEVRA/EVR comparators, ecosystem-specific normalisers, dependency chain scorers (AIAI-31-003 scope).
|
||||
- Exposed via internal interfaces to allow orchestrator/toolchain reuse; all helpers stay side-effect free and deterministic for golden testing.
|
||||
|
||||
## 6) Output persistence
|
||||
|
||||
- Cached artefacts stored in `advisory_ai_outputs` with fields:
|
||||
- `output_hash` (sha256 of JSON response).
|
||||
- `input_digest` (hash of context pack).
|
||||
- `summary`, `conflicts`, `remediation`, `citations`.
|
||||
- `generated_at`, `model_id`, `profile` (Sovereign/FIPS etc.).
|
||||
- `signatures` (optional DSSE if run in deterministic mode).
|
||||
- Offline bundle format contains `summary.md`, `citations.json`, `context_manifest.json`, `signatures/`.
|
||||
|
||||
## 7) Profiles & sovereignty
|
||||
|
||||
- **Profiles:** `default`, `fips-local` (FIPS-compliant local model), `gost-local`, `cloud-openai` (optional, disabled by default). Each profile defines allowed models, key management, and telemetry endpoints.
|
||||
- **CryptoProfile/RootPack integration:** generated artefacts can be signed using configured CryptoProfile to satisfy procurement/trust requirements.
|
||||
|
||||
## 8) APIs
|
||||
|
||||
- `POST /v1/advisory-ai/summaries` — generate (or retrieve cached) summary for `{advisoryKey, artifactId, policyVersion}`.
|
||||
- `POST /v1/advisory-ai/conflicts` — explain conflicting VEX statements with trust ranking.
|
||||
- `POST /v1/advisory-ai/remediation` — fetch remediation plan with target fix versions, prerequisites, verification steps.
|
||||
- `GET /v1/advisory-ai/outputs/{hash}` — retrieve cached artefact (used by CLI/Console/Export Center).
|
||||
|
||||
All endpoints accept `profile` parameter (default `fips-local`) and return `output_hash`, `input_digest`, and `citations` for verification.
|
||||
|
||||
## 9) Observability
|
||||
|
||||
- Metrics: `advisory_ai_requests_total{profile,type}`, `advisory_ai_latency_seconds`, `advisory_ai_validation_failures_total`.
|
||||
- Logs: include `output_hash`, `input_digest`, `profile`, `model_id`, `tenant`, `artifacts`. Sensitive context is not logged.
|
||||
- Traces: spans for retrieval, prompt assembly, model inference, validation, cache write.
|
||||
|
||||
## 10) Operational controls
|
||||
|
||||
- Feature flags per tenant (`ai.summary.enabled`, `ai.remediation.enabled`).
|
||||
- Rate limits (per tenant, per profile) enforced by Orchestrator to prevent runaway usage.
|
||||
- Offline/air-gapped deployments run local models packaged with Offline Kit; model weights validated via manifest digests.
|
||||
|
||||
82
docs/modules/advisory-ai/orchestration-pipeline.md
Normal file
82
docs/modules/advisory-ai/orchestration-pipeline.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Advisory AI Orchestration Pipeline (Planning Notes)
|
||||
|
||||
> **Status:** Draft – prerequisite design for AIAI-31-004 integration work.
|
||||
> **Audience:** Advisory AI guild, WebService/Worker guilds, CLI guild, Docs/QA support teams.
|
||||
|
||||
## 1. Goal
|
||||
|
||||
Wire the deterministic pipeline (Summary / Conflict / Remediation flows) into the Advisory AI service, workers, and CLI with deterministic caching, prompt preparation, and guardrail fallback. This document captures the pre-integration checklist and task breakdown so each guild understands their responsibilities before coding begins.
|
||||
|
||||
## 2. Prerequisites
|
||||
|
||||
| Area | Requirement | Owner | Status |
|
||||
|------|-------------|-------|--------|
|
||||
| **Toolset** | Deterministic comparators, dependency analyzer (`IDeterministicToolset`, `AdvisoryPipelineOrchestrator`) | Advisory AI | ✅ landed (AIAI-31-003) |
|
||||
| **SBOM context** | Real SBOM context client delivering timelines + dependency paths | SBOM Service Guild | ⏳ pending (AIAI-31-002) |
|
||||
| **Prompt artifacts** | Liquid/Handlebars prompt templates for summary/conflict/remediation | Advisory AI Docs Guild | ⏳ authoring needed |
|
||||
| **Cache strategy** | Decision on DSSE or hash-only cache entries, TTLs, and eviction policy | Advisory AI + Platform | 🔲 define |
|
||||
| **Auth scopes** | Confirm service account scopes for new API endpoints/worker-to-service calls | Authority Guild | 🔲 define |
|
||||
|
||||
**Blocking risk:** SBOM client and prompt templates must exist (even stubbed) before the orchestrator can produce stable plans.
|
||||
|
||||
## 3. Integration plan (high-level)
|
||||
|
||||
1. **Service layer (WebService / Worker)**
|
||||
- Inject `IAdvisoryPipelineOrchestrator` via `AddAdvisoryPipeline`.
|
||||
- Define REST endpoint `POST /v1/advisories/{key}/pipeline/{task}` (task ∈ summary/conflict/remediation).
|
||||
- Worker consumes queue messages (`advisory.pipeline.execute`) -> fetches plan -> executes prompt -> persists output & provenance.
|
||||
- Add metrics: `advisory_pipeline_requests_total`, `advisory_pipeline_plan_cache_hits_total`, `advisory_pipeline_latency_seconds`.
|
||||
2. **CLI**
|
||||
- New command `stella advise run <task>` with flags for artifact id, profile, policy version, `--force-refresh`.
|
||||
- Render JSON/Markdown outputs; handle caching hints (print cache key, status).
|
||||
3. **Caching / storage**
|
||||
- Choose storage (Mongo collection vs existing DSSE output store).
|
||||
- Persist `AdvisoryTaskPlan` metadata + generated output keyed by cache key + policy version.
|
||||
- Expose TTL/force-refresh semantics.
|
||||
4. **Docs & QA**
|
||||
- Publish API spec (`docs/advisory-ai/api.md`) + CLI docs.
|
||||
- Add golden outputs for deterministic runs; property tests for cache key stability.
|
||||
|
||||
## 4. Task Breakdown
|
||||
|
||||
### AIAI-31-004A (Service orchestration wiring)
|
||||
|
||||
- **Scope:** WebService/Worker injection, REST/queue plumbing, metrics counters, basic cache stub.
|
||||
- **Dependencies:** `AddAdvisoryPipeline`, SBOM client stub.
|
||||
- **Exit:** API responds with plan metadata + queue message; worker logs execution attempt; metrics emitted.
|
||||
|
||||
### AIAI-31-004B (Prompt assembly & cache persistence)
|
||||
|
||||
- **Scope:** Implement prompt assembler, connect to guardrails, persist cache entries w/ DSSE metadata.
|
||||
- **Dependencies:** Prompt templates, cache storage decision, guardrail interface.
|
||||
- **Exit:** Deterministic outputs stored; force-refresh honoured; tests cover prompt assembly + caching.
|
||||
|
||||
### AIAI-31-004C (CLI integration & docs)
|
||||
|
||||
- **Scope:** CLI command + output renderer, docs updates, CLI tests (golden outputs).
|
||||
- **Dependencies:** Service endpoints stable, caching semantics documented.
|
||||
- **Exit:** CLI command produces deterministic output, docs updated, smoke tests recorded.
|
||||
|
||||
### Supporting tasks (other guilds)
|
||||
|
||||
- **AUTH-AIAI-31-004** – Update scopes and DSSE policy (Authority guild).
|
||||
- **DOCS-AIAI-31-003** – Publish API documentation, CLI guide updates (Docs guild).
|
||||
- **QA-AIAI-31-004** – Golden/properties/perf suite for pipeline (QA guild).
|
||||
|
||||
## 5. Acceptance checklist (per task)
|
||||
|
||||
| Item | Notes |
|
||||
|------|-------|
|
||||
| Cache key stability | `AdvisoryPipelineOrchestrator` hash must remain stable under re-run of identical inputs. |
|
||||
| Metrics & logging | Request id, cache key, task type, profile, latency; guardrail results logged without sensitive prompt data. |
|
||||
| Offline readiness | All prompt templates bundled with Offline Kit; CLI works in air-gapped mode with cached data. |
|
||||
| Policy awareness | Plans encode policy version used; outputs reference policy digest for audit. |
|
||||
| Testing | Unit tests (plan generation, cache keys, DI), integration (service endpoint, worker, CLI), deterministic golden outputs. |
|
||||
|
||||
## 6. Next steps
|
||||
|
||||
1. Finalize SBOM context client (AIAI-31-002) and prompt templates.
|
||||
2. Create queue schema spec (`docs/modules/advisory-ai/queue-contracts.md`) if not already available.
|
||||
3. Schedule cross-guild kickoff to agree on cache store & DSSE policy.
|
||||
|
||||
_Last updated: 2025-11-02_
|
||||
@@ -1,7 +1,7 @@
|
||||
# Vexer agent guide
|
||||
# Excitor agent guide
|
||||
|
||||
## Mission
|
||||
Vexer computes deterministic consensus across VEX claims, preserving conflicts and producing attestable evidence for policy suppression.
|
||||
Excitor computes deterministic consensus across VEX claims, preserving conflicts and producing attestable evidence for policy suppression.
|
||||
|
||||
## Key docs
|
||||
- [Module README](./README.md)
|
||||
@@ -21,9 +21,9 @@ Vexer computes deterministic consensus across VEX claims, preserving conflicts a
|
||||
- Keep Offline Kit parity in mind—document air-gapped workflows for any new feature.
|
||||
- Update runbooks/observability assets when operational characteristics change.
|
||||
## Required Reading
|
||||
- `docs/modules/vexer/README.md`
|
||||
- `docs/modules/vexer/architecture.md`
|
||||
- `docs/modules/vexer/implementation_plan.md`
|
||||
- `docs/modules/excitor/README.md`
|
||||
- `docs/modules/excitor/architecture.md`
|
||||
- `docs/modules/excitor/implementation_plan.md`
|
||||
- `docs/modules/platform/architecture-overview.md`
|
||||
|
||||
## Working Agreement
|
||||
@@ -1,34 +1,34 @@
|
||||
# StellaOps Vexer
|
||||
|
||||
Vexer computes deterministic consensus across VEX claims, preserving conflicts and producing attestable evidence for policy suppression.
|
||||
|
||||
## Responsibilities
|
||||
- Ingest Excititor observations and compute per-product consensus snapshots.
|
||||
- Provide APIs for querying canonical VEX positions and conflict sets.
|
||||
- Publish exports and DSSE-ready digests for downstream consumption.
|
||||
- Keep provenance weights and disagreement metadata.
|
||||
|
||||
## Key components
|
||||
- Consensus engine and API host in `StellaOps.Vexer.*` (to-be-implemented).
|
||||
- Storage schema for consensus graphs.
|
||||
- Integration hooks for Policy Engine suppression logic.
|
||||
|
||||
## Integrations & dependencies
|
||||
- Excititor for raw observations.
|
||||
- Policy Engine and UI for suppression stories.
|
||||
- CLI for evidence inspection.
|
||||
|
||||
## Operational notes
|
||||
- Deterministic consensus algorithms (see architecture).
|
||||
- Planned telemetry for disagreement counts and freshness.
|
||||
- Offline exports aligning with Concelier/Excititor timelines.
|
||||
|
||||
## Related resources
|
||||
- ./scoring.md
|
||||
|
||||
## Backlog references
|
||||
- DOCS-VEXER backlog referenced in architecture doc.
|
||||
- CLI parity tracked in ../../TASKS.md (CLI-GRAPH/VEX stories).
|
||||
|
||||
## Epic alignment
|
||||
- **Epic 7 – VEX Consensus Lens:** deliver trust-weighted consensus snapshots, disagreement metadata, and explain APIs.
|
||||
# StellaOps Excitor
|
||||
|
||||
Excitor computes deterministic consensus across VEX claims, preserving conflicts and producing attestable evidence for policy suppression.
|
||||
|
||||
## Responsibilities
|
||||
- Ingest Excititor observations and compute per-product consensus snapshots.
|
||||
- Provide APIs for querying canonical VEX positions and conflict sets.
|
||||
- Publish exports and DSSE-ready digests for downstream consumption.
|
||||
- Keep provenance weights and disagreement metadata.
|
||||
|
||||
## Key components
|
||||
- Consensus engine and API host in `StellaOps.Excitor.*` (to-be-implemented).
|
||||
- Storage schema for consensus graphs.
|
||||
- Integration hooks for Policy Engine suppression logic.
|
||||
|
||||
## Integrations & dependencies
|
||||
- Excititor for raw observations.
|
||||
- Policy Engine and UI for suppression stories.
|
||||
- CLI for evidence inspection.
|
||||
|
||||
## Operational notes
|
||||
- Deterministic consensus algorithms (see architecture).
|
||||
- Planned telemetry for disagreement counts and freshness.
|
||||
- Offline exports aligning with Concelier/Excititor timelines.
|
||||
|
||||
## Related resources
|
||||
- ./scoring.md
|
||||
|
||||
## Backlog references
|
||||
- DOCS-EXCITOR backlog referenced in architecture doc.
|
||||
- CLI parity tracked in ../../TASKS.md (CLI-GRAPH/VEX stories).
|
||||
|
||||
## Epic alignment
|
||||
- **Epic 7 – VEX Consensus Lens:** deliver trust-weighted consensus snapshots, disagreement metadata, and explain APIs.
|
||||
9
docs/modules/excitor/TASKS.md
Normal file
9
docs/modules/excitor/TASKS.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Task board — Excitor
|
||||
|
||||
> Local tasks should link back to ./AGENTS.md and mirror status updates into ../../TASKS.md when applicable.
|
||||
|
||||
| ID | Status | Owner(s) | Description | Notes |
|
||||
|----|--------|----------|-------------|-------|
|
||||
| EXCITOR-DOCS-0001 | DOING (2025-10-29) | Docs Guild | Validate that ./README.md aligns with the latest release notes. | See ./AGENTS.md |
|
||||
| EXCITOR-OPS-0001 | TODO | Ops Guild | Review runbooks/observability assets after next sprint demo. | Sync outcomes back to ../../TASKS.md |
|
||||
| EXCITOR-ENG-0001 | TODO | Module Team | Cross-check implementation plan milestones against ../../implplan/SPRINTS.md. | Update status via ./AGENTS.md workflow |
|
||||
@@ -1,465 +1,465 @@
|
||||
# component_architecture_vexer.md — **Stella Ops Vexer** (2025Q4)
|
||||
# component_architecture_excitor.md — **Stella Ops Excitor** (2025Q4)
|
||||
|
||||
> Built to satisfy Epic 7 – VEX Consensus Lens requirements.
|
||||
|
||||
> **Scope.** This document specifies the **Vexer** service: its purpose, trust model, data structures, APIs, plug‑in contracts, storage schema, normalization/consensus algorithms, performance budgets, testing matrix, and how it integrates with Scanner, Policy, Feedser, and the attestation chain. It is implementation‑ready.
|
||||
|
||||
---
|
||||
|
||||
## 0) Mission & role in the platform
|
||||
|
||||
**Mission.** Convert heterogeneous **VEX** statements (OpenVEX, CSAF VEX, CycloneDX VEX; vendor/distro/platform sources) into **canonical, queryable claims**; compute **deterministic consensus** per *(vuln, product)*; preserve **conflicts with provenance**; publish **stable, attestable exports** that the backend uses to suppress non‑exploitable findings, prioritize remaining risk, and explain decisions.
|
||||
|
||||
**Boundaries.**
|
||||
|
||||
* Vexer **does not** decide PASS/FAIL. It supplies **evidence** (statuses + justifications + provenance weights).
|
||||
* Vexer preserves **conflicting claims** unchanged; consensus encodes how we would pick, but the raw set is always exportable.
|
||||
* VEX consumption is **backend‑only**: Scanner never applies VEX. The backend’s **Policy Engine** asks Vexer for status evidence and then decides what to show.
|
||||
|
||||
---
|
||||
|
||||
## 1) Inputs, outputs & canonical domain
|
||||
|
||||
### 1.1 Accepted input formats (ingest)
|
||||
|
||||
* **OpenVEX** JSON documents (attested or raw).
|
||||
* **CSAF VEX** 2.x (vendor PSIRTs and distros commonly publish CSAF).
|
||||
* **CycloneDX VEX** 1.4+ (standalone VEX or embedded VEX blocks).
|
||||
* **OCI‑attached attestations** (VEX statements shipped as OCI referrers) — optional connectors.
|
||||
|
||||
All connectors register **source metadata**: provider identity, trust tier, signature expectations (PGP/cosign/PKI), fetch windows, rate limits, and time anchors.
|
||||
|
||||
### 1.2 Canonical model (normalized)
|
||||
|
||||
Every incoming statement becomes a set of **VexClaim** records:
|
||||
|
||||
```
|
||||
VexClaim
|
||||
- providerId // 'redhat', 'suse', 'ubuntu', 'github', 'vendorX'
|
||||
- vulnId // 'CVE-2025-12345', 'GHSA-xxxx', canonicalized
|
||||
- productKey // canonical product identity (see §2.2)
|
||||
- status // affected | not_affected | fixed | under_investigation
|
||||
- justification? // for 'not_affected'/'affected' where provided
|
||||
- introducedVersion? // semantics per provider (range or exact)
|
||||
- fixedVersion? // where provided (range or exact)
|
||||
- lastObserved // timestamp from source or fetch time
|
||||
- provenance // doc digest, signature status, fetch URI, line/offset anchors
|
||||
- evidence[] // raw source snippets for explainability
|
||||
- supersedes? // optional cross-doc chain (docDigest → docDigest)
|
||||
```
|
||||
|
||||
### 1.3 Exports (consumption)
|
||||
|
||||
* **VexConsensus** per `(vulnId, productKey)` with:
|
||||
|
||||
* `rollupStatus` (after policy weights/justification gates),
|
||||
* `sources[]` (winning + losing claims with weights & reasons),
|
||||
* `policyRevisionId` (identifier of the Vexer policy used),
|
||||
* `consensusDigest` (stable SHA‑256 over canonical JSON).
|
||||
* **Raw claims** export for auditing (unchanged, with provenance).
|
||||
* **Provider snapshots** (per source, last N days) for operator debugging.
|
||||
* **Index** optimized for backend joins: `(productKey, vulnId) → (status, confidence, sourceSet)`.
|
||||
|
||||
All exports are **deterministic**, and (optionally) **attested** via DSSE and logged to Rekor v2.
|
||||
|
||||
---
|
||||
|
||||
## 2) Identity model — products & joins
|
||||
|
||||
### 2.1 Vuln identity
|
||||
|
||||
* Accepts **CVE**, **GHSA**, vendor IDs (MSRC, RHSA…), distro IDs (DSA/USN/RHSA…) — normalized to `vulnId` with alias sets.
|
||||
* **Alias graph** maintained (from Feedser) to map vendor/distro IDs → CVE (primary) and to **GHSA** where applicable.
|
||||
|
||||
### 2.2 Product identity (`productKey`)
|
||||
|
||||
* **Primary:** `purl` (Package URL).
|
||||
* **Secondary links:** `cpe`, **OS package NVRA/EVR**, NuGet/Maven/Golang identity, and **OS package name** when purl unavailable.
|
||||
* **Fallback:** `oci:<registry>/<repo>@<digest>` for image‑level VEX.
|
||||
* **Special cases:** kernel modules, firmware, platforms → provider‑specific mapping helpers (connector captures provider’s product taxonomy → canonical `productKey`).
|
||||
|
||||
> Vexer does not invent identities. If a provider cannot be mapped to purl/CPE/NVRA deterministically, we keep the native **product string** and mark the claim as **non‑joinable**; the backend will ignore it unless a policy explicitly whitelists that provider mapping.
|
||||
|
||||
---
|
||||
|
||||
## 3) Storage schema (MongoDB)
|
||||
|
||||
Database: `vexer`
|
||||
|
||||
### 3.1 Collections
|
||||
|
||||
**`vex.providers`**
|
||||
|
||||
```
|
||||
_id: providerId
|
||||
name, homepage, contact
|
||||
trustTier: enum {vendor, distro, platform, hub, attestation}
|
||||
signaturePolicy: { type: pgp|cosign|x509|none, keys[], certs[], cosignKeylessRoots[] }
|
||||
fetch: { baseUrl, kind: http|oci|file, rateLimit, etagSupport, windowDays }
|
||||
enabled: bool
|
||||
createdAt, modifiedAt
|
||||
```
|
||||
|
||||
**`vex.raw`** (immutable raw documents)
|
||||
|
||||
```
|
||||
_id: sha256(doc bytes)
|
||||
providerId
|
||||
uri
|
||||
ingestedAt
|
||||
contentType
|
||||
sig: { verified: bool, method: pgp|cosign|x509|none, keyId|certSubject, bundle? }
|
||||
payload: GridFS pointer (if large)
|
||||
disposition: kept|replaced|superseded
|
||||
correlation: { replaces?: sha256, replacedBy?: sha256 }
|
||||
```
|
||||
|
||||
**`vex.claims`** (normalized rows; dedupe on providerId+vulnId+productKey+docDigest)
|
||||
|
||||
```
|
||||
_id
|
||||
providerId
|
||||
vulnId
|
||||
productKey
|
||||
status
|
||||
justification?
|
||||
introducedVersion?
|
||||
fixedVersion?
|
||||
lastObserved
|
||||
docDigest
|
||||
provenance { uri, line?, pointer?, signatureState }
|
||||
evidence[] { key, value, locator }
|
||||
indices:
|
||||
- {vulnId:1, productKey:1}
|
||||
- {providerId:1, lastObserved:-1}
|
||||
- {status:1}
|
||||
- text index (optional) on evidence.value for debugging
|
||||
```
|
||||
|
||||
**`vex.consensus`** (rollups)
|
||||
|
||||
```
|
||||
_id: sha256(canonical(vulnId, productKey, policyRevision))
|
||||
vulnId
|
||||
productKey
|
||||
rollupStatus
|
||||
sources[]: [
|
||||
{ providerId, status, justification?, weight, lastObserved, accepted:bool, reason }
|
||||
]
|
||||
policyRevisionId
|
||||
evaluatedAt
|
||||
consensusDigest // same as _id
|
||||
indices:
|
||||
- {vulnId:1, productKey:1}
|
||||
- {policyRevisionId:1, evaluatedAt:-1}
|
||||
```
|
||||
|
||||
**`vex.exports`** (manifest of emitted artifacts)
|
||||
|
||||
```
|
||||
_id
|
||||
querySignature
|
||||
format: raw|consensus|index
|
||||
artifactSha256
|
||||
rekor { uuid, index, url }?
|
||||
createdAt
|
||||
policyRevisionId
|
||||
cacheable: bool
|
||||
```
|
||||
|
||||
**`vex.cache`**
|
||||
|
||||
```
|
||||
querySignature -> exportId (for fast reuse)
|
||||
ttl, hits
|
||||
```
|
||||
|
||||
**`vex.migrations`**
|
||||
|
||||
* ordered migrations applied at bootstrap to ensure indexes.
|
||||
|
||||
### 3.2 Indexing strategy
|
||||
|
||||
* Hot path queries use exact `(vulnId, productKey)` and time‑bounded windows; compound indexes cover both.
|
||||
* Providers list view by `lastObserved` for monitoring staleness.
|
||||
* `vex.consensus` keyed by `(vulnId, productKey, policyRevision)` for deterministic reuse.
|
||||
|
||||
---
|
||||
|
||||
## 4) Ingestion pipeline
|
||||
|
||||
### 4.1 Connector contract
|
||||
|
||||
```csharp
|
||||
public interface IVexConnector
|
||||
{
|
||||
string ProviderId { get; }
|
||||
Task FetchAsync(VexConnectorContext ctx, CancellationToken ct); // raw docs
|
||||
Task NormalizeAsync(VexConnectorContext ctx, CancellationToken ct); // raw -> VexClaim[]
|
||||
}
|
||||
```
|
||||
|
||||
* **Fetch** must implement: window scheduling, conditional GET (ETag/If‑Modified‑Since), rate limiting, retry/backoff.
|
||||
* **Normalize** parses the format, validates schema, maps product identities deterministically, emits `VexClaim` records with **provenance**.
|
||||
|
||||
### 4.2 Signature verification (per provider)
|
||||
|
||||
* **cosign (keyless or keyful)** for OCI referrers or HTTP‑served JSON with Sigstore bundles.
|
||||
* **PGP** (provider keyrings) for distro/vendor feeds that sign docs.
|
||||
* **x509** (mutual TLS / provider‑pinned certs) where applicable.
|
||||
* Signature state is stored on **vex.raw.sig** and copied into **provenance.signatureState** on claims.
|
||||
|
||||
> Claims from sources failing signature policy are marked `"signatureState.verified=false"` and **policy** can down‑weight or ignore them.
|
||||
|
||||
### 4.3 Time discipline
|
||||
|
||||
* For each doc, prefer **provider’s document timestamp**; if absent, use fetch time.
|
||||
* Claims carry `lastObserved` which drives **tie‑breaking** within equal weight tiers.
|
||||
|
||||
---
|
||||
|
||||
## 5) Normalization: product & status semantics
|
||||
|
||||
### 5.1 Product mapping
|
||||
|
||||
* **purl** first; **cpe** second; OS package NVRA/EVR mapping helpers (distro connectors) produce purls via canonical tables (e.g., rpm→purl:rpm, deb→purl:deb).
|
||||
* Where a provider publishes **platform‑level** VEX (e.g., “RHEL 9 not affected”), connectors expand to known product inventory rules (e.g., map to sets of packages/components shipped in the platform). Expansion tables are versioned and kept per provider; every expansion emits **evidence** indicating the rule applied.
|
||||
* If expansion would be speculative, the claim remains **platform‑scoped** with `productKey="platform:redhat:rhel:9"` and is flagged **non‑joinable**; backend can decide to use platform VEX only when Scanner proves the platform runtime.
|
||||
|
||||
### 5.2 Status + justification mapping
|
||||
|
||||
* Canonical **status**: `affected | not_affected | fixed | under_investigation`.
|
||||
* **Justifications** normalized to a controlled vocabulary (CISA‑aligned), e.g.:
|
||||
|
||||
* `component_not_present`
|
||||
* `vulnerable_code_not_in_execute_path`
|
||||
* `vulnerable_configuration_unused`
|
||||
* `inline_mitigation_applied`
|
||||
* `fix_available` (with `fixedVersion`)
|
||||
* `under_investigation`
|
||||
* Providers with free‑text justifications are mapped by deterministic tables; raw text preserved as `evidence`.
|
||||
|
||||
---
|
||||
|
||||
## 6) Consensus algorithm
|
||||
|
||||
**Goal:** produce a **stable**, explainable `rollupStatus` per `(vulnId, productKey)` given possibly conflicting claims.
|
||||
|
||||
### 6.1 Inputs
|
||||
|
||||
* Set **S** of `VexClaim` for the key.
|
||||
* **Vexer policy snapshot**:
|
||||
|
||||
* **weights** per provider tier and per provider overrides.
|
||||
* **justification gates** (e.g., require justification for `not_affected` to be acceptable).
|
||||
* **minEvidence** rules (e.g., `not_affected` must come from ≥1 vendor or 2 distros).
|
||||
* **signature requirements** (e.g., require verified signature for ‘fixed’ to be considered).
|
||||
|
||||
### 6.2 Steps
|
||||
|
||||
1. **Filter invalid** claims by signature policy & justification gates → set `S'`.
|
||||
2. **Score** each claim:
|
||||
`score = weight(provider) * freshnessFactor(lastObserved)` where freshnessFactor ∈ [0.8, 1.0] for staleness decay (configurable; small effect).
|
||||
3. **Aggregate** scores per status: `W(status) = Σ score(claims with that status)`.
|
||||
4. **Pick** `rollupStatus = argmax_status W(status)`.
|
||||
5. **Tie‑breakers** (in order):
|
||||
|
||||
* Higher **max single** provider score wins (vendor > distro > platform > hub).
|
||||
* More **recent** lastObserved wins.
|
||||
* Deterministic lexicographic order of status (`fixed` > `not_affected` > `under_investigation` > `affected`) as final tiebreaker.
|
||||
6. **Explain**: mark accepted sources (`accepted=true; reason="weight"`/`"freshness"`), mark rejected sources with explicit `reason` (`"insufficient_justification"`, `"signature_unverified"`, `"lower_weight"`).
|
||||
|
||||
> The algorithm is **pure** given S and policy snapshot; result is reproducible and hashed into `consensusDigest`.
|
||||
|
||||
---
|
||||
|
||||
## 7) Query & export APIs
|
||||
|
||||
All endpoints are versioned under `/api/v1/vex`.
|
||||
|
||||
### 7.1 Query (online)
|
||||
|
||||
```
|
||||
POST /claims/search
|
||||
body: { vulnIds?: string[], productKeys?: string[], providers?: string[], since?: timestamp, limit?: int, pageToken?: string }
|
||||
→ { claims[], nextPageToken? }
|
||||
|
||||
POST /consensus/search
|
||||
body: { vulnIds?: string[], productKeys?: string[], policyRevisionId?: string, since?: timestamp, limit?: int, pageToken?: string }
|
||||
→ { entries[], nextPageToken? }
|
||||
|
||||
POST /excititor/resolve (scope: vex.read)
|
||||
body: { productKeys?: string[], purls?: string[], vulnerabilityIds: string[], policyRevisionId?: string }
|
||||
→ { policy, resolvedAt, results: [ { vulnerabilityId, productKey, status, sources[], conflicts[], decisions[], signals?, summary?, envelope: { artifact, contentSignature?, attestation?, attestationEnvelope?, attestationSignature? } } ] }
|
||||
```
|
||||
|
||||
### 7.2 Exports (cacheable snapshots)
|
||||
|
||||
```
|
||||
POST /exports
|
||||
body: { signature: { vulnFilter?, productFilter?, providers?, since? }, format: raw|consensus|index, policyRevisionId?: string, force?: bool }
|
||||
→ { exportId, artifactSha256, rekor? }
|
||||
|
||||
GET /exports/{exportId} → bytes (application/json or binary index)
|
||||
GET /exports/{exportId}/meta → { signature, policyRevisionId, createdAt, artifactSha256, rekor? }
|
||||
```
|
||||
|
||||
### 7.3 Provider operations
|
||||
|
||||
```
|
||||
GET /providers → provider list & signature policy
|
||||
POST /providers/{id}/refresh → trigger fetch/normalize window
|
||||
GET /providers/{id}/status → last fetch, doc counts, signature stats
|
||||
```
|
||||
|
||||
**Auth:** service‑to‑service via Authority tokens; operator operations via UI/CLI with RBAC.
|
||||
|
||||
---
|
||||
|
||||
## 8) Attestation integration
|
||||
|
||||
* Exports can be **DSSE‑signed** via **Signer** and logged to **Rekor v2** via **Attestor** (optional but recommended for regulated pipelines).
|
||||
* `vex.exports.rekor` stores `{uuid, index, url}` when present.
|
||||
* **Predicate type**: `https://stella-ops.org/attestations/vex-export/1` with fields:
|
||||
|
||||
* `querySignature`, `policyRevisionId`, `artifactSha256`, `createdAt`.
|
||||
|
||||
---
|
||||
|
||||
## 9) Configuration (YAML)
|
||||
|
||||
```yaml
|
||||
vexer:
|
||||
mongo: { uri: "mongodb://mongo/vexer" }
|
||||
s3:
|
||||
endpoint: http://minio:9000
|
||||
bucket: stellaops
|
||||
policy:
|
||||
weights:
|
||||
vendor: 1.0
|
||||
distro: 0.9
|
||||
platform: 0.7
|
||||
hub: 0.5
|
||||
attestation: 0.6
|
||||
providerOverrides:
|
||||
redhat: 1.0
|
||||
suse: 0.95
|
||||
requireJustificationForNotAffected: true
|
||||
signatureRequiredForFixed: true
|
||||
minEvidence:
|
||||
not_affected:
|
||||
vendorOrTwoDistros: true
|
||||
connectors:
|
||||
- providerId: redhat
|
||||
kind: csaf
|
||||
baseUrl: https://access.redhat.com/security/data/csaf/v2/
|
||||
signaturePolicy: { type: pgp, keys: [ "…redhat-pgp-key…" ] }
|
||||
windowDays: 7
|
||||
- providerId: suse
|
||||
kind: csaf
|
||||
baseUrl: https://ftp.suse.com/pub/projects/security/csaf/
|
||||
signaturePolicy: { type: pgp, keys: [ "…suse-pgp-key…" ] }
|
||||
- providerId: ubuntu
|
||||
kind: openvex
|
||||
baseUrl: https://…/vex/
|
||||
signaturePolicy: { type: none }
|
||||
- providerId: vendorX
|
||||
kind: cyclonedx-vex
|
||||
ociRef: ghcr.io/vendorx/vex@sha256:…
|
||||
signaturePolicy: { type: cosign, cosignKeylessRoots: [ "sigstore-root" ] }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10) Security model
|
||||
|
||||
* **Input signature verification** enforced per provider policy (PGP, cosign, x509).
|
||||
* **Connector allowlists**: outbound fetch constrained to configured domains.
|
||||
* **Tenant isolation**: per‑tenant DB prefixes or separate DBs; per‑tenant S3 prefixes; per‑tenant policies.
|
||||
* **AuthN/Z**: Authority‑issued OpToks; RBAC roles (`vex.read`, `vex.admin`, `vex.export`).
|
||||
* **No secrets in logs**; deterministic logging contexts include providerId, docDigest, claim keys.
|
||||
|
||||
---
|
||||
|
||||
## 11) Performance & scale
|
||||
|
||||
* **Targets:**
|
||||
|
||||
* Normalize 10k VEX claims/minute/core.
|
||||
* Consensus compute ≤ 50 ms for 1k unique `(vuln, product)` pairs in hot cache.
|
||||
* Export (consensus) 1M rows in ≤ 60 s on 8 cores with streaming writer.
|
||||
|
||||
* **Scaling:**
|
||||
|
||||
* WebService handles control APIs; **Worker** background services (same image) execute fetch/normalize in parallel with rate‑limits; Mongo writes batched; upserts by natural keys.
|
||||
* Exports stream straight to S3 (MinIO) with rolling buffers.
|
||||
|
||||
* **Caching:**
|
||||
|
||||
* `vex.cache` maps query signatures → export; TTL to avoid stampedes; optimistic reuse unless `force`.
|
||||
|
||||
---
|
||||
|
||||
## 12) Observability
|
||||
|
||||
* **Metrics:**
|
||||
|
||||
* `vex.ingest.docs_total{provider}`
|
||||
* `vex.normalize.claims_total{provider}`
|
||||
* `vex.signature.failures_total{provider,method}`
|
||||
* `vex.consensus.conflicts_total{vulnId}`
|
||||
* `vex.exports.bytes{format}` / `vex.exports.latency_seconds`
|
||||
* **Tracing:** spans for fetch, verify, parse, map, consensus, export.
|
||||
* **Dashboards:** provider staleness, top conflicting vulns/components, signature posture, export cache hit‑rate.
|
||||
|
||||
---
|
||||
|
||||
## 13) Testing matrix
|
||||
|
||||
* **Connectors:** golden raw docs → deterministic claims (fixtures per provider/format).
|
||||
* **Signature policies:** valid/invalid PGP/cosign/x509 samples; ensure rejects are recorded but not accepted.
|
||||
* **Normalization edge cases:** platform‑only claims, free‑text justifications, non‑purl products.
|
||||
* **Consensus:** conflict scenarios across tiers; check tie‑breakers; justification gates.
|
||||
* **Performance:** 1M‑row export timing; memory ceilings; stream correctness.
|
||||
* **Determinism:** same inputs + policy → identical `consensusDigest` and export bytes.
|
||||
* **API contract tests:** pagination, filters, RBAC, rate limits.
|
||||
|
||||
---
|
||||
|
||||
## 14) Integration points
|
||||
|
||||
* **Backend Policy Engine** (in Scanner.WebService): calls `POST /excititor/resolve` (scope `vex.read`) with batched `(purl, vulnId)` pairs to fetch `rollupStatus + sources`.
|
||||
* **Feedser**: provides alias graph (CVE↔vendor IDs) and may supply VEX‑adjacent metadata (e.g., KEV flag) for policy escalation.
|
||||
* **UI**: VEX explorer screens use `/claims/search` and `/consensus/search`; show conflicts & provenance.
|
||||
* **CLI**: `stellaops vex export --consensus --since 7d --out vex.json` for audits.
|
||||
|
||||
---
|
||||
|
||||
## 15) Failure modes & fallback
|
||||
|
||||
* **Provider unreachable:** stale thresholds trigger warnings; policy can down‑weight stale providers automatically (freshness factor).
|
||||
* **Signature outage:** continue to ingest but mark `signatureState.verified=false`; consensus will likely exclude or down‑weight per policy.
|
||||
* **Schema drift:** unknown fields are preserved as `evidence`; normalization rejects only on **invalid identity** or **status**.
|
||||
|
||||
---
|
||||
|
||||
## 16) Rollout plan (incremental)
|
||||
|
||||
1. **MVP**: OpenVEX + CSAF connectors for 3 major providers (e.g., Red Hat/SUSE/Ubuntu), normalization + consensus + `/excititor/resolve`.
|
||||
2. **Signature policies**: PGP for distros; cosign for OCI.
|
||||
3. **Exports + optional attestation**.
|
||||
4. **CycloneDX VEX** connectors; platform claim expansion tables; UI explorer.
|
||||
5. **Scale hardening**: export indexes; conflict analytics.
|
||||
|
||||
---
|
||||
|
||||
## 17) Appendix — canonical JSON (stable ordering)
|
||||
|
||||
All exports and consensus entries are serialized via `VexCanonicalJsonSerializer`:
|
||||
|
||||
* UTF‑8 without BOM;
|
||||
* keys sorted (ASCII);
|
||||
* arrays sorted by `(providerId, vulnId, productKey, lastObserved)` unless semantic order mandated;
|
||||
* timestamps in `YYYY‑MM‑DDThh:mm:ssZ`;
|
||||
* no insignificant whitespace.
|
||||
|
||||
|
||||
> **Scope.** This document specifies the **Excitor** service: its purpose, trust model, data structures, APIs, plug‑in contracts, storage schema, normalization/consensus algorithms, performance budgets, testing matrix, and how it integrates with Scanner, Policy, Conselier, and the attestation chain. It is implementation‑ready.
|
||||
|
||||
---
|
||||
|
||||
## 0) Mission & role in the platform
|
||||
|
||||
**Mission.** Convert heterogeneous **VEX** statements (OpenVEX, CSAF VEX, CycloneDX VEX; vendor/distro/platform sources) into **canonical, queryable claims**; compute **deterministic consensus** per *(vuln, product)*; preserve **conflicts with provenance**; publish **stable, attestable exports** that the backend uses to suppress non‑exploitable findings, prioritize remaining risk, and explain decisions.
|
||||
|
||||
**Boundaries.**
|
||||
|
||||
* Excitor **does not** decide PASS/FAIL. It supplies **evidence** (statuses + justifications + provenance weights).
|
||||
* Excitor preserves **conflicting claims** unchanged; consensus encodes how we would pick, but the raw set is always exportable.
|
||||
* VEX consumption is **backend‑only**: Scanner never applies VEX. The backend’s **Policy Engine** asks Excitor for status evidence and then decides what to show.
|
||||
|
||||
---
|
||||
|
||||
## 1) Inputs, outputs & canonical domain
|
||||
|
||||
### 1.1 Accepted input formats (ingest)
|
||||
|
||||
* **OpenVEX** JSON documents (attested or raw).
|
||||
* **CSAF VEX** 2.x (vendor PSIRTs and distros commonly publish CSAF).
|
||||
* **CycloneDX VEX** 1.4+ (standalone VEX or embedded VEX blocks).
|
||||
* **OCI‑attached attestations** (VEX statements shipped as OCI referrers) — optional connectors.
|
||||
|
||||
All connectors register **source metadata**: provider identity, trust tier, signature expectations (PGP/cosign/PKI), fetch windows, rate limits, and time anchors.
|
||||
|
||||
### 1.2 Canonical model (normalized)
|
||||
|
||||
Every incoming statement becomes a set of **VexClaim** records:
|
||||
|
||||
```
|
||||
VexClaim
|
||||
- providerId // 'redhat', 'suse', 'ubuntu', 'github', 'vendorX'
|
||||
- vulnId // 'CVE-2025-12345', 'GHSA-xxxx', canonicalized
|
||||
- productKey // canonical product identity (see §2.2)
|
||||
- status // affected | not_affected | fixed | under_investigation
|
||||
- justification? // for 'not_affected'/'affected' where provided
|
||||
- introducedVersion? // semantics per provider (range or exact)
|
||||
- fixedVersion? // where provided (range or exact)
|
||||
- lastObserved // timestamp from source or fetch time
|
||||
- provenance // doc digest, signature status, fetch URI, line/offset anchors
|
||||
- evidence[] // raw source snippets for explainability
|
||||
- supersedes? // optional cross-doc chain (docDigest → docDigest)
|
||||
```
|
||||
|
||||
### 1.3 Exports (consumption)
|
||||
|
||||
* **VexConsensus** per `(vulnId, productKey)` with:
|
||||
|
||||
* `rollupStatus` (after policy weights/justification gates),
|
||||
* `sources[]` (winning + losing claims with weights & reasons),
|
||||
* `policyRevisionId` (identifier of the Excitor policy used),
|
||||
* `consensusDigest` (stable SHA‑256 over canonical JSON).
|
||||
* **Raw claims** export for auditing (unchanged, with provenance).
|
||||
* **Provider snapshots** (per source, last N days) for operator debugging.
|
||||
* **Index** optimized for backend joins: `(productKey, vulnId) → (status, confidence, sourceSet)`.
|
||||
|
||||
All exports are **deterministic**, and (optionally) **attested** via DSSE and logged to Rekor v2.
|
||||
|
||||
---
|
||||
|
||||
## 2) Identity model — products & joins
|
||||
|
||||
### 2.1 Vuln identity
|
||||
|
||||
* Accepts **CVE**, **GHSA**, vendor IDs (MSRC, RHSA…), distro IDs (DSA/USN/RHSA…) — normalized to `vulnId` with alias sets.
|
||||
* **Alias graph** maintained (from Conselier) to map vendor/distro IDs → CVE (primary) and to **GHSA** where applicable.
|
||||
|
||||
### 2.2 Product identity (`productKey`)
|
||||
|
||||
* **Primary:** `purl` (Package URL).
|
||||
* **Secondary links:** `cpe`, **OS package NVRA/EVR**, NuGet/Maven/Golang identity, and **OS package name** when purl unavailable.
|
||||
* **Fallback:** `oci:<registry>/<repo>@<digest>` for image‑level VEX.
|
||||
* **Special cases:** kernel modules, firmware, platforms → provider‑specific mapping helpers (connector captures provider’s product taxonomy → canonical `productKey`).
|
||||
|
||||
> Excitor does not invent identities. If a provider cannot be mapped to purl/CPE/NVRA deterministically, we keep the native **product string** and mark the claim as **non‑joinable**; the backend will ignore it unless a policy explicitly whitelists that provider mapping.
|
||||
|
||||
---
|
||||
|
||||
## 3) Storage schema (MongoDB)
|
||||
|
||||
Database: `excitor`
|
||||
|
||||
### 3.1 Collections
|
||||
|
||||
**`vex.providers`**
|
||||
|
||||
```
|
||||
_id: providerId
|
||||
name, homepage, contact
|
||||
trustTier: enum {vendor, distro, platform, hub, attestation}
|
||||
signaturePolicy: { type: pgp|cosign|x509|none, keys[], certs[], cosignKeylessRoots[] }
|
||||
fetch: { baseUrl, kind: http|oci|file, rateLimit, etagSupport, windowDays }
|
||||
enabled: bool
|
||||
createdAt, modifiedAt
|
||||
```
|
||||
|
||||
**`vex.raw`** (immutable raw documents)
|
||||
|
||||
```
|
||||
_id: sha256(doc bytes)
|
||||
providerId
|
||||
uri
|
||||
ingestedAt
|
||||
contentType
|
||||
sig: { verified: bool, method: pgp|cosign|x509|none, keyId|certSubject, bundle? }
|
||||
payload: GridFS pointer (if large)
|
||||
disposition: kept|replaced|superseded
|
||||
correlation: { replaces?: sha256, replacedBy?: sha256 }
|
||||
```
|
||||
|
||||
**`vex.claims`** (normalized rows; dedupe on providerId+vulnId+productKey+docDigest)
|
||||
|
||||
```
|
||||
_id
|
||||
providerId
|
||||
vulnId
|
||||
productKey
|
||||
status
|
||||
justification?
|
||||
introducedVersion?
|
||||
fixedVersion?
|
||||
lastObserved
|
||||
docDigest
|
||||
provenance { uri, line?, pointer?, signatureState }
|
||||
evidence[] { key, value, locator }
|
||||
indices:
|
||||
- {vulnId:1, productKey:1}
|
||||
- {providerId:1, lastObserved:-1}
|
||||
- {status:1}
|
||||
- text index (optional) on evidence.value for debugging
|
||||
```
|
||||
|
||||
**`vex.consensus`** (rollups)
|
||||
|
||||
```
|
||||
_id: sha256(canonical(vulnId, productKey, policyRevision))
|
||||
vulnId
|
||||
productKey
|
||||
rollupStatus
|
||||
sources[]: [
|
||||
{ providerId, status, justification?, weight, lastObserved, accepted:bool, reason }
|
||||
]
|
||||
policyRevisionId
|
||||
evaluatedAt
|
||||
consensusDigest // same as _id
|
||||
indices:
|
||||
- {vulnId:1, productKey:1}
|
||||
- {policyRevisionId:1, evaluatedAt:-1}
|
||||
```
|
||||
|
||||
**`vex.exports`** (manifest of emitted artifacts)
|
||||
|
||||
```
|
||||
_id
|
||||
querySignature
|
||||
format: raw|consensus|index
|
||||
artifactSha256
|
||||
rekor { uuid, index, url }?
|
||||
createdAt
|
||||
policyRevisionId
|
||||
cacheable: bool
|
||||
```
|
||||
|
||||
**`vex.cache`**
|
||||
|
||||
```
|
||||
querySignature -> exportId (for fast reuse)
|
||||
ttl, hits
|
||||
```
|
||||
|
||||
**`vex.migrations`**
|
||||
|
||||
* ordered migrations applied at bootstrap to ensure indexes.
|
||||
|
||||
### 3.2 Indexing strategy
|
||||
|
||||
* Hot path queries use exact `(vulnId, productKey)` and time‑bounded windows; compound indexes cover both.
|
||||
* Providers list view by `lastObserved` for monitoring staleness.
|
||||
* `vex.consensus` keyed by `(vulnId, productKey, policyRevision)` for deterministic reuse.
|
||||
|
||||
---
|
||||
|
||||
## 4) Ingestion pipeline
|
||||
|
||||
### 4.1 Connector contract
|
||||
|
||||
```csharp
|
||||
public interface IVexConnector
|
||||
{
|
||||
string ProviderId { get; }
|
||||
Task FetchAsync(VexConnectorContext ctx, CancellationToken ct); // raw docs
|
||||
Task NormalizeAsync(VexConnectorContext ctx, CancellationToken ct); // raw -> VexClaim[]
|
||||
}
|
||||
```
|
||||
|
||||
* **Fetch** must implement: window scheduling, conditional GET (ETag/If‑Modified‑Since), rate limiting, retry/backoff.
|
||||
* **Normalize** parses the format, validates schema, maps product identities deterministically, emits `VexClaim` records with **provenance**.
|
||||
|
||||
### 4.2 Signature verification (per provider)
|
||||
|
||||
* **cosign (keyless or keyful)** for OCI referrers or HTTP‑served JSON with Sigstore bundles.
|
||||
* **PGP** (provider keyrings) for distro/vendor feeds that sign docs.
|
||||
* **x509** (mutual TLS / provider‑pinned certs) where applicable.
|
||||
* Signature state is stored on **vex.raw.sig** and copied into **provenance.signatureState** on claims.
|
||||
|
||||
> Claims from sources failing signature policy are marked `"signatureState.verified=false"` and **policy** can down‑weight or ignore them.
|
||||
|
||||
### 4.3 Time discipline
|
||||
|
||||
* For each doc, prefer **provider’s document timestamp**; if absent, use fetch time.
|
||||
* Claims carry `lastObserved` which drives **tie‑breaking** within equal weight tiers.
|
||||
|
||||
---
|
||||
|
||||
## 5) Normalization: product & status semantics
|
||||
|
||||
### 5.1 Product mapping
|
||||
|
||||
* **purl** first; **cpe** second; OS package NVRA/EVR mapping helpers (distro connectors) produce purls via canonical tables (e.g., rpm→purl:rpm, deb→purl:deb).
|
||||
* Where a provider publishes **platform‑level** VEX (e.g., “RHEL 9 not affected”), connectors expand to known product inventory rules (e.g., map to sets of packages/components shipped in the platform). Expansion tables are versioned and kept per provider; every expansion emits **evidence** indicating the rule applied.
|
||||
* If expansion would be speculative, the claim remains **platform‑scoped** with `productKey="platform:redhat:rhel:9"` and is flagged **non‑joinable**; backend can decide to use platform VEX only when Scanner proves the platform runtime.
|
||||
|
||||
### 5.2 Status + justification mapping
|
||||
|
||||
* Canonical **status**: `affected | not_affected | fixed | under_investigation`.
|
||||
* **Justifications** normalized to a controlled vocabulary (CISA‑aligned), e.g.:
|
||||
|
||||
* `component_not_present`
|
||||
* `vulnerable_code_not_in_execute_path`
|
||||
* `vulnerable_configuration_unused`
|
||||
* `inline_mitigation_applied`
|
||||
* `fix_available` (with `fixedVersion`)
|
||||
* `under_investigation`
|
||||
* Providers with free‑text justifications are mapped by deterministic tables; raw text preserved as `evidence`.
|
||||
|
||||
---
|
||||
|
||||
## 6) Consensus algorithm
|
||||
|
||||
**Goal:** produce a **stable**, explainable `rollupStatus` per `(vulnId, productKey)` given possibly conflicting claims.
|
||||
|
||||
### 6.1 Inputs
|
||||
|
||||
* Set **S** of `VexClaim` for the key.
|
||||
* **Excitor policy snapshot**:
|
||||
|
||||
* **weights** per provider tier and per provider overrides.
|
||||
* **justification gates** (e.g., require justification for `not_affected` to be acceptable).
|
||||
* **minEvidence** rules (e.g., `not_affected` must come from ≥1 vendor or 2 distros).
|
||||
* **signature requirements** (e.g., require verified signature for ‘fixed’ to be considered).
|
||||
|
||||
### 6.2 Steps
|
||||
|
||||
1. **Filter invalid** claims by signature policy & justification gates → set `S'`.
|
||||
2. **Score** each claim:
|
||||
`score = weight(provider) * freshnessFactor(lastObserved)` where freshnessFactor ∈ [0.8, 1.0] for staleness decay (configurable; small effect).
|
||||
3. **Aggregate** scores per status: `W(status) = Σ score(claims with that status)`.
|
||||
4. **Pick** `rollupStatus = argmax_status W(status)`.
|
||||
5. **Tie‑breakers** (in order):
|
||||
|
||||
* Higher **max single** provider score wins (vendor > distro > platform > hub).
|
||||
* More **recent** lastObserved wins.
|
||||
* Deterministic lexicographic order of status (`fixed` > `not_affected` > `under_investigation` > `affected`) as final tiebreaker.
|
||||
6. **Explain**: mark accepted sources (`accepted=true; reason="weight"`/`"freshness"`), mark rejected sources with explicit `reason` (`"insufficient_justification"`, `"signature_unverified"`, `"lower_weight"`).
|
||||
|
||||
> The algorithm is **pure** given S and policy snapshot; result is reproducible and hashed into `consensusDigest`.
|
||||
|
||||
---
|
||||
|
||||
## 7) Query & export APIs
|
||||
|
||||
All endpoints are versioned under `/api/v1/vex`.
|
||||
|
||||
### 7.1 Query (online)
|
||||
|
||||
```
|
||||
POST /claims/search
|
||||
body: { vulnIds?: string[], productKeys?: string[], providers?: string[], since?: timestamp, limit?: int, pageToken?: string }
|
||||
→ { claims[], nextPageToken? }
|
||||
|
||||
POST /consensus/search
|
||||
body: { vulnIds?: string[], productKeys?: string[], policyRevisionId?: string, since?: timestamp, limit?: int, pageToken?: string }
|
||||
→ { entries[], nextPageToken? }
|
||||
|
||||
POST /excititor/resolve (scope: vex.read)
|
||||
body: { productKeys?: string[], purls?: string[], vulnerabilityIds: string[], policyRevisionId?: string }
|
||||
→ { policy, resolvedAt, results: [ { vulnerabilityId, productKey, status, sources[], conflicts[], decisions[], signals?, summary?, envelope: { artifact, contentSignature?, attestation?, attestationEnvelope?, attestationSignature? } } ] }
|
||||
```
|
||||
|
||||
### 7.2 Exports (cacheable snapshots)
|
||||
|
||||
```
|
||||
POST /exports
|
||||
body: { signature: { vulnFilter?, productFilter?, providers?, since? }, format: raw|consensus|index, policyRevisionId?: string, force?: bool }
|
||||
→ { exportId, artifactSha256, rekor? }
|
||||
|
||||
GET /exports/{exportId} → bytes (application/json or binary index)
|
||||
GET /exports/{exportId}/meta → { signature, policyRevisionId, createdAt, artifactSha256, rekor? }
|
||||
```
|
||||
|
||||
### 7.3 Provider operations
|
||||
|
||||
```
|
||||
GET /providers → provider list & signature policy
|
||||
POST /providers/{id}/refresh → trigger fetch/normalize window
|
||||
GET /providers/{id}/status → last fetch, doc counts, signature stats
|
||||
```
|
||||
|
||||
**Auth:** service‑to‑service via Authority tokens; operator operations via UI/CLI with RBAC.
|
||||
|
||||
---
|
||||
|
||||
## 8) Attestation integration
|
||||
|
||||
* Exports can be **DSSE‑signed** via **Signer** and logged to **Rekor v2** via **Attestor** (optional but recommended for regulated pipelines).
|
||||
* `vex.exports.rekor` stores `{uuid, index, url}` when present.
|
||||
* **Predicate type**: `https://stella-ops.org/attestations/vex-export/1` with fields:
|
||||
|
||||
* `querySignature`, `policyRevisionId`, `artifactSha256`, `createdAt`.
|
||||
|
||||
---
|
||||
|
||||
## 9) Configuration (YAML)
|
||||
|
||||
```yaml
|
||||
excitor:
|
||||
mongo: { uri: "mongodb://mongo/excitor" }
|
||||
s3:
|
||||
endpoint: http://minio:9000
|
||||
bucket: stellaops
|
||||
policy:
|
||||
weights:
|
||||
vendor: 1.0
|
||||
distro: 0.9
|
||||
platform: 0.7
|
||||
hub: 0.5
|
||||
attestation: 0.6
|
||||
providerOverrides:
|
||||
redhat: 1.0
|
||||
suse: 0.95
|
||||
requireJustificationForNotAffected: true
|
||||
signatureRequiredForFixed: true
|
||||
minEvidence:
|
||||
not_affected:
|
||||
vendorOrTwoDistros: true
|
||||
connectors:
|
||||
- providerId: redhat
|
||||
kind: csaf
|
||||
baseUrl: https://access.redhat.com/security/data/csaf/v2/
|
||||
signaturePolicy: { type: pgp, keys: [ "…redhat-pgp-key…" ] }
|
||||
windowDays: 7
|
||||
- providerId: suse
|
||||
kind: csaf
|
||||
baseUrl: https://ftp.suse.com/pub/projects/security/csaf/
|
||||
signaturePolicy: { type: pgp, keys: [ "…suse-pgp-key…" ] }
|
||||
- providerId: ubuntu
|
||||
kind: openvex
|
||||
baseUrl: https://…/vex/
|
||||
signaturePolicy: { type: none }
|
||||
- providerId: vendorX
|
||||
kind: cyclonedx-vex
|
||||
ociRef: ghcr.io/vendorx/vex@sha256:…
|
||||
signaturePolicy: { type: cosign, cosignKeylessRoots: [ "sigstore-root" ] }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10) Security model
|
||||
|
||||
* **Input signature verification** enforced per provider policy (PGP, cosign, x509).
|
||||
* **Connector allowlists**: outbound fetch constrained to configured domains.
|
||||
* **Tenant isolation**: per‑tenant DB prefixes or separate DBs; per‑tenant S3 prefixes; per‑tenant policies.
|
||||
* **AuthN/Z**: Authority‑issued OpToks; RBAC roles (`vex.read`, `vex.admin`, `vex.export`).
|
||||
* **No secrets in logs**; deterministic logging contexts include providerId, docDigest, claim keys.
|
||||
|
||||
---
|
||||
|
||||
## 11) Performance & scale
|
||||
|
||||
* **Targets:**
|
||||
|
||||
* Normalize 10k VEX claims/minute/core.
|
||||
* Consensus compute ≤ 50 ms for 1k unique `(vuln, product)` pairs in hot cache.
|
||||
* Export (consensus) 1M rows in ≤ 60 s on 8 cores with streaming writer.
|
||||
|
||||
* **Scaling:**
|
||||
|
||||
* WebService handles control APIs; **Worker** background services (same image) execute fetch/normalize in parallel with rate‑limits; Mongo writes batched; upserts by natural keys.
|
||||
* Exports stream straight to S3 (MinIO) with rolling buffers.
|
||||
|
||||
* **Caching:**
|
||||
|
||||
* `vex.cache` maps query signatures → export; TTL to avoid stampedes; optimistic reuse unless `force`.
|
||||
|
||||
---
|
||||
|
||||
## 12) Observability
|
||||
|
||||
* **Metrics:**
|
||||
|
||||
* `vex.ingest.docs_total{provider}`
|
||||
* `vex.normalize.claims_total{provider}`
|
||||
* `vex.signature.failures_total{provider,method}`
|
||||
* `vex.consensus.conflicts_total{vulnId}`
|
||||
* `vex.exports.bytes{format}` / `vex.exports.latency_seconds`
|
||||
* **Tracing:** spans for fetch, verify, parse, map, consensus, export.
|
||||
* **Dashboards:** provider staleness, top conflicting vulns/components, signature posture, export cache hit‑rate.
|
||||
|
||||
---
|
||||
|
||||
## 13) Testing matrix
|
||||
|
||||
* **Connectors:** golden raw docs → deterministic claims (fixtures per provider/format).
|
||||
* **Signature policies:** valid/invalid PGP/cosign/x509 samples; ensure rejects are recorded but not accepted.
|
||||
* **Normalization edge cases:** platform‑only claims, free‑text justifications, non‑purl products.
|
||||
* **Consensus:** conflict scenarios across tiers; check tie‑breakers; justification gates.
|
||||
* **Performance:** 1M‑row export timing; memory ceilings; stream correctness.
|
||||
* **Determinism:** same inputs + policy → identical `consensusDigest` and export bytes.
|
||||
* **API contract tests:** pagination, filters, RBAC, rate limits.
|
||||
|
||||
---
|
||||
|
||||
## 14) Integration points
|
||||
|
||||
* **Backend Policy Engine** (in Scanner.WebService): calls `POST /excititor/resolve` (scope `vex.read`) with batched `(purl, vulnId)` pairs to fetch `rollupStatus + sources`.
|
||||
* **Conselier**: provides alias graph (CVE↔vendor IDs) and may supply VEX‑adjacent metadata (e.g., KEV flag) for policy escalation.
|
||||
* **UI**: VEX explorer screens use `/claims/search` and `/consensus/search`; show conflicts & provenance.
|
||||
* **CLI**: `stellaops vex export --consensus --since 7d --out vex.json` for audits.
|
||||
|
||||
---
|
||||
|
||||
## 15) Failure modes & fallback
|
||||
|
||||
* **Provider unreachable:** stale thresholds trigger warnings; policy can down‑weight stale providers automatically (freshness factor).
|
||||
* **Signature outage:** continue to ingest but mark `signatureState.verified=false`; consensus will likely exclude or down‑weight per policy.
|
||||
* **Schema drift:** unknown fields are preserved as `evidence`; normalization rejects only on **invalid identity** or **status**.
|
||||
|
||||
---
|
||||
|
||||
## 16) Rollout plan (incremental)
|
||||
|
||||
1. **MVP**: OpenVEX + CSAF connectors for 3 major providers (e.g., Red Hat/SUSE/Ubuntu), normalization + consensus + `/excititor/resolve`.
|
||||
2. **Signature policies**: PGP for distros; cosign for OCI.
|
||||
3. **Exports + optional attestation**.
|
||||
4. **CycloneDX VEX** connectors; platform claim expansion tables; UI explorer.
|
||||
5. **Scale hardening**: export indexes; conflict analytics.
|
||||
|
||||
---
|
||||
|
||||
## 17) Appendix — canonical JSON (stable ordering)
|
||||
|
||||
All exports and consensus entries are serialized via `VexCanonicalJsonSerializer`:
|
||||
|
||||
* UTF‑8 without BOM;
|
||||
* keys sorted (ASCII);
|
||||
* arrays sorted by `(providerId, vulnId, productKey, lastObserved)` unless semantic order mandated;
|
||||
* timestamps in `YYYY‑MM‑DDThh:mm:ssZ`;
|
||||
* no insignificant whitespace.
|
||||
|
||||
@@ -1,65 +1,65 @@
|
||||
# Implementation plan — Vexer
|
||||
|
||||
## Delivery phases
|
||||
- **Phase 1 – Connectors & normalization**
|
||||
Build connectors for OpenVEX, CSAF VEX, CycloneDX VEX, OCI attestations; capture provenance, signatures, and source metadata; normalise into `VexClaim`.
|
||||
- **Phase 2 – Mapping & trust registry**
|
||||
Implement product mapping (CPE → purl/version), issuer registry (trust tiers, signatures), scope scoring, and justification taxonomy.
|
||||
- **Phase 3 – Consensus & projections**
|
||||
Deliver consensus computation, conflict preservation, projections (`vex_consensus`, history, provider snapshots), and DSSE events.
|
||||
- **Phase 4 – APIs & integrations**
|
||||
Expose REST/CLI endpoints for claims, consensus, conflicts, exports; integrate Policy Engine, Vuln Explorer, Advisory AI, Export Center.
|
||||
- **Phase 5 – Observability & offline**
|
||||
Ship metrics, logs, traces, dashboards, incident runbooks, Offline Kit bundles, and performance tuning (10M claims/tenant).
|
||||
|
||||
## Work breakdown
|
||||
- **Connectors**
|
||||
- Fetchers for vendor feeds, CSAF repositories, OpenVEX docs, OCI referrers.
|
||||
- Signature verification (PGP, cosign, PKI) per source; schema validation; rate limiting.
|
||||
- Source configuration (trust tier, fetch cadence, blackout windows) stored in metadata registry.
|
||||
- **Normalization**
|
||||
- Canonical `VexClaim` schema with deterministic IDs, provenance, supersedes chains.
|
||||
- Product tree parsing, mapping to canonical product keys and environments.
|
||||
- Justification and scope scoring derived from source semantics.
|
||||
- **Consensus & projections**
|
||||
- Lattice join with precedence rules, conflict tracking, confidence scores, recency decay.
|
||||
- Append-only history, conflict queue, DSSE events (`vex.consensus.updated`).
|
||||
- Export-ready JSONL & DSSE bundles for Offline Kit and Export Center.
|
||||
- **APIs & UX**
|
||||
- REST endpoints (`/claims`, `/consensus`, `/conflicts`, `/providers`) with tenant RBAC.
|
||||
- CLI commands `stella vex claims|consensus|conflicts|export`.
|
||||
- Console modules (list/detail, conflict diagnostics, provider health, simulation hooks).
|
||||
- **Integrations**
|
||||
- Policy Engine trust knobs, Vuln Explorer consensus badges, Advisory AI narrative generation, Notify alerts for conflicts.
|
||||
- Orchestrator jobs for recompute/backfill triggered by Excitator deltas.
|
||||
- **Observability & Ops**
|
||||
- Metrics (ingest latency, signature failure rate, conflict rate, consensus latency).
|
||||
- Logs/traces with tenant/issuer/provenance context.
|
||||
- Runbooks for mapping failures, signature errors, recompute storms, quota exhaustion.
|
||||
|
||||
## Acceptance criteria
|
||||
- Connectors ingest validated VEX statements with signed provenance, deterministic mapping, and tenant isolation.
|
||||
- Consensus outputs reproducible, include conflicts, and integrate with Policy Engine/Vuln Explorer/Export Center.
|
||||
- CLI/Console provide evidence inspection, conflict analysis, and exports; Offline Kit bundles replay verification offline.
|
||||
- Observability dashboards/alerts capture ingest health, trust anomalies, conflict spikes, and performance budgets.
|
||||
- Recompute pipeline handles policy changes and new evidence without dropping deterministic outcomes.
|
||||
|
||||
## Risks & mitigations
|
||||
- **Mapping ambiguity:** maintain scope scores, manual overrides, highlight warnings.
|
||||
- **Signature trust gaps:** issuer registry with auditing, fallback trust policies, tenant overrides.
|
||||
- **Evidence surges:** orchestrator backpressure, prioritised queues, shardable workers.
|
||||
- **Performance regressions:** indexing, caching, load tests, budget enforcement.
|
||||
- **Tenant leakage:** strict RBAC/filters, fuzz tests, compliance reviews.
|
||||
|
||||
## Test strategy
|
||||
- **Unit:** connector parsers, normalization, mapping conversions, lattice operations.
|
||||
- **Property:** randomised evidence ensuring commutative consensus and deterministic digests.
|
||||
- **Integration:** end-to-end pipeline from Excitator to consensus export, policy simulation, conflict handling.
|
||||
- **Performance:** large feed ingestion, recompute stress, CLI export throughput.
|
||||
- **Security:** signature tampering, issuer revocation, RBAC.
|
||||
- **Offline:** export/import verification, DSSE bundle validation.
|
||||
|
||||
## Definition of done
|
||||
- Connectors, normalization, consensus, APIs, and integrations deployed with telemetry, runbooks, and Offline Kit parity.
|
||||
- Documentation (overview, architecture, algorithm, issuer registry, API/CLI, runbooks) updated with imposed rule compliance.
|
||||
- ./TASKS.md and ../../TASKS.md reflect active status and dependencies.
|
||||
# Implementation plan — Excitor
|
||||
|
||||
## Delivery phases
|
||||
- **Phase 1 – Connectors & normalization**
|
||||
Build connectors for OpenVEX, CSAF VEX, CycloneDX VEX, OCI attestations; capture provenance, signatures, and source metadata; normalise into `VexClaim`.
|
||||
- **Phase 2 – Mapping & trust registry**
|
||||
Implement product mapping (CPE → purl/version), issuer registry (trust tiers, signatures), scope scoring, and justification taxonomy.
|
||||
- **Phase 3 – Consensus & projections**
|
||||
Deliver consensus computation, conflict preservation, projections (`vex_consensus`, history, provider snapshots), and DSSE events.
|
||||
- **Phase 4 – APIs & integrations**
|
||||
Expose REST/CLI endpoints for claims, consensus, conflicts, exports; integrate Policy Engine, Vuln Explorer, Advisory AI, Export Center.
|
||||
- **Phase 5 – Observability & offline**
|
||||
Ship metrics, logs, traces, dashboards, incident runbooks, Offline Kit bundles, and performance tuning (10M claims/tenant).
|
||||
|
||||
## Work breakdown
|
||||
- **Connectors**
|
||||
- Fetchers for vendor feeds, CSAF repositories, OpenVEX docs, OCI referrers.
|
||||
- Signature verification (PGP, cosign, PKI) per source; schema validation; rate limiting.
|
||||
- Source configuration (trust tier, fetch cadence, blackout windows) stored in metadata registry.
|
||||
- **Normalization**
|
||||
- Canonical `VexClaim` schema with deterministic IDs, provenance, supersedes chains.
|
||||
- Product tree parsing, mapping to canonical product keys and environments.
|
||||
- Justification and scope scoring derived from source semantics.
|
||||
- **Consensus & projections**
|
||||
- Lattice join with precedence rules, conflict tracking, confidence scores, recency decay.
|
||||
- Append-only history, conflict queue, DSSE events (`vex.consensus.updated`).
|
||||
- Export-ready JSONL & DSSE bundles for Offline Kit and Export Center.
|
||||
- **APIs & UX**
|
||||
- REST endpoints (`/claims`, `/consensus`, `/conflicts`, `/providers`) with tenant RBAC.
|
||||
- CLI commands `stella vex claims|consensus|conflicts|export`.
|
||||
- Console modules (list/detail, conflict diagnostics, provider health, simulation hooks).
|
||||
- **Integrations**
|
||||
- Policy Engine trust knobs, Vuln Explorer consensus badges, Advisory AI narrative generation, Notify alerts for conflicts.
|
||||
- Orchestrator jobs for recompute/backfill triggered by Excitor deltas.
|
||||
- **Observability & Ops**
|
||||
- Metrics (ingest latency, signature failure rate, conflict rate, consensus latency).
|
||||
- Logs/traces with tenant/issuer/provenance context.
|
||||
- Runbooks for mapping failures, signature errors, recompute storms, quota exhaustion.
|
||||
|
||||
## Acceptance criteria
|
||||
- Connectors ingest validated VEX statements with signed provenance, deterministic mapping, and tenant isolation.
|
||||
- Consensus outputs reproducible, include conflicts, and integrate with Policy Engine/Vuln Explorer/Export Center.
|
||||
- CLI/Console provide evidence inspection, conflict analysis, and exports; Offline Kit bundles replay verification offline.
|
||||
- Observability dashboards/alerts capture ingest health, trust anomalies, conflict spikes, and performance budgets.
|
||||
- Recompute pipeline handles policy changes and new evidence without dropping deterministic outcomes.
|
||||
|
||||
## Risks & mitigations
|
||||
- **Mapping ambiguity:** maintain scope scores, manual overrides, highlight warnings.
|
||||
- **Signature trust gaps:** issuer registry with auditing, fallback trust policies, tenant overrides.
|
||||
- **Evidence surges:** orchestrator backpressure, prioritised queues, shardable workers.
|
||||
- **Performance regressions:** indexing, caching, load tests, budget enforcement.
|
||||
- **Tenant leakage:** strict RBAC/filters, fuzz tests, compliance reviews.
|
||||
|
||||
## Test strategy
|
||||
- **Unit:** connector parsers, normalization, mapping conversions, lattice operations.
|
||||
- **Property:** randomised evidence ensuring commutative consensus and deterministic digests.
|
||||
- **Integration:** end-to-end pipeline from Excitor to consensus export, policy simulation, conflict handling.
|
||||
- **Performance:** large feed ingestion, recompute stress, CLI export throughput.
|
||||
- **Security:** signature tampering, issuer revocation, RBAC.
|
||||
- **Offline:** export/import verification, DSSE bundle validation.
|
||||
|
||||
## Definition of done
|
||||
- Connectors, normalization, consensus, APIs, and integrations deployed with telemetry, runbooks, and Offline Kit parity.
|
||||
- Documentation (overview, architecture, algorithm, issuer registry, API/CLI, runbooks) updated with imposed rule compliance.
|
||||
- ./TASKS.md and ../../TASKS.md reflect active status and dependencies.
|
||||
@@ -1,83 +1,83 @@
|
||||
## Status
|
||||
|
||||
This document tracks the future-looking risk scoring model for Vexer. The calculation below is not active yet; Sprint 7 work will add the required schema fields, policy controls, and services. Until that ships, Vexer emits consensus statuses without numeric scores.
|
||||
|
||||
## Scoring model (target state)
|
||||
|
||||
**S = Gate(VEX_status) × W_trust(source) × [Severity_base × (1 + α·KEV + β·EPSS)]**
|
||||
|
||||
* **Gate(VEX_status)**: `affected`/`under_investigation` → 1, `not_affected`/`fixed` → 0. A trusted “not affected” or “fixed” still zeroes the score.
|
||||
* **W_trust(source)**: normalized policy weight (baseline 0‒1). Policies may opt into >1 boosts for signed vendor feeds once Phase 1 closes.
|
||||
* **Severity_base**: canonical numeric severity from Feedser (CVSS or org-defined scale).
|
||||
* **KEV flag**: 0/1 boost when CISA Known Exploited Vulnerabilities applies.
|
||||
* **EPSS**: probability [0,1]; bounded multiplier.
|
||||
* **α, β**: configurable coefficients (default α=0.25, β=0.5) stored in policy.
|
||||
|
||||
Safeguards: freeze boosts when product identity is unknown, clamp outputs ≥0, and log every factor in the audit trail.
|
||||
|
||||
## Implementation roadmap
|
||||
|
||||
| Phase | Scope | Artifacts |
|
||||
| --- | --- | --- |
|
||||
| **Phase 1 – Schema foundations** | Extend Vexer consensus/claims and Feedser canonical advisories with severity, KEV, EPSS, and expose α/β + weight ceilings in policy. | Sprint 7 tasks `VEXER-CORE-02-001`, `VEXER-POLICY-02-001`, `VEXER-STORAGE-02-001`, `FEEDCORE-ENGINE-07-001`. |
|
||||
| **Phase 2 – Deterministic score engine** | Implement a scoring component that executes alongside consensus and persists score envelopes with hashes. | Planned task `VEXER-CORE-02-002` (backlog). |
|
||||
| **Phase 3 – Surfacing & enforcement** | Expose scores via WebService/CLI, integrate with Feedser noise priors, and enforce policy-based suppressions. | To be scheduled after Phase 2. |
|
||||
|
||||
## Data model (after Phase 1)
|
||||
|
||||
```json
|
||||
{
|
||||
"vulnerabilityId": "CVE-2025-12345",
|
||||
"product": "pkg:name@version",
|
||||
"consensus": {
|
||||
"status": "affected",
|
||||
"policyRevisionId": "rev-12",
|
||||
"policyDigest": "0D9AEC…"
|
||||
},
|
||||
"signals": {
|
||||
"severity": {"scheme": "CVSS:3.1", "score": 7.5},
|
||||
"kev": true,
|
||||
"epss": 0.40
|
||||
},
|
||||
"policy": {
|
||||
"weight": 1.15,
|
||||
"alpha": 0.25,
|
||||
"beta": 0.5
|
||||
},
|
||||
"score": {
|
||||
"value": 10.8,
|
||||
"generatedAt": "2025-11-05T14:12:30Z",
|
||||
"audit": [
|
||||
"gate:affected",
|
||||
"weight:1.15",
|
||||
"severity:7.5",
|
||||
"kev:1",
|
||||
"epss:0.40"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Operational guidance
|
||||
|
||||
* **Inputs**: Feedser delivers severity/KEV/EPSS via the advisory event log; Vexer connectors load VEX statements. Policy owns trust tiers and coefficients.
|
||||
* **Processing**: the scoring engine (Phase 2) runs next to consensus, storing results with deterministic hashes so exports and attestations can reference them.
|
||||
* **Consumption**: WebService/CLI will return consensus plus score; scanners may suppress findings only when policy-authorized VEX gating and signed score envelopes agree.
|
||||
|
||||
## Pseudocode (Phase 2 preview)
|
||||
|
||||
```python
|
||||
def risk_score(gate, weight, severity, kev, epss, alpha, beta, freeze_boosts=False):
|
||||
if gate == 0:
|
||||
return 0
|
||||
if freeze_boosts:
|
||||
kev, epss = 0, 0
|
||||
boost = 1 + alpha * kev + beta * epss
|
||||
return max(0, weight * severity * boost)
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
* **Can operators opt out?** Set α=β=0 or keep weights ≤1.0 via policy.
|
||||
* **What about missing signals?** Treat them as zero and log the omission.
|
||||
* **When will this ship?** Phase 1 is planned for Sprint 7; later phases depend on connector coverage and attestation delivery.
|
||||
## Status
|
||||
|
||||
This document tracks the future-looking risk scoring model for Excitor. The calculation below is not active yet; Sprint 7 work will add the required schema fields, policy controls, and services. Until that ships, Excitor emits consensus statuses without numeric scores.
|
||||
|
||||
## Scoring model (target state)
|
||||
|
||||
**S = Gate(VEX_status) × W_trust(source) × [Severity_base × (1 + α·KEV + β·EPSS)]**
|
||||
|
||||
* **Gate(VEX_status)**: `affected`/`under_investigation` → 1, `not_affected`/`fixed` → 0. A trusted “not affected” or “fixed” still zeroes the score.
|
||||
* **W_trust(source)**: normalized policy weight (baseline 0‒1). Policies may opt into >1 boosts for signed vendor feeds once Phase 1 closes.
|
||||
* **Severity_base**: canonical numeric severity from Conselier (CVSS or org-defined scale).
|
||||
* **KEV flag**: 0/1 boost when CISA Known Exploited Vulnerabilities applies.
|
||||
* **EPSS**: probability [0,1]; bounded multiplier.
|
||||
* **α, β**: configurable coefficients (default α=0.25, β=0.5) stored in policy.
|
||||
|
||||
Safeguards: freeze boosts when product identity is unknown, clamp outputs ≥0, and log every factor in the audit trail.
|
||||
|
||||
## Implementation roadmap
|
||||
|
||||
| Phase | Scope | Artifacts |
|
||||
| --- | --- | --- |
|
||||
| **Phase 1 – Schema foundations** | Extend Excitor consensus/claims and Conselier canonical advisories with severity, KEV, EPSS, and expose α/β + weight ceilings in policy. | Sprint 7 tasks `EXCITOR-CORE-02-001`, `EXCITOR-POLICY-02-001`, `EXCITOR-STORAGE-02-001`, `FEEDCORE-ENGINE-07-001`. |
|
||||
| **Phase 2 – Deterministic score engine** | Implement a scoring component that executes alongside consensus and persists score envelopes with hashes. | Planned task `EXCITOR-CORE-02-002` (backlog). |
|
||||
| **Phase 3 – Surfacing & enforcement** | Expose scores via WebService/CLI, integrate with Conselier noise priors, and enforce policy-based suppressions. | To be scheduled after Phase 2. |
|
||||
|
||||
## Data model (after Phase 1)
|
||||
|
||||
```json
|
||||
{
|
||||
"vulnerabilityId": "CVE-2025-12345",
|
||||
"product": "pkg:name@version",
|
||||
"consensus": {
|
||||
"status": "affected",
|
||||
"policyRevisionId": "rev-12",
|
||||
"policyDigest": "0D9AEC…"
|
||||
},
|
||||
"signals": {
|
||||
"severity": {"scheme": "CVSS:3.1", "score": 7.5},
|
||||
"kev": true,
|
||||
"epss": 0.40
|
||||
},
|
||||
"policy": {
|
||||
"weight": 1.15,
|
||||
"alpha": 0.25,
|
||||
"beta": 0.5
|
||||
},
|
||||
"score": {
|
||||
"value": 10.8,
|
||||
"generatedAt": "2025-11-05T14:12:30Z",
|
||||
"audit": [
|
||||
"gate:affected",
|
||||
"weight:1.15",
|
||||
"severity:7.5",
|
||||
"kev:1",
|
||||
"epss:0.40"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Operational guidance
|
||||
|
||||
* **Inputs**: Conselier delivers severity/KEV/EPSS via the advisory event log; Excitor connectors load VEX statements. Policy owns trust tiers and coefficients.
|
||||
* **Processing**: the scoring engine (Phase 2) runs next to consensus, storing results with deterministic hashes so exports and attestations can reference them.
|
||||
* **Consumption**: WebService/CLI will return consensus plus score; scanners may suppress findings only when policy-authorized VEX gating and signed score envelopes agree.
|
||||
|
||||
## Pseudocode (Phase 2 preview)
|
||||
|
||||
```python
|
||||
def risk_score(gate, weight, severity, kev, epss, alpha, beta, freeze_boosts=False):
|
||||
if gate == 0:
|
||||
return 0
|
||||
if freeze_boosts:
|
||||
kev, epss = 0, 0
|
||||
boost = 1 + alpha * kev + beta * epss
|
||||
return max(0, weight * severity * boost)
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
* **Can operators opt out?** Set α=β=0 or keep weights ≤1.0 via policy.
|
||||
* **What about missing signals?** Treat them as zero and log the omission.
|
||||
* **When will this ship?** Phase 1 is planned for Sprint 7; later phases depend on connector coverage and attestation delivery.
|
||||
@@ -1,150 +1,150 @@
|
||||
# Export Center Provenance & Signing
|
||||
|
||||
> **Imposed rule:** Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.
|
||||
|
||||
Export Center runs emit deterministic manifests, provenance records, and signatures so operators can prove bundle integrity end-to-end—whether the artefact is downloaded over HTTPS, pulled as an OCI object, or staged through the Offline Kit. This guide captures the canonical artefacts, signing pipeline, verification workflows, and failure handling expectations that backlogs `EXPORT-SVC-35-005` and `EXPORT-SVC-37-002` implement.
|
||||
|
||||
---
|
||||
|
||||
## 1. Goals & scope
|
||||
|
||||
- **Authenticity.** Every export manifest and provenance document is signed using Authority-managed KMS keys (cosign-compatible) with optional SLSA Level 3 attestation.
|
||||
- **Traceability.** Provenance links each bundle to the inputs that produced it: tenant, findings ledger queries, policy snapshots, SBOM identifiers, adapter versions, and encryption recipients.
|
||||
- **Determinism.** Canonical JSON (sorted keys, RFC 3339 UTC timestamps, normalized numbers) guarantees byte-for-byte stability across reruns with identical input.
|
||||
- **Portability.** Signatures and attestations travel with filesystem bundles, OCI artefacts, and Offline Kit staging trees. Verification does not require online Authority access when the bundle includes the cosign public key.
|
||||
|
||||
---
|
||||
|
||||
## 2. Artefact inventory
|
||||
|
||||
| File | Location | Description | Notes |
|
||||
|------|----------|-------------|-------|
|
||||
| `export.json` | `manifests/export.json` or HTTP `GET /api/export/runs/{id}/manifest` | Canonical manifest describing profile, selectors, counts, SHA-256 digests, compression hints, distribution targets. | Hash of this file is included in provenance `subjects[]`. |
|
||||
| `provenance.json` | `manifests/provenance.json` or `GET /api/export/runs/{id}/provenance` | In-toto provenance record listing subjects, materials, toolchain metadata, encryption recipients, and KMS key identifiers. | Mirrors SLSA Level 2 schema; optionally upgraded to Level 3 with builder attestations. |
|
||||
| `export.json.sig` / `export.json.dsse` | `signatures/export.json.sig` | Cosign signature (and optional DSSE envelope) for manifest. | File naming matches cosign defaults; offline verification scripts expect `.sig`. |
|
||||
| `provenance.json.sig` / `provenance.json.dsse` | `signatures/provenance.json.sig` | Cosign signature (and optional DSSE envelope) for provenance document. | `dsse` present when SLSA Level 3 is enabled. |
|
||||
| `bundle.attestation` | `signatures/bundle.attestation` (optional) | SLSA Level 2/3 attestation binding bundle tarball/OCI digest to the run. | Only produced when `export.attestation.enabled=true`. |
|
||||
| `manifest.yaml` | bundle root | Human-readable summary including digests, sizes, encryption metadata, and verification hints. | Unsigned but redundant; signatures cover the JSON manifests. |
|
||||
|
||||
All digests use lowercase hex SHA-256 (`sha256:<digest>`). When bundle encryption is enabled, `provenance.json` records wrapped data keys and recipient fingerprints under `encryption.recipients[]`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Signing pipeline
|
||||
|
||||
1. **Canonicalisation.** Export worker serialises `export.json` and `provenance.json` using `NotifyCanonicalJsonSerializer` (identical canonical JSON helpers shared across services). Keys are sorted lexicographically, arrays ordered deterministically, timestamps normalised to UTC.
|
||||
2. **Digest creation.** SHA-256 digests are computed and recorded:
|
||||
- `manifest_hash` and `provenance_hash` stored in the run metadata (Mongo) and exported via `/api/export/runs/{id}`.
|
||||
- Provenance `subjects[]` contains both manifest hash and bundle/archive hash.
|
||||
3. **Key retrieval.** Worker obtains a short-lived signing token from Authority’s KMS client using tenant-scoped credentials (`export.sign` scope). Keys live in Authority or tenant-specific HSMs depending on deployment.
|
||||
4. **Signature emission.** Cosign generates detached signatures (`*.sig`). If DSSE is enabled, cosign wraps payload bytes in a DSSE envelope (`*.dsse`). Attestations follow the SLSA Level 2 provenance template; Level 3 requires builder metadata (`EXPORT-SVC-37-002` optional feature flag).
|
||||
5. **Storage & distribution.** Signatures and attestations are written alongside manifests in object storage, included in filesystem bundles, and attached as OCI artefact layers/annotations.
|
||||
6. **Audit trail.** Run metadata captures signer identity (`signing_key_id`), cosign certificate serial, signature timestamps, and verification hints. Console/CLI surface these details for downstream automation.
|
||||
|
||||
> **Key management.** Secrets and key references are configured per tenant via `export.signing`, pointing to Authority clients or external HSM aliases. Offline deployments pre-load cosign public keys into the bundle (`signatures/pubkeys/{tenant}.pem`).
|
||||
|
||||
---
|
||||
|
||||
## 4. Provenance schema highlights
|
||||
|
||||
`provenance.json` follows the SLSA provenance (`https://slsa.dev/provenance/v1`) structure with StellaOps-specific extensions. Key fields:
|
||||
|
||||
| Path | Description |
|
||||
|------|-------------|
|
||||
| `subject[]` | Array of `{name,digest}` pairs. Includes bundle tarball/OCI digest and `export.json` digest. |
|
||||
| `predicateType` | SLSA v1 (default). |
|
||||
| `predicate.builder` | `{id:"stellaops/export-center@<region>"}` identifies the worker instance/cluster. |
|
||||
| `predicate.buildType` | Profile identifier (`mirror:full`, `mirror:delta`, etc.). |
|
||||
| `predicate.invocation.parameters` | Profile selectors, retention flags, encryption mode, base export references. |
|
||||
| `predicate.materials[]` | Source artefacts with digests: findings ledger query snapshots, policy snapshot IDs + hashes, SBOM identifiers, adapter release digests. |
|
||||
| `predicate.metadata.buildFinishedOn` | RFC 3339 timestamp when signing completed. |
|
||||
| `predicate.metadata.reproducible` | Always `true`—workers guarantee determinism. |
|
||||
| `predicate.environment.encryption` | Records encryption recipients, wrapped keys, algorithm (`age` or `aes-gcm`). |
|
||||
| `predicate.environment.kms` | Signing key identifier (`authority://tenant/export-signing-key`) and certificate chain fingerprints. |
|
||||
|
||||
Sample (abridged):
|
||||
|
||||
```json
|
||||
{
|
||||
"subject": [
|
||||
{ "name": "bundle.tar.zst", "digest": { "sha256": "c1fe..." } },
|
||||
{ "name": "manifests/export.json", "digest": { "sha256": "ad42..." } }
|
||||
],
|
||||
"predicate": {
|
||||
"buildType": "mirror:delta",
|
||||
"invocation": {
|
||||
"parameters": {
|
||||
"tenant": "tenant-01",
|
||||
"baseExportId": "run-20251020-01",
|
||||
"selectors": { "sources": ["concelier","vexer"], "profiles": ["mirror"] }
|
||||
}
|
||||
},
|
||||
"materials": [
|
||||
{ "uri": "ledger://tenant-01/findings?cursor=rev-42", "digest": { "sha256": "0f9a..." } },
|
||||
{ "uri": "policy://tenant-01/snapshots/rev-17", "digest": { "sha256": "8c3d..." } }
|
||||
],
|
||||
"environment": {
|
||||
"encryption": {
|
||||
"mode": "age",
|
||||
"recipients": [
|
||||
{ "recipient": "age1qxyz...", "wrappedKey": "BASE64...", "keyId": "tenant-01/notify-age" }
|
||||
]
|
||||
},
|
||||
"kms": {
|
||||
"signingKeyId": "authority://tenant-01/export-signing",
|
||||
"certificateChainSha256": "1f5e..."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Verification workflows
|
||||
|
||||
| Scenario | Steps |
|
||||
|----------|-------|
|
||||
| **CLI verification** | 1. `stella export manifest <runId> --output manifests/export.json --signature manifests/export.json.sig`<br>2. `stella export provenance <runId> --output manifests/provenance.json --signature manifests/provenance.json.sig`<br>3. `cosign verify-blob --key pubkeys/tenant.pem --signature manifests/export.json.sig manifests/export.json`<br>4. `cosign verify-blob --key pubkeys/tenant.pem --signature manifests/provenance.json.sig manifests/provenance.json` |
|
||||
| **Bundle verification (offline)** | 1. Extract bundle (or mount OCI artefact).<br>2. Validate manifest/provenance signatures using bundled public key.<br>3. Recompute SHA-256 for `data/` files and compare with entries in `export.json`.<br>4. If encrypted, decrypt with Age/AES-GCM recipient key, then re-run digest comparisons on decrypted content. |
|
||||
| **CI pipeline** | Use `stella export verify --manifest manifests/export.json --provenance manifests/provenance.json --signature manifests/export.json.sig --signature manifests/provenance.json.sig` (task `CLI-EXPORT-37-001`). Failure exits non-zero with reason codes (`ERR_EXPORT_SIG_INVALID`, `ERR_EXPORT_DIGEST_MISMATCH`). |
|
||||
| **Console download** | Console automatically verifies signatures before exposing the bundle; failure surfaces an actionable error referencing the export run ID and required remediation. |
|
||||
|
||||
Verification guidance (docs/modules/cli/guides/cli-reference.md §export) cross-links here; keep both docs in sync when CLI behaviour changes.
|
||||
|
||||
---
|
||||
|
||||
## 6. Distribution considerations
|
||||
|
||||
- **HTTP headers.** `X-Export-Digest` includes bundle digest; `X-Export-Provenance` references `provenance.json` URL; `X-Export-Signature` references `.sig`. Clients use these hints to short-circuit re-downloads.
|
||||
- **OCI annotations.** `org.opencontainers.image.ref.name`, `io.stellaops.export.manifest-digest`, and `io.stellaops.export.provenance-ref` allow registry tooling to locate manifests/signatures quickly.
|
||||
- **Offline Kit staging.** Offline kit assembler copies `manifests/`, `signatures/`, and `pubkeys/` verbatim. Verification scripts (`offline-kits/bin/verify-export.sh`) wrap the cosign commands described above.
|
||||
|
||||
---
|
||||
|
||||
## 7. Failure handling & observability
|
||||
|
||||
- Runs surface signature status via `/api/export/runs/{id}` (`signing.status`, `signing.lastError`). Common errors include `ERR_EXPORT_KMS_UNAVAILABLE`, `ERR_EXPORT_ATTESTATION_FAILED`, `ERR_EXPORT_CANONICALIZE`.
|
||||
- Metrics: `exporter_sign_duration_seconds`, `exporter_sign_failures_total{error_code}`, `exporter_provenance_verify_failures_total`.
|
||||
- Logs: `phase=sign`, `error_code`, `signing_key_id`, `cosign_certificate_sn`.
|
||||
- Alerts: DevOps dashboards (task `DEVOPS-EXPORT-37-001`) trigger on consecutive signing failures or verification failures >0.
|
||||
|
||||
When verification fails downstream, operators should:
|
||||
1. Confirm signatures using the known-good key.
|
||||
2. Inspect `provenance.json` materials; rerun the source queries to ensure matching digests.
|
||||
3. Review run audit logs and retry export with `--resume` to regenerate manifests.
|
||||
|
||||
---
|
||||
|
||||
## 8. Compliance checklist
|
||||
|
||||
- [ ] Manifests and provenance documents generated with canonical JSON, deterministic digests, and signatures.
|
||||
- [ ] Cosign public keys published per tenant, rotated through Authority, and distributed to Offline Kit consumers.
|
||||
- [ ] SLSA attestations enabled where supply-chain requirements demand Level 3 evidence.
|
||||
- [ ] CLI/Console verification paths documented and tested (CI pipelines exercise `stella export verify`).
|
||||
- [ ] Encryption metadata (recipients, wrapped keys) recorded in provenance and validated during verification.
|
||||
- [ ] Run audit logs capture signature timestamps, signer identity, and failure reasons.
|
||||
|
||||
---
|
||||
|
||||
> **Imposed rule reminder:** Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.
|
||||
# Export Center Provenance & Signing
|
||||
|
||||
> **Imposed rule:** Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.
|
||||
|
||||
Export Center runs emit deterministic manifests, provenance records, and signatures so operators can prove bundle integrity end-to-end—whether the artefact is downloaded over HTTPS, pulled as an OCI object, or staged through the Offline Kit. This guide captures the canonical artefacts, signing pipeline, verification workflows, and failure handling expectations that backlogs `EXPORT-SVC-35-005` and `EXPORT-SVC-37-002` implement.
|
||||
|
||||
---
|
||||
|
||||
## 1. Goals & scope
|
||||
|
||||
- **Authenticity.** Every export manifest and provenance document is signed using Authority-managed KMS keys (cosign-compatible) with optional SLSA Level 3 attestation.
|
||||
- **Traceability.** Provenance links each bundle to the inputs that produced it: tenant, findings ledger queries, policy snapshots, SBOM identifiers, adapter versions, and encryption recipients.
|
||||
- **Determinism.** Canonical JSON (sorted keys, RFC 3339 UTC timestamps, normalized numbers) guarantees byte-for-byte stability across reruns with identical input.
|
||||
- **Portability.** Signatures and attestations travel with filesystem bundles, OCI artefacts, and Offline Kit staging trees. Verification does not require online Authority access when the bundle includes the cosign public key.
|
||||
|
||||
---
|
||||
|
||||
## 2. Artefact inventory
|
||||
|
||||
| File | Location | Description | Notes |
|
||||
|------|----------|-------------|-------|
|
||||
| `export.json` | `manifests/export.json` or HTTP `GET /api/export/runs/{id}/manifest` | Canonical manifest describing profile, selectors, counts, SHA-256 digests, compression hints, distribution targets. | Hash of this file is included in provenance `subjects[]`. |
|
||||
| `provenance.json` | `manifests/provenance.json` or `GET /api/export/runs/{id}/provenance` | In-toto provenance record listing subjects, materials, toolchain metadata, encryption recipients, and KMS key identifiers. | Mirrors SLSA Level 2 schema; optionally upgraded to Level 3 with builder attestations. |
|
||||
| `export.json.sig` / `export.json.dsse` | `signatures/export.json.sig` | Cosign signature (and optional DSSE envelope) for manifest. | File naming matches cosign defaults; offline verification scripts expect `.sig`. |
|
||||
| `provenance.json.sig` / `provenance.json.dsse` | `signatures/provenance.json.sig` | Cosign signature (and optional DSSE envelope) for provenance document. | `dsse` present when SLSA Level 3 is enabled. |
|
||||
| `bundle.attestation` | `signatures/bundle.attestation` (optional) | SLSA Level 2/3 attestation binding bundle tarball/OCI digest to the run. | Only produced when `export.attestation.enabled=true`. |
|
||||
| `manifest.yaml` | bundle root | Human-readable summary including digests, sizes, encryption metadata, and verification hints. | Unsigned but redundant; signatures cover the JSON manifests. |
|
||||
|
||||
All digests use lowercase hex SHA-256 (`sha256:<digest>`). When bundle encryption is enabled, `provenance.json` records wrapped data keys and recipient fingerprints under `encryption.recipients[]`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Signing pipeline
|
||||
|
||||
1. **Canonicalisation.** Export worker serialises `export.json` and `provenance.json` using `NotifyCanonicalJsonSerializer` (identical canonical JSON helpers shared across services). Keys are sorted lexicographically, arrays ordered deterministically, timestamps normalised to UTC.
|
||||
2. **Digest creation.** SHA-256 digests are computed and recorded:
|
||||
- `manifest_hash` and `provenance_hash` stored in the run metadata (Mongo) and exported via `/api/export/runs/{id}`.
|
||||
- Provenance `subjects[]` contains both manifest hash and bundle/archive hash.
|
||||
3. **Key retrieval.** Worker obtains a short-lived signing token from Authority’s KMS client using tenant-scoped credentials (`export.sign` scope). Keys live in Authority or tenant-specific HSMs depending on deployment.
|
||||
4. **Signature emission.** Cosign generates detached signatures (`*.sig`). If DSSE is enabled, cosign wraps payload bytes in a DSSE envelope (`*.dsse`). Attestations follow the SLSA Level 2 provenance template; Level 3 requires builder metadata (`EXPORT-SVC-37-002` optional feature flag).
|
||||
5. **Storage & distribution.** Signatures and attestations are written alongside manifests in object storage, included in filesystem bundles, and attached as OCI artefact layers/annotations.
|
||||
6. **Audit trail.** Run metadata captures signer identity (`signing_key_id`), cosign certificate serial, signature timestamps, and verification hints. Console/CLI surface these details for downstream automation.
|
||||
|
||||
> **Key management.** Secrets and key references are configured per tenant via `export.signing`, pointing to Authority clients or external HSM aliases. Offline deployments pre-load cosign public keys into the bundle (`signatures/pubkeys/{tenant}.pem`).
|
||||
|
||||
---
|
||||
|
||||
## 4. Provenance schema highlights
|
||||
|
||||
`provenance.json` follows the SLSA provenance (`https://slsa.dev/provenance/v1`) structure with StellaOps-specific extensions. Key fields:
|
||||
|
||||
| Path | Description |
|
||||
|------|-------------|
|
||||
| `subject[]` | Array of `{name,digest}` pairs. Includes bundle tarball/OCI digest and `export.json` digest. |
|
||||
| `predicateType` | SLSA v1 (default). |
|
||||
| `predicate.builder` | `{id:"stellaops/export-center@<region>"}` identifies the worker instance/cluster. |
|
||||
| `predicate.buildType` | Profile identifier (`mirror:full`, `mirror:delta`, etc.). |
|
||||
| `predicate.invocation.parameters` | Profile selectors, retention flags, encryption mode, base export references. |
|
||||
| `predicate.materials[]` | Source artefacts with digests: findings ledger query snapshots, policy snapshot IDs + hashes, SBOM identifiers, adapter release digests. |
|
||||
| `predicate.metadata.buildFinishedOn` | RFC 3339 timestamp when signing completed. |
|
||||
| `predicate.metadata.reproducible` | Always `true`—workers guarantee determinism. |
|
||||
| `predicate.environment.encryption` | Records encryption recipients, wrapped keys, algorithm (`age` or `aes-gcm`). |
|
||||
| `predicate.environment.kms` | Signing key identifier (`authority://tenant/export-signing-key`) and certificate chain fingerprints. |
|
||||
|
||||
Sample (abridged):
|
||||
|
||||
```json
|
||||
{
|
||||
"subject": [
|
||||
{ "name": "bundle.tar.zst", "digest": { "sha256": "c1fe..." } },
|
||||
{ "name": "manifests/export.json", "digest": { "sha256": "ad42..." } }
|
||||
],
|
||||
"predicate": {
|
||||
"buildType": "mirror:delta",
|
||||
"invocation": {
|
||||
"parameters": {
|
||||
"tenant": "tenant-01",
|
||||
"baseExportId": "run-20251020-01",
|
||||
"selectors": { "sources": ["concelier","excitor"], "profiles": ["mirror"] }
|
||||
}
|
||||
},
|
||||
"materials": [
|
||||
{ "uri": "ledger://tenant-01/findings?cursor=rev-42", "digest": { "sha256": "0f9a..." } },
|
||||
{ "uri": "policy://tenant-01/snapshots/rev-17", "digest": { "sha256": "8c3d..." } }
|
||||
],
|
||||
"environment": {
|
||||
"encryption": {
|
||||
"mode": "age",
|
||||
"recipients": [
|
||||
{ "recipient": "age1qxyz...", "wrappedKey": "BASE64...", "keyId": "tenant-01/notify-age" }
|
||||
]
|
||||
},
|
||||
"kms": {
|
||||
"signingKeyId": "authority://tenant-01/export-signing",
|
||||
"certificateChainSha256": "1f5e..."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Verification workflows
|
||||
|
||||
| Scenario | Steps |
|
||||
|----------|-------|
|
||||
| **CLI verification** | 1. `stella export manifest <runId> --output manifests/export.json --signature manifests/export.json.sig`<br>2. `stella export provenance <runId> --output manifests/provenance.json --signature manifests/provenance.json.sig`<br>3. `cosign verify-blob --key pubkeys/tenant.pem --signature manifests/export.json.sig manifests/export.json`<br>4. `cosign verify-blob --key pubkeys/tenant.pem --signature manifests/provenance.json.sig manifests/provenance.json` |
|
||||
| **Bundle verification (offline)** | 1. Extract bundle (or mount OCI artefact).<br>2. Validate manifest/provenance signatures using bundled public key.<br>3. Recompute SHA-256 for `data/` files and compare with entries in `export.json`.<br>4. If encrypted, decrypt with Age/AES-GCM recipient key, then re-run digest comparisons on decrypted content. |
|
||||
| **CI pipeline** | Use `stella export verify --manifest manifests/export.json --provenance manifests/provenance.json --signature manifests/export.json.sig --signature manifests/provenance.json.sig` (task `CLI-EXPORT-37-001`). Failure exits non-zero with reason codes (`ERR_EXPORT_SIG_INVALID`, `ERR_EXPORT_DIGEST_MISMATCH`). |
|
||||
| **Console download** | Console automatically verifies signatures before exposing the bundle; failure surfaces an actionable error referencing the export run ID and required remediation. |
|
||||
|
||||
Verification guidance (docs/modules/cli/guides/cli-reference.md §export) cross-links here; keep both docs in sync when CLI behaviour changes.
|
||||
|
||||
---
|
||||
|
||||
## 6. Distribution considerations
|
||||
|
||||
- **HTTP headers.** `X-Export-Digest` includes bundle digest; `X-Export-Provenance` references `provenance.json` URL; `X-Export-Signature` references `.sig`. Clients use these hints to short-circuit re-downloads.
|
||||
- **OCI annotations.** `org.opencontainers.image.ref.name`, `io.stellaops.export.manifest-digest`, and `io.stellaops.export.provenance-ref` allow registry tooling to locate manifests/signatures quickly.
|
||||
- **Offline Kit staging.** Offline kit assembler copies `manifests/`, `signatures/`, and `pubkeys/` verbatim. Verification scripts (`offline-kits/bin/verify-export.sh`) wrap the cosign commands described above.
|
||||
|
||||
---
|
||||
|
||||
## 7. Failure handling & observability
|
||||
|
||||
- Runs surface signature status via `/api/export/runs/{id}` (`signing.status`, `signing.lastError`). Common errors include `ERR_EXPORT_KMS_UNAVAILABLE`, `ERR_EXPORT_ATTESTATION_FAILED`, `ERR_EXPORT_CANONICALIZE`.
|
||||
- Metrics: `exporter_sign_duration_seconds`, `exporter_sign_failures_total{error_code}`, `exporter_provenance_verify_failures_total`.
|
||||
- Logs: `phase=sign`, `error_code`, `signing_key_id`, `cosign_certificate_sn`.
|
||||
- Alerts: DevOps dashboards (task `DEVOPS-EXPORT-37-001`) trigger on consecutive signing failures or verification failures >0.
|
||||
|
||||
When verification fails downstream, operators should:
|
||||
1. Confirm signatures using the known-good key.
|
||||
2. Inspect `provenance.json` materials; rerun the source queries to ensure matching digests.
|
||||
3. Review run audit logs and retry export with `--resume` to regenerate manifests.
|
||||
|
||||
---
|
||||
|
||||
## 8. Compliance checklist
|
||||
|
||||
- [ ] Manifests and provenance documents generated with canonical JSON, deterministic digests, and signatures.
|
||||
- [ ] Cosign public keys published per tenant, rotated through Authority, and distributed to Offline Kit consumers.
|
||||
- [ ] SLSA attestations enabled where supply-chain requirements demand Level 3 evidence.
|
||||
- [ ] CLI/Console verification paths documented and tested (CI pipelines exercise `stella export verify`).
|
||||
- [ ] Encryption metadata (recipients, wrapped keys) recorded in provenance and validated during verification.
|
||||
- [ ] Run audit logs capture signature timestamps, signer identity, and failure reasons.
|
||||
|
||||
---
|
||||
|
||||
> **Imposed rule reminder:** Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.
|
||||
|
||||
@@ -90,6 +90,11 @@ Payloads follow the contract in `Contracts/IssuerDtos.cs` and align with domain
|
||||
3. **SDK integration (ISSUER-30-004)** — supply cached issuer metadata to VEX Lens and Excititor clients.
|
||||
4. **Observability & Ops (ISSUER-30-005/006)** — metrics, dashboards, deployment automation, offline kit.
|
||||
|
||||
## 9. Operations & runbooks
|
||||
- [Deployment guide](operations/deployment.md)
|
||||
- [Backup & restore](operations/backup-restore.md)
|
||||
- [Offline kit notes](operations/offline-kit.md)
|
||||
|
||||
---
|
||||
|
||||
*Document owner: Issuer Directory Guild*
|
||||
|
||||
104
docs/modules/issuer-directory/operations/backup-restore.md
Normal file
104
docs/modules/issuer-directory/operations/backup-restore.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Issuer Directory Backup & Restore
|
||||
|
||||
## Scope
|
||||
- **Applies to:** Issuer Directory when deployed via Docker Compose (`deploy/compose/docker-compose.*.yaml`) or the Helm chart (`deploy/helm/stellaops`).
|
||||
- **Artifacts covered:** MongoDB database `issuer-directory`, service configuration (`etc/issuer-directory.yaml`), CSAF seed file (`data/csaf-publishers.json`), and secret material for the Mongo connection string.
|
||||
- **Frequency:** Take a hot backup before every upgrade and at least daily in production. Keep encrypted copies off-site/air-gapped according to your compliance program.
|
||||
|
||||
## Inventory checklist
|
||||
| Component | Location (Compose default) | Notes |
|
||||
| --- | --- | --- |
|
||||
| Mongo data | `mongo-data` volume (`/var/lib/docker/volumes/.../mongo-data`) | Contains `issuers`, `issuer_keys`, `issuer_trust_overrides`, and `issuer_audit` collections. |
|
||||
| Configuration | `etc/issuer-directory.yaml` | Mounted read-only at `/etc/issuer-directory.yaml` inside the container. |
|
||||
| CSAF seed file | `src/IssuerDirectory/StellaOps.IssuerDirectory/data/csaf-publishers.json` | Ensure customised seeds are part of the backup; regenerate if you ship regional overrides. |
|
||||
| Mongo secret | `.env` entry `ISSUER_DIRECTORY_MONGO_CONNECTION_STRING` or secret store export | Required to restore connectivity; treat as sensitive. |
|
||||
|
||||
> **Tip:** Export the secret via `kubectl get secret issuer-directory-secrets -o yaml` (sanitize before storage) or copy the Compose `.env` file into an encrypted vault.
|
||||
|
||||
## Hot backup (no downtime)
|
||||
1. **Create output directory**
|
||||
```bash
|
||||
BACKUP_DIR=backup/issuer-directory/$(date +%Y-%m-%dT%H%M%S)
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
```
|
||||
2. **Dump Mongo collections**
|
||||
```bash
|
||||
docker compose -f deploy/compose/docker-compose.prod.yaml exec mongo \
|
||||
mongodump --archive=/dump/issuer-directory-$(date +%Y%m%dT%H%M%SZ).gz \
|
||||
--gzip --db issuer-directory
|
||||
|
||||
docker compose -f deploy/compose/docker-compose.prod.yaml cp \
|
||||
mongo:/dump/issuer-directory-$(date +%Y%m%dT%H%M%SZ).gz "$BACKUP_DIR/"
|
||||
```
|
||||
For Kubernetes, run the same `mongodump` command inside the `stellaops-mongo` pod and copy the archive via `kubectl cp`.
|
||||
3. **Capture configuration and seeds**
|
||||
```bash
|
||||
cp etc/issuer-directory.yaml "$BACKUP_DIR/"
|
||||
cp src/IssuerDirectory/StellaOps.IssuerDirectory/data/csaf-publishers.json "$BACKUP_DIR/"
|
||||
```
|
||||
4. **Capture secrets**
|
||||
```bash
|
||||
grep '^ISSUER_DIRECTORY_MONGO_CONNECTION_STRING=' dev.env > "$BACKUP_DIR/issuer-directory.mongo.secret"
|
||||
chmod 600 "$BACKUP_DIR/issuer-directory.mongo.secret"
|
||||
```
|
||||
5. **Generate checksums and encrypt**
|
||||
```bash
|
||||
(cd "$BACKUP_DIR" && sha256sum * > SHA256SUMS)
|
||||
tar czf "$BACKUP_DIR.tar.gz" -C "$BACKUP_DIR" .
|
||||
age -r you@example.org "$BACKUP_DIR.tar.gz" > "$BACKUP_DIR.tar.gz.age"
|
||||
```
|
||||
|
||||
## Cold backup (planned downtime)
|
||||
1. Notify stakeholders and pause automation calling the API.
|
||||
2. Stop services:
|
||||
```bash
|
||||
docker compose -f deploy/compose/docker-compose.prod.yaml down issuer-directory
|
||||
```
|
||||
(For Helm: `kubectl scale deploy stellaops-issuer-directory --replicas=0`.)
|
||||
3. Snapshot volumes:
|
||||
```bash
|
||||
docker run --rm -v mongo-data:/data \
|
||||
-v "$(pwd)":/backup busybox tar czf /backup/mongo-data-$(date +%Y%m%d).tar.gz -C /data .
|
||||
```
|
||||
4. Copy configuration, seeds, and secrets as in the hot backup.
|
||||
5. Restart services and confirm `/health/live` returns `200 OK`.
|
||||
|
||||
## Restore procedure
|
||||
1. **Provision clean volumes**
|
||||
- Compose: `docker volume rm mongo-data` (optional) then `docker compose up -d mongo`.
|
||||
- Helm: delete the Mongo PVC or attach a fresh volume snapshot.
|
||||
2. **Restore Mongo**
|
||||
```bash
|
||||
docker compose exec -T mongo \
|
||||
mongorestore --archive \
|
||||
--gzip --drop < issuer-directory-YYYYMMDDTHHMMSSZ.gz
|
||||
```
|
||||
3. **Restore configuration/secrets**
|
||||
- Copy `issuer-directory.yaml` into `etc/`.
|
||||
- Reapply the secret: `kubectl apply -f issuer-directory-secret.yaml` or repopulate `.env`.
|
||||
4. **Restore CSAF seeds** (optional)
|
||||
- If you maintain a customised seed file, copy it back before starting the container. Otherwise the bundled file will be used.
|
||||
5. **Start services**
|
||||
```bash
|
||||
docker compose up -d issuer-directory
|
||||
# or
|
||||
kubectl scale deploy stellaops-issuer-directory --replicas=1
|
||||
```
|
||||
6. **Validate**
|
||||
- `curl -fsSL https://localhost:8447/health/live`
|
||||
- Issue an access token and list issuers to confirm results.
|
||||
- Check Mongo counts match expectations (`db.issuers.countDocuments()`, etc.).
|
||||
- Confirm Prometheus scrapes `issuer_directory_changes_total` and `issuer_directory_key_operations_total` for the tenants you restored.
|
||||
|
||||
## Disaster recovery notes
|
||||
- **Retention:** Maintain 30 daily + 12 monthly archives. Store copies in geographically separate, access-controlled vaults.
|
||||
- **Audit reconciliation:** Ensure `issuer_audit` entries cover the restore window; export them for compliance.
|
||||
- **Seed replay:** If the CSAF seed file was lost, set `ISSUER_DIRECTORY_SEED_CSAF=true` for the first restart to rehydrate the global tenant.
|
||||
- **Testing:** Run quarterly restore drills in a staging environment to validate procedure drift.
|
||||
|
||||
## Verification checklist
|
||||
- [ ] `/health/live` returns `200 OK`.
|
||||
- [ ] Mongo collections (`issuers`, `issuer_keys`, `issuer_trust_overrides`) have expected counts.
|
||||
- [ ] `issuer_directory_changes_total`, `issuer_directory_key_operations_total`, and `issuer_directory_key_validation_failures_total` metrics resume within 1 minute.
|
||||
- [ ] Audit entries exist for post-restore CRUD activity.
|
||||
- [ ] Client integrations (VEX Lens, Excititor) resolve issuers successfully.
|
||||
107
docs/modules/issuer-directory/operations/deployment.md
Normal file
107
docs/modules/issuer-directory/operations/deployment.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# Issuer Directory Deployment Guide
|
||||
|
||||
## Scope
|
||||
- **Applies to:** Issuer Directory WebService (`stellaops/issuer-directory-web`) running via the provided Docker Compose bundles (`deploy/compose/docker-compose.*.yaml`) or the Helm chart (`deploy/helm/stellaops`).
|
||||
- **Covers:** Environment prerequisites, secret handling, Compose + Helm rollout steps, and post-deploy verification.
|
||||
- **Audience:** Platform/DevOps engineers responsible for Identity & Signing sprint deliverables.
|
||||
|
||||
## 1 · Prerequisites
|
||||
- Authority must be running and reachable at the issuer URL you configure (default Compose host: `https://authority:8440`).
|
||||
- MongoDB 4.2+ with credentials for the `issuer-directory` database (Compose defaults to the root user defined in `.env`).
|
||||
- Network access to Authority, MongoDB, and (optionally) Prometheus if you scrape metrics.
|
||||
- Issuer Directory configuration file `etc/issuer-directory.yaml` checked and customised for your environment (tenant header, audiences, telemetry level, CSAF seed path).
|
||||
|
||||
> **Secrets:** Use `etc/secrets/issuer-directory.mongo.secret.example` as a template. Store the real connection string in an untracked file or secrets manager and reference it via environment variables (`ISSUER_DIRECTORY_MONGO_CONNECTION_STRING`) rather than committing credentials.
|
||||
|
||||
## 2 · Deploy with Docker Compose
|
||||
1. **Prepare environment variables**
|
||||
```bash
|
||||
cp deploy/compose/env/dev.env.example dev.env
|
||||
cp etc/secrets/issuer-directory.mongo.secret.example issuer-directory.mongo.env
|
||||
# Edit dev.env and issuer-directory.mongo.env with production-ready secrets.
|
||||
```
|
||||
|
||||
2. **Inspect the merged configuration**
|
||||
```bash
|
||||
docker compose \
|
||||
--env-file dev.env \
|
||||
--env-file issuer-directory.mongo.env \
|
||||
-f deploy/compose/docker-compose.dev.yaml config
|
||||
```
|
||||
The command confirms the new `issuer-directory` service resolves the port (`${ISSUER_DIRECTORY_PORT:-8447}`) and the Mongo connection string is in place.
|
||||
|
||||
3. **Launch the stack**
|
||||
```bash
|
||||
docker compose \
|
||||
--env-file dev.env \
|
||||
--env-file issuer-directory.mongo.env \
|
||||
-f deploy/compose/docker-compose.dev.yaml up -d issuer-directory
|
||||
```
|
||||
Compose automatically mounts `../../etc/issuer-directory.yaml` into the container at `/etc/issuer-directory.yaml`, seeds CSAF publishers, and exposes the API on `https://localhost:8447`.
|
||||
|
||||
### Compose environment variables
|
||||
| Variable | Purpose | Default |
|
||||
| --- | --- | --- |
|
||||
| `ISSUER_DIRECTORY_PORT` | Host port that maps to container port `8080`. | `8447` |
|
||||
| `ISSUER_DIRECTORY_MONGO_CONNECTION_STRING` | Injected into `ISSUERDIRECTORY__MONGO__CONNECTIONSTRING`; should contain credentials. | `mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017` |
|
||||
| `ISSUER_DIRECTORY_SEED_CSAF` | Toggles CSAF bootstrap on startup. Set to `false` after the first production import if you manage issuers manually. | `true` |
|
||||
|
||||
4. **Smoke test**
|
||||
```bash
|
||||
curl -k https://localhost:8447/health/live
|
||||
stellaops-cli issuer-directory issuers list \
|
||||
--base-url https://localhost:8447 \
|
||||
--tenant demo \
|
||||
--access-token "$(stellaops-cli auth token issue --scope issuer-directory:read)"
|
||||
```
|
||||
|
||||
5. **Upgrade & rollback**
|
||||
- Update Compose images to the desired release manifest (`deploy/releases/*.yaml`), re-run `docker compose config`, then `docker compose up -d`.
|
||||
- Rollbacks follow the same steps with the previous manifest. Mongo collections are backwards compatible within `2025.10.x`.
|
||||
|
||||
## 3 · Deploy with Helm
|
||||
1. **Create or update the secret**
|
||||
```bash
|
||||
kubectl create secret generic issuer-directory-secrets \
|
||||
--from-literal=ISSUERDIRECTORY__MONGO__CONNECTIONSTRING='mongodb://stellaops:<password>@stellaops-mongo:27017' \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
```
|
||||
Add optional overrides (e.g. `ISSUERDIRECTORY__AUTHORITY__ISSUER`) if your Authority issuer differs from the default.
|
||||
|
||||
2. **Template for validation**
|
||||
```bash
|
||||
helm template issuer-directory deploy/helm/stellaops \
|
||||
-f deploy/helm/stellaops/values-prod.yaml \
|
||||
--set services.issuer-directory.env.ISSUERDIRECTORY__AUTHORITY__ISSUER=https://authority.prod.stella-ops.org \
|
||||
> /tmp/issuer-directory.yaml
|
||||
```
|
||||
|
||||
3. **Install / upgrade**
|
||||
```bash
|
||||
helm upgrade --install stellaops deploy/helm/stellaops \
|
||||
-f deploy/helm/stellaops/values-prod.yaml \
|
||||
--set services.issuer-directory.env.ISSUERDIRECTORY__AUTHORITY__ISSUER=https://authority.prod.stella-ops.org
|
||||
```
|
||||
The chart provisions:
|
||||
- ConfigMap `stellaops-issuer-directory-config` with `IssuerDirectory` settings.
|
||||
- Deployment `stellaops-issuer-directory` with readiness/liveness probes on `/health/live`.
|
||||
- Service on port `8080` (ClusterIP by default).
|
||||
|
||||
4. **Expose for operators (optional)**
|
||||
- Use an Ingress/HTTPRoute to publish `https://issuer-directory.<env>.stella-ops.org`.
|
||||
- Ensure the upstream includes DPoP headers if proxied through an API gateway.
|
||||
|
||||
5. **Post-deploy validation**
|
||||
```bash
|
||||
kubectl exec deploy/stellaops-issuer-directory -- \
|
||||
curl -sf http://127.0.0.1:8080/health/live
|
||||
kubectl logs deploy/stellaops-issuer-directory | grep 'IssuerDirectory Mongo connected'
|
||||
```
|
||||
Prometheus should begin scraping `issuer_directory_changes_total` and related metrics (labels: `tenant`, `issuer`, `action`).
|
||||
|
||||
## 4 · Operational checklist
|
||||
- **Secrets:** Connection strings live in `issuer-directory-secrets` (Helm) or an `.env` file stored in your secrets vault (Compose). Rotate credentials via secret update + pod restart.
|
||||
- **Audit streams:** Confirm `issuer_directory_audit` collection receives entries when CRUD operations run; export logs for compliance.
|
||||
- **Tenants:** The service enforces the `X-StellaOps-Tenant` header. For multi-tenant staging, configure the reverse proxy to inject the correct tenant or issue scoped tokens.
|
||||
- **CSAF seeds:** `ISSUER_DIRECTORY_SEED_CSAF=true` replays `data/csaf-publishers.json` on startup. Set to `false` once production tenants are fully managed, or override `csafSeedPath` with a curated bundle.
|
||||
- **Release alignment:** Before promotion, run `deploy/tools/validate-profiles.sh` to lint Compose/Helm bundles, then verify the new `issuer-directory-web` entry in `deploy/releases/2025.10-edge.yaml` (or the relevant manifest) matches the channel you intend to ship.
|
||||
73
docs/modules/issuer-directory/operations/offline-kit.md
Normal file
73
docs/modules/issuer-directory/operations/offline-kit.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Issuer Directory Offline Kit Notes
|
||||
|
||||
## Purpose
|
||||
Operators bundling Stella Ops for fully disconnected environments must include the Issuer Directory service so VEX Lens, Excititor, and Policy Engine can resolve trusted issuers without reaching external registries.
|
||||
|
||||
## 1 · Bundle contents
|
||||
Include the following artefacts in your Offline Update Kit staging tree:
|
||||
|
||||
| Path (within kit) | Source | Notes |
|
||||
| --- | --- | --- |
|
||||
| `images/issuer-directory-web.tar` | `registry.stella-ops.org/stellaops/issuer-directory-web` (digest from `deploy/releases/<channel>.yaml`) | Export with `crane pull --format=tar` or `skopeo copy docker://... oci:...`. |
|
||||
| `config/issuer-directory/issuer-directory.yaml` | `etc/issuer-directory.yaml` (customised) | Replace Authority issuer, tenant header, and log level as required. |
|
||||
| `config/issuer-directory/csaf-publishers.json` | `src/IssuerDirectory/StellaOps.IssuerDirectory/data/csaf-publishers.json` or regional override | Operators can edit before import to add private publishers. |
|
||||
| `secrets/issuer-directory/connection.env` | Secure secret store export (`ISSUER_DIRECTORY_MONGO_CONNECTION_STRING=`) | Encrypt at rest; Offline Kit importer places it in the Compose/Helm secret. |
|
||||
| `env/issuer-directory.env` (optional) | Curated `.env` snippet (for example `ISSUER_DIRECTORY_SEED_CSAF=false`) | Helps operators disable reseeding after their first import without editing the main profile. |
|
||||
| `docs/issuer-directory/deployment.md` | `docs/modules/issuer-directory/operations/deployment.md` | Ship alongside kit documentation for operators. |
|
||||
|
||||
> **Image digests:** Update `deploy/releases/2025.10-edge.yaml` (or the relevant manifest) with the exact digest before building the kit so `offline-manifest.json` can assert integrity.
|
||||
|
||||
## 2 · Compose (air-gapped) deployment
|
||||
1. Load images locally on the target:
|
||||
```bash
|
||||
docker load < images/issuer-directory-web.tar
|
||||
```
|
||||
2. Copy Compose artefacts:
|
||||
```bash
|
||||
cp deploy/compose/docker-compose.airgap.yaml .
|
||||
cp deploy/compose/env/airgap.env.example airgap.env
|
||||
cp secrets/issuer-directory/connection.env issuer-directory.mongo.env
|
||||
```
|
||||
3. Update `airgap.env` with site-specific values (Authority issuer, tenant, ports) and remove outbound endpoints.
|
||||
4. Bring up the service:
|
||||
```bash
|
||||
docker compose \
|
||||
--env-file airgap.env \
|
||||
--env-file issuer-directory.mongo.env \
|
||||
-f docker-compose.airgap.yaml up -d issuer-directory
|
||||
```
|
||||
5. Verify via `curl -k https://issuer-directory.airgap.local:8447/health/live`.
|
||||
|
||||
## 3 · Kubernetes (air-gapped) deployment
|
||||
1. Pre-load the OCI image into your local registry mirror and update `values-airgap.yaml` to reference it.
|
||||
2. Apply the secret bundled in the kit:
|
||||
```bash
|
||||
kubectl apply -f secrets/issuer-directory/connection-secret.yaml
|
||||
```
|
||||
(Generate this file during packaging with `kubectl create secret generic issuer-directory-secrets ... --dry-run=client -o yaml`.)
|
||||
3. Install/upgrade the chart:
|
||||
```bash
|
||||
helm upgrade --install stellaops deploy/helm/stellaops \
|
||||
-f deploy/helm/stellaops/values-airgap.yaml \
|
||||
--set services.issuer-directory.env.ISSUERDIRECTORY__AUTHORITY__ISSUER=https://authority.airgap.local/realms/stellaops
|
||||
```
|
||||
4. Confirm `issuer_directory_changes_total` is visible in your offline Prometheus stack.
|
||||
|
||||
## 4 · Import workflow summary
|
||||
1. Run `ops/offline-kit/build_offline_kit.py` with the additional artefacts noted above.
|
||||
2. Sign the resulting tarball and manifest (Cosign) and record the SHA-256 in the release notes.
|
||||
3. At the destination:
|
||||
```bash
|
||||
stellaops-cli offline kit import \
|
||||
--bundle stella-ops-offline-kit-<version>-airgap.tar.gz \
|
||||
--destination /opt/stellaops/offline-kit
|
||||
```
|
||||
4. Follow the Compose or Helm path depending on your topology.
|
||||
|
||||
## 5 · Post-import validation
|
||||
- [ ] `docker images | grep issuer-directory` (Compose) or `kubectl get deploy stellaops-issuer-directory` (Helm) shows the expected version.
|
||||
- [ ] `csaf-publishers.json` in the container matches the offline bundle (hash check).
|
||||
- [ ] `/issuer-directory/issuers` returns global seed issuers (requires token with `issuer-directory:read` scope).
|
||||
- [ ] Audit collection receives entries when you create/update issuers offline.
|
||||
- [ ] Offline kit manifest (`offline-manifest.json`) lists `images/issuer-directory-web.tar` and `config/issuer-directory/issuer-directory.yaml` with SHA-256 values you recorded during packaging.
|
||||
- [ ] Prometheus in the offline environment reports `issuer_directory_changes_total` for the tenants imported from the kit.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,56 +1,56 @@
|
||||
{
|
||||
"$id": "https://stella-ops.org/schemas/notify/notify-event@1.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Notify Event Envelope",
|
||||
"type": "object",
|
||||
"required": ["eventId", "kind", "tenant", "ts", "payload"],
|
||||
"properties": {
|
||||
"eventId": {"type": "string", "format": "uuid"},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"description": "Event kind identifier (e.g. scanner.report.ready).",
|
||||
"enum": [
|
||||
"scanner.report.ready",
|
||||
"scanner.scan.completed",
|
||||
"scheduler.rescan.delta",
|
||||
"attestor.logged",
|
||||
"zastava.admission",
|
||||
"feedser.export.completed",
|
||||
"vexer.export.completed"
|
||||
]
|
||||
},
|
||||
"version": {"type": "string"},
|
||||
"tenant": {"type": "string"},
|
||||
"ts": {"type": "string", "format": "date-time"},
|
||||
"actor": {"type": "string"},
|
||||
"scope": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"namespace": {"type": "string"},
|
||||
"repo": {"type": "string"},
|
||||
"digest": {"type": "string"},
|
||||
"component": {"type": "string"},
|
||||
"image": {"type": "string"},
|
||||
"labels": {"$ref": "#/$defs/stringMap"},
|
||||
"attributes": {"$ref": "#/$defs/stringMap"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"payload": {
|
||||
"type": "object",
|
||||
"description": "Event specific body; see individual schemas for shapes.",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"attributes": {"$ref": "#/$defs/stringMap"}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"$defs": {
|
||||
"stringMap": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
".*": {"type": "string"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"$id": "https://stella-ops.org/schemas/notify/notify-event@1.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Notify Event Envelope",
|
||||
"type": "object",
|
||||
"required": ["eventId", "kind", "tenant", "ts", "payload"],
|
||||
"properties": {
|
||||
"eventId": {"type": "string", "format": "uuid"},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"description": "Event kind identifier (e.g. scanner.report.ready).",
|
||||
"enum": [
|
||||
"scanner.report.ready",
|
||||
"scanner.scan.completed",
|
||||
"scheduler.rescan.delta",
|
||||
"attestor.logged",
|
||||
"zastava.admission",
|
||||
"conselier.export.completed",
|
||||
"excitor.export.completed"
|
||||
]
|
||||
},
|
||||
"version": {"type": "string"},
|
||||
"tenant": {"type": "string"},
|
||||
"ts": {"type": "string", "format": "date-time"},
|
||||
"actor": {"type": "string"},
|
||||
"scope": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"namespace": {"type": "string"},
|
||||
"repo": {"type": "string"},
|
||||
"digest": {"type": "string"},
|
||||
"component": {"type": "string"},
|
||||
"image": {"type": "string"},
|
||||
"labels": {"$ref": "#/$defs/stringMap"},
|
||||
"attributes": {"$ref": "#/$defs/stringMap"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"payload": {
|
||||
"type": "object",
|
||||
"description": "Event specific body; see individual schemas for shapes.",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"attributes": {"$ref": "#/$defs/stringMap"}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"$defs": {
|
||||
"stringMap": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
".*": {"type": "string"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ Policy Engine compiles and evaluates Stella DSL policies deterministically, prod
|
||||
- [Architecture](./architecture.md)
|
||||
- [Implementation plan](./implementation_plan.md)
|
||||
- [Task board](./TASKS.md)
|
||||
- [Secret leak detection readiness](../policy/secret-leak-detection-readiness.md)
|
||||
- [Windows package readiness](../policy/windows-package-readiness.md)
|
||||
|
||||
## How to get started
|
||||
1. Open ../../implplan/SPRINTS.md and locate the stories referencing this module.
|
||||
|
||||
@@ -1,31 +1,33 @@
|
||||
# StellaOps Policy Engine
|
||||
|
||||
Policy Engine compiles and evaluates Stella DSL policies deterministically, producing explainable findings with full provenance.
|
||||
|
||||
## Responsibilities
|
||||
- Compile `stella-dsl@1` packs into executable graphs.
|
||||
- Join advisories, VEX evidence, and SBOM inventories to derive effective findings.
|
||||
- Expose simulation and diff APIs for UI/CLI workflows.
|
||||
- Emit change-stream driven events for Notify/Scheduler integrations.
|
||||
|
||||
## Key components
|
||||
- `StellaOps.Policy.Engine` service host.
|
||||
- Shared libraries under `StellaOps.Policy.*` for evaluation, storage, DSL tooling.
|
||||
|
||||
## Integrations & dependencies
|
||||
- MongoDB findings collections, RustFS explain bundles.
|
||||
- Scheduler for incremental re-evaluation triggers.
|
||||
- CLI/UI for policy authoring and runs.
|
||||
|
||||
## Operational notes
|
||||
- DSL grammar and lifecycle docs in ../../policy/.
|
||||
- Observability guidance in ../../observability/policy.md.
|
||||
- Governance and scope mapping in ../../security/policy-governance.md.
|
||||
|
||||
## Backlog references
|
||||
- DOCS-POLICY-20-001 … DOCS-POLICY-20-012 (completed baseline).
|
||||
- DOCS-POLICY-23-007 (upcoming command updates).
|
||||
|
||||
## Epic alignment
|
||||
- **Epic 2 – Policy Engine & Editor:** deliver deterministic evaluation, DSL infrastructure, explain traces, and incremental runs.
|
||||
- **Epic 4 – Policy Studio:** integrate registry workflows, simulation at scale, approvals, and promotion semantics.
|
||||
# StellaOps Policy Engine
|
||||
|
||||
Policy Engine compiles and evaluates Stella DSL policies deterministically, producing explainable findings with full provenance.
|
||||
|
||||
## Responsibilities
|
||||
- Compile `stella-dsl@1` packs into executable graphs.
|
||||
- Join advisories, VEX evidence, and SBOM inventories to derive effective findings.
|
||||
- Expose simulation and diff APIs for UI/CLI workflows.
|
||||
- Emit change-stream driven events for Notify/Scheduler integrations.
|
||||
|
||||
## Key components
|
||||
- `StellaOps.Policy.Engine` service host.
|
||||
- Shared libraries under `StellaOps.Policy.*` for evaluation, storage, DSL tooling.
|
||||
|
||||
## Integrations & dependencies
|
||||
- MongoDB findings collections, RustFS explain bundles.
|
||||
- Scheduler for incremental re-evaluation triggers.
|
||||
- CLI/UI for policy authoring and runs.
|
||||
|
||||
## Operational notes
|
||||
- DSL grammar and lifecycle docs in ../../policy/.
|
||||
- Observability guidance in ../../observability/policy.md.
|
||||
- Governance and scope mapping in ../../security/policy-governance.md.
|
||||
- Readiness briefs: ../policy/secret-leak-detection-readiness.md, ../policy/windows-package-readiness.md.
|
||||
- Readiness briefs: ../scanner/design/macos-analyzer.md, ../scanner/design/windows-analyzer.md, ../policy/secret-leak-detection-readiness.md, ../policy/windows-package-readiness.md.
|
||||
|
||||
## Backlog references
|
||||
- DOCS-POLICY-20-001 … DOCS-POLICY-20-012 (completed baseline).
|
||||
- DOCS-POLICY-23-007 (upcoming command updates).
|
||||
|
||||
## Epic alignment
|
||||
- **Epic 2 – Policy Engine & Editor:** deliver deterministic evaluation, DSL infrastructure, explain traces, and incremental runs.
|
||||
- **Epic 4 – Policy Studio:** integrate registry workflows, simulation at scale, approvals, and promotion semantics.
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# Task board — Policy Engine
|
||||
|
||||
> Local tasks should link back to ./AGENTS.md and mirror status updates into ../../TASKS.md when applicable.
|
||||
|
||||
| ID | Status | Owner(s) | Description | Notes |
|
||||
|----|--------|----------|-------------|-------|
|
||||
| POLICY ENGINE-DOCS-0001 | TODO | Docs Guild | Validate that ./README.md aligns with the latest release notes. | See ./AGENTS.md |
|
||||
| POLICY ENGINE-OPS-0001 | TODO | Ops Guild | Review runbooks/observability assets after next sprint demo. | Sync outcomes back to ../../TASKS.md |
|
||||
| POLICY ENGINE-ENG-0001 | TODO | Module Team | Cross-check implementation plan milestones against ../../implplan/SPRINTS.md. | Update status via ./AGENTS.md workflow |
|
||||
# Task board — Policy Engine
|
||||
|
||||
> Local tasks should link back to ./AGENTS.md and mirror status updates into ../../TASKS.md when applicable.
|
||||
|
||||
| ID | Status | Owner(s) | Description | Notes |
|
||||
|----|--------|----------|-------------|-------|
|
||||
| POLICY ENGINE-DOCS-0001 | TODO | Docs Guild | Validate that ./README.md aligns with the latest release notes. | See ./AGENTS.md |
|
||||
| POLICY ENGINE-OPS-0001 | TODO | Ops Guild | Review runbooks/observability assets after next sprint demo. | Sync outcomes back to ../../TASKS.md |
|
||||
| POLICY ENGINE-ENG-0001 | TODO | Module Team | Cross-check implementation plan milestones against ../../implplan/SPRINTS.md. | Update status via ./AGENTS.md workflow |
|
||||
| POLICY-READINESS-0001 | DOING (2025-11-03) | Policy Guild, Security Guild | Resolve open questions in `../policy/secret-leak-detection-readiness.md` ahead of SCANNER-ENG-0007. | Decision workshop 2025-11-10 (Northwind demo); cover masking depth, telemetry retention, bundle defaults, tenant overrides. |
|
||||
| POLICY-READINESS-0002 | DOING (2025-11-03) | Policy Guild, Security Guild, Offline Kit Guild | Review `../policy/windows-package-readiness.md`, set signature verification locus, feed mirroring scopes, and legacy installer posture. | FinSecure PCI blocker; deliver Authenticode/feed decision by 2025-11-07 before analyzer spike kickoff. |
|
||||
|
||||
80
docs/modules/policy/secret-leak-detection-readiness.md
Normal file
80
docs/modules/policy/secret-leak-detection-readiness.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Secret Leak Detection Readiness — Policy & Security Brief
|
||||
|
||||
> Audience: Policy Guild, Security Guild
|
||||
> Related backlog: SCANNER-ENG-0007 (deterministic leak detection pipeline), DOCS-SCANNER-BENCH-62-007 (rule bundle documentation), SCANNER-SECRETS-01..03 (Surface.Secrets alignment)
|
||||
|
||||
## 1. Goal & scope
|
||||
- Provide a shared understanding of how the planned `StellaOps.Scanner.Analyzers.Secrets` plug-in will operate so Policy/Security can prepare governance controls in parallel with engineering delivery.
|
||||
- Document evidence flow, policy predicates, and offline distribution requirements to minimise lead time once implementation lands.
|
||||
- Capture open questions requiring Policy/Security sign-off (masking rules, tenancy constraints, waiver workflows).
|
||||
|
||||
## 2. Proposed evidence pipeline
|
||||
1. **Source resolution**
|
||||
- Surface.Secrets providers (Kubernetes, file bundle, inline) continue to resolve operational credentials. Handles remain opaque and never enter analyzer outputs.
|
||||
2. **Deterministic scanning**
|
||||
- New plug-in executes signed rule bundles (regex + entropy signatures) stored under `scanner/rules/secrets/`.
|
||||
- Execution context restricted to read-only layer mount; analyzers emit `secret.leak` evidence with: `{rule.id, rule.version, confidence, severity, mask, file, line}`.
|
||||
3. **Analysis store persistence**
|
||||
- Findings are written into `ScanAnalysisStore` (`ScanAnalysisKeys.secretFindings`) so Policy Engine can ingest them alongside component fragments.
|
||||
4. **Policy overlay**
|
||||
- Policy predicates (see §3) evaluate evidence, lattice scores, and tenant-scoped allow/deny lists.
|
||||
- CLI/export surfaces show masked snippets and remediation hints.
|
||||
5. **Offline parity**
|
||||
- Rule bundles, signature manifests, and validator hash lists ship with Offline Kit; rule updates must be signed and versioned to preserve determinism.
|
||||
|
||||
## 3. Policy Engine considerations
|
||||
- **New predicates**
|
||||
- `secret.hasFinding(ruleId?, severity?, confidence?)`
|
||||
- `secret.bundle.version(requiredVersion)`
|
||||
- `secret.mask.applied` (bool) — verify masking for high severity hits.
|
||||
- `secret.path.allowlist` — tenant-configured allow list keyed by digest/path.
|
||||
- **Lattice weight suggestions**
|
||||
- High severity & high confidence → escalate to `block` unless waived.
|
||||
- Low confidence → default to `warn` with optional escalation when multiple matches occur (`secret.match.count >= N`).
|
||||
- **Waiver workflow**
|
||||
- Reuse VEX-first lattice approach: require attach of remediation note, ticket reference, and expiration date.
|
||||
- Ensure waivers attach rule version so upgraded rules re-evaluate automatically.
|
||||
- **Masking / privacy**
|
||||
- Minimum masking: first and last 2 characters retained; remainder replaced with `*`.
|
||||
- Persist masked payload only; full value never leaves scanner context.
|
||||
|
||||
## 4. Security guardrails
|
||||
- Rule bundle signing: Signer issues DSSE envelope for each ruleset; Policy must verify signature before enabling new bundle.
|
||||
- Tenant isolation: bundle enablement scoped per tenant; defaults deny unknown bundles.
|
||||
- Telemetry: emit `scanner.secret.finding_total{tenant, ruleId, severity}` with masking applied after count aggregation.
|
||||
- Access control: restrict retrieval of raw finding payloads to roles with `scanner.secret.read` scope; audits log query + tenant + rule id.
|
||||
|
||||
## 5. Offline & update flow
|
||||
1. Engineering publishes new bundle → Signer signs → Offline Kit includes bundle + manifest.
|
||||
2. Operators import bundle via CLI (`stella secrets bundle install --path <bundle>`).
|
||||
- CLI verifies signature, version monotonicity, and rule hash list.
|
||||
3. Policy update: push config snippet enabling bundle, severity mapping, and waiver templates.
|
||||
4. Run `stella secrets scan --dry-run` to verify deterministic output against golden fixtures before enabling in production.
|
||||
|
||||
## 6. Open questions / owners
|
||||
| Topic | Question | Owner | Target decision |
|
||||
| --- | --- | --- | --- |
|
||||
| Masking depth | Do we mask file paths or only payloads? | Security Guild | Sprint 132 design review |
|
||||
| Telemetry retention | Should secret finding metrics be sampled or full fidelity? | Policy + Observability Guild | Sprint 132 |
|
||||
| Default bundles | Which rule families ship enabled-by-default (cloud creds, SSH keys, JWT)? | Security Guild | Sprint 133 |
|
||||
| Tenant overrides | Format for per-tenant allow lists (path glob vs digest)? | Policy Guild | Sprint 133 |
|
||||
|
||||
### Decision tracker
|
||||
| Decision | Owner(s) | Target date | Status |
|
||||
| --- | --- | --- | --- |
|
||||
| Masking depth (paths vs payloads) | Security Guild | 2025-11-10 | Pending — workshop aligned with Northwind demo |
|
||||
| Telemetry retention granularity | Policy + Observability Guild | 2025-11-10 | Pending |
|
||||
| Default rule bundles (cloud creds/SSH/JWT) | Security Guild | 2025-11-10 | Draft proposals under review |
|
||||
| Tenant override format | Policy Guild | 2025-11-10 | Pending |
|
||||
|
||||
## 7. Next steps
|
||||
1. Policy Guild drafts predicate specs + policy templates (map to DOCS-SCANNER-BENCH-62-007 exit criteria).
|
||||
2. Security Guild reviews signing + masking requirements; align with Surface.Secrets roadmap.
|
||||
3. Docs Guild (this task) continues maintaining `docs/benchmarks/scanner/deep-dives/secrets.md` with finalized rule taxonomy and references.
|
||||
4. Engineering provides prototype fixture outputs for review once SCANNER-ENG-0007 spikes begin.
|
||||
|
||||
|
||||
## Coordination
|
||||
- Capture macOS customer requirements via `docs/benchmarks/scanner/windows-macos-demand.md` (Northwind Health Services).
|
||||
- Update dashboard (`docs/api/scanner/windows-macos-summary.md`) after readiness decisions.
|
||||
- Share outcomes from 2025-11-10 macOS demo before finalising POLICY-READINESS-0001.
|
||||
92
docs/modules/policy/windows-package-readiness.md
Normal file
92
docs/modules/policy/windows-package-readiness.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Windows Package Coverage — Policy & Security Readiness Brief
|
||||
|
||||
> Audience: Policy Guild, Security Guild, Offline Kit Guild
|
||||
> Related engineering backlog (proposed): SCANNER-ENG-0024..0027
|
||||
> Docs linkage: DOCS-SCANNER-BENCH-62-016
|
||||
|
||||
## 1. Goal
|
||||
- Prepare policy and security guidance ahead of Windows analyzer implementation (MSI, WinSxS, Chocolatey, registry).
|
||||
- Define evidence handling, predicates, waiver expectations, and offline prerequisites so engineering can align during spike execution.
|
||||
|
||||
## 2. Evidence pipeline snapshot (from `design/windows-analyzer.md`)
|
||||
1. **Collection**
|
||||
- MSI database parsing → component records keyed by ProductCode/ComponentCode.
|
||||
- WinSxS manifests → assembly identities, catalog signatures.
|
||||
- Chocolatey packages → nuspec metadata, feed provenance, script hashes.
|
||||
- Registry exports → uninstall/service entries, legacy installers.
|
||||
- Driver/service mapper → capability overlays (kernel-mode, auto-start).
|
||||
2. **Storage**
|
||||
- Results persisted as `LayerComponentFragment`s plus capability overlays (`ScanAnalysisKeys.capability.windows`).
|
||||
- Provenance metadata includes signature thumbprint, catalog hash, feed URL, install context.
|
||||
3. **Downstream**
|
||||
- Policy Engine consumes component + capability evidence; Export Center bundles MSI manifests, nuspec metadata, catalog hashes.
|
||||
|
||||
## 3. Policy predicate requirements
|
||||
| Predicate | Description | Initial default |
|
||||
| --- | --- | --- |
|
||||
| `windows.package.signed(thumbprint?)` | True when Authenticode signature/cert matches allowlist. | Warn on missing signature, fail on mismatched thumbprint for kernel drivers. |
|
||||
| `windows.package.sourceAllowed(sourceId)` | Validates Chocolatey/nuget feed against tenant allowlist. | Fail if feed not in tenant policy. |
|
||||
| `windows.driver.kernelMode()` | Flags kernel-mode drivers for extra scrutiny. | Fail when unsigned; warn otherwise. |
|
||||
| `windows.driver.signedBy(publisher)` | Checks driver publisher matches allowlist. | Warn on unknown publisher. |
|
||||
| `windows.service.autoStart(name)` | Identifies auto-start services. | Warn if unsigned binary or service not in allowlist. |
|
||||
| `windows.package.legacyInstaller()` | Legacy EXE-only installers detected via registry. | Warn by default; escalate if binary unsigned. |
|
||||
|
||||
Additional considerations:
|
||||
- Map KB references (from WinSxS/MSP metadata) to vulnerability posture once Policy Engine supports patch layering.
|
||||
- Provide predicates to waive specific ProductCodes or AssemblyIdentities with expiration.
|
||||
|
||||
## 4. Waiver & governance model
|
||||
- Waiver key: `{productCode, version, signatureThumbprint}` or for drivers `{driverName, serviceName, signatureThumbprint}`.
|
||||
- Required metadata: remediation ticket, justification, expiry date.
|
||||
- Automated re-evaluation when version or signature changes.
|
||||
- Tenants maintain allow lists for Chocolatey feeds and driver publishers via policy configuration.
|
||||
|
||||
## 5. Masking & privacy
|
||||
- Findings should not include raw script contents; provide SHA256 hash and limited excerpt (first/last 8 chars).
|
||||
- Registry values (install paths, command lines) must be truncated if they contain secrets; rely on Surface.Secrets to manage environment variables referenced during install scripts.
|
||||
|
||||
## 6. Offline kit guidance
|
||||
- Bundle:
|
||||
- MSI parser binary + schema definitions.
|
||||
- Chocolatey feed snapshot(s) (nupkg files) with hash manifest.
|
||||
- Microsoft root/intermediate certificate bundles; optional CRL/OCSP cache instructions.
|
||||
- Operators must export registry hives (`SOFTWARE`, `SYSTEM`) during image extraction; document PowerShell script and required access.
|
||||
- Provide checksum manifest to verify feed snapshot integrity.
|
||||
|
||||
## 7. Telemetry expectations
|
||||
- Metrics:
|
||||
- `scanner.windows.package_total{tenant,signed}` — count packages per signature state.
|
||||
- `scanner.windows.driver_unsigned_total{tenant}`.
|
||||
- `scanner.windows.choco_feed_total{tenant,feed}`.
|
||||
- Logs:
|
||||
- Include product code, version, signature thumbprint, feed ID (no file paths unless sanitized).
|
||||
- Traces:
|
||||
- Annotate collector spans (`collector.windows.msi`, `collector.windows.winsxs`, etc.) with component counts and parsing duration.
|
||||
|
||||
## 8. Open questions
|
||||
| Topic | Question | Owner | Target decision |
|
||||
| --- | --- | --- | --- |
|
||||
| Signature verification locus | Scanner vs Policy: where to verify Authenticode signatures + revocation? | Security Guild | Sprint 133 |
|
||||
| Feed mirroring scope | Default set of Chocolatey feeds to mirror (official/community). | Product + Security Guild | Sprint 133 |
|
||||
| Legacy installers | Should we block unsigned EXE installers by default or allow warn-only posture? | Policy Guild | Sprint 134 |
|
||||
| Driver taxonomy | Define high-risk driver categories (kernel-mode, filter drivers) for policy severity. | Policy Guild | Sprint 134 |
|
||||
|
||||
### Decision tracker
|
||||
| Decision | Owner(s) | Target date | Status |
|
||||
| --- | --- | --- | --- |
|
||||
| Authenticode verification locus (Scanner vs Policy) | Security Guild | 2025-11-07 | Pending — blocker for FinSecure |
|
||||
| Chocolatey feed mirroring scope | Product + Security Guild | 2025-11-07 | Draft proposal circulating |
|
||||
| Legacy installer posture (warn vs fail) | Policy Guild | 2025-11-14 | Not started |
|
||||
| Driver risk taxonomy | Policy Guild | 2025-11-14 | Not started |
|
||||
|
||||
## 9. Next steps
|
||||
1. Policy Guild drafts predicate specs + policy templates; align with DOCS-SCANNER-BENCH-62-016.
|
||||
2. Security Guild evaluates signature verification approach and revocation handling (online vs offline CRL cache).
|
||||
3. Offline Kit Guild scopes snapshot size and update cadence for Chocolatey feeds and certificate bundles.
|
||||
4. Docs Guild prepares policy/user guidance updates once predicates are finalised.
|
||||
5. Security Guild to report decision for FinSecure Corp (POLICY-READINESS-0002) by 2025-11-07; feed outcome into dashboards.
|
||||
|
||||
## Coordination
|
||||
- Sync demand signals via `docs/benchmarks/scanner/windows-macos-demand.md`.
|
||||
- Log policy readiness status in `docs/api/scanner/windows-coverage.md`.
|
||||
- Update Windows/macOS metrics dashboard when decisions change (`docs/api/scanner/windows-macos-summary.md`).
|
||||
@@ -8,6 +8,12 @@ Scanner analyses container images layer-by-layer, producing deterministic SBOM f
|
||||
- [Architecture](./architecture.md)
|
||||
- [Implementation plan](./implementation_plan.md)
|
||||
- [Task board](./TASKS.md)
|
||||
- [macOS analyzer design](./design/macos-analyzer.md)
|
||||
- [Windows analyzer design](./design/windows-analyzer.md)
|
||||
- [Field engagement workflow](./operations/field-engagement.md)
|
||||
- [Design dossiers](./design/README.md)
|
||||
- [Benchmarks overview](../../benchmarks/scanner/README.md)
|
||||
- [Benchmarks overview](../../benchmarks/scanner/README.md)
|
||||
|
||||
## How to get started
|
||||
1. Open ../../implplan/SPRINTS.md and locate the stories referencing this module.
|
||||
|
||||
@@ -1,38 +1,46 @@
|
||||
# StellaOps Scanner
|
||||
|
||||
Scanner analyses container images layer-by-layer, producing deterministic SBOM fragments, diffs, and signed reports.
|
||||
|
||||
## Responsibilities
|
||||
- Expose APIs (WebService) for scan orchestration, diffing, and artifact retrieval.
|
||||
- Run Worker analyzers for OS, language, and native ecosystems with restart-only plug-ins.
|
||||
- Store SBOM fragments and artifacts in RustFS/object storage.
|
||||
- Publish DSSE-ready metadata for Signer/Attestor and downstream policy evaluation.
|
||||
|
||||
## Key components
|
||||
- `StellaOps.Scanner.WebService` minimal API host.
|
||||
- `StellaOps.Scanner.Worker` analyzer executor.
|
||||
- Analyzer libraries under `StellaOps.Scanner.Analyzers.*`.
|
||||
|
||||
## Integrations & dependencies
|
||||
- Scheduler for job intake and retries.
|
||||
- Policy Engine for evidence handoff.
|
||||
- Export Center / Offline Kit for artifact packaging.
|
||||
|
||||
## Operational notes
|
||||
- CAS caches, bounded retries, DSSE integration.
|
||||
- Monitoring dashboards (see ./operations/analyzers-grafana-dashboard.json).
|
||||
- RustFS migration playbook.
|
||||
|
||||
## Related resources
|
||||
- ./operations/analyzers.md
|
||||
- ./operations/analyzers-grafana-dashboard.json
|
||||
- ./operations/rustfs-migration.md
|
||||
- ./operations/entrypoint.md
|
||||
|
||||
## Backlog references
|
||||
- DOCS-SCANNER updates tracked in ../../TASKS.md.
|
||||
- Analyzer parity work in src/Scanner/**/TASKS.md.
|
||||
|
||||
## Epic alignment
|
||||
- **Epic 6 – Vulnerability Explorer:** provide policy-aware scan outputs, explain traces, and findings ledger hooks for triage workflows.
|
||||
- **Epic 10 – Export Center:** generate export-ready artefacts, manifests, and DSSE metadata for bundles.
|
||||
# StellaOps Scanner
|
||||
|
||||
Scanner analyses container images layer-by-layer, producing deterministic SBOM fragments, diffs, and signed reports.
|
||||
|
||||
## Responsibilities
|
||||
- Expose APIs (WebService) for scan orchestration, diffing, and artifact retrieval.
|
||||
- Run Worker analyzers for OS, language, and native ecosystems with restart-only plug-ins.
|
||||
- Store SBOM fragments and artifacts in RustFS/object storage.
|
||||
- Publish DSSE-ready metadata for Signer/Attestor and downstream policy evaluation.
|
||||
|
||||
## Key components
|
||||
- `StellaOps.Scanner.WebService` minimal API host.
|
||||
- `StellaOps.Scanner.Worker` analyzer executor.
|
||||
- Analyzer libraries under `StellaOps.Scanner.Analyzers.*`.
|
||||
|
||||
## Integrations & dependencies
|
||||
- Scheduler for job intake and retries.
|
||||
- Policy Engine for evidence handoff.
|
||||
- Export Center / Offline Kit for artifact packaging.
|
||||
|
||||
## Operational notes
|
||||
- CAS caches, bounded retries, DSSE integration.
|
||||
- Monitoring dashboards (see ./operations/analyzers-grafana-dashboard.json).
|
||||
- RustFS migration playbook.
|
||||
|
||||
## Related resources
|
||||
- ./operations/analyzers.md
|
||||
- ./operations/analyzers-grafana-dashboard.json
|
||||
- ./operations/rustfs-migration.md
|
||||
- ./operations/entrypoint.md
|
||||
- ./design/macos-analyzer.md
|
||||
- ./design/windows-analyzer.md
|
||||
- ../benchmarks/scanner/deep-dives/macos.md
|
||||
- ../benchmarks/scanner/deep-dives/windows.md
|
||||
- ../benchmarks/scanner/windows-macos-demand.md
|
||||
- ../benchmarks/scanner/windows-macos-interview-template.md
|
||||
- ./operations/field-engagement.md
|
||||
- ./design/README.md
|
||||
|
||||
## Backlog references
|
||||
- DOCS-SCANNER updates tracked in ../../TASKS.md.
|
||||
- Analyzer parity work in src/Scanner/**/TASKS.md.
|
||||
|
||||
## Epic alignment
|
||||
- **Epic 6 – Vulnerability Explorer:** provide policy-aware scan outputs, explain traces, and findings ledger hooks for triage workflows.
|
||||
- **Epic 10 – Export Center:** generate export-ready artefacts, manifests, and DSSE metadata for bundles.
|
||||
|
||||
@@ -6,5 +6,35 @@
|
||||
|----|--------|----------|-------------|-------|
|
||||
| SCANNER-DOCS-0001 | DOING (2025-10-29) | Docs Guild | Validate that ./README.md aligns with the latest release notes. | See ./AGENTS.md |
|
||||
| SCANNER-DOCS-0002 | DONE (2025-11-02) | Docs Guild | Keep scanner benchmark comparisons (Trivy/Grype/Snyk) and deep-dive matrix current with source references. | Coordinate with docs/benchmarks owners |
|
||||
| SCANNER-DOCS-0003 | TODO | Docs Guild, Product Guild | Gather Windows/macOS analyzer demand signals and record findings in `docs/benchmarks/scanner/windows-macos-demand.md`. | Coordinate with Product Marketing & Sales enablement |
|
||||
| SCANNER-ENG-0008 | TODO | EntryTrace Guild, QA Guild | Maintain EntryTrace heuristic cadence per `docs/benchmarks/scanner/scanning-gaps-stella-misses-from-competitors.md`. | Include quarterly pattern review + explain trace updates |
|
||||
| SCANNER-ENG-0009 | DOING (2025-11-02) | Ruby Analyzer Guild | SCANNER-ANALYZERS-RUBY-28-001..012 | Deliver Ruby analyzer parity and observation pipeline per gap doc (lockfiles, runtime graph, policy signals). | Design complete; fixtures published; CLI/Offline docs updated. |
|
||||
| SCANNER-ENG-0010 | TODO | PHP Analyzer Guild | SCANNER-ANALYZERS-PHP-27-001..012 | Ship PHP analyzer pipeline (composer lock, autoload graph, capability signals) to close comparison gaps. | Analyzer + policy integration merged; fixtures + docs aligned. |
|
||||
| SCANNER-ENG-0011 | TODO | Language Analyzer Guild | — | Scope Deno runtime analyzer (lockfile resolver, import graphs) based on competitor techniques. | Design doc approved; backlog split into analyzer/runtime work. |
|
||||
| SCANNER-ENG-0012 | TODO | Language Analyzer Guild | — | Evaluate Dart analyzer requirements (pubspec parsing, AOT artifacts) to restore parity. | Investigation summary + task split filed with Dart guild. |
|
||||
| SCANNER-ENG-0013 | TODO | Swift Analyzer Guild | — | Plan Swift Package Manager coverage (Package.resolved, xcframeworks, runtime hints) with policy hooks. | Design brief approved; backlog seeded with analyzer tasks. |
|
||||
| SCANNER-ENG-0014 | TODO | Runtime Guild, Zastava Guild | — | Align Kubernetes/VM target coverage roadmap between Scanner and Zastava per comparison findings. | Joint roadmap doc approved; cross-guild tasks opened. |
|
||||
| SCANNER-ENG-0015 | TODO | Export Center Guild, Scanner Guild | — | Document DSSE/Rekor operator enablement guidance and rollout levers surfaced in gap analysis. | Playbook drafted; Export Center backlog updated. |
|
||||
| SCANNER-ENG-0016 | DOING (2025-11-02) | Ruby Analyzer Guild (Lockfile Squad) | Implement `RubyLockCollector` and vendor cache ingestion per design §4.1–4.3. | Coordinate fixtures under `fixtures/lang/ruby/lockfiles`; target alpha by Sprint 21. |
|
||||
| SCANNER-ENG-0017 | TODO | Ruby Analyzer Guild (Runtime Squad) | Build runtime require/autoload graph builder with tree-sitter Ruby per design §4.4. | Deliver edges with reason codes and integrate EntryTrace hints. |
|
||||
| SCANNER-ENG-0018 | TODO | Ruby Analyzer Guild (Capability Squad) | Emit Ruby capability and framework surface signals as defined in design §4.5. | Policy predicates prototyped; capability records available in SBOM overlays. |
|
||||
| SCANNER-ENG-0019 | TODO | Ruby Analyzer Guild, CLI Guild | Ship Ruby CLI verbs (`stella ruby inspect|resolve`) and Offline Kit packaging per design §4.6. | CLI commands documented; offline manifest updated; e2e tests pass. |
|
||||
| SCANNER-LIC-0001 | DOING (2025-11-02) | Scanner Guild, Legal Guild | Vet tree-sitter Ruby licensing and Offline Kit packaging requirements. | SPDX review complete; packaging plan approved. |
|
||||
| SCANNER-POLICY-0001 | TODO | Policy Guild, Ruby Analyzer Guild | Define Policy Engine predicates for Ruby groups/capabilities and align lattice weights. | Policy schema merged; tests cover new predicates. |
|
||||
| SCANNER-CLI-0001 | TODO | CLI Guild, Ruby Analyzer Guild | Coordinate CLI UX/help text for new Ruby verbs and update CLI docs. | CLI help + docs updated; golden outputs recorded. |
|
||||
| SCANNER-ENG-0002 | TODO | Scanner Guild, CLI Guild | Design Node.js lockfile collector/CLI validator per `docs/benchmarks/scanner/scanning-gaps-stella-misses-from-competitors.md`. | Capture Surface & policy requirements before implementation |
|
||||
| SCANNER-ENG-0003 | TODO | Python Analyzer Guild, CLI Guild | Design Python lockfile/editable install parity checks per `docs/benchmarks/scanner/scanning-gaps-stella-misses-from-competitors.md`. | Include policy predicates & CLI story in design |
|
||||
| SCANNER-ENG-0004 | TODO | Java Analyzer Guild, CLI Guild | Design Java lockfile ingestion & validation per `docs/benchmarks/scanner/scanning-gaps-stella-misses-from-competitors.md`. | Cover Gradle/SBT collectors, CLI verb, policy hooks |
|
||||
| SCANNER-ENG-0005 | TODO | Go Analyzer Guild | Enhance Go stripped-binary fallback inference per `docs/benchmarks/scanner/scanning-gaps-stella-misses-from-competitors.md`. | Include inferred module metadata & policy integration |
|
||||
| SCANNER-ENG-0006 | TODO | Rust Analyzer Guild | Expand Rust fingerprint coverage per `docs/benchmarks/scanner/scanning-gaps-stella-misses-from-competitors.md`. | Ship enriched fingerprint catalogue + policy controls |
|
||||
| SCANNER-ENG-0007 | TODO | Scanner Guild, Policy Guild | Design deterministic secret leak detection pipeline per `docs/benchmarks/scanner/scanning-gaps-stella-misses-from-competitors.md`. | Include rule packaging, Policy Engine integration, CLI workflow |
|
||||
| SCANNER-ENG-0020 | TODO | Scanner Guild (macOS Cellar Squad) | Implement Homebrew collector and fragment mapper per `design/macos-analyzer.md` §3.1. | Emit brew component fragments with tap provenance; integrate Surface.Validation/FS limits. |
|
||||
| SCANNER-ENG-0021 | TODO | Scanner Guild (macOS Receipts Squad) | Implement pkgutil receipt collector per `design/macos-analyzer.md` §3.2. | Parse receipts/BOMs into deterministic component records with install metadata. |
|
||||
| SCANNER-ENG-0022 | TODO | Scanner Guild, Policy Guild (macOS Bundles Squad) | Implement macOS bundle inspector & capability overlays per `design/macos-analyzer.md` §3.3. | Extract signing/entitlements, emit capability evidence, merge with receipts/Homebrew. |
|
||||
| SCANNER-ENG-0023 | TODO | Scanner Guild, Offline Kit Guild, Policy Guild | Deliver macOS policy/offline integration per `design/macos-analyzer.md` §5–6. | Define policy predicates, CLI toggles, Offline Kit packaging, and documentation. |
|
||||
| SCANNER-ENG-0024 | TODO | Scanner Guild (Windows MSI Squad) | Implement Windows MSI collector per `design/windows-analyzer.md` §3.1. | Parse MSI databases, emit component fragments with provenance metadata; blocked until POLICY-READINESS-0002 (decision due 2025-11-07). |
|
||||
| SCANNER-ENG-0025 | TODO | Scanner Guild (Windows WinSxS Squad) | Implement WinSxS manifest collector per `design/windows-analyzer.md` §3.2. | Correlate assemblies with MSI components and catalog signatures; dependent on POLICY-READINESS-0002 outcome. |
|
||||
| SCANNER-ENG-0026 | TODO | Scanner Guild (Windows Packages Squad) | Implement Chocolatey & registry collectors per `design/windows-analyzer.md` §3.3–3.4. | Harvest nuspec metadata and registry uninstall/service evidence; merge with filesystem artefacts; align with feed decisions from POLICY-READINESS-0002. |
|
||||
| SCANNER-ENG-0027 | TODO | Scanner Guild, Policy Guild, Offline Kit Guild | Deliver Windows policy/offline integration per `design/windows-analyzer.md` §5–6. | Define predicates, CLI/Offline docs, and packaging for feeds/certs; start after POLICY-READINESS-0002 sign-off. |
|
||||
| SCANNER-OPS-0001 | TODO | Ops Guild | Review runbooks/observability assets after next sprint demo. | Sync outcomes back to ../../TASKS.md |
|
||||
| SCANNER-ENG-0001 | TODO | Module Team | Cross-check implementation plan milestones against ../../implplan/SPRINTS.md. | Update status via ./AGENTS.md workflow |
|
||||
|
||||
35
docs/modules/scanner/design/README.md
Normal file
35
docs/modules/scanner/design/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Scanner Design Dossiers
|
||||
|
||||
This directory contains deep technical designs for current and upcoming analyzers and surface components.
|
||||
|
||||
## Language analyzers
|
||||
- `ruby-analyzer.md` — lockfile, runtime graph, capability signals for Ruby.
|
||||
|
||||
## Surface & platform contracts
|
||||
- `surface-fs.md`
|
||||
- `surface-env.md`
|
||||
- `surface-validation.md`
|
||||
- `surface-secrets.md`
|
||||
|
||||
## OS ecosystem designs
|
||||
- `macos-analyzer.md` — Homebrew, pkgutil, `.app` bundle plan.
|
||||
- `windows-analyzer.md` — MSI, WinSxS, Chocolatey, registry collectors.
|
||||
|
||||
## Demand & dashboards
|
||||
- `../../benchmarks/scanner/windows-macos-demand.md` — demand tracker.
|
||||
- `../../benchmarks/scanner/windows-macos-interview-template.md` — interview template.
|
||||
- `../../api/scanner/windows-coverage.md` — coverage summary dashboard.
|
||||
- `../../api/scanner/windows-macos-summary.md` — metric snapshot.
|
||||
|
||||
## Utility & reference
|
||||
- `../operations/field-engagement.md` — SE workflow guidance.
|
||||
- `../operations/analyzers.md` — operational runbook.
|
||||
- `../operations/rustfs-migration.md` — storage migration notes.
|
||||
|
||||
## Maintenance tips
|
||||
- Keep demand tracker (`../../benchmarks/scanner/windows-macos-demand.md`) and API dashboards in sync when updating macOS/Windows designs.
|
||||
- Cross-reference policy readiness briefs for associated predicates and waiver models.
|
||||
|
||||
## Policy readiness
|
||||
- `../policy/secret-leak-detection-readiness.md` — secret leak pipeline decisions.
|
||||
- `../policy/windows-package-readiness.md` — Windows analyzer policy decisions.
|
||||
123
docs/modules/scanner/design/macos-analyzer.md
Normal file
123
docs/modules/scanner/design/macos-analyzer.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# macOS Analyzer Design Brief (Draft)
|
||||
|
||||
> Owners: Scanner Guild, Policy Guild, Offline Kit Guild
|
||||
> Related backlog (proposed): SCANNER-ENG-0020..0023, DOCS-SCANNER-BENCH-62-002
|
||||
> Status: Draft pending demand validation (see `docs/benchmarks/scanner/windows-macos-demand.md`)
|
||||
|
||||
## 1. Scope & objectives
|
||||
- Deliver deterministic inventory coverage for macOS container and VM images, focusing on Homebrew, Apple/pkgutil receipts, and `.app` bundles.
|
||||
- Preserve StellaOps principles: per-layer provenance, offline parity, policy explainability, and signed evidence pipelines.
|
||||
- Provide capability signals (entitlements, hardened runtime, launch agents) to enable Policy Engine gating.
|
||||
|
||||
Out of scope (Phase 1):
|
||||
- Dynamic runtime tracing of macOS services (deferred to Zastava/EntryTrace).
|
||||
- iOS/tvOS/visionOS package formats (will reuse bundle inspection where feasible).
|
||||
- Direct notarization ticket validation (delegated to Policy Engine unless otherwise decided).
|
||||
|
||||
## 2. High-level architecture
|
||||
```
|
||||
Scanner.Worker (macOS profile)
|
||||
├─ Surface.Validation (enforce allowlists, bundle size limits)
|
||||
├─ Surface.FS (layer/materialized filesystem)
|
||||
├─ HomebrewCollector (new) -> LayerComponentFragment (brew)
|
||||
├─ PkgutilCollector (new) -> LayerComponentFragment (pkgutil)
|
||||
├─ BundleInspector (new) -> Capability records + component fragments
|
||||
├─ LaunchAgentMapper (optional) -> Usage hints
|
||||
└─ MacOsAggregator (new) -> merges fragments, emits ComponentGraph & capability overlays
|
||||
```
|
||||
|
||||
- Each collector runs deterministically against the mounted filesystem; results persist in `ScanAnalysisStore` under dedicated keys before being normalized by `MacOsComponentMapper`.
|
||||
- Layer digests follow existing `LayerComponentFragment` semantics to maintain diff/replay parity.
|
||||
|
||||
## 3. Collectors & data sources
|
||||
### 3.1 Homebrew collector
|
||||
- Scan `/usr/local/Cellar/**` and `/opt/homebrew/Cellar/**` for `INSTALL_RECEIPT.json` and `*.rb` formula metadata.
|
||||
- Output fields: `tap`, `formula`, `version`, `revision`, `poured_from_bottle`, `installed_with`: [].
|
||||
- Store `bottle.sha256`, `source.url`, and `tapped_from` metadata for provenance.
|
||||
- Map to PURL: `pkg:brew/<tap>/<formula>@<version>?revision=<revision>`.
|
||||
- Guardrails: limit traversal depth, ignore caches (`/Caskroom` optional), enforce 200MB per formula cap (configurable).
|
||||
|
||||
### 3.2 pkgutil receipt collector
|
||||
- Parse `/var/db/receipts/*.plist` for pkg identifiers, version, install time, volume, installer domain.
|
||||
- Use `.bom` files to enumerate installed files; capture path hashes via `osx.BomParser`.
|
||||
- Emit `ComponentRecord`s keyed by `pkgutil:<identifier>` with metadata: `bundleIdentifier`, `installTimeUtc`, `volume`.
|
||||
- Provide dependency mapping between pkg receipts and Homebrew formulae when overlapping file hashes exist (optional Phase 2).
|
||||
|
||||
### 3.3 Bundle inspector
|
||||
- Traverse `/Applications`, `/System/Applications`, `/Users/*/Applications`, `/Library/Application Support`.
|
||||
- For each `.app`:
|
||||
- Read `Info.plist` (bundle id, version, short version, minimum system).
|
||||
- Extract code signing metadata via `codesign --display --xml` style parsing (Team ID, certificate chain, hardened runtime flag).
|
||||
- Parse entitlements (`archived-entitlements.xcent`) and map to capability taxonomy (network, camera, automation, etc.).
|
||||
- Hash `CodeResources` manifest to support provenance comparisons.
|
||||
- Link `.app` bundles to receipts and Homebrew formulae using bundle id or install path heuristics.
|
||||
- Emit capability overlays (e.g., `macos.entitlement("com.apple.security.network.server") == true`).
|
||||
|
||||
### 3.4 Launch agent mapper (optional Phase 1 extension)
|
||||
- Inspect `/Library/Launch{Agents,Daemons}` and user equivalents.
|
||||
- Parse `plist` for program arguments, run conditions, sockets, environment.
|
||||
- Feed derived runtime hints into EntryTrace (`UsageHints`) to mark active binaries vs dormant installations.
|
||||
|
||||
## 4. Aggregation & output
|
||||
- `MacOsComponentMapper` converts collector results into:
|
||||
- `LayerComponentFragment` arrays keyed by synthetic digests (`sha256:stellaops-os-macbrew`, etc.).
|
||||
- `ComponentMetadata` entries capturing tap origin, Team ID, entitlements, notarization flag (when available).
|
||||
- Capability overlays stored under `ScanAnalysisKeys.capability.macOS`.
|
||||
- Export Center enhancements:
|
||||
- Include Homebrew metadata manifests and CodeResources hashes in attested bundles.
|
||||
- Provide optional notarization proof attachments if Policy Engine later requires them.
|
||||
|
||||
## 5. Policy & governance integration
|
||||
- Predicates to introduce:
|
||||
- `macos.bundle.signed(teamId?, hardenedRuntime?)`
|
||||
- `macos.entitlement(name)`
|
||||
- `macos.pkg.receipt(identifier, version?)`
|
||||
- `macos.notarized` (pending Security decision).
|
||||
- Lattice guidance:
|
||||
- Unsigned/unnotarized third-party apps default to `warn`.
|
||||
- High-risk entitlements (camera, screen capture) escalate severity unless whitelisted.
|
||||
- Waiver model similar to existing EntryTrace/Secrets: require bundle hash + Team ID to avoid broad exceptions.
|
||||
|
||||
## 6. Offline kit considerations
|
||||
- Mirror required Homebrew taps (`homebrew/core`, `homebrew/cask`) and freeze metadata per release.
|
||||
- Bundle notarization cache instructions (CRL/OCSP) so operators can prefetch without Apple connectivity.
|
||||
- Package Apple certificate chain updates (WWDR) and provide verification script to ensure validity.
|
||||
- Document disk space impacts (Homebrew cellar snapshots ~500MB per tap snapshot).
|
||||
|
||||
## 7. Testing strategy
|
||||
- Unit tests with fixture directories:
|
||||
- Sample Cellar tree with multiple formulas (bottled vs source builds).
|
||||
- Synthetic pkg receipts + BOM files.
|
||||
- `.app` bundles with varying signing states (signed/notarized/unsigned).
|
||||
- Integration tests:
|
||||
- Build macOS rootfs tarballs via CI job (runner requiring macOS) that mimic layered container conversion.
|
||||
- Verify deterministic output by re-running collectors and diffing results (CI gating).
|
||||
- Offline compliance tests:
|
||||
- Ensure rule bundles and caches load without network by running integration suite in sealed environment.
|
||||
|
||||
## 8. Dependencies & open items
|
||||
| Item | Description | Owner | Status |
|
||||
| --- | --- | --- | --- |
|
||||
| Demand threshold | Need ≥3 qualified customer asks to justify engineering investment | Product Guild | Active (DOCS-SCANNER-BENCH-62-002) |
|
||||
| macOS rootfs fixtures | Require automation to produce macOS layer tarballs for tests | Scanner Guild | Pending design |
|
||||
| Notarization validation | Decide whether scanner performs `spctl --assess` or defers | Security Guild | TBD |
|
||||
| Entitlement taxonomy | Finalize capability grouping for Policy Engine | Policy Guild | TBD |
|
||||
|
||||
## 9. Proposed backlog entries
|
||||
| ID (proposed) | Title | Summary |
|
||||
| --- | --- | --- |
|
||||
| SCANNER-ENG-0020 | Implement Homebrew collector and fragment mapper | Parse cellar manifests, emit brew component records, integrate with Surface.FS/Validation. |
|
||||
| SCANNER-ENG-0021 | Implement pkgutil receipt collector | Parse receipts/BOM, output installer component records with provenance. |
|
||||
| SCANNER-ENG-0022 | Implement macOS bundle inspector & capability overlays | Extract plist/signing/entitlements, produce capability evidence and merge with receipts. |
|
||||
| SCANNER-ENG-0023 | Policy & Offline integration for macOS | Define predicates, CLI toggles, Offline Kit packaging, and documentation. |
|
||||
|
||||
## 10. References
|
||||
- `docs/benchmarks/scanner/deep-dives/macos.md` — competitor snapshot and roadmap summary.
|
||||
- `docs/benchmarks/scanner/windows-macos-demand.md` — demand capture log.
|
||||
- `docs/modules/scanner/design/surface-secrets.md`, `surface-fs.md`, `surface-validation.md` — surface contracts leveraged by collectors.
|
||||
|
||||
Further reading: `../../api/scanner/windows-coverage.md` (summary) and `../../api/scanner/windows-macos-summary.md` (metrics dashboard).
|
||||
|
||||
Policy readiness alignment: see `../policy/secret-leak-detection-readiness.md` (POLICY-READINESS-0001).
|
||||
|
||||
Upcoming milestone: Northwind Health Services demo on 2025-11-10 to validate notarization/entitlement outputs before final policy sign-off.
|
||||
137
docs/modules/scanner/design/ruby-analyzer.md
Normal file
137
docs/modules/scanner/design/ruby-analyzer.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Ruby Analyzer Parity Design (SCANNER-ENG-0009)
|
||||
|
||||
**Status:** Draft • Owner: Ruby Analyzer Guild • Updated: 2025-11-02
|
||||
|
||||
## 1. Goals & Non-Goals
|
||||
- **Goals**
|
||||
- Deterministically catalogue Ruby application dependencies (Gemfile/Gemfile.lock, vendored specs, .gem archives) for container layers and local workspaces.
|
||||
- Build runtime usage graphs (require/require_relative, Zeitwerk autoloads, Rack boot chains, Sidekiq/ActiveJob schedulers).
|
||||
- Emit capability signals (exec/fs/net/serialization, framework fingerprints, job schedulers) consumable by Policy Engine and explain traces.
|
||||
- Provide CLI verbs (`stella ruby inspect`, `stella ruby resolve`) and Offline Kit parity for air-gapped deployments.
|
||||
- **Non-Goals**
|
||||
- Shipping dynamic runtime profilers (log-based or APM) in this iteration.
|
||||
- Implementing UI changes beyond exposing explain traces the Policy/UI guilds already support.
|
||||
|
||||
## 2. Scope & Inputs
|
||||
| Input | Location | Notes |
|
||||
|-------|----------|-------|
|
||||
| Gemfile / Gemfile.lock | Source tree, layer filesystem | Handle multiple apps per repo; honour Bundler groups. |
|
||||
| Vendor bundles (`vendor/bundle`, `.bundle/config`) | Layer filesystem | Needed for offline/built images; avoid double-counting platform-specific gems. |
|
||||
| `.gemspec` files / cached specs | `~/.bundle/cache`, `vendor/cache`, gems in layers | Support deterministic parsing without executing gem metadata. |
|
||||
| Framework configs | `config/application.rb`, `config/routes.rb`, `config/sidekiq.yml`, etc. | Feed framework surface mapper. |
|
||||
| Container metadata | Layer digests via RustFS CAS | Support incremental composition per layer. |
|
||||
|
||||
## 3. High-Level Architecture
|
||||
```
|
||||
┌─────────────────────────┐ ┌────────────────────┐
|
||||
│ Bundler Lock Collector │───────▶│ Package Graph │
|
||||
└─────────────────────────┘ │ Aggregator │
|
||||
└─────────┬──────────┘
|
||||
┌─────────────────────────┐ │
|
||||
│ Gemspec Inspector │───────────────▶│
|
||||
└─────────────────────────┘ │
|
||||
▼
|
||||
┌────────────────────┐
|
||||
┌─────────────────────────┐ │ Runtime Graph │
|
||||
│ Require/Autoload Scan │───────▶│ Builder (Zeitwerk) │
|
||||
└─────────────────────────┘ └─────────┬──────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ Capability Emitter │
|
||||
└─────────┬──────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ SBOM Writer │
|
||||
│ + Policy Signals │
|
||||
└────────────────────┘
|
||||
```
|
||||
|
||||
## 4. Detailed Components
|
||||
### 4.1 Bundler Lock Collector
|
||||
- Parse `Gemfile.lock` deterministically (no network) using new `RubyLockCollector` under `StellaOps.Scanner.Analyzers.Lang.Ruby`.
|
||||
- Support alternative manifests (`gems.rb`, `gems.locked`) and workspace overrides.
|
||||
- Emit package nodes with fields: `name`, `version`, `source` (path/git/rubygems), `bundlerGroup[]`, `platform`, `declaredOnly` flag.
|
||||
- Implementation:
|
||||
- Reuse parsing strategy from Trivy (`pkg/fanal/analyzer/language/ruby/bundler`) but port to C# with streaming reader and stable ordering.
|
||||
- Integrate with Surface.Validation to enforce size limits and tenant allowlists for git/path sources.
|
||||
|
||||
### 4.2 Gemspec Inspector
|
||||
- Scan cached specs under `vendor/cache`, `.bundle/cache`, and gem directories to pick up transitive packages when lockfiles missing.
|
||||
- Parse without executing Ruby by using a deterministic DSL subset (similar to Trivy gemspec parser).
|
||||
- Link results to lockfile entries by `<name, version, platform>`; create new records flagged `InferredFromSpec` when lockfile absent.
|
||||
|
||||
### 4.3 Package Aggregator
|
||||
- New orchestrator `RubyPackageAggregator` merges lock and gemspec data with installed gems from container layers (once runtime analyzer ships).
|
||||
- Precedence: Installed > Lockfile > Gemspec.
|
||||
- Deduplicate by package key (name+version+platform) and attach provenance bits for Policy Engine.
|
||||
|
||||
### 4.4 Runtime Graph Builder
|
||||
- Static analysis for `require`, `require_relative`, `autoload`, Zeitwerk conventions, and Rails initialisers.
|
||||
- Implementation phases:
|
||||
1. Parse AST using tree-sitter Ruby embedded under `StellaOps.Scanner.Analyzers.Lang.Ruby.Syntax` with deterministic bindings.
|
||||
2. Generate edges `entrypoint -> file` and `file -> package` with reason codes (`require-static`, `autoload-zeitwerk`, `autoload-const_missing`).
|
||||
3. Identify framework entrypoints (Rails controllers, Rack middleware, Sidekiq workers) via heuristics defined in `SCANNER-ANALYZERS-RUBY-28-*` tasks.
|
||||
- Output merges with EntryTrace usage hints to support runtime filtering in Policy Engine.
|
||||
|
||||
### 4.5 Capability & Surface Signals
|
||||
- Emit evidence documents for:
|
||||
- Process/exec usage (`Kernel.system`, `` `cmd` ``, `Open3`).
|
||||
- Network clients (`Net::HTTP`, `Faraday`, `Redis`, `ActiveRecord::Base.establish_connection`).
|
||||
- Serialization sinks (`Marshal.load`, `YAML.load`, `Oj.load`).
|
||||
- Job schedulers (Sidekiq, Resque, ActiveJob, Whenever, Clockwork) with schedule metadata.
|
||||
- Capability records flow to Policy Engine under `capability.ruby.*` namespaces to allow gating on dangerous constructs.
|
||||
|
||||
### 4.6 CLI & Offline Integration
|
||||
- Add CLI verbs:
|
||||
- `stella ruby inspect <path>` – runs collector locally, outputs JSON summary with provenance.
|
||||
- `stella ruby resolve --image <ref>` – fetches scan artifacts, prints dependency graph grouped by bundler group/platform.
|
||||
- Ship analyzer DLLs and rules in Offline Kit manifest; include autoload/zeitwerk fingerprints and heuristics hashed for determinism.
|
||||
|
||||
## 5. Data Contracts
|
||||
| Artifact | Shape | Consumer |
|
||||
|----------|-------|----------|
|
||||
| `ruby_packages.json` | Array `{id, name, version, source, provenance, groups[], platform}` | SBOM Composer, Policy Engine |
|
||||
| `ruby_runtime_edges.json` | Edges `{from, to, reason, confidence}` | EntryTrace overlay, Policy explain traces |
|
||||
| `ruby_capabilities.json` | Capability `{kind, location, evidenceHash, params}` | Policy Engine (capability predicates) |
|
||||
|
||||
All records follow AOC appender rules (immutable, tenant-scoped) and include `hash`, `layerDigest`, and `timestamp` normalized to UTC ISO-8601.
|
||||
|
||||
## 6. Testing Strategy
|
||||
- **Fixtures**: Extend `fixtures/lang/ruby` with Rails, Sinatra, Sidekiq, Rack, container images (with/without vendor cache).
|
||||
- **Determinism**: Golden snapshots for package lists and capability outputs across repeated runs.
|
||||
- **Integration**: Worker e2e to ensure per-layer aggregation; CLI golden outputs (`stella ruby inspect`).
|
||||
- **Policy**: Unit tests verifying new predicates (`ruby.group`, `ruby.capability.exec`, etc.) in Policy Engine test suite.
|
||||
|
||||
## 7. Rollout Plan & Dependencies
|
||||
1. Implement collectors and aggregators (SCANNER-ANALYZERS-RUBY-28-001..004).
|
||||
2. Add capability analyzer and observations (SCANNER-ANALYZERS-RUBY-28-005..008).
|
||||
3. Wire CLI commands and Offline Kit packaging (SCANNER-ANALYZERS-RUBY-28-011).
|
||||
4. Update docs (DOCS-SCANNER-BENCH-62-009 follow-up) once analyzer alpha ready.
|
||||
|
||||
**Dependencies**
|
||||
- Tree-sitter Ruby grammar inclusion (needs Offline Kit packaging and licensing check).
|
||||
- Policy Engine support for new predicates and capability schemas.
|
||||
- Surface.Validation updates for git/path gem sources and secret resolution.
|
||||
|
||||
## 8. Open Questions
|
||||
- Do we require dynamic runtime logs (e.g., `ActiveSupport::Notifications`) for confidence boosts? (defer to future iteration)
|
||||
- Should we enforce signed gem provenance in MVP? Pending Product decision.
|
||||
- Need alignment with Export Center on Ruby-specific manifest emissions.
|
||||
|
||||
## 9. Licensing & Offline Packaging (SCANNER-LIC-0001)
|
||||
- **License**: tree-sitter core and `tree-sitter-ruby` grammar are MIT licensed (confirmed via upstream LICENSE files retrieved 2025-11-02).
|
||||
- **Obligations**:
|
||||
1. Include both MIT license texts in `/third-party-licenses/` and in Offline Kit manifests.
|
||||
2. Update `NOTICE.md` to acknowledge embedded grammars per company policy.
|
||||
3. Record the grammar commit hashes in build metadata; regenerate generated C/WASM artifacts deterministically.
|
||||
4. Ensure build pipeline uses `tree-sitter-cli` only as a build-time tool (not redistributed) to avoid extra licensing obligations.
|
||||
- **Deliverables**:
|
||||
- SCANNER-LIC-0001 to capture Legal sign-off and update packaging scripts.
|
||||
- Export Center to mirror license files into Offline Kit bundle.
|
||||
|
||||
---
|
||||
*References:*
|
||||
- Trivy: `pkg/fanal/analyzer/language/ruby/bundler`, `pkg/fanal/analyzer/language/ruby/gemspec`
|
||||
- Gap analysis: `docs/benchmarks/scanner/scanning-gaps-stella-misses-from-competitors.md#ruby-analyzer-parity-trivy-grype-snyk`
|
||||
135
docs/modules/scanner/design/windows-analyzer.md
Normal file
135
docs/modules/scanner/design/windows-analyzer.md
Normal file
@@ -0,0 +1,135 @@
|
||||
# Windows Analyzer Design Brief (Draft)
|
||||
|
||||
> Owners: Scanner Guild, Policy Guild, Offline Kit Guild, Security Guild
|
||||
> Related backlog (proposed): SCANNER-ENG-0024..0027, DOCS-SCANNER-BENCH-62-002
|
||||
> Status: Draft — contingent on Windows demand threshold (see `docs/benchmarks/scanner/windows-macos-demand.md`)
|
||||
|
||||
## 1. Objectives & boundaries
|
||||
- Provide deterministic inventory for Windows Server/container images covering MSI/WinSxS assemblies, Chocolatey packages, and registry-derived installers.
|
||||
- Preserve replayability (layer fragments, provenance metadata) and align outputs with existing SBOM/policy pipelines.
|
||||
- Respect sovereignty constraints: offline-friendly, signed rule bundles, no reliance on Windows APIs unavailable in containerized scans.
|
||||
|
||||
Out of scope (Phase 1):
|
||||
- Live registry queries on running Windows hosts (requires runtime agent; defer to Zastava/Runtime roadmap).
|
||||
- Windows Update patch baseline comparison (tracked separately under Runtime/Posture).
|
||||
- UWP/MSIX packages (flagged for follow-up once MSI parity is complete).
|
||||
|
||||
## 2. Architecture overview
|
||||
```
|
||||
Scanner.Worker (Windows profile)
|
||||
├─ Surface.Validation (enforce layer size, path allowlists)
|
||||
├─ Surface.FS (materialized NTFS image via 7z/guestmount)
|
||||
├─ MsiCollector -> LayerComponentFragment (windows-msi)
|
||||
├─ WinSxSCollector -> LayerComponentFragment (windows-winsxs)
|
||||
├─ ChocolateyCollector -> LayerComponentFragment (windows-choco)
|
||||
├─ RegistryCollector -> Evidence overlays (uninstall/services)
|
||||
├─ DriverCapabilityMapper -> Capability overlays (kernel/user drivers)
|
||||
└─ WindowsComponentMapper -> ComponentGraph + capability metadata
|
||||
```
|
||||
|
||||
- Collectors operate on extracted filesystem snapshots; registry access performed on exported hive files produced during image extraction (document in ops runbooks).
|
||||
- `WindowsComponentMapper` normalizes component identities (ProductCode, AssemblyIdentity, Chocolatey package ID) and merges overlapping evidence into deterministic fragments.
|
||||
|
||||
## 3. Collectors
|
||||
### 3.1 MSI collector
|
||||
- Input: `Windows/Installer/*.msi` database files (Jet OLE DB), registry hive exports for product mapping.
|
||||
- Implementation approach:
|
||||
- Use open-source MSI parser (custom or MIT-compatible) to avoid COM dependencies.
|
||||
- Extract Product, Component, File, Feature, Media tables.
|
||||
- Compute SHA256 for installed files via Component table, linking to WinSxS manifests.
|
||||
- Output metadata: `productCode`, `upgradeCode`, `productVersion`, `manufacturer`, `language`, `installContext`, `packageCode`, `sourceList`.
|
||||
- Evidence: file paths with digests, component IDs, CAB/patch references.
|
||||
|
||||
### 3.2 WinSxS collector
|
||||
- Input: `Windows/WinSxS/Manifests/*.manifest`, `Windows/WinSxS/` payload directories, catalog (.cat) files.
|
||||
- Parse XML assembly identities (name, version, processor architecture, public key token, language).
|
||||
- Map to MSI components when file hashes match.
|
||||
- Capture catalog signature thumbprint and optional patch KB references for policy gating.
|
||||
|
||||
### 3.3 Chocolatey collector
|
||||
- Input: `ProgramData/Chocolatey/lib/**`, `ProgramData/Chocolatey/package.backup`, `chocolateyinstall.ps1`, `.nuspec`.
|
||||
- Extract package ID, version, checksum, source feed, installed files and scripts.
|
||||
- Note whether install used cache or remote feed; record script hash for determinism.
|
||||
|
||||
### 3.4 Registry collector
|
||||
- Input: Exported `SOFTWARE` hive covering:
|
||||
- `Microsoft\Windows\CurrentVersion\Uninstall`
|
||||
- `Microsoft\Windows\CurrentVersion\Installer\UserData`
|
||||
- `Microsoft\Windows\CurrentVersion\Run` (startup apps)
|
||||
- Service/driver configuration from `SYSTEM` hive under `Services`.
|
||||
- Emit fallback evidence for installers not captured by MSI/Chocolatey (legacy EXE installers).
|
||||
- Record uninstall strings, install dates, publisher, estimated size, install location.
|
||||
|
||||
### 3.5 Driver & service mapper
|
||||
- Parse `SYSTEM` hive `Services` entries to detect drivers (type=1 or 2) and critical services (start mode auto/boot).
|
||||
- Output capability overlays (e.g., `windows.driver.kernelMode(true)`, `windows.service.autoStart("Spooler")`) for Policy Engine.
|
||||
|
||||
## 4. Component mapping & output
|
||||
- `WindowsComponentMapper`:
|
||||
- Generate `LayerComponentFragment`s with synthetic layer digests (e.g., `sha256:stellaops-windows-msi`).
|
||||
- Build `ComponentIdentity` with PURL-like scheme: `pkg:msi/<productCode>` or `pkg:winsxs/<assemblyIdentity>`.
|
||||
- Include metadata: signature thumbprint, catalog hash, KB references, install context, manufacturer.
|
||||
- Capability overlays stored under `ScanAnalysisKeys.capability.windows` for policy consumption.
|
||||
- Export Center bundling:
|
||||
- Include MSI manifest extracts, WinSxS assembly manifests, Chocolatey nuspec snapshots, and service/driver capability CSV.
|
||||
|
||||
## 5. Policy integration
|
||||
- Predicates to introduce:
|
||||
- `windows.package.signed(expectedThumbprint?)`
|
||||
- `windows.package.unsupportedInstallerType`
|
||||
- `windows.driver.kernelMode`, `windows.driver.unsigned`
|
||||
- `windows.service.autoStart(name)`
|
||||
- `windows.choco.sourceAllowed(feed)`
|
||||
- Lattice approach:
|
||||
- Unsigned kernel drivers → default `fail`.
|
||||
- Unknown installer sources → `warn` with escalation on critical services.
|
||||
- Chocolatey packages from non-whitelisted feeds → configurable severity.
|
||||
- Waiver semantics bind to product code + signature thumbprint; waivers expire when package version changes.
|
||||
|
||||
## 6. Offline kit & distribution
|
||||
- Package:
|
||||
- MSI schema definitions and parser binaries (signed).
|
||||
- Chocolatey feed snapshot (nupkg archives + index) for allow-listed feeds.
|
||||
- Windows catalog certificate chains + optional CRL/OCSP caches.
|
||||
- Documentation:
|
||||
- Provide instructions for exporting registry hives during image extraction (PowerShell script included).
|
||||
- Note disk space expectations (Chocolatey snapshot size, WinSxS manifest volume).
|
||||
|
||||
## 7. Testing strategy
|
||||
- Fixtures:
|
||||
- Sample MSI packages (with/without transforms), WinSxS manifests, Chocolatey packages.
|
||||
- Registry hive exports representing mixed installer types.
|
||||
- Tests:
|
||||
- Unit tests for each collector parsing edge cases (language-specific manifests, transforms, script hashing).
|
||||
- Integration tests using synthetic Windows container image layers (generated via CI on Windows worker).
|
||||
- Determinism checks ensuring repeated runs produce identical fragments.
|
||||
- Security review:
|
||||
- Validate script execution paths (collectors must never execute Chocolatey scripts; inspect only).
|
||||
|
||||
## 8. Dependencies & open questions
|
||||
| Item | Description | Owner | Status |
|
||||
| --- | --- | --- | --- |
|
||||
| MSI parser choice | Select MIT/Apache-compatible parser or build internal reader | Scanner Guild | TBD |
|
||||
| Registry export tooling | Determine standard script/utility for hive exports in container context | Ops Guild | TBD |
|
||||
| Authenticodes verification locus | Decide scanner vs policy responsibility for signature verification | Security Guild | TBD |
|
||||
| Feed mirroring policy | Which Chocolatey feeds to mirror by default | Product + Security Guilds | TBD |
|
||||
|
||||
## 9. Proposed backlog entries
|
||||
| ID (proposed) | Title | Summary |
|
||||
| --- | --- | --- |
|
||||
| SCANNER-ENG-0024 | Implement Windows MSI collector | Parse MSI databases, emit component fragments with provenance metadata. |
|
||||
| SCANNER-ENG-0025 | Implement WinSxS manifest collector | Correlate assemblies with MSI components and catalog signatures. |
|
||||
| SCANNER-ENG-0026 | Implement Chocolatey & registry collectors | Harvest nuspec metadata and uninstall/service registry data. |
|
||||
| SCANNER-ENG-0027 | Policy & Offline integration for Windows | Define predicates, CLI toggles, Offline Kit packaging, documentation. |
|
||||
|
||||
## 10. References
|
||||
- `docs/benchmarks/scanner/deep-dives/windows.md`
|
||||
- `docs/benchmarks/scanner/windows-macos-demand.md`
|
||||
- `docs/modules/scanner/design/macos-analyzer.md` (structure/composition parallels)
|
||||
- Surface design docs (`surface-fs.md`, `surface-validation.md`, `surface-secrets.md`) for interfacing expectations.
|
||||
|
||||
Further reading: `../../api/scanner/windows-coverage.md` (summary) and `../../api/scanner/windows-macos-summary.md` (metrics dashboard).
|
||||
|
||||
Policy readiness alignment: see `../policy/windows-package-readiness.md` (POLICY-READINESS-0002).
|
||||
|
||||
Upcoming milestone: FinSecure Corp PCI review requires Authenticode/feed decision by 2025-11-07 before Windows analyzer spike kickoff.
|
||||
30
docs/modules/scanner/operations/field-engagement.md
Normal file
30
docs/modules/scanner/operations/field-engagement.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Field Engagement Playbook — Windows & macOS Coverage
|
||||
|
||||
> Audience: Field SEs, Product Specialists • Status: Draft
|
||||
|
||||
## Purpose
|
||||
Provide quick-reference guidance when prospects or customers ask about Windows/macOS coverage.
|
||||
|
||||
## Key talking points
|
||||
- **Current scope**: Scanner supports deterministic Linux coverage; Windows/macOS analyzers are in design.
|
||||
- **Roadmap**: macOS design (brew/pkgutil/.app) at `../design/macos-analyzer.md`; Windows design (MSI/WinSxS/Chocolatey) at `../design/windows-analyzer.md`.
|
||||
- **Demand tracking**: All signals captured in `../../benchmarks/scanner/windows-macos-demand.md` using the interview template.
|
||||
- **Policy readiness**: Secret leak detection briefing (`../../policy/secret-leak-detection-readiness.md`) and Windows package readiness (`../../policy/windows-package-readiness.md`).
|
||||
- **Backlog IDs**: MacOS (SCANNER-ENG-0020..0023), Windows (SCANNER-ENG-0024..0027), policy follow-ups (POLICY-READINESS-0001/0002).
|
||||
|
||||
## SE workflow
|
||||
1. Use the interview template to capture customer needs.
|
||||
2. Append structured summary to `windows-macos-demand.md` and update the API dashboards (`docs/api/scanner/windows-macos-summary.md`, `docs/api/scanner/windows-coverage.md`).
|
||||
3. Notify Product/Scanner guild during weekly sync; flag blockers in Jira.
|
||||
4. Add highlight to the “Recent updates” section in `docs/api/scanner/windows-macos-summary.md`.
|
||||
5. Track upcoming milestones (FinSecure decision 2025-11-07, Northwind demo 2025-11-10) and ensure readiness tasks reflect outcomes.
|
||||
|
||||
## FAQ snippets
|
||||
- *When will Windows/macOS analyzers be GA?* — Pending demand threshold; design complete, awaiting prioritisation.
|
||||
- *Can we run scans offline?* — Offline parity is a requirement; Offline Kit packaging detailed in design briefs.
|
||||
- *Do we cover Authenticode/notarization?* — Planned via Policy Engine predicates as part of readiness tasks.
|
||||
|
||||
## Contacts
|
||||
- Product lead: TBD (record in demand log when assigned)
|
||||
- Scanner guild rep: TBD
|
||||
- Policy guild rep: TBD
|
||||
@@ -1,426 +1,426 @@
|
||||
# component_architecture_scheduler.md — **Stella Ops Scheduler** (2025Q4)
|
||||
|
||||
> Synthesises the scheduling requirements documented across the Policy, Vulnerability Explorer, and Orchestrator module guides and implementation plans.
|
||||
|
||||
> **Scope.** Implementation‑ready architecture for **Scheduler**: a service that (1) **re‑evaluates** already‑cataloged images when intel changes (Feedser/Vexer/policy), (2) orchestrates **nightly** and **ad‑hoc** runs, (3) targets only the **impacted** images using the BOM‑Index, and (4) emits **report‑ready** events that downstream **Notify** fans out. Default mode is **analysis‑only** (no image pull); optional **content‑refresh** can be enabled per schedule.
|
||||
|
||||
---
|
||||
|
||||
## 0) Mission & boundaries
|
||||
|
||||
**Mission.** Keep scan results **current** without rescanning the world. When new advisories or VEX claims land, **pinpoint** affected images and ask the backend to recompute **verdicts** against the **existing SBOMs**. Surface only **meaningful deltas** to humans and ticket queues.
|
||||
|
||||
**Boundaries.**
|
||||
|
||||
* Scheduler **does not** compute SBOMs and **does not** sign. It calls Scanner/WebService’s **/reports (analysis‑only)** endpoint and lets the backend (Policy + Vexer + Feedser) decide PASS/FAIL.
|
||||
* Scheduler **may** ask Scanner to **content‑refresh** selected targets (e.g., mutable tags) but the default is **no** image pull.
|
||||
* Notifications are **not** sent directly; Scheduler emits events consumed by **Notify**.
|
||||
|
||||
---
|
||||
|
||||
## 1) Runtime shape & projects
|
||||
|
||||
```
|
||||
src/
|
||||
├─ StellaOps.Scheduler.WebService/ # REST (schedules CRUD, runs, admin)
|
||||
├─ StellaOps.Scheduler.Worker/ # planners + runners (N replicas)
|
||||
├─ StellaOps.Scheduler.ImpactIndex/ # purl→images inverted index (roaring bitmaps)
|
||||
├─ StellaOps.Scheduler.Models/ # DTOs (Schedule, Run, ImpactSet, Deltas)
|
||||
├─ StellaOps.Scheduler.Storage.Mongo/ # schedules, runs, cursors, locks
|
||||
├─ StellaOps.Scheduler.Queue/ # Redis Streams / NATS abstraction
|
||||
├─ StellaOps.Scheduler.Tests.* # unit/integration/e2e
|
||||
```
|
||||
|
||||
**Deployables**:
|
||||
|
||||
* **Scheduler.WebService** (stateless)
|
||||
* **Scheduler.Worker** (scale‑out; planners + executors)
|
||||
|
||||
**Dependencies**: Authority (OpTok + DPoP/mTLS), Scanner.WebService, Feedser, Vexer, MongoDB, Redis/NATS, (optional) Notify.
|
||||
|
||||
---
|
||||
|
||||
## 2) Core responsibilities
|
||||
|
||||
1. **Time‑based** runs: cron windows per tenant/timezone (e.g., “02:00 Europe/Sofia”).
|
||||
2. **Event‑driven** runs: react to **Feedser export** and **Vexer export** deltas (changed product keys / advisories / claims).
|
||||
3. **Impact targeting**: map changes to **image sets** using a **global inverted index** built from Scanner’s per‑image **BOM‑Index** sidecars.
|
||||
4. **Run planning**: shard, pace, and rate‑limit jobs to avoid thundering herds.
|
||||
5. **Execution**: call Scanner **/reports (analysis‑only)** or **/scans (content‑refresh)**; aggregate **delta** results.
|
||||
6. **Events**: publish `rescan.delta` and `report.ready` summaries for **Notify** & **UI**.
|
||||
7. **Control plane**: CRUD schedules, **pause/resume**, dry‑run previews, audit.
|
||||
|
||||
---
|
||||
|
||||
## 3) Data model (Mongo)
|
||||
|
||||
**Database**: `scheduler`
|
||||
|
||||
* `schedules`
|
||||
|
||||
```
|
||||
{ _id, tenantId, name, enabled, whenCron, timezone,
|
||||
mode: "analysis-only" | "content-refresh",
|
||||
selection: { scope: "all-images" | "by-namespace" | "by-repo" | "by-digest" | "by-labels",
|
||||
includeTags?: ["prod-*"], digests?: [sha256...], resolvesTags?: bool },
|
||||
onlyIf: { lastReportOlderThanDays?: int, policyRevision?: string },
|
||||
notify: { onNewFindings: bool, minSeverity: "low|medium|high|critical", includeKEV: bool },
|
||||
limits: { maxJobs?: int, ratePerSecond?: int, parallelism?: int },
|
||||
createdAt, updatedAt, createdBy, updatedBy }
|
||||
```
|
||||
|
||||
* `runs`
|
||||
|
||||
```
|
||||
{ _id, scheduleId?, tenantId, trigger: "cron|feedser|vexer|manual",
|
||||
reason?: { feedserExportId?, vexerExportId?, cursor? },
|
||||
state: "planning|queued|running|completed|error|cancelled",
|
||||
stats: { candidates: int, deduped: int, queued: int, completed: int, deltas: int, newCriticals: int },
|
||||
startedAt, finishedAt, error? }
|
||||
```
|
||||
|
||||
* `impact_cursors`
|
||||
|
||||
```
|
||||
{ _id: tenantId, feedserLastExportId, vexerLastExportId, updatedAt }
|
||||
```
|
||||
|
||||
* `locks` (singleton schedulers, run leases)
|
||||
|
||||
* `audit` (CRUD actions, run outcomes)
|
||||
|
||||
**Indexes**:
|
||||
|
||||
* `schedules` on `{tenantId, enabled}`, `{whenCron}`.
|
||||
* `runs` on `{tenantId, startedAt desc}`, `{state}`.
|
||||
* TTL optional for completed runs (e.g., 180 days).
|
||||
|
||||
---
|
||||
|
||||
## 4) ImpactIndex (global inverted index)
|
||||
|
||||
Goal: translate **change keys** → **image sets** in **milliseconds**.
|
||||
|
||||
**Source**: Scanner produces per‑image **BOM‑Index** sidecars (purls, and `usedByEntrypoint` bitmaps). Scheduler ingests/refreshes them to build a **global** index.
|
||||
|
||||
**Representation**:
|
||||
|
||||
* Assign **image IDs** (dense ints) to catalog images.
|
||||
* Keep **Roaring Bitmaps**:
|
||||
|
||||
* `Contains[purl] → bitmap(imageIds)`
|
||||
* `UsedBy[purl] → bitmap(imageIds)` (subset of Contains)
|
||||
* Optionally keep **Owner maps**: `{imageId → {tenantId, namespaces[], repos[]}}` for selection filters.
|
||||
* Persist in RocksDB/LMDB or Redis‑modules; cache hot shards in memory; snapshot to Mongo for cold start.
|
||||
|
||||
**Update paths**:
|
||||
|
||||
* On new/updated image SBOM: **merge** per‑image set into global maps.
|
||||
* On image remove/expiry: **clear** id from bitmaps.
|
||||
|
||||
**API (internal)**:
|
||||
|
||||
```csharp
|
||||
IImpactIndex {
|
||||
ImpactSet ResolveByPurls(IEnumerable<string> purls, bool usageOnly, Selector sel);
|
||||
ImpactSet ResolveByVulns(IEnumerable<string> vulnIds, bool usageOnly, Selector sel); // optional (vuln->purl precomputed by Feedser)
|
||||
ImpactSet ResolveAll(Selector sel); // for nightly
|
||||
}
|
||||
```
|
||||
|
||||
**Selector filters**: tenant, namespaces, repos, labels, digest allowlists, `includeTags` patterns.
|
||||
|
||||
---
|
||||
|
||||
## 5) External interfaces (REST)
|
||||
|
||||
Base path: `/api/v1/scheduler` (Authority OpToks; scopes: `scheduler.read`, `scheduler.admin`).
|
||||
|
||||
### 5.1 Schedules CRUD
|
||||
|
||||
* `POST /schedules` → create
|
||||
* `GET /schedules` → list (filter by tenant)
|
||||
* `GET /schedules/{id}` → details + next run
|
||||
* `PATCH /schedules/{id}` → pause/resume/update
|
||||
* `DELETE /schedules/{id}` → delete (soft delete, optional)
|
||||
|
||||
### 5.2 Run control & introspection
|
||||
|
||||
* `POST /run` — ad‑hoc run
|
||||
|
||||
```json
|
||||
{ "mode": "analysis-only|content-refresh", "selection": {...}, "reason": "manual" }
|
||||
```
|
||||
* `GET /runs` — list with paging
|
||||
* `GET /runs/{id}` — status, stats, links to deltas
|
||||
* `POST /runs/{id}/cancel` — best‑effort cancel
|
||||
|
||||
### 5.3 Previews (dry‑run)
|
||||
|
||||
* `POST /preview/impact` — returns **candidate count** and a small sample of impacted digests for given change keys or selection.
|
||||
|
||||
### 5.4 Event webhooks (optional push from Feedser/Vexer)
|
||||
|
||||
* `POST /events/feedser-export`
|
||||
|
||||
```json
|
||||
{ "exportId":"...", "changedProductKeys":["pkg:rpm/openssl", ...], "kev": ["CVE-..."], "window": { "from":"...","to":"..." } }
|
||||
```
|
||||
* `POST /events/vexer-export`
|
||||
|
||||
```json
|
||||
{ "exportId":"...", "changedClaims":[ { "productKey":"pkg:deb/...", "vulnId":"CVE-...", "status":"not_affected→affected"} ], ... }
|
||||
```
|
||||
|
||||
**Security**: webhook requires **mTLS** or an **HMAC** `X-Scheduler-Signature` (Ed25519 / SHA‑256) plus Authority token.
|
||||
|
||||
---
|
||||
|
||||
## 6) Planner → Runner pipeline
|
||||
|
||||
### 6.1 Planning algorithm (event‑driven)
|
||||
|
||||
```
|
||||
On Export Event (Feedser/Vexer):
|
||||
keys = Normalize(change payload) # productKeys or vulnIds→productKeys
|
||||
usageOnly = schedule/policy hint? # default true
|
||||
sel = Selector for tenant/scope from schedules subscribed to events
|
||||
|
||||
impacted = ImpactIndex.ResolveByPurls(keys, usageOnly, sel)
|
||||
impacted = ApplyOwnerFilters(impacted, sel) # namespaces/repos/labels
|
||||
impacted = DeduplicateByDigest(impacted)
|
||||
impacted = EnforceLimits(impacted, limits.maxJobs)
|
||||
shards = Shard(impacted, byHashPrefix, n=limits.parallelism)
|
||||
|
||||
For each shard:
|
||||
Enqueue RunSegment (runId, shard, rate=limits.ratePerSecond)
|
||||
```
|
||||
|
||||
**Fairness & pacing**
|
||||
|
||||
* Use **leaky bucket** per tenant and per registry host.
|
||||
* Prioritize **KEV‑tagged** and **critical** first if oversubscribed.
|
||||
|
||||
### 6.2 Nightly planning
|
||||
|
||||
```
|
||||
At cron tick:
|
||||
sel = resolve selection
|
||||
candidates = ImpactIndex.ResolveAll(sel)
|
||||
if lastReportOlderThanDays present → filter by report age (via Scanner catalog)
|
||||
shard & enqueue as above
|
||||
```
|
||||
|
||||
### 6.3 Execution (Runner)
|
||||
|
||||
* Pop **RunSegment** job → for each image digest:
|
||||
|
||||
* **analysis‑only**: `POST scanner/reports { imageDigest, policyRevision? }`
|
||||
* **content‑refresh**: resolve tag→digest if needed; `POST scanner/scans { imageRef, attest? false }` then `POST /reports`
|
||||
* Collect **delta**: `newFindings`, `newCriticals`/`highs`, `links` (UI deep link, Rekor if present).
|
||||
* Persist per‑image outcome in `runs.{id}.stats` (incremental counters).
|
||||
* Emit `scheduler.rescan.delta` events to **Notify** only when **delta > 0** and matches severity rule.
|
||||
|
||||
---
|
||||
|
||||
## 7) Event model (outbound)
|
||||
|
||||
**Topic**: `rescan.delta` (internal bus → Notify; UI subscribes via backend).
|
||||
|
||||
```json
|
||||
{
|
||||
"tenant": "tenant-01",
|
||||
"runId": "324af…",
|
||||
"imageDigest": "sha256:…",
|
||||
"newCriticals": 1,
|
||||
"newHigh": 2,
|
||||
"kevHits": ["CVE-2025-..."],
|
||||
"topFindings": [
|
||||
{ "purl":"pkg:rpm/openssl@3.0.12-...","vulnId":"CVE-2025-...","severity":"critical","link":"https://ui/scans/..." }
|
||||
],
|
||||
"reportUrl": "https://ui/.../scans/sha256:.../report",
|
||||
"attestation": { "uuid":"rekor-uuid", "verified": true },
|
||||
"ts": "2025-10-18T03:12:45Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Also**: `report.ready` for “no‑change” summaries (digest + zero delta), which Notify can ignore by rule.
|
||||
|
||||
---
|
||||
|
||||
## 8) Security posture
|
||||
|
||||
* **AuthN/Z**: Authority OpToks with `aud=scheduler`; DPoP (preferred) or mTLS.
|
||||
* **Multi‑tenant**: every schedule, run, and event carries `tenantId`; ImpactIndex filters by tenant‑visible images.
|
||||
* **Webhook** callers (Feedser/Vexer) present **mTLS** or **HMAC** and Authority token.
|
||||
* **Input hardening**: size caps on changed key lists; reject >100k keys per event; compress (zstd/gzip) allowed with limits.
|
||||
* **No secrets** in logs; redact tokens and signatures.
|
||||
|
||||
---
|
||||
|
||||
## 9) Observability & SLOs
|
||||
|
||||
**Metrics (Prometheus)**
|
||||
|
||||
* `scheduler.events_total{source, result}`
|
||||
* `scheduler.impact_resolve_seconds{quantile}`
|
||||
* `scheduler.images_selected_total{mode}`
|
||||
* `scheduler.jobs_enqueued_total{mode}`
|
||||
* `scheduler.run_latency_seconds{quantile}` // event → first verdict
|
||||
* `scheduler.delta_images_total{severity}`
|
||||
* `scheduler.rate_limited_total{reason}`
|
||||
|
||||
**Targets**
|
||||
|
||||
* Resolve 10k changed keys → impacted set in **<300 ms** (hot cache).
|
||||
* Event → first rescan verdict in **≤60 s** (p95).
|
||||
* Nightly coverage 50k images in **≤10 min** with 10 workers (analysis‑only).
|
||||
|
||||
**Tracing** (OTEL): spans `plan`, `resolve`, `enqueue`, `report_call`, `persist`, `emit`.
|
||||
|
||||
---
|
||||
|
||||
## 10) Configuration (YAML)
|
||||
|
||||
```yaml
|
||||
scheduler:
|
||||
authority:
|
||||
issuer: "https://authority.internal"
|
||||
require: "dpop" # or "mtls"
|
||||
queue:
|
||||
kind: "redis" # or "nats"
|
||||
url: "redis://redis:6379/4"
|
||||
mongo:
|
||||
uri: "mongodb://mongo/scheduler"
|
||||
impactIndex:
|
||||
storage: "rocksdb" # "rocksdb" | "redis" | "memory"
|
||||
warmOnStart: true
|
||||
usageOnlyDefault: true
|
||||
limits:
|
||||
defaultRatePerSecond: 50
|
||||
defaultParallelism: 8
|
||||
maxJobsPerRun: 50000
|
||||
integrates:
|
||||
scannerUrl: "https://scanner-web.internal"
|
||||
feedserWebhook: true
|
||||
vexerWebhook: true
|
||||
notifications:
|
||||
emitBus: "internal" # deliver to Notify via internal bus
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11) UI touch‑points
|
||||
|
||||
* **Schedules** page: CRUD, enable/pause, next run, last run stats, mode (analysis/content), selector preview.
|
||||
* **Runs** page: timeline; heat‑map of deltas; drill‑down to affected images.
|
||||
* **Dry‑run preview** modal: “This Feedser export touches ~3,214 images; projected deltas: ~420 (34 KEV).”
|
||||
|
||||
---
|
||||
|
||||
## 12) Failure modes & degradations
|
||||
|
||||
| Condition | Behavior |
|
||||
| ------------------------------------ | ---------------------------------------------------------------------------------------- |
|
||||
| ImpactIndex cold / incomplete | Fall back to **All** selection for nightly; for events, cap to KEV+critical until warmed |
|
||||
| Feedser/Vexer webhook storm | Coalesce by exportId; debounce 30–60 s; keep last |
|
||||
| Scanner under load (429) | Backoff with jitter; respect per‑tenant/leaky bucket |
|
||||
| Oversubscription (too many impacted) | Prioritize KEV/critical first; spillover to next window; UI banner shows backlog |
|
||||
| Notify down | Buffer outbound events in queue (TTL 24h) |
|
||||
| Mongo slow | Cut batch sizes; sample‑log; alert ops; don’t drop runs unless critical |
|
||||
|
||||
---
|
||||
|
||||
## 13) Testing matrix
|
||||
|
||||
* **ImpactIndex**: correctness (purl→image sets), performance, persistence after restart, memory pressure with 1M purls.
|
||||
* **Planner**: dedupe, shard, fairness, limit enforcement, KEV prioritization.
|
||||
* **Runner**: parallel report calls, error backoff, partial failures, idempotency.
|
||||
* **End‑to‑end**: Feedser export → deltas visible in UI in ≤60 s.
|
||||
* **Security**: webhook auth (mTLS/HMAC), DPoP nonce dance, tenant isolation.
|
||||
* **Chaos**: drop scanner availability; simulate registry throttles (content‑refresh mode).
|
||||
* **Nightly**: cron tick correctness across timezones and DST.
|
||||
|
||||
---
|
||||
|
||||
## 14) Implementation notes
|
||||
|
||||
* **Language**: .NET 10 minimal API; Channels‑based pipeline; `System.Threading.RateLimiting`.
|
||||
* **Bitmaps**: Roaring via `RoaringBitmap` bindings; memory‑map large shards if RocksDB used.
|
||||
* **Cron**: Quartz‑style parser with timezone support; clock skew tolerated ±60 s.
|
||||
* **Dry‑run**: use ImpactIndex only; never call scanner.
|
||||
* **Idempotency**: run segments carry deterministic keys; retries safe.
|
||||
* **Backpressure**: per‑tenant buckets; per‑host registry budgets respected when content‑refresh enabled.
|
||||
|
||||
---
|
||||
|
||||
## 15) Sequences (representative)
|
||||
|
||||
**A) Event‑driven rescan (Feedser delta)**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant FE as Feedser
|
||||
participant SCH as Scheduler.Worker
|
||||
participant IDX as ImpactIndex
|
||||
participant SC as Scanner.WebService
|
||||
participant NO as Notify
|
||||
|
||||
FE->>SCH: POST /events/feedser-export {exportId, changedProductKeys}
|
||||
SCH->>IDX: ResolveByPurls(keys, usageOnly=true, sel)
|
||||
IDX-->>SCH: bitmap(imageIds) → digests list
|
||||
SCH->>SC: POST /reports {imageDigest} (batch/sequenced)
|
||||
SC-->>SCH: report deltas (new criticals/highs)
|
||||
alt delta>0
|
||||
SCH->>NO: rescan.delta {digest, newCriticals, links}
|
||||
end
|
||||
```
|
||||
|
||||
**B) Nightly rescan**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant CRON as Cron
|
||||
participant SCH as Scheduler.Worker
|
||||
participant IDX as ImpactIndex
|
||||
participant SC as Scanner.WebService
|
||||
|
||||
CRON->>SCH: tick (02:00 Europe/Sofia)
|
||||
SCH->>IDX: ResolveAll(selector)
|
||||
IDX-->>SCH: candidates
|
||||
SCH->>SC: POST /reports {digest} (paced)
|
||||
SC-->>SCH: results
|
||||
SCH-->>SCH: aggregate, store run stats
|
||||
```
|
||||
|
||||
**C) Content‑refresh (tag followers)**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant SCH as Scheduler
|
||||
participant SC as Scanner
|
||||
SCH->>SC: resolve tag→digest (if changed)
|
||||
alt digest changed
|
||||
SCH->>SC: POST /scans {imageRef} # new SBOM
|
||||
SC-->>SCH: scan complete (artifacts)
|
||||
SCH->>SC: POST /reports {imageDigest}
|
||||
else unchanged
|
||||
SCH->>SC: POST /reports {imageDigest} # analysis-only
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 16) Roadmap
|
||||
|
||||
* **Vuln‑centric impact**: pre‑join vuln→purl→images to rank by **KEV** and **exploited‑in‑the‑wild** signals.
|
||||
* **Policy diff preview**: when a staged policy changes, show projected breakage set before promotion.
|
||||
* **Cross‑cluster federation**: one Scheduler instance driving many Scanner clusters (tenant isolation).
|
||||
* **Windows containers**: integrate Zastava runtime hints for Usage view tightening.
|
||||
|
||||
---
|
||||
|
||||
**End — component_architecture_scheduler.md**
|
||||
|
||||
> **Scope.** Implementation‑ready architecture for **Scheduler**: a service that (1) **re‑evaluates** already‑cataloged images when intel changes (Conselier/Excitor/policy), (2) orchestrates **nightly** and **ad‑hoc** runs, (3) targets only the **impacted** images using the BOM‑Index, and (4) emits **report‑ready** events that downstream **Notify** fans out. Default mode is **analysis‑only** (no image pull); optional **content‑refresh** can be enabled per schedule.
|
||||
|
||||
---
|
||||
|
||||
## 0) Mission & boundaries
|
||||
|
||||
**Mission.** Keep scan results **current** without rescanning the world. When new advisories or VEX claims land, **pinpoint** affected images and ask the backend to recompute **verdicts** against the **existing SBOMs**. Surface only **meaningful deltas** to humans and ticket queues.
|
||||
|
||||
**Boundaries.**
|
||||
|
||||
* Scheduler **does not** compute SBOMs and **does not** sign. It calls Scanner/WebService’s **/reports (analysis‑only)** endpoint and lets the backend (Policy + Excitor + Conselier) decide PASS/FAIL.
|
||||
* Scheduler **may** ask Scanner to **content‑refresh** selected targets (e.g., mutable tags) but the default is **no** image pull.
|
||||
* Notifications are **not** sent directly; Scheduler emits events consumed by **Notify**.
|
||||
|
||||
---
|
||||
|
||||
## 1) Runtime shape & projects
|
||||
|
||||
```
|
||||
src/
|
||||
├─ StellaOps.Scheduler.WebService/ # REST (schedules CRUD, runs, admin)
|
||||
├─ StellaOps.Scheduler.Worker/ # planners + runners (N replicas)
|
||||
├─ StellaOps.Scheduler.ImpactIndex/ # purl→images inverted index (roaring bitmaps)
|
||||
├─ StellaOps.Scheduler.Models/ # DTOs (Schedule, Run, ImpactSet, Deltas)
|
||||
├─ StellaOps.Scheduler.Storage.Mongo/ # schedules, runs, cursors, locks
|
||||
├─ StellaOps.Scheduler.Queue/ # Redis Streams / NATS abstraction
|
||||
├─ StellaOps.Scheduler.Tests.* # unit/integration/e2e
|
||||
```
|
||||
|
||||
**Deployables**:
|
||||
|
||||
* **Scheduler.WebService** (stateless)
|
||||
* **Scheduler.Worker** (scale‑out; planners + executors)
|
||||
|
||||
**Dependencies**: Authority (OpTok + DPoP/mTLS), Scanner.WebService, Conselier, Excitor, MongoDB, Redis/NATS, (optional) Notify.
|
||||
|
||||
---
|
||||
|
||||
## 2) Core responsibilities
|
||||
|
||||
1. **Time‑based** runs: cron windows per tenant/timezone (e.g., “02:00 Europe/Sofia”).
|
||||
2. **Event‑driven** runs: react to **Conselier export** and **Excitor export** deltas (changed product keys / advisories / claims).
|
||||
3. **Impact targeting**: map changes to **image sets** using a **global inverted index** built from Scanner’s per‑image **BOM‑Index** sidecars.
|
||||
4. **Run planning**: shard, pace, and rate‑limit jobs to avoid thundering herds.
|
||||
5. **Execution**: call Scanner **/reports (analysis‑only)** or **/scans (content‑refresh)**; aggregate **delta** results.
|
||||
6. **Events**: publish `rescan.delta` and `report.ready` summaries for **Notify** & **UI**.
|
||||
7. **Control plane**: CRUD schedules, **pause/resume**, dry‑run previews, audit.
|
||||
|
||||
---
|
||||
|
||||
## 3) Data model (Mongo)
|
||||
|
||||
**Database**: `scheduler`
|
||||
|
||||
* `schedules`
|
||||
|
||||
```
|
||||
{ _id, tenantId, name, enabled, whenCron, timezone,
|
||||
mode: "analysis-only" | "content-refresh",
|
||||
selection: { scope: "all-images" | "by-namespace" | "by-repo" | "by-digest" | "by-labels",
|
||||
includeTags?: ["prod-*"], digests?: [sha256...], resolvesTags?: bool },
|
||||
onlyIf: { lastReportOlderThanDays?: int, policyRevision?: string },
|
||||
notify: { onNewFindings: bool, minSeverity: "low|medium|high|critical", includeKEV: bool },
|
||||
limits: { maxJobs?: int, ratePerSecond?: int, parallelism?: int },
|
||||
createdAt, updatedAt, createdBy, updatedBy }
|
||||
```
|
||||
|
||||
* `runs`
|
||||
|
||||
```
|
||||
{ _id, scheduleId?, tenantId, trigger: "cron|conselier|excitor|manual",
|
||||
reason?: { conselierExportId?, excitorExportId?, cursor? },
|
||||
state: "planning|queued|running|completed|error|cancelled",
|
||||
stats: { candidates: int, deduped: int, queued: int, completed: int, deltas: int, newCriticals: int },
|
||||
startedAt, finishedAt, error? }
|
||||
```
|
||||
|
||||
* `impact_cursors`
|
||||
|
||||
```
|
||||
{ _id: tenantId, conselierLastExportId, excitorLastExportId, updatedAt }
|
||||
```
|
||||
|
||||
* `locks` (singleton schedulers, run leases)
|
||||
|
||||
* `audit` (CRUD actions, run outcomes)
|
||||
|
||||
**Indexes**:
|
||||
|
||||
* `schedules` on `{tenantId, enabled}`, `{whenCron}`.
|
||||
* `runs` on `{tenantId, startedAt desc}`, `{state}`.
|
||||
* TTL optional for completed runs (e.g., 180 days).
|
||||
|
||||
---
|
||||
|
||||
## 4) ImpactIndex (global inverted index)
|
||||
|
||||
Goal: translate **change keys** → **image sets** in **milliseconds**.
|
||||
|
||||
**Source**: Scanner produces per‑image **BOM‑Index** sidecars (purls, and `usedByEntrypoint` bitmaps). Scheduler ingests/refreshes them to build a **global** index.
|
||||
|
||||
**Representation**:
|
||||
|
||||
* Assign **image IDs** (dense ints) to catalog images.
|
||||
* Keep **Roaring Bitmaps**:
|
||||
|
||||
* `Contains[purl] → bitmap(imageIds)`
|
||||
* `UsedBy[purl] → bitmap(imageIds)` (subset of Contains)
|
||||
* Optionally keep **Owner maps**: `{imageId → {tenantId, namespaces[], repos[]}}` for selection filters.
|
||||
* Persist in RocksDB/LMDB or Redis‑modules; cache hot shards in memory; snapshot to Mongo for cold start.
|
||||
|
||||
**Update paths**:
|
||||
|
||||
* On new/updated image SBOM: **merge** per‑image set into global maps.
|
||||
* On image remove/expiry: **clear** id from bitmaps.
|
||||
|
||||
**API (internal)**:
|
||||
|
||||
```csharp
|
||||
IImpactIndex {
|
||||
ImpactSet ResolveByPurls(IEnumerable<string> purls, bool usageOnly, Selector sel);
|
||||
ImpactSet ResolveByVulns(IEnumerable<string> vulnIds, bool usageOnly, Selector sel); // optional (vuln->purl precomputed by Conselier)
|
||||
ImpactSet ResolveAll(Selector sel); // for nightly
|
||||
}
|
||||
```
|
||||
|
||||
**Selector filters**: tenant, namespaces, repos, labels, digest allowlists, `includeTags` patterns.
|
||||
|
||||
---
|
||||
|
||||
## 5) External interfaces (REST)
|
||||
|
||||
Base path: `/api/v1/scheduler` (Authority OpToks; scopes: `scheduler.read`, `scheduler.admin`).
|
||||
|
||||
### 5.1 Schedules CRUD
|
||||
|
||||
* `POST /schedules` → create
|
||||
* `GET /schedules` → list (filter by tenant)
|
||||
* `GET /schedules/{id}` → details + next run
|
||||
* `PATCH /schedules/{id}` → pause/resume/update
|
||||
* `DELETE /schedules/{id}` → delete (soft delete, optional)
|
||||
|
||||
### 5.2 Run control & introspection
|
||||
|
||||
* `POST /run` — ad‑hoc run
|
||||
|
||||
```json
|
||||
{ "mode": "analysis-only|content-refresh", "selection": {...}, "reason": "manual" }
|
||||
```
|
||||
* `GET /runs` — list with paging
|
||||
* `GET /runs/{id}` — status, stats, links to deltas
|
||||
* `POST /runs/{id}/cancel` — best‑effort cancel
|
||||
|
||||
### 5.3 Previews (dry‑run)
|
||||
|
||||
* `POST /preview/impact` — returns **candidate count** and a small sample of impacted digests for given change keys or selection.
|
||||
|
||||
### 5.4 Event webhooks (optional push from Conselier/Excitor)
|
||||
|
||||
* `POST /events/conselier-export`
|
||||
|
||||
```json
|
||||
{ "exportId":"...", "changedProductKeys":["pkg:rpm/openssl", ...], "kev": ["CVE-..."], "window": { "from":"...","to":"..." } }
|
||||
```
|
||||
* `POST /events/excitor-export`
|
||||
|
||||
```json
|
||||
{ "exportId":"...", "changedClaims":[ { "productKey":"pkg:deb/...", "vulnId":"CVE-...", "status":"not_affected→affected"} ], ... }
|
||||
```
|
||||
|
||||
**Security**: webhook requires **mTLS** or an **HMAC** `X-Scheduler-Signature` (Ed25519 / SHA‑256) plus Authority token.
|
||||
|
||||
---
|
||||
|
||||
## 6) Planner → Runner pipeline
|
||||
|
||||
### 6.1 Planning algorithm (event‑driven)
|
||||
|
||||
```
|
||||
On Export Event (Conselier/Excitor):
|
||||
keys = Normalize(change payload) # productKeys or vulnIds→productKeys
|
||||
usageOnly = schedule/policy hint? # default true
|
||||
sel = Selector for tenant/scope from schedules subscribed to events
|
||||
|
||||
impacted = ImpactIndex.ResolveByPurls(keys, usageOnly, sel)
|
||||
impacted = ApplyOwnerFilters(impacted, sel) # namespaces/repos/labels
|
||||
impacted = DeduplicateByDigest(impacted)
|
||||
impacted = EnforceLimits(impacted, limits.maxJobs)
|
||||
shards = Shard(impacted, byHashPrefix, n=limits.parallelism)
|
||||
|
||||
For each shard:
|
||||
Enqueue RunSegment (runId, shard, rate=limits.ratePerSecond)
|
||||
```
|
||||
|
||||
**Fairness & pacing**
|
||||
|
||||
* Use **leaky bucket** per tenant and per registry host.
|
||||
* Prioritize **KEV‑tagged** and **critical** first if oversubscribed.
|
||||
|
||||
### 6.2 Nightly planning
|
||||
|
||||
```
|
||||
At cron tick:
|
||||
sel = resolve selection
|
||||
candidates = ImpactIndex.ResolveAll(sel)
|
||||
if lastReportOlderThanDays present → filter by report age (via Scanner catalog)
|
||||
shard & enqueue as above
|
||||
```
|
||||
|
||||
### 6.3 Execution (Runner)
|
||||
|
||||
* Pop **RunSegment** job → for each image digest:
|
||||
|
||||
* **analysis‑only**: `POST scanner/reports { imageDigest, policyRevision? }`
|
||||
* **content‑refresh**: resolve tag→digest if needed; `POST scanner/scans { imageRef, attest? false }` then `POST /reports`
|
||||
* Collect **delta**: `newFindings`, `newCriticals`/`highs`, `links` (UI deep link, Rekor if present).
|
||||
* Persist per‑image outcome in `runs.{id}.stats` (incremental counters).
|
||||
* Emit `scheduler.rescan.delta` events to **Notify** only when **delta > 0** and matches severity rule.
|
||||
|
||||
---
|
||||
|
||||
## 7) Event model (outbound)
|
||||
|
||||
**Topic**: `rescan.delta` (internal bus → Notify; UI subscribes via backend).
|
||||
|
||||
```json
|
||||
{
|
||||
"tenant": "tenant-01",
|
||||
"runId": "324af…",
|
||||
"imageDigest": "sha256:…",
|
||||
"newCriticals": 1,
|
||||
"newHigh": 2,
|
||||
"kevHits": ["CVE-2025-..."],
|
||||
"topFindings": [
|
||||
{ "purl":"pkg:rpm/openssl@3.0.12-...","vulnId":"CVE-2025-...","severity":"critical","link":"https://ui/scans/..." }
|
||||
],
|
||||
"reportUrl": "https://ui/.../scans/sha256:.../report",
|
||||
"attestation": { "uuid":"rekor-uuid", "verified": true },
|
||||
"ts": "2025-10-18T03:12:45Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Also**: `report.ready` for “no‑change” summaries (digest + zero delta), which Notify can ignore by rule.
|
||||
|
||||
---
|
||||
|
||||
## 8) Security posture
|
||||
|
||||
* **AuthN/Z**: Authority OpToks with `aud=scheduler`; DPoP (preferred) or mTLS.
|
||||
* **Multi‑tenant**: every schedule, run, and event carries `tenantId`; ImpactIndex filters by tenant‑visible images.
|
||||
* **Webhook** callers (Conselier/Excitor) present **mTLS** or **HMAC** and Authority token.
|
||||
* **Input hardening**: size caps on changed key lists; reject >100k keys per event; compress (zstd/gzip) allowed with limits.
|
||||
* **No secrets** in logs; redact tokens and signatures.
|
||||
|
||||
---
|
||||
|
||||
## 9) Observability & SLOs
|
||||
|
||||
**Metrics (Prometheus)**
|
||||
|
||||
* `scheduler.events_total{source, result}`
|
||||
* `scheduler.impact_resolve_seconds{quantile}`
|
||||
* `scheduler.images_selected_total{mode}`
|
||||
* `scheduler.jobs_enqueued_total{mode}`
|
||||
* `scheduler.run_latency_seconds{quantile}` // event → first verdict
|
||||
* `scheduler.delta_images_total{severity}`
|
||||
* `scheduler.rate_limited_total{reason}`
|
||||
|
||||
**Targets**
|
||||
|
||||
* Resolve 10k changed keys → impacted set in **<300 ms** (hot cache).
|
||||
* Event → first rescan verdict in **≤60 s** (p95).
|
||||
* Nightly coverage 50k images in **≤10 min** with 10 workers (analysis‑only).
|
||||
|
||||
**Tracing** (OTEL): spans `plan`, `resolve`, `enqueue`, `report_call`, `persist`, `emit`.
|
||||
|
||||
---
|
||||
|
||||
## 10) Configuration (YAML)
|
||||
|
||||
```yaml
|
||||
scheduler:
|
||||
authority:
|
||||
issuer: "https://authority.internal"
|
||||
require: "dpop" # or "mtls"
|
||||
queue:
|
||||
kind: "redis" # or "nats"
|
||||
url: "redis://redis:6379/4"
|
||||
mongo:
|
||||
uri: "mongodb://mongo/scheduler"
|
||||
impactIndex:
|
||||
storage: "rocksdb" # "rocksdb" | "redis" | "memory"
|
||||
warmOnStart: true
|
||||
usageOnlyDefault: true
|
||||
limits:
|
||||
defaultRatePerSecond: 50
|
||||
defaultParallelism: 8
|
||||
maxJobsPerRun: 50000
|
||||
integrates:
|
||||
scannerUrl: "https://scanner-web.internal"
|
||||
conselierWebhook: true
|
||||
excitorWebhook: true
|
||||
notifications:
|
||||
emitBus: "internal" # deliver to Notify via internal bus
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11) UI touch‑points
|
||||
|
||||
* **Schedules** page: CRUD, enable/pause, next run, last run stats, mode (analysis/content), selector preview.
|
||||
* **Runs** page: timeline; heat‑map of deltas; drill‑down to affected images.
|
||||
* **Dry‑run preview** modal: “This Conselier export touches ~3,214 images; projected deltas: ~420 (34 KEV).”
|
||||
|
||||
---
|
||||
|
||||
## 12) Failure modes & degradations
|
||||
|
||||
| Condition | Behavior |
|
||||
| ------------------------------------ | ---------------------------------------------------------------------------------------- |
|
||||
| ImpactIndex cold / incomplete | Fall back to **All** selection for nightly; for events, cap to KEV+critical until warmed |
|
||||
| Conselier/Excitor webhook storm | Coalesce by exportId; debounce 30–60 s; keep last |
|
||||
| Scanner under load (429) | Backoff with jitter; respect per‑tenant/leaky bucket |
|
||||
| Oversubscription (too many impacted) | Prioritize KEV/critical first; spillover to next window; UI banner shows backlog |
|
||||
| Notify down | Buffer outbound events in queue (TTL 24h) |
|
||||
| Mongo slow | Cut batch sizes; sample‑log; alert ops; don’t drop runs unless critical |
|
||||
|
||||
---
|
||||
|
||||
## 13) Testing matrix
|
||||
|
||||
* **ImpactIndex**: correctness (purl→image sets), performance, persistence after restart, memory pressure with 1M purls.
|
||||
* **Planner**: dedupe, shard, fairness, limit enforcement, KEV prioritization.
|
||||
* **Runner**: parallel report calls, error backoff, partial failures, idempotency.
|
||||
* **End‑to‑end**: Conselier export → deltas visible in UI in ≤60 s.
|
||||
* **Security**: webhook auth (mTLS/HMAC), DPoP nonce dance, tenant isolation.
|
||||
* **Chaos**: drop scanner availability; simulate registry throttles (content‑refresh mode).
|
||||
* **Nightly**: cron tick correctness across timezones and DST.
|
||||
|
||||
---
|
||||
|
||||
## 14) Implementation notes
|
||||
|
||||
* **Language**: .NET 10 minimal API; Channels‑based pipeline; `System.Threading.RateLimiting`.
|
||||
* **Bitmaps**: Roaring via `RoaringBitmap` bindings; memory‑map large shards if RocksDB used.
|
||||
* **Cron**: Quartz‑style parser with timezone support; clock skew tolerated ±60 s.
|
||||
* **Dry‑run**: use ImpactIndex only; never call scanner.
|
||||
* **Idempotency**: run segments carry deterministic keys; retries safe.
|
||||
* **Backpressure**: per‑tenant buckets; per‑host registry budgets respected when content‑refresh enabled.
|
||||
|
||||
---
|
||||
|
||||
## 15) Sequences (representative)
|
||||
|
||||
**A) Event‑driven rescan (Conselier delta)**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant FE as Conselier
|
||||
participant SCH as Scheduler.Worker
|
||||
participant IDX as ImpactIndex
|
||||
participant SC as Scanner.WebService
|
||||
participant NO as Notify
|
||||
|
||||
FE->>SCH: POST /events/conselier-export {exportId, changedProductKeys}
|
||||
SCH->>IDX: ResolveByPurls(keys, usageOnly=true, sel)
|
||||
IDX-->>SCH: bitmap(imageIds) → digests list
|
||||
SCH->>SC: POST /reports {imageDigest} (batch/sequenced)
|
||||
SC-->>SCH: report deltas (new criticals/highs)
|
||||
alt delta>0
|
||||
SCH->>NO: rescan.delta {digest, newCriticals, links}
|
||||
end
|
||||
```
|
||||
|
||||
**B) Nightly rescan**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant CRON as Cron
|
||||
participant SCH as Scheduler.Worker
|
||||
participant IDX as ImpactIndex
|
||||
participant SC as Scanner.WebService
|
||||
|
||||
CRON->>SCH: tick (02:00 Europe/Sofia)
|
||||
SCH->>IDX: ResolveAll(selector)
|
||||
IDX-->>SCH: candidates
|
||||
SCH->>SC: POST /reports {digest} (paced)
|
||||
SC-->>SCH: results
|
||||
SCH-->>SCH: aggregate, store run stats
|
||||
```
|
||||
|
||||
**C) Content‑refresh (tag followers)**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant SCH as Scheduler
|
||||
participant SC as Scanner
|
||||
SCH->>SC: resolve tag→digest (if changed)
|
||||
alt digest changed
|
||||
SCH->>SC: POST /scans {imageRef} # new SBOM
|
||||
SC-->>SCH: scan complete (artifacts)
|
||||
SCH->>SC: POST /reports {imageDigest}
|
||||
else unchanged
|
||||
SCH->>SC: POST /reports {imageDigest} # analysis-only
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 16) Roadmap
|
||||
|
||||
* **Vuln‑centric impact**: pre‑join vuln→purl→images to rank by **KEV** and **exploited‑in‑the‑wild** signals.
|
||||
* **Policy diff preview**: when a staged policy changes, show projected breakage set before promotion.
|
||||
* **Cross‑cluster federation**: one Scheduler instance driving many Scanner clusters (tenant isolation).
|
||||
* **Windows containers**: integrate Zastava runtime hints for Usage view tightening.
|
||||
|
||||
---
|
||||
|
||||
**End — component_architecture_scheduler.md**
|
||||
|
||||
@@ -1,82 +1,82 @@
|
||||
# Scheduler Worker – Observability & Runbook
|
||||
|
||||
## Purpose
|
||||
Monitor planner and runner health for the Scheduler Worker (Sprint 16 telemetry). The new .NET meters surface queue throughput, latency, backlog, and delta severities so operators can detect stalled runs before rescan SLAs slip.
|
||||
|
||||
> **Grafana note:** Import `docs/modules/scheduler/operations/worker-grafana-dashboard.json` into the Prometheus-backed Grafana stack that scrapes the OpenTelemetry Collector.
|
||||
|
||||
---
|
||||
|
||||
## Key metrics
|
||||
|
||||
| Metric | Use case | Suggested query |
|
||||
| --- | --- | --- |
|
||||
| `scheduler_planner_runs_total{status}` | Planner throughput & failure ratio | `sum by (status) (rate(scheduler_planner_runs_total[5m]))` |
|
||||
| `scheduler_planner_latency_seconds_bucket` | Planning latency (p95 / p99) | `histogram_quantile(0.95, sum by (le) (rate(scheduler_planner_latency_seconds_bucket[5m])))` |
|
||||
| `scheduler_runner_segments_total{status}` | Runner success vs retries | `sum by (status) (rate(scheduler_runner_segments_total[5m]))` |
|
||||
| `scheduler_runner_delta_{critical,high,total}` | Newly-detected findings | `sum(rate(scheduler_runner_delta_critical_total[5m]))` |
|
||||
| `scheduler_runner_backlog{scheduleId}` | Remaining digests awaiting runner | `max by (scheduleId) (scheduler_runner_backlog)` |
|
||||
| `scheduler_runs_active{mode}` | Active runs in-flight | `sum(scheduler_runs_active)` |
|
||||
|
||||
Reference queries power the bundled Grafana dashboard panels. Use the `mode` template variable to focus on `analysisOnly` versus `contentRefresh` schedules.
|
||||
|
||||
---
|
||||
|
||||
## Grafana dashboard
|
||||
|
||||
1. Import `docs/modules/scheduler/operations/worker-grafana-dashboard.json` (UID `scheduler-worker-observability`).
|
||||
2. Point the `datasource` variable to the Prometheus instance scraping the collector. Optional: pin the `mode` variable to a specific schedule mode.
|
||||
3. Panels included:
|
||||
- **Planner Runs per Status** – visualises success vs failure ratio.
|
||||
- **Planner Latency P95** – highlights degradations in ImpactIndex or Mongo lookups.
|
||||
- **Runner Segments per Status** – shows retry pressure and queue health.
|
||||
- **New Findings per Severity** – rolls up delta counters (critical/high/total).
|
||||
- **Runner Backlog by Schedule** – tabulates outstanding digests per schedule.
|
||||
- **Active Runs** – stat panel showing the current number of in-flight runs.
|
||||
|
||||
Capture screenshots once Grafana provisioning completes and store them under `docs/assets/dashboards/` (pending automation ticket OBS-157).
|
||||
|
||||
---
|
||||
|
||||
## Prometheus alerts
|
||||
|
||||
Import `docs/modules/scheduler/operations/worker-prometheus-rules.yaml` into your Prometheus rule configuration. The bundle defines:
|
||||
|
||||
- **SchedulerPlannerFailuresHigh** – 5%+ of planner runs failed for 10 minutes. Page SRE.
|
||||
- **SchedulerPlannerLatencyHigh** – planner p95 latency remains above 45 s for 10 minutes. Investigate ImpactIndex, Mongo, and Feedser/Vexer event queues.
|
||||
- **SchedulerRunnerBacklogGrowing** – backlog exceeded 500 images for 15 minutes. Inspect runner workers, Scanner availability, and rate limiting.
|
||||
- **SchedulerRunStuck** – active run count stayed flat for 30 minutes while remaining non-zero. Check stuck segments, expired leases, and scanner retries.
|
||||
|
||||
Hook these alerts into the existing Observability notification pathway (`observability-pager` routing key) and ensure `service=scheduler-worker` is mapped to the on-call rotation.
|
||||
|
||||
---
|
||||
|
||||
## Runbook snapshot
|
||||
|
||||
1. **Planner failure/latency:**
|
||||
- Check Planner logs for ImpactIndex or Mongo exceptions.
|
||||
- Verify Feedser/Vexer webhook health; requeue events if necessary.
|
||||
- If planner is overwhelmed, temporarily reduce schedule parallelism via `stella scheduler schedule update`.
|
||||
2. **Runner backlog spike:**
|
||||
- Confirm Scanner WebService health (`/healthz`).
|
||||
- Inspect runner queue for stuck segments; consider increasing runner workers or scaling scanner capacity.
|
||||
- Review rate limits (schedule limits, ImpactIndex throughput) before changing global throttles.
|
||||
3. **Stuck runs:**
|
||||
- Use `stella scheduler runs list --state running` to identify affected runs.
|
||||
- Drill into Grafana panel “Runner Backlog by Schedule” to see offending schedule IDs.
|
||||
- If a segment will not progress, use `stella scheduler segments release --segment <id>` to force retry after resolving root cause.
|
||||
4. **Unexpected critical deltas:**
|
||||
- Correlate `scheduler_runner_delta_critical_total` spikes with Notify events (`scheduler.rescan.delta`).
|
||||
- Pivot to Scanner report links for impacted digests and confirm they match upstream advisories/policies.
|
||||
|
||||
Document incidents and mitigation in `ops/runbooks/INCIDENT_LOG.md` (per SRE policy) and attach Grafana screenshots for post-mortems.
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Grafana dashboard imported and wired to Prometheus datasource.
|
||||
- [ ] Prometheus alert rules deployed (see above).
|
||||
- [ ] Runbook linked from on-call rotation portal.
|
||||
- [ ] Observability Guild sign-off captured for Sprint 16 telemetry (OWNER: @obs-guild).
|
||||
|
||||
# Scheduler Worker – Observability & Runbook
|
||||
|
||||
## Purpose
|
||||
Monitor planner and runner health for the Scheduler Worker (Sprint 16 telemetry). The new .NET meters surface queue throughput, latency, backlog, and delta severities so operators can detect stalled runs before rescan SLAs slip.
|
||||
|
||||
> **Grafana note:** Import `docs/modules/scheduler/operations/worker-grafana-dashboard.json` into the Prometheus-backed Grafana stack that scrapes the OpenTelemetry Collector.
|
||||
|
||||
---
|
||||
|
||||
## Key metrics
|
||||
|
||||
| Metric | Use case | Suggested query |
|
||||
| --- | --- | --- |
|
||||
| `scheduler_planner_runs_total{status}` | Planner throughput & failure ratio | `sum by (status) (rate(scheduler_planner_runs_total[5m]))` |
|
||||
| `scheduler_planner_latency_seconds_bucket` | Planning latency (p95 / p99) | `histogram_quantile(0.95, sum by (le) (rate(scheduler_planner_latency_seconds_bucket[5m])))` |
|
||||
| `scheduler_runner_segments_total{status}` | Runner success vs retries | `sum by (status) (rate(scheduler_runner_segments_total[5m]))` |
|
||||
| `scheduler_runner_delta_{critical,high,total}` | Newly-detected findings | `sum(rate(scheduler_runner_delta_critical_total[5m]))` |
|
||||
| `scheduler_runner_backlog{scheduleId}` | Remaining digests awaiting runner | `max by (scheduleId) (scheduler_runner_backlog)` |
|
||||
| `scheduler_runs_active{mode}` | Active runs in-flight | `sum(scheduler_runs_active)` |
|
||||
|
||||
Reference queries power the bundled Grafana dashboard panels. Use the `mode` template variable to focus on `analysisOnly` versus `contentRefresh` schedules.
|
||||
|
||||
---
|
||||
|
||||
## Grafana dashboard
|
||||
|
||||
1. Import `docs/modules/scheduler/operations/worker-grafana-dashboard.json` (UID `scheduler-worker-observability`).
|
||||
2. Point the `datasource` variable to the Prometheus instance scraping the collector. Optional: pin the `mode` variable to a specific schedule mode.
|
||||
3. Panels included:
|
||||
- **Planner Runs per Status** – visualises success vs failure ratio.
|
||||
- **Planner Latency P95** – highlights degradations in ImpactIndex or Mongo lookups.
|
||||
- **Runner Segments per Status** – shows retry pressure and queue health.
|
||||
- **New Findings per Severity** – rolls up delta counters (critical/high/total).
|
||||
- **Runner Backlog by Schedule** – tabulates outstanding digests per schedule.
|
||||
- **Active Runs** – stat panel showing the current number of in-flight runs.
|
||||
|
||||
Capture screenshots once Grafana provisioning completes and store them under `docs/assets/dashboards/` (pending automation ticket OBS-157).
|
||||
|
||||
---
|
||||
|
||||
## Prometheus alerts
|
||||
|
||||
Import `docs/modules/scheduler/operations/worker-prometheus-rules.yaml` into your Prometheus rule configuration. The bundle defines:
|
||||
|
||||
- **SchedulerPlannerFailuresHigh** – 5%+ of planner runs failed for 10 minutes. Page SRE.
|
||||
- **SchedulerPlannerLatencyHigh** – planner p95 latency remains above 45 s for 10 minutes. Investigate ImpactIndex, Mongo, and Conselier/Excitor event queues.
|
||||
- **SchedulerRunnerBacklogGrowing** – backlog exceeded 500 images for 15 minutes. Inspect runner workers, Scanner availability, and rate limiting.
|
||||
- **SchedulerRunStuck** – active run count stayed flat for 30 minutes while remaining non-zero. Check stuck segments, expired leases, and scanner retries.
|
||||
|
||||
Hook these alerts into the existing Observability notification pathway (`observability-pager` routing key) and ensure `service=scheduler-worker` is mapped to the on-call rotation.
|
||||
|
||||
---
|
||||
|
||||
## Runbook snapshot
|
||||
|
||||
1. **Planner failure/latency:**
|
||||
- Check Planner logs for ImpactIndex or Mongo exceptions.
|
||||
- Verify Conselier/Excitor webhook health; requeue events if necessary.
|
||||
- If planner is overwhelmed, temporarily reduce schedule parallelism via `stella scheduler schedule update`.
|
||||
2. **Runner backlog spike:**
|
||||
- Confirm Scanner WebService health (`/healthz`).
|
||||
- Inspect runner queue for stuck segments; consider increasing runner workers or scaling scanner capacity.
|
||||
- Review rate limits (schedule limits, ImpactIndex throughput) before changing global throttles.
|
||||
3. **Stuck runs:**
|
||||
- Use `stella scheduler runs list --state running` to identify affected runs.
|
||||
- Drill into Grafana panel “Runner Backlog by Schedule” to see offending schedule IDs.
|
||||
- If a segment will not progress, use `stella scheduler segments release --segment <id>` to force retry after resolving root cause.
|
||||
4. **Unexpected critical deltas:**
|
||||
- Correlate `scheduler_runner_delta_critical_total` spikes with Notify events (`scheduler.rescan.delta`).
|
||||
- Pivot to Scanner report links for impacted digests and confirm they match upstream advisories/policies.
|
||||
|
||||
Document incidents and mitigation in `ops/runbooks/INCIDENT_LOG.md` (per SRE policy) and attach Grafana screenshots for post-mortems.
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Grafana dashboard imported and wired to Prometheus datasource.
|
||||
- [ ] Prometheus alert rules deployed (see above).
|
||||
- [ ] Runbook linked from on-call rotation portal.
|
||||
- [ ] Observability Guild sign-off captured for Sprint 16 telemetry (OWNER: @obs-guild).
|
||||
|
||||
|
||||
@@ -1,63 +1,63 @@
|
||||
# Implementation plan — VEX Consensus Lens
|
||||
|
||||
## Delivery phases
|
||||
- **Phase 1 – Core lens service**
|
||||
Build normalisation pipeline (CSAF/OpenVEX/CycloneDX), product mapping library, trust weighting functions, consensus algorithm, and persistence (`vex_consensus`, history, conflicts).
|
||||
- **Phase 2 – API & integrations**
|
||||
Expose `/vex/consensus` query/detail/simulate/export endpoints, integrate Policy Engine thresholds, Vuln Explorer UI chips, and VEX Lens change events.
|
||||
- **Phase 3 – Issuer Directory & signatures**
|
||||
Deliver issuer registry, key management, signature verification, RBAC, audit logs, and tenant overrides.
|
||||
- **Phase 4 – Console & CLI experiences**
|
||||
Ship Console module (lists, evidence table, quorum bar, conflicts, simulation drawer) and CLI commands (`stella vex consensus ...`) with export support.
|
||||
- **Phase 5 – Recompute & performance**
|
||||
Implement recompute scheduling (policy activation, Excitator deltas), caching, load tests (10M records/tenant), observability dashboards, and Offline Kit exports.
|
||||
|
||||
## Work breakdown
|
||||
- **VEX Lens service**
|
||||
- Normalise VEX payloads, maintain scope scores, compute consensus digest.
|
||||
- Trust weighting functions (issuer tier, freshness decay, scope quality).
|
||||
- Idempotent workers for consensus projection and history tracking.
|
||||
- Conflict handling queue for manual review and notifications.
|
||||
- **Integrations**
|
||||
- Excitator: enrich VEX events with issuer hints, signatures, product trees.
|
||||
- Policy Engine: trust knobs, simulation endpoints, policy-driven recompute.
|
||||
- Vuln Explorer & Advisory AI: consensus badges, conflict surfacing.
|
||||
- **Issuer Directory**
|
||||
- CRUD for issuers/keys, audit logs, import CSAF publishers, tenant overrides.
|
||||
- Signature verification endpoints consumed by Lens.
|
||||
- **APIs & UX**
|
||||
- REST endpoints for query/detail/conflict export, trust weight updates.
|
||||
- Console module with filters, saved views, evidence table, simulation drawer.
|
||||
- CLI commands for list/show/simulate/export with JSON/CSV output.
|
||||
- **Observability & Ops**
|
||||
- Metrics (consensus latency, conflict rate, signature failures, cache hit rate), logs, traces.
|
||||
- Dashboards + runbooks for recompute storms, mapping failures, signature errors, quota breaches.
|
||||
- Offline exports for Export Center/Offline Kit.
|
||||
|
||||
## Acceptance criteria
|
||||
- Consensus results reproducible across supported VEX formats with deterministic digests and provenance.
|
||||
- Signature verification influences trust weights; unverifiable evidence is down-weighted without pipeline failure.
|
||||
- Policy simulations show quorum shifts without persisting state; Vuln Explorer consumes consensus signals.
|
||||
- Issuer Directory enforces RBAC, audit logs, and key rotation; CLI & Console parity achieved.
|
||||
- Recompute pipeline handles Excitator deltas and policy activations with backpressure and incident surfacing.
|
||||
- Observability dashboards/alerts cover ingestion lag, conflict spikes, signature failures, performance budgets (P95 < 500 ms for 100-row pages at 10M records/tenant).
|
||||
|
||||
## Risks & mitigations
|
||||
- **Product mapping ambiguity:** conservative scope scoring, manual overrides, surfaced warnings, policy review hooks.
|
||||
- **Issuer compromise:** signature verification, trust weighting, tenant overrides, revocation runbooks.
|
||||
- **Evidence storms:** batching, worker sharding, orchestrator rate limiting, priority queues.
|
||||
- **Performance degradation:** caching, indexing, load tests, quota enforcement.
|
||||
- **Offline gaps:** deterministic exports, manifest hashes, Offline Kit tests.
|
||||
|
||||
## Test strategy
|
||||
- **Unit:** normalisers, mapping, trust weights, consensus lattice, signature verification.
|
||||
- **Property:** randomised evidence sets verifying lattice commutativity and determinism.
|
||||
- **Integration:** Excitator → Lens → Policy/Vuln Explorer flow, issuer overrides, simulation.
|
||||
- **Performance:** large tenant datasets, cache behaviour, concurrency tests.
|
||||
- **Security:** RBAC, tenant scoping, signature tampering, issuer revocation.
|
||||
- **Offline:** export/import verification, CLI parity.
|
||||
|
||||
## Definition of done
|
||||
- Lens service, issuer directory, API/CLI/Console components deployed with telemetry and runbooks.
|
||||
- Documentation set (overview, algorithm, issuer directory, API, console, policy trust) updated with imposed rule statements.
|
||||
- ./TASKS.md and ../../TASKS.md reflect current status; Offline Kit parity confirmed.
|
||||
# Implementation plan — VEX Consensus Lens
|
||||
|
||||
## Delivery phases
|
||||
- **Phase 1 – Core lens service**
|
||||
Build normalisation pipeline (CSAF/OpenVEX/CycloneDX), product mapping library, trust weighting functions, consensus algorithm, and persistence (`vex_consensus`, history, conflicts).
|
||||
- **Phase 2 – API & integrations**
|
||||
Expose `/vex/consensus` query/detail/simulate/export endpoints, integrate Policy Engine thresholds, Vuln Explorer UI chips, and VEX Lens change events.
|
||||
- **Phase 3 – Issuer Directory & signatures**
|
||||
Deliver issuer registry, key management, signature verification, RBAC, audit logs, and tenant overrides.
|
||||
- **Phase 4 – Console & CLI experiences**
|
||||
Ship Console module (lists, evidence table, quorum bar, conflicts, simulation drawer) and CLI commands (`stella vex consensus ...`) with export support.
|
||||
- **Phase 5 – Recompute & performance**
|
||||
Implement recompute scheduling (policy activation, Excitor deltas), caching, load tests (10M records/tenant), observability dashboards, and Offline Kit exports.
|
||||
|
||||
## Work breakdown
|
||||
- **VEX Lens service**
|
||||
- Normalise VEX payloads, maintain scope scores, compute consensus digest.
|
||||
- Trust weighting functions (issuer tier, freshness decay, scope quality).
|
||||
- Idempotent workers for consensus projection and history tracking.
|
||||
- Conflict handling queue for manual review and notifications.
|
||||
- **Integrations**
|
||||
- Excitor: enrich VEX events with issuer hints, signatures, product trees.
|
||||
- Policy Engine: trust knobs, simulation endpoints, policy-driven recompute.
|
||||
- Vuln Explorer & Advisory AI: consensus badges, conflict surfacing.
|
||||
- **Issuer Directory**
|
||||
- CRUD for issuers/keys, audit logs, import CSAF publishers, tenant overrides.
|
||||
- Signature verification endpoints consumed by Lens.
|
||||
- **APIs & UX**
|
||||
- REST endpoints for query/detail/conflict export, trust weight updates.
|
||||
- Console module with filters, saved views, evidence table, simulation drawer.
|
||||
- CLI commands for list/show/simulate/export with JSON/CSV output.
|
||||
- **Observability & Ops**
|
||||
- Metrics (consensus latency, conflict rate, signature failures, cache hit rate), logs, traces.
|
||||
- Dashboards + runbooks for recompute storms, mapping failures, signature errors, quota breaches.
|
||||
- Offline exports for Export Center/Offline Kit.
|
||||
|
||||
## Acceptance criteria
|
||||
- Consensus results reproducible across supported VEX formats with deterministic digests and provenance.
|
||||
- Signature verification influences trust weights; unverifiable evidence is down-weighted without pipeline failure.
|
||||
- Policy simulations show quorum shifts without persisting state; Vuln Explorer consumes consensus signals.
|
||||
- Issuer Directory enforces RBAC, audit logs, and key rotation; CLI & Console parity achieved.
|
||||
- Recompute pipeline handles Excitor deltas and policy activations with backpressure and incident surfacing.
|
||||
- Observability dashboards/alerts cover ingestion lag, conflict spikes, signature failures, performance budgets (P95 < 500 ms for 100-row pages at 10M records/tenant).
|
||||
|
||||
## Risks & mitigations
|
||||
- **Product mapping ambiguity:** conservative scope scoring, manual overrides, surfaced warnings, policy review hooks.
|
||||
- **Issuer compromise:** signature verification, trust weighting, tenant overrides, revocation runbooks.
|
||||
- **Evidence storms:** batching, worker sharding, orchestrator rate limiting, priority queues.
|
||||
- **Performance degradation:** caching, indexing, load tests, quota enforcement.
|
||||
- **Offline gaps:** deterministic exports, manifest hashes, Offline Kit tests.
|
||||
|
||||
## Test strategy
|
||||
- **Unit:** normalisers, mapping, trust weights, consensus lattice, signature verification.
|
||||
- **Property:** randomised evidence sets verifying lattice commutativity and determinism.
|
||||
- **Integration:** Excitor → Lens → Policy/Vuln Explorer flow, issuer overrides, simulation.
|
||||
- **Performance:** large tenant datasets, cache behaviour, concurrency tests.
|
||||
- **Security:** RBAC, tenant scoping, signature tampering, issuer revocation.
|
||||
- **Offline:** export/import verification, CLI parity.
|
||||
|
||||
## Definition of done
|
||||
- Lens service, issuer directory, API/CLI/Console components deployed with telemetry and runbooks.
|
||||
- Documentation set (overview, algorithm, issuer directory, API, console, policy trust) updated with imposed rule statements.
|
||||
- ./TASKS.md and ../../TASKS.md reflect current status; Offline Kit parity confirmed.
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# Task board — Vexer
|
||||
|
||||
> Local tasks should link back to ./AGENTS.md and mirror status updates into ../../TASKS.md when applicable.
|
||||
|
||||
| ID | Status | Owner(s) | Description | Notes |
|
||||
|----|--------|----------|-------------|-------|
|
||||
| VEXER-DOCS-0001 | DOING (2025-10-29) | Docs Guild | Validate that ./README.md aligns with the latest release notes. | See ./AGENTS.md |
|
||||
| VEXER-OPS-0001 | TODO | Ops Guild | Review runbooks/observability assets after next sprint demo. | Sync outcomes back to ../../TASKS.md |
|
||||
| VEXER-ENG-0001 | TODO | Module Team | Cross-check implementation plan milestones against ../../implplan/SPRINTS.md. | Update status via ./AGENTS.md workflow |
|
||||
@@ -47,18 +47,25 @@ CLI mirrors these endpoints (`stella findings list|view|update|export`). Console
|
||||
- Scheduler integration triggers follow-up scans or policy re-evaluation when remediation plan reaches checkpoint.
|
||||
- Zastava (Differential SBOM) feeds runtime exposure signals to reprioritise findings automatically.
|
||||
|
||||
## 5) Observability & compliance
|
||||
|
||||
- Metrics: `findings_open_total{severity,tenant}`, `findings_mttr_seconds`, `triage_actions_total{type}`, `report_generation_seconds`.
|
||||
- Logs: structured with `findingId`, `artifactId`, `advisory`, `policyVersion`, `actor`, `actionType`.
|
||||
- Audit exports: `audit_log.jsonl` appended whenever state changes; offline bundles include signed audit log and manifest.
|
||||
- Compliance: accepted risk requires dual approval and stores justification plus expiry reminders (raised through Notify).
|
||||
|
||||
## 6) Offline bundle requirements
|
||||
|
||||
- Bundle structure:
|
||||
- `manifest.json` (hashes, counts, policy version, generation timestamp).
|
||||
- `findings.jsonl` (current open findings).
|
||||
## 5) Observability & compliance
|
||||
|
||||
- Metrics: `findings_open_total{severity,tenant}`, `findings_mttr_seconds`, `triage_actions_total{type}`, `report_generation_seconds`.
|
||||
- Logs: structured with `findingId`, `artifactId`, `advisory`, `policyVersion`, `actor`, `actionType`.
|
||||
- Audit exports: `audit_log.jsonl` appended whenever state changes; offline bundles include signed audit log and manifest.
|
||||
- Compliance: accepted risk requires dual approval and stores justification plus expiry reminders (raised through Notify).
|
||||
|
||||
## 6) Identity & access integration
|
||||
|
||||
- **Scopes** – `vuln:view`, `vuln:investigate`, `vuln:operate`, `vuln:audit` map to read-only, triage, workflow, and audit experiences respectively. The deprecated `vuln:read` scope is still honoured for legacy tokens but is no longer advertised.
|
||||
- **Attribute filters (ABAC)** – Authority enforces per-service-account filters via the client-credential parameters `vuln_env`, `vuln_owner`, and `vuln_business_tier`. Service accounts define the allowed values in `authority.yaml` (`attributes` block). Tokens include the resolved filters as claims (`stellaops:vuln_env`, `stellaops:vuln_owner`, `stellaops:vuln_business_tier`), and tokens persisted to Mongo retain the same values for audit and revocation.
|
||||
- **Audit trail** – Every token issuance emits `authority.vuln_attr.*` audit properties that mirror the resolved filter set, along with `delegation.service_account` and ordered `delegation.actor[n]` entries so Vuln Explorer can correlate access decisions.
|
||||
- **Permalinks** – Signed permalinks inherit the caller’s ABAC filters; consuming services must enforce the embedded claims in addition to scope checks when resolving permalinks.
|
||||
|
||||
## 7) Offline bundle requirements
|
||||
|
||||
- Bundle structure:
|
||||
- `manifest.json` (hashes, counts, policy version, generation timestamp).
|
||||
- `findings.jsonl` (current open findings).
|
||||
- `history.jsonl` (state changes).
|
||||
- `actions.jsonl` (comments, assignments, tickets).
|
||||
- `reports/` (generated PDFs/CSVs).
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
# Implementation plan — Vulnerability Explorer
|
||||
|
||||
## Delivery phases
|
||||
- **Phase 1 – Findings Ledger & resolver**
|
||||
Create append-only ledger, projector, ecosystem resolvers (npm/Maven/PyPI/Go/RPM/DEB), canonical advisory keys, and provenance hashing.
|
||||
- **Phase 2 – API & simulation**
|
||||
Ship Vuln Explorer API (list/detail/grouping/simulation), batch evaluation with Policy Engine rationales, and export orchestrator.
|
||||
- **Phase 3 – Console & CLI workflows**
|
||||
Deliver triage UI (assignments, comments, remediation plans, simulation bar), keyboard accessibility, and CLI commands (`stella vuln ...`) with JSON/CSV output.
|
||||
- **Phase 4 – Automation & integrations**
|
||||
Integrate Advisory AI hints, Zastava runtime exposure, Notify rules, Scheduler follow-up scans, and Graph Explorer deep links.
|
||||
- **Phase 5 – Exports & offline parity**
|
||||
Generate deterministic bundles (JSON, CSV, PDF, Offline Kit manifests), audit logs, and signed reports.
|
||||
- **Phase 6 – Observability & hardening**
|
||||
Complete dashboards (projection lag, MTTR, accepted-risk cadence), alerts, runbooks, performance tuning (5M findings/tenant), and security/RBAC validation.
|
||||
|
||||
## Work breakdown
|
||||
- **Findings Ledger**
|
||||
- Define event schema, Merkle root anchoring, append-only storage, history tables.
|
||||
- Projector to `finding_records` and `finding_history`, idempotent event processing, time travel snapshots.
|
||||
- Resolver pipelines referencing SBOM inventory deltas, policy outputs, VEX consensus, runtime signals.
|
||||
- **API & exports**
|
||||
- REST endpoints (`/v1/findings`, `/v1/findings/{id}`, `/actions`, `/reports`, `/exports`) with ABAC filters.
|
||||
- Simulation endpoint returning diffs, integration with Policy Engine batch evaluation.
|
||||
- Export jobs for JSON/CSV/PDF plus Offline Kit bundle assembly and signing.
|
||||
- **Console**
|
||||
- Feature module `vuln-explorer` with grid, filters, saved views, deep links, detail tabs (policy, evidence, paths, remediation).
|
||||
- Simulation drawer, delta chips, accepted-risk approvals, evidence bundle viewer.
|
||||
- Accessibility (keyboard navigation, ARIA), virtualization for large result sets.
|
||||
- **CLI**
|
||||
- Commands `stella vuln list|show|simulate|assign|accept-risk|verify-fix|export`.
|
||||
- Stable schemas for automation; piping support; tests for exit codes.
|
||||
- **Integrations**
|
||||
- Conseiller/Excitator: normalized advisory keys, linksets, evidence retrieval.
|
||||
- SBOM Service: inventory deltas with scope/runtime flags, safe version hints.
|
||||
- Notify: events for SLA breaches, accepted-risk expiries, remediation deadlines.
|
||||
- Scheduler: trigger rescans when remediation plan milestones complete.
|
||||
- **Observability & ops**
|
||||
- Metrics (open findings, MTTR, projection lag, export duration, SLA burn), logs/traces with correlation IDs.
|
||||
- Alerting on projector backlog, API 5xx spikes, export failures, accepted-risk nearing expiry.
|
||||
- Runbooks covering recompute storms, mapping errors, report issues.
|
||||
|
||||
## Acceptance criteria
|
||||
- Ledger/event sourcing reproduces historical states byte-for-byte; Merkle hashes verify integrity.
|
||||
- Resolver respects ecosystem semantics, scope, and runtime context; path evidence presented in UI/CLI.
|
||||
- Triage workflows (assignment, comments, accepted-risk) enforce justification and approval requirements with audit records.
|
||||
- Simulation returns policy diffs without mutating state; CLI/UI parity achieved for simulation and exports.
|
||||
- Exports and Offline Kit bundles reproducible with signed manifests and provenance; reports available in JSON/CSV/PDF.
|
||||
- Observability dashboards show green SLOs, alerts fire for projection lag or SLA burns, and runbooks documented.
|
||||
- RBAC/ABAC validated; attachments encrypted; tenant isolation guaranteed.
|
||||
|
||||
## Risks & mitigations
|
||||
- **Advisory identity collisions:** strict canonicalization, linkset references, raw evidence access.
|
||||
- **Resolver inaccuracies:** property-based tests, path verification, manual override workflows.
|
||||
- **Projection lag/backlog:** autoscaling, queue backpressure, alerting, pause controls.
|
||||
- **Export size/performance:** streaming NDJSON, size estimators, chunked downloads.
|
||||
- **User confusion on suppression:** rationale tab, explicit badges, explain traces.
|
||||
|
||||
## Test strategy
|
||||
- **Unit:** resolver algorithms, state machine transitions, policy mapping, export builders.
|
||||
- **Integration:** ingestion → ledger → projector → API flow, simulation, Notify notifications.
|
||||
- **E2E:** Console triage scenarios, CLI flows, accessibility tests.
|
||||
- **Performance:** 5M findings/tenant, projection rebuild, export generation.
|
||||
- **Security:** RBAC/ABAC matrix, CSRF, attachment encryption, signed URL expiry.
|
||||
- **Determinism:** time-travel snapshots, export manifest hashing, Offline Kit replay.
|
||||
|
||||
## Definition of done
|
||||
- Services, UI/CLI, integrations, exports, and observability deployed with runbooks and Offline Kit parity.
|
||||
- Documentation suite (overview, using-console, API, CLI, findings ledger, policy mapping, VEX/SBOM integration, telemetry, security, runbooks, install) updated with imposed rule statement.
|
||||
- ./TASKS.md and ../../TASKS.md reflect active progress; compliance checklists appended where required.
|
||||
# Implementation plan — Vulnerability Explorer
|
||||
|
||||
## Delivery phases
|
||||
- **Phase 1 – Findings Ledger & resolver**
|
||||
Create append-only ledger, projector, ecosystem resolvers (npm/Maven/PyPI/Go/RPM/DEB), canonical advisory keys, and provenance hashing.
|
||||
- **Phase 2 – API & simulation**
|
||||
Ship Vuln Explorer API (list/detail/grouping/simulation), batch evaluation with Policy Engine rationales, and export orchestrator.
|
||||
- **Phase 3 – Console & CLI workflows**
|
||||
Deliver triage UI (assignments, comments, remediation plans, simulation bar), keyboard accessibility, and CLI commands (`stella vuln ...`) with JSON/CSV output.
|
||||
- **Phase 4 – Automation & integrations**
|
||||
Integrate Advisory AI hints, Zastava runtime exposure, Notify rules, Scheduler follow-up scans, and Graph Explorer deep links.
|
||||
- **Phase 5 – Exports & offline parity**
|
||||
Generate deterministic bundles (JSON, CSV, PDF, Offline Kit manifests), audit logs, and signed reports.
|
||||
- **Phase 6 – Observability & hardening**
|
||||
Complete dashboards (projection lag, MTTR, accepted-risk cadence), alerts, runbooks, performance tuning (5M findings/tenant), and security/RBAC validation.
|
||||
|
||||
## Work breakdown
|
||||
- **Findings Ledger**
|
||||
- Define event schema, Merkle root anchoring, append-only storage, history tables.
|
||||
- Projector to `finding_records` and `finding_history`, idempotent event processing, time travel snapshots.
|
||||
- Resolver pipelines referencing SBOM inventory deltas, policy outputs, VEX consensus, runtime signals.
|
||||
- **API & exports**
|
||||
- REST endpoints (`/v1/findings`, `/v1/findings/{id}`, `/actions`, `/reports`, `/exports`) with ABAC filters.
|
||||
- Simulation endpoint returning diffs, integration with Policy Engine batch evaluation.
|
||||
- Export jobs for JSON/CSV/PDF plus Offline Kit bundle assembly and signing.
|
||||
- **Console**
|
||||
- Feature module `vuln-explorer` with grid, filters, saved views, deep links, detail tabs (policy, evidence, paths, remediation).
|
||||
- Simulation drawer, delta chips, accepted-risk approvals, evidence bundle viewer.
|
||||
- Accessibility (keyboard navigation, ARIA), virtualization for large result sets.
|
||||
- **CLI**
|
||||
- Commands `stella vuln list|show|simulate|assign|accept-risk|verify-fix|export`.
|
||||
- Stable schemas for automation; piping support; tests for exit codes.
|
||||
- **Integrations**
|
||||
- Conseiller/Excitor: normalized advisory keys, linksets, evidence retrieval.
|
||||
- SBOM Service: inventory deltas with scope/runtime flags, safe version hints.
|
||||
- Notify: events for SLA breaches, accepted-risk expiries, remediation deadlines.
|
||||
- Scheduler: trigger rescans when remediation plan milestones complete.
|
||||
- **Observability & ops**
|
||||
- Metrics (open findings, MTTR, projection lag, export duration, SLA burn), logs/traces with correlation IDs.
|
||||
- Alerting on projector backlog, API 5xx spikes, export failures, accepted-risk nearing expiry.
|
||||
- Runbooks covering recompute storms, mapping errors, report issues.
|
||||
|
||||
## Acceptance criteria
|
||||
- Ledger/event sourcing reproduces historical states byte-for-byte; Merkle hashes verify integrity.
|
||||
- Resolver respects ecosystem semantics, scope, and runtime context; path evidence presented in UI/CLI.
|
||||
- Triage workflows (assignment, comments, accepted-risk) enforce justification and approval requirements with audit records.
|
||||
- Simulation returns policy diffs without mutating state; CLI/UI parity achieved for simulation and exports.
|
||||
- Exports and Offline Kit bundles reproducible with signed manifests and provenance; reports available in JSON/CSV/PDF.
|
||||
- Observability dashboards show green SLOs, alerts fire for projection lag or SLA burns, and runbooks documented.
|
||||
- RBAC/ABAC validated; attachments encrypted; tenant isolation guaranteed.
|
||||
|
||||
## Risks & mitigations
|
||||
- **Advisory identity collisions:** strict canonicalization, linkset references, raw evidence access.
|
||||
- **Resolver inaccuracies:** property-based tests, path verification, manual override workflows.
|
||||
- **Projection lag/backlog:** autoscaling, queue backpressure, alerting, pause controls.
|
||||
- **Export size/performance:** streaming NDJSON, size estimators, chunked downloads.
|
||||
- **User confusion on suppression:** rationale tab, explicit badges, explain traces.
|
||||
|
||||
## Test strategy
|
||||
- **Unit:** resolver algorithms, state machine transitions, policy mapping, export builders.
|
||||
- **Integration:** ingestion → ledger → projector → API flow, simulation, Notify notifications.
|
||||
- **E2E:** Console triage scenarios, CLI flows, accessibility tests.
|
||||
- **Performance:** 5M findings/tenant, projection rebuild, export generation.
|
||||
- **Security:** RBAC/ABAC matrix, CSRF, attachment encryption, signed URL expiry.
|
||||
- **Determinism:** time-travel snapshots, export manifest hashing, Offline Kit replay.
|
||||
|
||||
## Definition of done
|
||||
- Services, UI/CLI, integrations, exports, and observability deployed with runbooks and Offline Kit parity.
|
||||
- Documentation suite (overview, using-console, API, CLI, findings ledger, policy mapping, VEX/SBOM integration, telemetry, security, runbooks, install) updated with imposed rule statement.
|
||||
- ./TASKS.md and ../../TASKS.md reflect active progress; compliance checklists appended where required.
|
||||
|
||||
@@ -31,11 +31,12 @@ Tenant API│ REST + gRPC WIP │ │ rules/channels│
|
||||
│ Connectors │──────▶│ Slack/Teams/... │
|
||||
│ (plug-ins) │ │ External targets │
|
||||
└─────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
- **WebService** hosts REST endpoints (`/channels`, `/rules`, `/templates`, `/deliveries`, `/digests`, `/stats`) and handles schema normalisation, validation, and Authority enforcement.
|
||||
- **Worker** subscribes to the platform event bus, evaluates rules per tenant, applies throttles/digests, renders payloads, writes ledger entries, and invokes connectors.
|
||||
- **Plug-ins** live under `plugins/notify/` and are loaded deterministically at service start (`orderedPlugins` list). Each implements connector contracts and optional health/test-preview providers.
|
||||
```
|
||||
|
||||
- **2025-11-02 decision — module boundaries.** Keep `src/Notify/` as the shared notification toolkit (engine, storage, queue, connectors) that multiple hosts can consume. `src/Notifier/` remains the Notifications Studio runtime (WebService + Worker) composed from those libraries. Do not collapse the directories until a packaging RFC covers build impacts, offline kit parity, and imposed-rule propagation.
|
||||
- **WebService** hosts REST endpoints (`/channels`, `/rules`, `/templates`, `/deliveries`, `/digests`, `/stats`) and handles schema normalisation, validation, and Authority enforcement.
|
||||
- **Worker** subscribes to the platform event bus, evaluates rules per tenant, applies throttles/digests, renders payloads, writes ledger entries, and invokes connectors.
|
||||
- **Plug-ins** live under `plugins/notify/` and are loaded deterministically at service start (`orderedPlugins` list). Each implements connector contracts and optional health/test-preview providers.
|
||||
|
||||
Both services share options via `notify.yaml` (see `etc/notify.yaml.sample`). For dev/test scenarios, an in-memory repository exists but production requires Mongo + Redis/NATS for durability and coordination.
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ The Notify WebService fronts worker state with REST APIs used by the UI and CLI.
|
||||
| **Scaling** | Workers scale horizontally; per-tenant rule snapshots are cached and refreshed from Mongo change streams. Redis (or equivalent) guards throttles and locks. |
|
||||
| **Offline** | Offline Kits include plug-ins, default templates, and seed rules. Operators can edit YAML/JSON manifests before air-gapped deployment. |
|
||||
| **Security** | Channel secrets use indirection (`secretRef`), Authority-protected OAuth clients secure API access, and delivery payloads are redacted before storage where required. |
|
||||
| **Module boundaries** | 2025-11-02 decision: keep `src/Notify/` as the shared notification toolkit and `src/Notifier/` as the Notifications Studio runtime host until a packaging RFC covers the implications of merging. |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,57 +1,57 @@
|
||||
# Risk Scoring Profiles
|
||||
|
||||
> Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.
|
||||
|
||||
## Overview
|
||||
|
||||
Risk Scoring Profiles define customizable formulas that convert raw evidence (CVSS, EPSS-like exploit likelihood, KEV exploited lists, VEX status, reachability, runtime evidence, fix availability, asset criticality, provenance trust) into normalized risk scores (0–100) with severity buckets. Profiles are authored in Policy Studio, simulated, versioned, and executed by the scoring engine with full explainability.
|
||||
|
||||
- **Primary components:** Policy Engine, Findings Ledger, Conseiller, Excitator, Console, Policy Studio, CLI, Export Center, Authority & Tenancy, Observability.
|
||||
- **Surfaces:** policy documents, scoring engine, factor providers, explainability artefacts, APIs, CLI, UI.
|
||||
|
||||
Aggregation-Only Contract remains in force: Conseiller and Excitator never merge or mutate source records. Risk scoring consumes linked evidence and preserves provenance for explainability.
|
||||
|
||||
## Core workflow
|
||||
|
||||
1. **Profile authoring:** Policy Studio exposes declarative DSL to define factors, weights, thresholds, and severity buckets.
|
||||
2. **Simulation:** operators preview profiles against historical findings/SBOMs, compare with existing policies, and inspect factor breakdowns.
|
||||
3. **Activation:** Policy Engine evaluates profiles on change streams, producing scores and detailed factor contributions per finding and per asset.
|
||||
4. **Explainability:** CLI/Console display math traces, provenance IDs, and rationale for each factor. Export Center packages reports for auditors.
|
||||
5. **Versioning:** profiles carry semantic versions, promotion workflows, and rollback hooks; Authority scopes enforce who can publish or edit.
|
||||
|
||||
## Factor model
|
||||
|
||||
| Factor | Description | Typical signal source |
|
||||
| --- | --- | --- |
|
||||
| Exploit likelihood | EPSS/KEV or internal intel | Conseiller enrichment |
|
||||
| VEX status | not_affected / affected / fixed | Excitator (VEX Lens) |
|
||||
| Reachability | entrypoint closure, runtime observations | Scanner + Zastava |
|
||||
| Fix availability | patch released, vendor guidance | Conseiller, Policy Engine |
|
||||
| Asset criticality | business context, tenant overrides | Policy Studio inputs |
|
||||
| Provenance trust | signed evidence, attestation status | Attestor, Authority |
|
||||
|
||||
Factors feed into a weighted scoring engine with per-factor contribution reporting.
|
||||
|
||||
## Governance & guardrails
|
||||
|
||||
- Profiles live in Policy Studio with draft/review/approval workflows.
|
||||
- Policy Engine enforces deterministic evaluation; simulations and production runs share the same scoring code.
|
||||
- CLI parity enables automated promotion, export/import, and simulation from pipelines.
|
||||
- Observability records scoring latency, factor distribution, and profile usage.
|
||||
- Offline support: profiles, factor plugins, and explain bundles ship inside mirror bundles for air-gapped environments.
|
||||
|
||||
## Deliverables
|
||||
|
||||
- Policy language reference and examples.
|
||||
- Simulation APIs/CLI with diff output.
|
||||
- Scoring engine implementation with explain traces and determinism checks.
|
||||
- Console visualizations (severity heatmaps, contribution waterfalls).
|
||||
- Export Center reports with risk scoring sections.
|
||||
- Observability dashboards for profile health and scoring throughput.
|
||||
|
||||
## References
|
||||
|
||||
- Policy core: `docs/modules/policy/architecture.md`
|
||||
- Findings ledger: `docs/modules/vuln-explorer/architecture.md`
|
||||
- VEX consensus: `docs/modules/vex-lens/architecture.md`
|
||||
- Offline operations: `docs/airgap/airgap-mode.md`
|
||||
# Risk Scoring Profiles
|
||||
|
||||
> Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.
|
||||
|
||||
## Overview
|
||||
|
||||
Risk Scoring Profiles define customizable formulas that convert raw evidence (CVSS, EPSS-like exploit likelihood, KEV exploited lists, VEX status, reachability, runtime evidence, fix availability, asset criticality, provenance trust) into normalized risk scores (0–100) with severity buckets. Profiles are authored in Policy Studio, simulated, versioned, and executed by the scoring engine with full explainability.
|
||||
|
||||
- **Primary components:** Policy Engine, Findings Ledger, Conseiller, Excitor, Console, Policy Studio, CLI, Export Center, Authority & Tenancy, Observability.
|
||||
- **Surfaces:** policy documents, scoring engine, factor providers, explainability artefacts, APIs, CLI, UI.
|
||||
|
||||
Aggregation-Only Contract remains in force: Conseiller and Excitor never merge or mutate source records. Risk scoring consumes linked evidence and preserves provenance for explainability.
|
||||
|
||||
## Core workflow
|
||||
|
||||
1. **Profile authoring:** Policy Studio exposes declarative DSL to define factors, weights, thresholds, and severity buckets.
|
||||
2. **Simulation:** operators preview profiles against historical findings/SBOMs, compare with existing policies, and inspect factor breakdowns.
|
||||
3. **Activation:** Policy Engine evaluates profiles on change streams, producing scores and detailed factor contributions per finding and per asset.
|
||||
4. **Explainability:** CLI/Console display math traces, provenance IDs, and rationale for each factor. Export Center packages reports for auditors.
|
||||
5. **Versioning:** profiles carry semantic versions, promotion workflows, and rollback hooks; Authority scopes enforce who can publish or edit.
|
||||
|
||||
## Factor model
|
||||
|
||||
| Factor | Description | Typical signal source |
|
||||
| --- | --- | --- |
|
||||
| Exploit likelihood | EPSS/KEV or internal intel | Conseiller enrichment |
|
||||
| VEX status | not_affected / affected / fixed | Excitor (VEX Lens) |
|
||||
| Reachability | entrypoint closure, runtime observations | Scanner + Zastava |
|
||||
| Fix availability | patch released, vendor guidance | Conseiller, Policy Engine |
|
||||
| Asset criticality | business context, tenant overrides | Policy Studio inputs |
|
||||
| Provenance trust | signed evidence, attestation status | Attestor, Authority |
|
||||
|
||||
Factors feed into a weighted scoring engine with per-factor contribution reporting.
|
||||
|
||||
## Governance & guardrails
|
||||
|
||||
- Profiles live in Policy Studio with draft/review/approval workflows.
|
||||
- Policy Engine enforces deterministic evaluation; simulations and production runs share the same scoring code.
|
||||
- CLI parity enables automated promotion, export/import, and simulation from pipelines.
|
||||
- Observability records scoring latency, factor distribution, and profile usage.
|
||||
- Offline support: profiles, factor plugins, and explain bundles ship inside mirror bundles for air-gapped environments.
|
||||
|
||||
## Deliverables
|
||||
|
||||
- Policy language reference and examples.
|
||||
- Simulation APIs/CLI with diff output.
|
||||
- Scoring engine implementation with explain traces and determinism checks.
|
||||
- Console visualizations (severity heatmaps, contribution waterfalls).
|
||||
- Export Center reports with risk scoring sections.
|
||||
- Observability dashboards for profile health and scoring throughput.
|
||||
|
||||
## References
|
||||
|
||||
- Policy core: `docs/modules/policy/architecture.md`
|
||||
- Findings ledger: `docs/modules/vuln-explorer/architecture.md`
|
||||
- VEX consensus: `docs/modules/vex-lens/architecture.md`
|
||||
- Offline operations: `docs/airgap/airgap-mode.md`
|
||||
|
||||
@@ -45,9 +45,15 @@ Authority issues short-lived tokens bound to tenants and scopes. Sprint 19 int
|
||||
| `policy:review` | Policy Studio review panes | Review drafts, leave comments, request changes. | Tenant required; pair with `policy:simulate` for diff previews. |
|
||||
| `policy:approve` | Policy Studio approvals | Approve or reject policy drafts. | Tenant required; fresh-auth enforced by Console UI. |
|
||||
| `policy:operate` | Policy Studio promotion controls | Trigger batch simulations, promotions, and canary runs. | Tenant required; combine with `policy:run`/`policy:activate`. |
|
||||
| `policy:publish` | Policy Studio / CLI attestation flows | Publish approved policy versions and generate signing bundles. | Interactive only; tenant required; tokens must include `policy_reason`, `policy_ticket`, and policy digest (fresh-auth enforced). |
|
||||
| `policy:promote` | Policy Studio / CLI attestation flows | Promote policy attestations between environments (e.g., staging → prod). | Interactive only; tenant required; requires `policy_reason`, `policy_ticket`, digest, and fresh-auth within 5 minutes. |
|
||||
| `policy:audit` | Policy audit exports | Access immutable policy history, comments, and signatures. | Tenant required; read-only access. |
|
||||
| `policy:simulate` | Policy Studio / CLI simulations | Run simulations against tenant inventories. | Tenant required; available to authors, reviewers, operators. |
|
||||
| `vuln:read` | Vuln Explorer API/UI | Read normalized vulnerability data. | Tenant required. |
|
||||
| `vuln:view` | Vuln Explorer API/UI | Read normalized vulnerability data, issue permalinks. | Tenant required; ABAC attributes (`env`, `owner`, `business_tier`) further constrain access. |
|
||||
| `vuln:investigate` | Vuln Explorer triage workflows | Assign findings, add comments, attach remediation notes. | Tenant + ABAC attributes required; typically paired with `vuln:view`. |
|
||||
| `vuln:operate` | Vuln Explorer state transitions | Change remediation state, accept risk, trigger remediation plans. | Tenant + ABAC attributes required; interactive flows should enforce fresh-auth on prod tenants. |
|
||||
| `vuln:audit` | Vuln Explorer audit/report exports | Access immutable ledgers, reports, and offline bundles. | Tenant required; ABAC attributes restrict which assets may be exported. |
|
||||
> **Legacy:** `vuln:read` remains available for backwards compatibility and is still emitted on Vuln Explorer permalinks. New clients should request the granular scopes above.
|
||||
| `export.viewer` | Export Center APIs | List export profiles/runs, fetch manifests and bundles. | Tenant required; read-only access. |
|
||||
| `export.operator` | Export Center APIs | Trigger export runs, manage schedules, request verifications. | Tenant required; pair with `export.admin` for retention/encryption changes. |
|
||||
| `export.admin` | Export Center administrative APIs | Configure retention policies, encryption keys, and scheduling defaults. | Tenant required; token requests must include `export_reason` + `export_ticket`; Authority audits denials. |
|
||||
@@ -78,7 +84,7 @@ Authority issues short-lived tokens bound to tenants and scopes. Sprint 19 int
|
||||
- **`role/policy-engine`** → `effective:write`, `findings:read`.
|
||||
- **`role/cartographer-service`** → `graph:write`, `graph:read`.
|
||||
- **`role/graph-gateway`** → `graph:read`, `graph:export`, `graph:simulate`.
|
||||
- **`role/console`** → `ui.read`, `advisory:read`, `vex:read`, `exceptions:read`, `aoc:verify`, `findings:read`, `airgap:status:read`, `orch:read`, `vuln:read`.
|
||||
- **`role/console`** → `ui.read`, `advisory:read`, `vex:read`, `exceptions:read`, `aoc:verify`, `findings:read`, `airgap:status:read`, `orch:read`, `vuln:view`, `vuln:investigate`.
|
||||
- **`role/ui-console-admin`** → `ui.read`, `authority:tenants.read`, `authority:roles.read`, `authority:tokens.read`, `authority:clients.read` (paired with write scopes where required).
|
||||
- **`role/orch-viewer`** *(Authority role: `Orch.Viewer`)* → `orch:read`.
|
||||
- **`role/orch-operator`** *(Authority role: `Orch.Operator`)* → `orch:read`, `orch:operate`.
|
||||
@@ -89,7 +95,7 @@ Authority issues short-lived tokens bound to tenants and scopes. Sprint 19 int
|
||||
- **`role/policy-author`** → `policy:author`, `policy:read`, `policy:simulate`, `findings:read`.
|
||||
- **`role/policy-reviewer`** → `policy:review`, `policy:read`, `policy:simulate`, `findings:read`.
|
||||
- **`role/policy-approver`** → `policy:approve`, `policy:review`, `policy:read`, `policy:simulate`, `findings:read`.
|
||||
- **`role/policy-operator`** → `policy:operate`, `policy:run`, `policy:activate`, `policy:read`, `policy:simulate`, `findings:read`.
|
||||
- **`role/policy-operator`** → `policy:operate`, `policy:run`, `policy:activate`, `policy:publish`, `policy:promote`, `policy:read`, `policy:simulate`, `findings:read`.
|
||||
- **`role/policy-auditor`** → `policy:audit`, `policy:read`, `policy:simulate`, `findings:read`.
|
||||
- **`role/export-viewer`** *(Authority role: `Export.Viewer`)* → `export.viewer`.
|
||||
- **`role/export-operator`** *(Authority role: `Export.Operator`)* → `export.viewer`, `export.operator`.
|
||||
@@ -130,7 +136,7 @@ tenants:
|
||||
policy-approver:
|
||||
scopes: [policy:approve, policy:review, policy:read, policy:simulate, findings:read]
|
||||
policy-operator:
|
||||
scopes: [policy:operate, policy:run, policy:activate, policy:read, policy:simulate, findings:read]
|
||||
scopes: [policy:operate, policy:run, policy:activate, policy:publish, policy:promote, policy:read, policy:simulate, findings:read]
|
||||
policy-auditor:
|
||||
scopes: [policy:audit, policy:read, policy:simulate, findings:read]
|
||||
pack-viewer:
|
||||
@@ -240,8 +246,14 @@ security:
|
||||
description: Export graph artefacts
|
||||
- name: graph:simulate
|
||||
description: Run graph what-if simulations
|
||||
- name: vuln:read
|
||||
description: Read Vuln Explorer data
|
||||
- name: vuln:view
|
||||
description: Read Vuln Explorer data, list findings, issue permalinks
|
||||
- name: vuln:investigate
|
||||
description: Perform triage actions (assign, comment, remediation notes)
|
||||
- name: vuln:operate
|
||||
description: Execute state changes and remediation workflows
|
||||
- name: vuln:audit
|
||||
description: Access Vuln Explorer audit ledgers and offline exports
|
||||
claimTransforms:
|
||||
- match: { scope: "effective:write" }
|
||||
require:
|
||||
@@ -260,7 +272,7 @@ Update service clients:
|
||||
- `Policy.Engine` → request `effective:write`, `findings:read`; set `properties.serviceIdentity=policy-engine`.
|
||||
- `Cartographer.Service` → request `graph:write`, `graph:read`; set `properties.serviceIdentity=cartographer`.
|
||||
- `Graph API Gateway` → request `graph:read`, `graph:export`, `graph:simulate`; tenant hint required.
|
||||
- `Console` → request `advisory:read`, `vex:read`, `aoc:verify`, `findings:read`, `vuln:read` plus existing UI scopes.
|
||||
- `Console` → request `advisory:read`, `vex:read`, `aoc:verify`, `findings:read`, `vuln:view`, `vuln:investigate`, `vuln:operate`, `vuln:audit` plus existing UI scopes.
|
||||
- `CLI automation` → request `aoc:verify`, `advisory:read`, `vex:read` as needed.
|
||||
|
||||
Client definition snippet:
|
||||
@@ -283,6 +295,31 @@ clients:
|
||||
serviceIdentity: cartographer
|
||||
```
|
||||
|
||||
### 3.3 Delegated service accounts
|
||||
|
||||
Add delegated service accounts when automation needs scoped tokens with shorter lifetimes:
|
||||
|
||||
```yaml
|
||||
delegation:
|
||||
quotas:
|
||||
maxActiveTokens: 50
|
||||
serviceAccounts:
|
||||
- accountId: "svc-observer"
|
||||
tenant: "tenant-default"
|
||||
allowedScopes: [ "jobs:read", "findings:read" ]
|
||||
authorizedClients: [ "export-center-worker" ]
|
||||
|
||||
tenants:
|
||||
- name: "tenant-default"
|
||||
delegation:
|
||||
maxActiveTokens: 25
|
||||
```
|
||||
|
||||
- Clients request delegated tokens by supplying `service_account=<accountId>` (and optional `delegation_actor`) alongside the usual client-credentials payload.
|
||||
- Authority enforces both tenant and service-account quotas. Exceeding either returns `invalid_request` and records `delegation.quota.exceeded` in audit events.
|
||||
- Only scopes listed in `allowedScopes` are granted; `authorizedClients` restricts which OAuth clients may impersonate the delegate.
|
||||
- Delegated tokens include `stellaops:service_account` and an `act` claim. The token store persists `tokenKind = "service_account"`, `serviceAccountId`, and the normalized actor chain for offline auditing.
|
||||
|
||||
---
|
||||
|
||||
## 4 · Operational safeguards
|
||||
@@ -321,10 +358,12 @@ clients:
|
||||
- [ ] Claim transforms enforce `serviceIdentity` for `effective:write`.
|
||||
- [ ] Claim transforms enforce `serviceIdentity` for `graph:write`.
|
||||
- [ ] Concelier/Excititor smoke tests cover missing tenant rejection.
|
||||
- [ ] Delegation quotas configured (`delegation.quotas.maxActiveTokens`, `tenants[].delegation.maxActiveTokens` where required).
|
||||
- [ ] Service account seeds (`delegation.serviceAccounts`) reviewed for allowed scopes and authorized clients; audit dashboards show `delegation.service_account` usage.
|
||||
- [ ] Offline kit credentials reviewed for least privilege.
|
||||
- [ ] Audit/monitoring guidance validated with Observability Guild.
|
||||
- [ ] Authority Core sign-off recorded (owner: @authority-core, due 2025-10-28).
|
||||
|
||||
---
|
||||
|
||||
*Last updated: 2025-10-27 (Sprint 19).*
|
||||
*Last updated: 2025-11-02 (Sprint 19).*
|
||||
|
||||
@@ -38,7 +38,7 @@ Each module directory bundles an ownership charter (`AGENTS.md`), current work (
|
||||
| UI / Console | [architecture.md](../../modules/ui/architecture.md), [console-architecture.md](../../modules/ui/console-architecture.md) | [implementation_plan.md](../../modules/ui/implementation_plan.md) | — |
|
||||
| Vuln Explorer | [architecture.md](../../modules/vuln-explorer/architecture.md) | [implementation_plan.md](../../modules/vuln-explorer/implementation_plan.md) | — |
|
||||
| VEX Lens | [architecture.md](../../modules/vex-lens/architecture.md) | [implementation_plan.md](../../modules/vex-lens/implementation_plan.md) | — |
|
||||
| Vexer | [architecture.md](../../modules/vexer/architecture.md) | [implementation_plan.md](../../modules/vexer/implementation_plan.md) | [scoring.md](../../modules/vexer/scoring.md) |
|
||||
| Excitor | [architecture.md](../../modules/excitor/architecture.md) | [implementation_plan.md](../../modules/excitor/implementation_plan.md) | [scoring.md](../../modules/excitor/scoring.md) |
|
||||
| Zastava | [architecture.md](../../modules/zastava/architecture.md) | [implementation_plan.md](../../modules/zastava/implementation_plan.md) | — |
|
||||
|
||||
> **Tip:** Every module directory also exposes `README.md`, `AGENTS.md`, and `TASKS.md` for roles, current backlog, and ownership responsibilities.
|
||||
|
||||
@@ -13,7 +13,7 @@ Resources for contributors building features, plug-ins, connectors, and tests.
|
||||
- [../10_PLUGIN_SDK_GUIDE.md](../../10_PLUGIN_SDK_GUIDE.md) – plug-in lifecycle, manifests, packaging.
|
||||
- [../10_CONCELIER_CLI_QUICKSTART.md](../../10_CONCELIER_CLI_QUICKSTART.md) – local Concelier + CLI workflow for advisory ingestion.
|
||||
- Developer guides under [../dev/](../../dev/):
|
||||
- Connector playbooks (`30_EXCITITOR_CONNECTOR_GUIDE.md`, `30_VEXER_CONNECTOR_GUIDE.md`, `concelier-connector-research-20251011.md`, `kisa_connector_notes.md`).
|
||||
- Connector playbooks (`30_EXCITITOR_CONNECTOR_GUIDE.md`, `30_EXCITOR_CONNECTOR_GUIDE.md`, `concelier-connector-research-20251011.md`, `kisa_connector_notes.md`).
|
||||
- Authority and DPoP guidance (`31_AUTHORITY_PLUGIN_DEVELOPER_GUIDE.md`, `authority-dpop-mtls-plan.md`, `authority-plugin-di-coordination.md`, `authority-rate-limit-tuning-outline.md`, `32_AUTH_CLIENT_GUIDE.md`).
|
||||
- Analyzer and cache configuration (`SCANNER_CACHE_CONFIGURATION.md`, `java-analyzer-observation-plan.md`, `EXCITITOR_STATEMENT_BACKFILL.md`).
|
||||
- Normalisation & merge references (`aoc-normalization-removal-notes.md`, `merge_semver_playbook.md`, `normalized-rule-recipes.md`, `normalized_versions_rollout.md`).
|
||||
|
||||
@@ -43,7 +43,7 @@ The header integrates the status ticker to show ingestion deltas and planner hea
|
||||
| Column | Description |
|
||||
|--------|-------------|
|
||||
| **Run ID** | Deterministic identifier (`run:<tenant>:<timestamp>:<nonce>`). Clicking opens detail drawer. |
|
||||
| **Trigger** | `cron`, `manual`, `feedser`, `vexer`, `policy`, `content-refresh`. Tooltip lists schedule and initiator. |
|
||||
| **Trigger** | `cron`, `manual`, `conselier`, `excitor`, `policy`, `content-refresh`. Tooltip lists schedule and initiator. |
|
||||
| **State** | Badges: `planning`, `queued`, `running`, `completed`, `cancelled`, `error`. Errors include error code (e.g., `ERR_RUN_005`). |
|
||||
| **Progress** | Percentage + processed/total candidates. SSE updates increment in real time. |
|
||||
| **Duration** | Elapsed time (auto-updating). Completed runs show total duration; running runs show timer. |
|
||||
|
||||
@@ -65,6 +65,32 @@ notifications:
|
||||
scope: "notify.escalate"
|
||||
requireAdminScope: true
|
||||
|
||||
delegation:
|
||||
quotas:
|
||||
# Maximum concurrent delegated (service account) tokens per tenant.
|
||||
maxActiveTokens: 50
|
||||
serviceAccounts:
|
||||
- accountId: "svc-observer"
|
||||
tenant: "tenant-default"
|
||||
displayName: "Observability Exporter"
|
||||
description: "Delegated identity used by Export Center to read findings."
|
||||
enabled: true
|
||||
allowedScopes:
|
||||
- "jobs:read"
|
||||
- "findings:read"
|
||||
authorizedClients:
|
||||
- "export-center-worker"
|
||||
attributes:
|
||||
env: [ "prod", "stage" ]
|
||||
owner: [ "secops" ]
|
||||
business_tier: [ "tier-1" ]
|
||||
# - accountId: "svc-airgap-import"
|
||||
# tenant: "tenant-default"
|
||||
# displayName: "Airgap Import Service Account"
|
||||
# enabled: true
|
||||
# allowedScopes: [ "airgap:import", "airgap:status:read" ]
|
||||
# authorizedClients: [ "airgap-importer" ]
|
||||
|
||||
apiLifecycle:
|
||||
legacyAuth:
|
||||
enabled: true
|
||||
@@ -220,7 +246,7 @@ clients:
|
||||
displayName: "StellaOps Console"
|
||||
grantTypes: [ "authorization_code", "refresh_token" ]
|
||||
audiences: [ "console" ]
|
||||
scopes: [ "openid", "profile", "email", "ui.read", "authority:tenants.read", "advisory:read", "vex:read", "exceptions:read", "exceptions:approve", "aoc:verify", "findings:read", "airgap:status:read", "obs:read", "obs:incident", "timeline:read", "evidence:read", "attest:read", "orch:read", "vuln:read" ]
|
||||
scopes: [ "openid", "profile", "email", "ui.read", "authority:tenants.read", "advisory:read", "vex:read", "exceptions:read", "exceptions:approve", "aoc:verify", "findings:read", "airgap:status:read", "obs:read", "obs:incident", "timeline:read", "evidence:read", "attest:read", "orch:read", "vuln:view", "vuln:investigate", "vuln:operate", "vuln:audit" ]
|
||||
# exceptions:approve is elevated via fresh-auth and requires an MFA-capable identity provider.
|
||||
tenant: "tenant-default"
|
||||
senderConstraint: "dpop"
|
||||
@@ -369,7 +395,7 @@ clients:
|
||||
displayName: "Vuln Explorer UI"
|
||||
grantTypes: [ "client_credentials" ]
|
||||
audiences: [ "api://vuln-explorer" ]
|
||||
scopes: [ "vuln:read" ]
|
||||
scopes: [ "vuln:view", "vuln:investigate", "vuln:operate", "vuln:audit" ]
|
||||
tenant: "tenant-default"
|
||||
senderConstraint: "dpop"
|
||||
auth:
|
||||
@@ -403,7 +429,7 @@ tenants:
|
||||
policy-approver:
|
||||
scopes: [ "policy:approve", "policy:review", "policy:read", "policy:simulate", "findings:read" ]
|
||||
policy-operator:
|
||||
scopes: [ "policy:operate", "policy:run", "policy:activate", "policy:read", "policy:simulate", "findings:read" ]
|
||||
scopes: [ "policy:operate", "policy:run", "policy:activate", "policy:publish", "policy:promote", "policy:read", "policy:simulate", "findings:read" ]
|
||||
policy-auditor:
|
||||
scopes: [ "policy:audit", "policy:read", "policy:simulate", "findings:read" ]
|
||||
pack-viewer:
|
||||
@@ -428,6 +454,9 @@ tenants:
|
||||
scopes: [ "notify.viewer", "notify.operator" ]
|
||||
notify-admin:
|
||||
scopes: [ "notify.viewer", "notify.operator", "notify.admin" ]
|
||||
delegation:
|
||||
# Override the default maxActiveTokens for this tenant (optional).
|
||||
maxActiveTokens: 25
|
||||
observability-viewer:
|
||||
scopes: [ "obs:read", "timeline:read", "evidence:read", "attest:read" ]
|
||||
observability-investigator:
|
||||
@@ -448,6 +477,30 @@ tenants:
|
||||
scopes: [ "advisory-ai:view", "advisory-ai:operate" ]
|
||||
advisory-ai-admin:
|
||||
scopes: [ "advisory-ai:view", "advisory-ai:operate", "advisory-ai:admin" ]
|
||||
vuln-viewer:
|
||||
scopes: [ "vuln:view" ]
|
||||
attributes:
|
||||
env: [ "*" ]
|
||||
owner: [ "*" ]
|
||||
business_tier: [ "*" ]
|
||||
vuln-investigator:
|
||||
scopes: [ "vuln:view", "vuln:investigate" ]
|
||||
attributes:
|
||||
env: [ "*" ]
|
||||
owner: [ "*" ]
|
||||
business_tier: [ "*" ]
|
||||
vuln-operator:
|
||||
scopes: [ "vuln:view", "vuln:investigate", "vuln:operate" ]
|
||||
attributes:
|
||||
env: [ "*" ]
|
||||
owner: [ "*" ]
|
||||
business_tier: [ "*" ]
|
||||
vuln-auditor:
|
||||
scopes: [ "vuln:view", "vuln:audit" ]
|
||||
attributes:
|
||||
env: [ "*" ]
|
||||
owner: [ "*" ]
|
||||
business_tier: [ "*" ]
|
||||
advisoryAi:
|
||||
remoteInference:
|
||||
consentGranted: false
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
IssuerDirectory:
|
||||
# Override connection secrets via environment variables (ISSUERDIRECTORY__MONGO__*)
|
||||
# rather than editing this file for production.
|
||||
telemetry:
|
||||
minimumLogLevel: Information
|
||||
authority:
|
||||
|
||||
6
etc/secrets/issuer-directory.mongo.secret.example
Normal file
6
etc/secrets/issuer-directory.mongo.secret.example
Normal file
@@ -0,0 +1,6 @@
|
||||
# Replace this value with the MongoDB connection string used by Issuer Directory.
|
||||
# Keep the file out of version control; mount it via docker-compose env_file or
|
||||
# your secrets manager when running the service. Compose expects the helper
|
||||
# variable below and injects it into ISSUERDIRECTORY__MONGO__CONNECTIONSTRING
|
||||
# at container runtime.
|
||||
ISSUER_DIRECTORY_MONGO_CONNECTION_STRING=mongodb://stellaops:change-me@mongo:27017
|
||||
@@ -76,6 +76,8 @@
|
||||
| DEVOPS-LNM-22-002 | BLOCKED (2025-10-27) | DevOps Guild, Excititor Guild | EXCITITOR-LNM-21-102 | Execute VEX observation/linkset backfill with monitoring; ensure NATS/Redis events integrated; document ops runbook. Blocked until Excititor storage migration lands. |
|
||||
| DEVOPS-LNM-22-003 | TODO | DevOps Guild, Observability Guild | CONCELIER-LNM-21-005, EXCITITOR-LNM-21-005 | Add CI/monitoring coverage for new metrics (`advisory_observations_total`, `linksets_total`, etc.) and alerts on ingest-to-API SLA breaches. | Metrics scraped into Grafana; alert thresholds set; CI job verifies metric emission. |
|
||||
|
||||
> 2025-11-03: Link-Not-Merge migration playbook (`docs/migration/no-merge.md`) published—use it to sequence DEVOPS-LNM-22-001 rehearsals and record Phase 0–3 config toggles in runbooks.
|
||||
|
||||
## Graph & Vuln Explorer v1
|
||||
|
||||
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|
||||
|
||||
@@ -26,6 +26,6 @@ COPY --from=build /workspace/dist/stellaops-web/ /usr/share/nginx/html/
|
||||
COPY ops/devops/release/docker/nginx-default.conf /etc/nginx/conf.d/default.conf
|
||||
LABEL org.opencontainers.image.version="${VERSION}" \
|
||||
org.opencontainers.image.revision="${GIT_SHA}" \
|
||||
org.opencontainers.image.source="https://git.stella-ops.org/stella-ops/feedser" \
|
||||
org.opencontainers.image.source="https://git.stella-ops.org/stella-ops/conselier" \
|
||||
org.stellaops.release.channel="${CHANNEL}"
|
||||
EXPOSE 8080
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
# syntax=docker/dockerfile:1.7-labs
|
||||
|
||||
ARG SDK_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:10.0
|
||||
ARG RUNTIME_IMAGE=gcr.io/distroless/dotnet/aspnet:latest
|
||||
|
||||
ARG PROJECT
|
||||
ARG ENTRYPOINT_DLL
|
||||
ARG VERSION=0.0.0
|
||||
ARG CHANNEL=dev
|
||||
ARG GIT_SHA=0000000
|
||||
ARG SOURCE_DATE_EPOCH=0
|
||||
|
||||
FROM ${SDK_IMAGE} AS build
|
||||
ARG PROJECT
|
||||
ARG GIT_SHA
|
||||
ARG SOURCE_DATE_EPOCH
|
||||
WORKDIR /src
|
||||
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 \
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 \
|
||||
NUGET_XMLDOC_MODE=skip \
|
||||
SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}
|
||||
COPY . .
|
||||
RUN --mount=type=cache,target=/root/.nuget/packages \
|
||||
dotnet restore "${PROJECT}"
|
||||
RUN --mount=type=cache,target=/root/.nuget/packages \
|
||||
dotnet publish "${PROJECT}" \
|
||||
-c Release \
|
||||
-o /app/publish \
|
||||
/p:UseAppHost=false \
|
||||
/p:ContinuousIntegrationBuild=true \
|
||||
/p:SourceRevisionId=${GIT_SHA} \
|
||||
/p:Deterministic=true \
|
||||
/p:TreatWarningsAsErrors=true
|
||||
|
||||
FROM ${RUNTIME_IMAGE} AS runtime
|
||||
WORKDIR /app
|
||||
ARG ENTRYPOINT_DLL
|
||||
ARG VERSION
|
||||
ARG CHANNEL
|
||||
ARG GIT_SHA
|
||||
ENV DOTNET_EnableDiagnostics=0 \
|
||||
ASPNETCORE_URLS=http://0.0.0.0:8080
|
||||
COPY --from=build /app/publish/ ./
|
||||
RUN set -eu; \
|
||||
printf '#!/usr/bin/env sh\nset -e\nexec dotnet %s "$@"\n' "${ENTRYPOINT_DLL}" > /entrypoint.sh; \
|
||||
chmod +x /entrypoint.sh
|
||||
EXPOSE 8080
|
||||
LABEL org.opencontainers.image.version="${VERSION}" \
|
||||
org.opencontainers.image.revision="${GIT_SHA}" \
|
||||
org.opencontainers.image.source="https://git.stella-ops.org/stella-ops/feedser" \
|
||||
org.stellaops.release.channel="${CHANNEL}"
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
# syntax=docker/dockerfile:1.7-labs
|
||||
|
||||
ARG SDK_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:10.0
|
||||
ARG RUNTIME_IMAGE=gcr.io/distroless/dotnet/aspnet:latest
|
||||
|
||||
ARG PROJECT
|
||||
ARG ENTRYPOINT_DLL
|
||||
ARG VERSION=0.0.0
|
||||
ARG CHANNEL=dev
|
||||
ARG GIT_SHA=0000000
|
||||
ARG SOURCE_DATE_EPOCH=0
|
||||
|
||||
FROM ${SDK_IMAGE} AS build
|
||||
ARG PROJECT
|
||||
ARG GIT_SHA
|
||||
ARG SOURCE_DATE_EPOCH
|
||||
WORKDIR /src
|
||||
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 \
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 \
|
||||
NUGET_XMLDOC_MODE=skip \
|
||||
SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}
|
||||
COPY . .
|
||||
RUN --mount=type=cache,target=/root/.nuget/packages \
|
||||
dotnet restore "${PROJECT}"
|
||||
RUN --mount=type=cache,target=/root/.nuget/packages \
|
||||
dotnet publish "${PROJECT}" \
|
||||
-c Release \
|
||||
-o /app/publish \
|
||||
/p:UseAppHost=false \
|
||||
/p:ContinuousIntegrationBuild=true \
|
||||
/p:SourceRevisionId=${GIT_SHA} \
|
||||
/p:Deterministic=true \
|
||||
/p:TreatWarningsAsErrors=true
|
||||
|
||||
FROM ${RUNTIME_IMAGE} AS runtime
|
||||
WORKDIR /app
|
||||
ARG ENTRYPOINT_DLL
|
||||
ARG VERSION
|
||||
ARG CHANNEL
|
||||
ARG GIT_SHA
|
||||
ENV DOTNET_EnableDiagnostics=0 \
|
||||
ASPNETCORE_URLS=http://0.0.0.0:8080
|
||||
COPY --from=build /app/publish/ ./
|
||||
RUN set -eu; \
|
||||
printf '#!/usr/bin/env sh\nset -e\nexec dotnet %s "$@"\n' "${ENTRYPOINT_DLL}" > /entrypoint.sh; \
|
||||
chmod +x /entrypoint.sh
|
||||
EXPOSE 8080
|
||||
LABEL org.opencontainers.image.version="${VERSION}" \
|
||||
org.opencontainers.image.revision="${GIT_SHA}" \
|
||||
org.opencontainers.image.source="https://git.stella-ops.org/stella-ops/conselier" \
|
||||
org.stellaops.release.channel="${CHANNEL}"
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"schemaVersion": "1.0",
|
||||
"id": "stellaops.analyzer.lang.ruby",
|
||||
"displayName": "StellaOps Ruby Analyzer",
|
||||
"version": "0.1.0",
|
||||
"requiresRestart": true,
|
||||
"entryPoint": {
|
||||
"type": "dotnet",
|
||||
"assembly": "StellaOps.Scanner.Analyzers.Lang.Ruby.dll",
|
||||
"typeName": "StellaOps.Scanner.Analyzers.Lang.Ruby.RubyAnalyzerPlugin"
|
||||
},
|
||||
"capabilities": [
|
||||
"language-analyzer",
|
||||
"ruby"
|
||||
],
|
||||
"metadata": {
|
||||
"org.stellaops.analyzer.language": "ruby",
|
||||
"org.stellaops.analyzer.kind": "language",
|
||||
"org.stellaops.restart.required": "true"
|
||||
}
|
||||
}
|
||||
@@ -1,101 +1,101 @@
|
||||
{
|
||||
"tenantId": "tenant-alpha",
|
||||
"scheduleId": "sch_20251018a",
|
||||
"updatedAt": "2025-10-18T22:10:10Z",
|
||||
"lastRun": {
|
||||
"runId": "run_20251018_0001",
|
||||
"trigger": "feedser",
|
||||
"state": "completed",
|
||||
"createdAt": "2025-10-18T22:03:14Z",
|
||||
"startedAt": "2025-10-18T22:03:20Z",
|
||||
"finishedAt": "2025-10-18T22:08:45Z",
|
||||
"stats": {
|
||||
"candidates": 1280,
|
||||
"deduped": 910,
|
||||
"queued": 0,
|
||||
"completed": 910,
|
||||
"deltas": 42,
|
||||
"newCriticals": 7,
|
||||
"newHigh": 11,
|
||||
"newMedium": 18,
|
||||
"newLow": 6
|
||||
},
|
||||
"error": null
|
||||
},
|
||||
"recent": [
|
||||
{
|
||||
"runId": "run_20251018_0001",
|
||||
"trigger": "feedser",
|
||||
"state": "completed",
|
||||
"createdAt": "2025-10-18T22:03:14Z",
|
||||
"startedAt": "2025-10-18T22:03:20Z",
|
||||
"finishedAt": "2025-10-18T22:08:45Z",
|
||||
"stats": {
|
||||
"candidates": 1280,
|
||||
"deduped": 910,
|
||||
"queued": 0,
|
||||
"completed": 910,
|
||||
"deltas": 42,
|
||||
"newCriticals": 7,
|
||||
"newHigh": 11,
|
||||
"newMedium": 18,
|
||||
"newLow": 6
|
||||
},
|
||||
"error": null
|
||||
},
|
||||
{
|
||||
"runId": "run_20251017_0003",
|
||||
"trigger": "cron",
|
||||
"state": "error",
|
||||
"createdAt": "2025-10-17T22:01:02Z",
|
||||
"startedAt": "2025-10-17T22:01:08Z",
|
||||
"finishedAt": "2025-10-17T22:04:11Z",
|
||||
"stats": {
|
||||
"candidates": 1040,
|
||||
"deduped": 812,
|
||||
"queued": 0,
|
||||
"completed": 640,
|
||||
"deltas": 18,
|
||||
"newCriticals": 2,
|
||||
"newHigh": 4,
|
||||
"newMedium": 7,
|
||||
"newLow": 3
|
||||
},
|
||||
"error": "scanner timeout"
|
||||
},
|
||||
{
|
||||
"runId": "run_20251016_0007",
|
||||
"trigger": "manual",
|
||||
"state": "cancelled",
|
||||
"createdAt": "2025-10-16T20:00:00Z",
|
||||
"startedAt": "2025-10-16T20:00:04Z",
|
||||
"finishedAt": null,
|
||||
"stats": {
|
||||
"candidates": 820,
|
||||
"deduped": 640,
|
||||
"queued": 0,
|
||||
"completed": 0,
|
||||
"deltas": 0,
|
||||
"newCriticals": 0,
|
||||
"newHigh": 0,
|
||||
"newMedium": 0,
|
||||
"newLow": 0
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
],
|
||||
"counters": {
|
||||
"total": 3,
|
||||
"planning": 0,
|
||||
"queued": 0,
|
||||
"running": 0,
|
||||
"completed": 1,
|
||||
"error": 1,
|
||||
"cancelled": 1,
|
||||
"totalDeltas": 60,
|
||||
"totalNewCriticals": 9,
|
||||
"totalNewHigh": 15,
|
||||
"totalNewMedium": 25,
|
||||
"totalNewLow": 9
|
||||
}
|
||||
}
|
||||
{
|
||||
"tenantId": "tenant-alpha",
|
||||
"scheduleId": "sch_20251018a",
|
||||
"updatedAt": "2025-10-18T22:10:10Z",
|
||||
"lastRun": {
|
||||
"runId": "run_20251018_0001",
|
||||
"trigger": "conselier",
|
||||
"state": "completed",
|
||||
"createdAt": "2025-10-18T22:03:14Z",
|
||||
"startedAt": "2025-10-18T22:03:20Z",
|
||||
"finishedAt": "2025-10-18T22:08:45Z",
|
||||
"stats": {
|
||||
"candidates": 1280,
|
||||
"deduped": 910,
|
||||
"queued": 0,
|
||||
"completed": 910,
|
||||
"deltas": 42,
|
||||
"newCriticals": 7,
|
||||
"newHigh": 11,
|
||||
"newMedium": 18,
|
||||
"newLow": 6
|
||||
},
|
||||
"error": null
|
||||
},
|
||||
"recent": [
|
||||
{
|
||||
"runId": "run_20251018_0001",
|
||||
"trigger": "conselier",
|
||||
"state": "completed",
|
||||
"createdAt": "2025-10-18T22:03:14Z",
|
||||
"startedAt": "2025-10-18T22:03:20Z",
|
||||
"finishedAt": "2025-10-18T22:08:45Z",
|
||||
"stats": {
|
||||
"candidates": 1280,
|
||||
"deduped": 910,
|
||||
"queued": 0,
|
||||
"completed": 910,
|
||||
"deltas": 42,
|
||||
"newCriticals": 7,
|
||||
"newHigh": 11,
|
||||
"newMedium": 18,
|
||||
"newLow": 6
|
||||
},
|
||||
"error": null
|
||||
},
|
||||
{
|
||||
"runId": "run_20251017_0003",
|
||||
"trigger": "cron",
|
||||
"state": "error",
|
||||
"createdAt": "2025-10-17T22:01:02Z",
|
||||
"startedAt": "2025-10-17T22:01:08Z",
|
||||
"finishedAt": "2025-10-17T22:04:11Z",
|
||||
"stats": {
|
||||
"candidates": 1040,
|
||||
"deduped": 812,
|
||||
"queued": 0,
|
||||
"completed": 640,
|
||||
"deltas": 18,
|
||||
"newCriticals": 2,
|
||||
"newHigh": 4,
|
||||
"newMedium": 7,
|
||||
"newLow": 3
|
||||
},
|
||||
"error": "scanner timeout"
|
||||
},
|
||||
{
|
||||
"runId": "run_20251016_0007",
|
||||
"trigger": "manual",
|
||||
"state": "cancelled",
|
||||
"createdAt": "2025-10-16T20:00:00Z",
|
||||
"startedAt": "2025-10-16T20:00:04Z",
|
||||
"finishedAt": null,
|
||||
"stats": {
|
||||
"candidates": 820,
|
||||
"deduped": 640,
|
||||
"queued": 0,
|
||||
"completed": 0,
|
||||
"deltas": 0,
|
||||
"newCriticals": 0,
|
||||
"newHigh": 0,
|
||||
"newMedium": 0,
|
||||
"newLow": 0
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
],
|
||||
"counters": {
|
||||
"total": 3,
|
||||
"planning": 0,
|
||||
"queued": 0,
|
||||
"running": 0,
|
||||
"completed": 1,
|
||||
"error": 1,
|
||||
"cancelled": 1,
|
||||
"totalDeltas": 60,
|
||||
"totalNewCriticals": 9,
|
||||
"totalNewHigh": 15,
|
||||
"totalNewMedium": 25,
|
||||
"totalNewLow": 9
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
{
|
||||
"schemaVersion": "scheduler.run@1",
|
||||
"id": "run_20251018_0001",
|
||||
"tenantId": "tenant-alpha",
|
||||
"scheduleId": "sch_20251018a",
|
||||
"trigger": "feedser",
|
||||
"state": "running",
|
||||
"stats": {
|
||||
"candidates": 1280,
|
||||
"deduped": 910,
|
||||
"queued": 624,
|
||||
"completed": 310,
|
||||
"deltas": 42,
|
||||
"newCriticals": 7,
|
||||
"newHigh": 11,
|
||||
"newMedium": 18,
|
||||
"newLow": 6
|
||||
},
|
||||
"reason": {
|
||||
"feedserExportId": "exp-20251018-03"
|
||||
},
|
||||
"createdAt": "2025-10-18T22:03:14+00:00",
|
||||
"startedAt": "2025-10-18T22:03:20+00:00",
|
||||
"deltas": [
|
||||
{
|
||||
"imageDigest": "sha256:a1b2c3",
|
||||
"newFindings": 3,
|
||||
"newCriticals": 1,
|
||||
"newHigh": 1,
|
||||
"newMedium": 1,
|
||||
"newLow": 0,
|
||||
"kevHits": [
|
||||
"CVE-2025-0002"
|
||||
],
|
||||
"topFindings": [
|
||||
{
|
||||
"purl": "pkg:rpm/openssl@3.0.12-5.el9",
|
||||
"vulnerabilityId": "CVE-2025-0002",
|
||||
"severity": "critical",
|
||||
"link": "https://ui.internal/scans/sha256:a1b2c3"
|
||||
}
|
||||
],
|
||||
"attestation": {
|
||||
"uuid": "rekor-314",
|
||||
"verified": true
|
||||
},
|
||||
"detectedAt": "2025-10-18T22:03:21+00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"schemaVersion": "scheduler.run@1",
|
||||
"id": "run_20251018_0001",
|
||||
"tenantId": "tenant-alpha",
|
||||
"scheduleId": "sch_20251018a",
|
||||
"trigger": "conselier",
|
||||
"state": "running",
|
||||
"stats": {
|
||||
"candidates": 1280,
|
||||
"deduped": 910,
|
||||
"queued": 624,
|
||||
"completed": 310,
|
||||
"deltas": 42,
|
||||
"newCriticals": 7,
|
||||
"newHigh": 11,
|
||||
"newMedium": 18,
|
||||
"newLow": 6
|
||||
},
|
||||
"reason": {
|
||||
"conselierExportId": "exp-20251018-03"
|
||||
},
|
||||
"createdAt": "2025-10-18T22:03:14+00:00",
|
||||
"startedAt": "2025-10-18T22:03:20+00:00",
|
||||
"deltas": [
|
||||
{
|
||||
"imageDigest": "sha256:a1b2c3",
|
||||
"newFindings": 3,
|
||||
"newCriticals": 1,
|
||||
"newHigh": 1,
|
||||
"newMedium": 1,
|
||||
"newLow": 0,
|
||||
"kevHits": [
|
||||
"CVE-2025-0002"
|
||||
],
|
||||
"topFindings": [
|
||||
{
|
||||
"purl": "pkg:rpm/openssl@3.0.12-5.el9",
|
||||
"vulnerabilityId": "CVE-2025-0002",
|
||||
"severity": "critical",
|
||||
"link": "https://ui.internal/scans/sha256:a1b2c3"
|
||||
}
|
||||
],
|
||||
"attestation": {
|
||||
"uuid": "rekor-314",
|
||||
"verified": true
|
||||
},
|
||||
"detectedAt": "2025-10-18T22:03:21+00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
193
src/AdvisoryAI/StellaOps.AdvisoryAI.sln
Normal file
193
src/AdvisoryAI/StellaOps.AdvisoryAI.sln
Normal file
@@ -0,0 +1,193 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.AdvisoryAI", "StellaOps.AdvisoryAI\StellaOps.AdvisoryAI.csproj", "{E41E2FDA-3827-4B18-8596-B25BDE882D5F}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Tests", "__Tests", "{56BCE1BF-7CBA-7CE8-203D-A88051F1D642}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.AdvisoryAI.Tests", "__Tests\StellaOps.AdvisoryAI.Tests\StellaOps.AdvisoryAI.Tests.csproj", "{F6860DE5-0C7C-4848-8356-7555E3C391A3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Testing", "..\Concelier\__Libraries\StellaOps.Concelier.Testing\StellaOps.Concelier.Testing.csproj", "{B53E4FED-8988-4354-8D1A-D3C618DBFD78}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Connector.Common", "..\Concelier\__Libraries\StellaOps.Concelier.Connector.Common\StellaOps.Concelier.Connector.Common.csproj", "{E98A7C01-1619-41A0-A586-84EF9952F75D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Storage.Mongo", "..\Concelier\__Libraries\StellaOps.Concelier.Storage.Mongo\StellaOps.Concelier.Storage.Mongo.csproj", "{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Core", "..\Concelier\__Libraries\StellaOps.Concelier.Core\StellaOps.Concelier.Core.csproj", "{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Models", "..\Concelier\__Libraries\StellaOps.Concelier.Models\StellaOps.Concelier.Models.csproj", "{BBB5CD3C-866A-4298-ACE1-598413631CF5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.RawModels", "..\Concelier\__Libraries\StellaOps.Concelier.RawModels\StellaOps.Concelier.RawModels.csproj", "{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Normalization", "..\Concelier\__Libraries\StellaOps.Concelier.Normalization\StellaOps.Concelier.Normalization.csproj", "{1313202A-E8A8-41E3-80BC-472096074681}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Plugin", "..\__Libraries\StellaOps.Plugin\StellaOps.Plugin.csproj", "{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.DependencyInjection", "..\__Libraries\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj", "{F567F20C-552F-4761-941A-0552CEF68160}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Aoc", "..\Aoc\__Libraries\StellaOps.Aoc\StellaOps.Aoc.csproj", "{C8CE71D3-952A-43F7-9346-20113E37F672}"
|
||||
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
|
||||
{E41E2FDA-3827-4B18-8596-B25BDE882D5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E41E2FDA-3827-4B18-8596-B25BDE882D5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E41E2FDA-3827-4B18-8596-B25BDE882D5F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E41E2FDA-3827-4B18-8596-B25BDE882D5F}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E41E2FDA-3827-4B18-8596-B25BDE882D5F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E41E2FDA-3827-4B18-8596-B25BDE882D5F}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E41E2FDA-3827-4B18-8596-B25BDE882D5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E41E2FDA-3827-4B18-8596-B25BDE882D5F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E41E2FDA-3827-4B18-8596-B25BDE882D5F}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E41E2FDA-3827-4B18-8596-B25BDE882D5F}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E41E2FDA-3827-4B18-8596-B25BDE882D5F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E41E2FDA-3827-4B18-8596-B25BDE882D5F}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3}.Release|x86.Build.0 = Release|Any CPU
|
||||
{B53E4FED-8988-4354-8D1A-D3C618DBFD78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B53E4FED-8988-4354-8D1A-D3C618DBFD78}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B53E4FED-8988-4354-8D1A-D3C618DBFD78}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{B53E4FED-8988-4354-8D1A-D3C618DBFD78}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{B53E4FED-8988-4354-8D1A-D3C618DBFD78}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B53E4FED-8988-4354-8D1A-D3C618DBFD78}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{B53E4FED-8988-4354-8D1A-D3C618DBFD78}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B53E4FED-8988-4354-8D1A-D3C618DBFD78}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B53E4FED-8988-4354-8D1A-D3C618DBFD78}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{B53E4FED-8988-4354-8D1A-D3C618DBFD78}.Release|x64.Build.0 = Release|Any CPU
|
||||
{B53E4FED-8988-4354-8D1A-D3C618DBFD78}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B53E4FED-8988-4354-8D1A-D3C618DBFD78}.Release|x86.Build.0 = Release|Any CPU
|
||||
{E98A7C01-1619-41A0-A586-84EF9952F75D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E98A7C01-1619-41A0-A586-84EF9952F75D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E98A7C01-1619-41A0-A586-84EF9952F75D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E98A7C01-1619-41A0-A586-84EF9952F75D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E98A7C01-1619-41A0-A586-84EF9952F75D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E98A7C01-1619-41A0-A586-84EF9952F75D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E98A7C01-1619-41A0-A586-84EF9952F75D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E98A7C01-1619-41A0-A586-84EF9952F75D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E98A7C01-1619-41A0-A586-84EF9952F75D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E98A7C01-1619-41A0-A586-84EF9952F75D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E98A7C01-1619-41A0-A586-84EF9952F75D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E98A7C01-1619-41A0-A586-84EF9952F75D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}.Release|x64.Build.0 = Release|Any CPU
|
||||
{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{973DD52D-AD3C-4526-92CB-F35FDD9AEA10}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F7FB8ABD-31D7-4B4D-8B2A-F4D2B696ACAF}.Release|x86.Build.0 = Release|Any CPU
|
||||
{BBB5CD3C-866A-4298-ACE1-598413631CF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BBB5CD3C-866A-4298-ACE1-598413631CF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BBB5CD3C-866A-4298-ACE1-598413631CF5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{BBB5CD3C-866A-4298-ACE1-598413631CF5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{BBB5CD3C-866A-4298-ACE1-598413631CF5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{BBB5CD3C-866A-4298-ACE1-598413631CF5}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{BBB5CD3C-866A-4298-ACE1-598413631CF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BBB5CD3C-866A-4298-ACE1-598413631CF5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BBB5CD3C-866A-4298-ACE1-598413631CF5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{BBB5CD3C-866A-4298-ACE1-598413631CF5}.Release|x64.Build.0 = Release|Any CPU
|
||||
{BBB5CD3C-866A-4298-ACE1-598413631CF5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{BBB5CD3C-866A-4298-ACE1-598413631CF5}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7E3D9A33-BD0E-424A-88E6-F4440E386A3C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1313202A-E8A8-41E3-80BC-472096074681}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1313202A-E8A8-41E3-80BC-472096074681}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1313202A-E8A8-41E3-80BC-472096074681}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{1313202A-E8A8-41E3-80BC-472096074681}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{1313202A-E8A8-41E3-80BC-472096074681}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1313202A-E8A8-41E3-80BC-472096074681}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1313202A-E8A8-41E3-80BC-472096074681}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1313202A-E8A8-41E3-80BC-472096074681}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1313202A-E8A8-41E3-80BC-472096074681}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{1313202A-E8A8-41E3-80BC-472096074681}.Release|x64.Build.0 = Release|Any CPU
|
||||
{1313202A-E8A8-41E3-80BC-472096074681}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1313202A-E8A8-41E3-80BC-472096074681}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1CC5F6F8-DF9A-4BCC-8C69-79E2DF604F6D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F567F20C-552F-4761-941A-0552CEF68160}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F567F20C-552F-4761-941A-0552CEF68160}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F567F20C-552F-4761-941A-0552CEF68160}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F567F20C-552F-4761-941A-0552CEF68160}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F567F20C-552F-4761-941A-0552CEF68160}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F567F20C-552F-4761-941A-0552CEF68160}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F567F20C-552F-4761-941A-0552CEF68160}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F567F20C-552F-4761-941A-0552CEF68160}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F567F20C-552F-4761-941A-0552CEF68160}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F567F20C-552F-4761-941A-0552CEF68160}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F567F20C-552F-4761-941A-0552CEF68160}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F567F20C-552F-4761-941A-0552CEF68160}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C8CE71D3-952A-43F7-9346-20113E37F672}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C8CE71D3-952A-43F7-9346-20113E37F672}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C8CE71D3-952A-43F7-9346-20113E37F672}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C8CE71D3-952A-43F7-9346-20113E37F672}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C8CE71D3-952A-43F7-9346-20113E37F672}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C8CE71D3-952A-43F7-9346-20113E37F672}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C8CE71D3-952A-43F7-9346-20113E37F672}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C8CE71D3-952A-43F7-9346-20113E37F672}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C8CE71D3-952A-43F7-9346-20113E37F672}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C8CE71D3-952A-43F7-9346-20113E37F672}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C8CE71D3-952A-43F7-9346-20113E37F672}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C8CE71D3-952A-43F7-9346-20113E37F672}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{F6860DE5-0C7C-4848-8356-7555E3C391A3} = {56BCE1BF-7CBA-7CE8-203D-A88051F1D642}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user