prep docs and service updates
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# DevPortal Offline Prep — PREP-DVOFF-64-002
|
||||
|
||||
Status: **Ready for implementation** (2025-11-20)
|
||||
Owners: DevPortal Offline Guild · AirGap Controller Guild
|
||||
Scope: Define sealed bundle sample + CLI verify flow for DevPortal offline verification (`stella devportal verify bundle.tgz`).
|
||||
|
||||
## Required inputs
|
||||
- EvidenceLocker sealed bundle contract: `docs/modules/evidence-locker/bundle-packaging.md` (bundle.tgz layout, determinism).
|
||||
- Portable bundle guidance: `docs/airgap/portable-evidence.md` (for redacted flow).
|
||||
|
||||
## Sample artefacts to publish
|
||||
- `out/devportal/samples/bundle.tgz` — copy of EvidenceLocker sealed bundle (write-once).
|
||||
- `out/devportal/samples/bundle.tgz.sha256` — `sha256 bundle.tgz` line.
|
||||
- `out/devportal/samples/verify-report.json` — expected CLI JSON output after verification (see below).
|
||||
|
||||
## CLI verification flow (contract)
|
||||
- Command: `stella devportal verify --bundle bundle.tgz --offline`
|
||||
- Steps performed:
|
||||
1) Validate SHA-256 against `.sha256` file.
|
||||
2) Extract `manifest.json`, `signature.json`, `bundle.json`, `checksums.txt` (no rewrite).
|
||||
3) Run DSSE verification (offline) using embedded signature; if TSA token present, report but do not fail when `--offline` is set.
|
||||
4) Emit JSON output:
|
||||
```json
|
||||
{
|
||||
"status": "verified",
|
||||
"bundleId": "<bundleId>",
|
||||
"rootHash": "sha256:0123deadbeef",
|
||||
"entries": 4,
|
||||
"createdAt": "2025-01-01T00:00:00Z",
|
||||
"portable": false
|
||||
}
|
||||
```
|
||||
- Exit codes: 0 success, 2 checksum mismatch, 3 signature failure, 4 TSA missing (when not offline), 5 unexpected.
|
||||
- Determinism: no network calls when `--offline`; output JSON keys sorted.
|
||||
|
||||
## Acceptance criteria
|
||||
- Sample bundle and .sha256 published under `out/devportal/samples/` with hashes listed in this sprint.
|
||||
- CLI flow documented above; exit codes and sample JSON provided.
|
||||
- Prep doc linked from Sprint 0162 P1 and DevPortal docs when implemented.
|
||||
|
||||
## Next steps
|
||||
- Publish the sample bundle + hashes; update sprint Delivery Tracker to DONE once artifacts exist.
|
||||
@@ -0,0 +1,12 @@
|
||||
# Export AirGap Prep — PREP-EXPORT-AIRGAP-56-001
|
||||
|
||||
Status: Draft (2025-11-20)
|
||||
Owners: Exporter Service Guild · Mirror Creator Guild
|
||||
Scope: EvidenceLocker contract + advisory schema to finalize DSSE contents for air-gapped exports.
|
||||
|
||||
## Needs
|
||||
- EvidenceLocker contract (bundle schema, retention).
|
||||
- Advisory schema alignment for DSSE contents.
|
||||
|
||||
## Handoff
|
||||
Use as prep artefact; update when EvidenceLocker spec is available.
|
||||
@@ -0,0 +1,36 @@
|
||||
# Export AirGap Prep — PREP-EXPORT-AIRGAP-56-002
|
||||
|
||||
Status: **Ready for implementation** (2025-11-20)
|
||||
Owners: Exporter Service Guild · DevOps Guild
|
||||
Scope: Bootstrap pack (images + charts) packaging for air-gap deploys, dependent on 56-001 evidence/mirror bundle inputs.
|
||||
|
||||
## Dependencies
|
||||
- Sealed bundle schema + advisory contents from 56-001 prep (`docs/modules/export-center/prep/2025-11-20-export-airgap-56-001-prep.md`).
|
||||
- Mirror/DevOps deployment expectations (values-airgap.yaml) to place bootstrap packs.
|
||||
|
||||
## Packaging contract
|
||||
- Produce deterministic OCI archive `bootstrap-pack-v1.tar` containing:
|
||||
- `charts/` Helm charts with pinned template timestamps (SOURCE_DATE_EPOCH=2025-01-01T00:00:00Z).
|
||||
- `images/` directory with referenced container layers/blobs; `manifest.json` aligning with `index.json` (OCI image layout).
|
||||
- `signatures/` optional DSSE/TUF metadata if provided by 56-001.
|
||||
- Tarball is gzip-compressed with mtime pinned to `2025-01-01T00:00:00Z`, `0644` perms, uid/gid 0.
|
||||
- Checksums: `bootstrap-pack-v1.tar.sha256` with `sha256 bootstrap-pack-v1.tar` exactly.
|
||||
|
||||
## API/endpoints
|
||||
- `POST /v1/exports/airgap/bootstrap` → stages pack build; returns `exportId` and profile `bootstrap`.
|
||||
- `GET /v1/exports/airgap/bootstrap/{exportId}` → status + `downloadUri`, `rootHash`, `artifactSha256`.
|
||||
- `GET /v1/exports/airgap/bootstrap/{exportId}/download` → serves `application/gzip` tarball; `ETag` = SHA-256.
|
||||
- Auth scopes: `export:write` for POST; `export:read` for GET/Download.
|
||||
|
||||
## Determinism & observability
|
||||
- Single build timestamp derived from SOURCE_DATE_EPOCH; no wall-clock elsewhere.
|
||||
- Structured logs `{exportId, profile:"bootstrap", rootHash, artifactSha256}`; metrics `export.bootstrap.completed`, `export.bootstrap.duration_ms`.
|
||||
|
||||
## Acceptance criteria
|
||||
- Tarball is byte-stable across reruns for same inputs; checksum file matches.
|
||||
- Status/download endpoints documented with headers (`ETag`, `Last-Modified`, quota headers).
|
||||
- Bootstrap pack content references evidence/mirror bundles from 56-001 (by digest/URL) without re-signing.
|
||||
|
||||
## Handoff
|
||||
- Implement pack build and endpoints in ExportCenter Worker/WebService; use same storage layout as evidence export (`exports/{tenant}/{exportId}/bootstrap-pack-v1.tar`).
|
||||
- Update Sprint 0162 Delivery Tracker entry P3 to DONE when contract is published.
|
||||
@@ -0,0 +1,61 @@
|
||||
# Export AirGap Prep — PREP-EXPORT-AIRGAP-57-001
|
||||
|
||||
Status: **Ready for implementation** (2025-11-20)
|
||||
Owners: Exporter Service Guild · Evidence Locker Guild
|
||||
Scope: Portable evidence export mode (air-gap) that reuses EvidenceLocker sealed/portable bundles and packages them for ExportCenter delivery.
|
||||
|
||||
## Dependencies (must remain green before coding)
|
||||
- EvidenceLocker packaging contract (sealed + portable): `docs/modules/evidence-locker/bundle-packaging.md`, `docs/airgap/portable-evidence.md`.
|
||||
- Upstream sealed bundle export readiness (56-001) and bootstrap pack alignment (56-002) — inputs are reused verbatim, no re-signing.
|
||||
- Orchestrator/Notifications envelopes for emission events remain pending; not required to start packaging but block notification wiring.
|
||||
|
||||
## Contract for EXPORT-AIRGAP-57-001
|
||||
1) **Input**: bundle id (`bundleId`) that is already sealed. Export service fetches the portable archive `portable-bundle-v1.tgz` via the EvidenceLocker portable endpoint (write-once cache).
|
||||
2) **Packaging**: create deterministic gzip/tar (`export-portable-bundle-v1.tgz`) with fixed mtime `2025-01-01T00:00:00Z`, PAX headers, and sorted entries:
|
||||
```
|
||||
export-portable-bundle-v1.tgz
|
||||
├── export.json # Export job metadata (bundleId, exportId, tenant, createdAtUtc, rootHash, sourceUri, portableVersion)
|
||||
├── portable-bundle-v1.tgz # Bit-for-bit copy from EvidenceLocker (no re-signing)
|
||||
├── checksums.txt # SHA256 for all files (portable bundle included) + Merkle root
|
||||
├── verify-export.sh # POSIX script: checksum portable bundle, call `stella evidence verify --bundle portable-bundle-v1.tgz`
|
||||
└── README.md # Operator instructions (ingress/egress steps, expected headers, schema links)
|
||||
```
|
||||
- Gzip header mtime and tar mtimes are pinned; permissions `0644`; owner/group `0`.
|
||||
- `checksums.txt` lists files in lexical order; first line `root <sha256(export-portable-bundle-v1.tgz)>`.
|
||||
- `verify-export.sh` uses only `tar` + `sha256sum`/`shasum`; no network calls.
|
||||
|
||||
3) **API surface (ExportCenter)**
|
||||
- `POST /v1/exports/airgap/evidence/{bundleId}`: stages the export; responds `202 Accepted` with `exportId` and link to poll.
|
||||
- `GET /v1/exports/airgap/evidence/{exportId}`: returns status + download link when ready; includes `rootHash`, `portableVersion`, `bundleId`.
|
||||
- `GET /v1/exports/airgap/evidence/{exportId}/download`: `application/gzip`, filename `export-portable-bundle-v1.tgz`, ETag = SHA256.
|
||||
- Auth: `export:read` for GET, `export:write` for POST; support tenant scoping identical to EvidenceLocker.
|
||||
|
||||
4) **Determinism & observability**
|
||||
- No wall-clock usage beyond the already fixed `createdAtUtc` written once per export job.
|
||||
- Emit structured log `{exportId,bundleId,portableVersion,rootHash}` on completion.
|
||||
- Metrics: counter `export.airgap.portable.completed`, histogram `export.airgap.portable.duration_ms`, gauge `export.airgap.portable.queue_depth`.
|
||||
|
||||
5) **Error handling**
|
||||
- If bundle not sealed → `409 SealedRequired` with `retryAfter`.
|
||||
- If portable artefact missing → trigger fetch from EvidenceLocker; return `202` with `pendingReason=PortableMaterialising`.
|
||||
- Verification failures of copied bundle (hash mismatch) → mark export `FAILED` and keep artefact; require operator acknowledgement.
|
||||
|
||||
## Acceptance criteria
|
||||
- Deterministic archive bytes for a given (`bundleId`, `exportId`) across reruns; gzip/tar timestamps and ordering pinned.
|
||||
- Export archive contains the unmodified EvidenceLocker portable bundle and top-level instructions for offline operators.
|
||||
- CLI verification path documented in README and script; succeeds with no network access using current `stella evidence verify`.
|
||||
- Status/Download endpoints documented and cover `202/404/409/500` cases; ETag and `Last-Modified` set.
|
||||
|
||||
## Implementation notes for developers
|
||||
- Reuse EvidenceLocker’s `PortableBundleVersion` constant to avoid drift; do not unzip/repack the inner portable archive.
|
||||
- Populate `export.json` using UTC ISO-8601; include `sourceUri` referencing the original EvidenceLocker portable endpoint used.
|
||||
- Store artefacts under object key `exports/{tenant}/{bundleId}/{exportId}/export-portable-bundle-v1.tgz` with write-once semantics.
|
||||
- Mirror logging/metrics naming with 56-001/56-002 to ease dashboard reuse.
|
||||
|
||||
## Open items / risks
|
||||
- Notifications/timeline emission remains pending on Wave 150/140 envelope drop; add once schemas land (tracked separately).
|
||||
- If portable bundle version bumps to v2, archive filename and `portableVersion` must be updated in tandem.
|
||||
|
||||
## Handoff
|
||||
- This prep artefact is ready to implement in `src/ExportCenter/StellaOps.ExportCenter.WebService` job + `StellaOps.ExportCenter.Worker` for queue processing.
|
||||
- Link back to this document from Sprint 0162 Delivery Tracker entry P4.
|
||||
@@ -0,0 +1,58 @@
|
||||
# Export AirGap Prep — PREP-EXPORT-AIRGAP-58-001
|
||||
|
||||
Status: **Ready for implementation** (2025-11-20)
|
||||
Owners: Exporter Service Guild · Notifications Guild
|
||||
Scope: Emit deterministic notifications/timeline events when portable evidence export (57-001) completes, without requiring enclave connectivity.
|
||||
|
||||
## Dependencies
|
||||
- Portable export artefact from 57-001: `export-portable-bundle-v1.tgz` (contains `portable-bundle-v1.tgz`).
|
||||
- Notification envelope decisions in Wave 150/140 (orchestrator/notifications), but this prep provides a concrete payload to unblock implementation.
|
||||
- EvidenceLocker bundle contracts: `docs/modules/evidence-locker/bundle-packaging.md`, `docs/airgap/portable-evidence.md`.
|
||||
|
||||
## Event contract (v1)
|
||||
- **Subject / type**: `export.airgap.ready.v1`
|
||||
- **Channel**: NATS topic `export.airgap.ready.v1` and mirrored to optional webhooks (`application/json`). Transport must be retryable with backoff and DLQ.
|
||||
- **Payload (canonical key order shown)**:
|
||||
```json
|
||||
{
|
||||
"type": "export.airgap.ready.v1",
|
||||
"export_id": "...",
|
||||
"bundle_id": "...",
|
||||
"tenant_id": "...",
|
||||
"profile_id": "airgap-evidence",
|
||||
"portable_version": "v1",
|
||||
"root_hash": "sha256:...",
|
||||
"artifact_uri": "/v1/exports/airgap/evidence/{exportId}/download",
|
||||
"artifact_sha256": "...",
|
||||
"created_at": "2025-11-20T00:00:00Z",
|
||||
"expires_at": "2026-11-20T00:00:00Z",
|
||||
"metadata": {
|
||||
"source_uri": "/evidence/{bundleId}/portable",
|
||||
"portable_size_bytes": 0,
|
||||
"export_size_bytes": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
- Timestamps UTC, RFC3339; numeric sizes optional but deterministic when present.
|
||||
- `artifact_sha256` is the SHA-256 of `export-portable-bundle-v1.tgz`; `root_hash` is the Merkle root from `checksums.txt` (same as portable bundle root).
|
||||
- `expires_at` is optional; when omitted, receivers assume standard retention from EvidenceLocker policy.
|
||||
|
||||
## Determinism & delivery rules
|
||||
- Serialize JSON without whitespace changes that affect ordering; server must sort top-level keys alphabetically before emission.
|
||||
- When delivering via webhooks, include headers: `X-Stella-Event-Type`, `X-Stella-Signature` (HMAC-SHA256), `X-Stella-Sent-At` (UTC ISO-8601).
|
||||
- Retries: exponential backoff (1s, 2s, 4s, 8s, 16s) with maximum 5 attempts; failed deliveries go to DLQ topic `export.airgap.ready.dlq` with failure reason.
|
||||
|
||||
## API linkage
|
||||
- Notifications reference the download endpoint defined in 57-001: `GET /v1/exports/airgap/evidence/{exportId}/download`.
|
||||
- Optional timeline event mirror (`timeline.export.airgap.ready`) may be emitted once orchestrator envelope schema lands; payload mirrors the notification without headers.
|
||||
|
||||
## Acceptance criteria
|
||||
- Notification emits once per successful export; idempotent on replays (same `export_id` + hash).
|
||||
- Payload fields match the portable export artefact (hashes, URIs, versions) and require no further network calls for verification.
|
||||
- DLQ captures failed deliveries with reason and last response status.
|
||||
- Documentation of headers, payload, and retry guarantees is published for consuming guilds.
|
||||
|
||||
## Handoff
|
||||
- Implement emission in ExportCenter Worker when export job transitions to `Completed`.
|
||||
- Add webhook signature secret to configuration surface; default to disabled for air-gap unless explicitly allowed.
|
||||
- Link this document from Sprint 0162 Delivery Tracker entry P5.
|
||||
@@ -0,0 +1,50 @@
|
||||
# Export Attestation Prep — PREP-EXPORT-ATTEST-74-001
|
||||
|
||||
Status: **Ready for implementation** (2025-11-20)
|
||||
Owners: Attestation Bundle Guild · Exporter Service Guild
|
||||
Scope: Produce deterministic attestation export bundles for air-gap/offline delivery, leveraging EvidenceLocker DSSE layout and orchestrator events.
|
||||
|
||||
## Dependencies
|
||||
- EvidenceLocker packaging & DSSE conventions: `docs/modules/evidence-locker/bundle-packaging.md`.
|
||||
- Attestor air-gap guidance: `docs/modules/attestor/airgap.md` (statement + predicate expectations).
|
||||
- Orchestrator event envelopes (Wave 150/140) for optional timeline/notification mirrors; not required to start packaging.
|
||||
|
||||
## Export bundle contract (v1)
|
||||
- **Input**: attestation record id (`attestationId`) referencing a sealed DSSE statement (e.g., in-toto) stored by EvidenceLocker/Attestor.
|
||||
- **Packaging**: create deterministic gzip/tar `export-attestation-bundle-v1.tgz` with fixed mtime `2025-01-01T00:00:00Z`, PAX headers, `0644` perms, owner/group `0`.
|
||||
```
|
||||
export-attestation-bundle-v1.tgz
|
||||
├── attestation.dsse.json # Original DSSE envelope (statement + signature), unchanged
|
||||
├── statement.json # Extracted statement/predicate for quick inspection
|
||||
├── transparency.ndjson # Optional Rekor/CT entries (one per line, canonical JSON)
|
||||
├── metadata.json # exportId, attestationId, subject digests, rootHash, createdAtUtc, sourceUri
|
||||
├── checksums.txt # SHA256 hashes (lexical order); first line `root <sha256(export-attestation-bundle-v1.tgz)>`
|
||||
└── verify-attestation.sh # POSIX script: checksum, DSSE verify (invokes `stella attest verify` if available)
|
||||
```
|
||||
- No re-signing; DSSE envelope is copied bit-for-bit from source.
|
||||
- `transparency.ndjson` omitted when no log entries exist; maintain deterministic ordering otherwise.
|
||||
|
||||
## API surface (ExportCenter)
|
||||
- `POST /v1/exports/attestations/{attestationId}` → `202 Accepted` with `exportId`, `status=pending`.
|
||||
- `GET /v1/exports/attestations/{exportId}` → status + metadata (`rootHash`, `downloadUri`, `attestationDigests`).
|
||||
- `GET /v1/exports/attestations/{exportId}/download` → `application/gzip`, filename `export-attestation-bundle-v1.tgz`, `ETag`=SHA256.
|
||||
- Auth: `export:write` for POST, `export:read` for GET/Download; tenant scoped.
|
||||
|
||||
## Determinism & observability
|
||||
- All timestamps captured once at export creation (UTC ISO-8601) and reused; archive mtimes/gzip mtime pinned.
|
||||
- Structured log on completion `{exportId, attestationId, subjectDigests, rootHash}`; counter `export.attest.completed` and histogram `export.attest.duration_ms`.
|
||||
- Retries for fetch/pack errors use exponential backoff identical to 57-001 portable export.
|
||||
|
||||
## Acceptance criteria
|
||||
- Export archive is byte-identical across replays for the same (`attestationId`,`exportId`).
|
||||
- DSSE envelope and statement are unchanged relative to source; hashes in `checksums.txt` match download and DSSE payload.
|
||||
- API responses document 202/404/409/500 paths; `downloadUri` returns sealed artifact with deterministic ETag.
|
||||
- Verification script runs offline using only `tar` + `sha256sum`/`shasum`; optionally calls `stella attest verify` when present.
|
||||
|
||||
## Open items / risks
|
||||
- Notification/timeline emission pending envelope schema; add once Wave 150/140 lands.
|
||||
- If attestation format changes (predicate versions), bump `statementVersion` in `metadata.json` and announce.
|
||||
|
||||
## Handoff
|
||||
- Implement in `StellaOps.ExportCenter.Worker` export job + WebService endpoints above.
|
||||
- Link this document from Sprint 0162 entry P6 and close PREP when endpoints + packaging align.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Export Attestation Prep — PREP-EXPORT-ATTEST-74-002
|
||||
|
||||
Status: **Ready for implementation** (2025-11-20)
|
||||
Owners: Attestation Bundle Guild · DevOps Guild
|
||||
Scope: Integrate attestation export bundle job (74-001) into CI/offline kit packaging, publish checksums, and ensure deterministic artefact promotion.
|
||||
|
||||
## Dependencies
|
||||
- Export bundle contract v1 from 74-001: `docs/modules/export-center/prep/2025-11-20-export-attest-74-001-prep.md`.
|
||||
- EvidenceLocker/Attestor attestation format (DSSE) — no re-signing allowed.
|
||||
- Air-gap kit structure (mirror/bootstrap packs) from Sprint 160/56-002 for placement of attestation bundles.
|
||||
|
||||
## CI/offline kit integration contract
|
||||
- **Build step**: Invoke ExportCenter job for targeted `attestationId` and stage `export-attestation-bundle-v1.tgz` under `out/export/attestations/{exportId}/`.
|
||||
- **Checksum publication**: emit `export-attestation-bundle-v1.tgz.sha256` alongside the archive; contents `sha256 filename` with filename exactly `export-attestation-bundle-v1.tgz`.
|
||||
- **Offline kit layout**:
|
||||
```
|
||||
offline-kit/
|
||||
checksums/
|
||||
attestations/
|
||||
export-attestation-bundle-v1.tgz.sha256
|
||||
attestations/
|
||||
export-attestation-bundle-v1.tgz
|
||||
```
|
||||
- **Promotion**: artefacts are immutable; CI publishes to `out/export/offline-kits/{kitVersion}/` with write-once semantics. Promotion between environments copies bytes; no rebuilds.
|
||||
- **Metadata**: append to `out/export/offline-kits/{kitVersion}/manifest.json`:
|
||||
```json
|
||||
{
|
||||
"kind": "attestation-export",
|
||||
"exportId": "...",
|
||||
"attestationId": "...",
|
||||
"rootHash": "sha256:...",
|
||||
"artifact": "attestations/export-attestation-bundle-v1.tgz",
|
||||
"checksum": "checksums/attestations/export-attestation-bundle-v1.tgz.sha256",
|
||||
"createdAt": "2025-11-20T00:00:00Z"
|
||||
}
|
||||
```
|
||||
- **Determinism**: CI must set `SOURCE_DATE_EPOCH=1735689600` (2025-01-01T00:00:00Z) for any tar/gzip operations when re-wrapping kits; do not re-tar the inner export bundle.
|
||||
|
||||
## Acceptance criteria
|
||||
- Export bundle generated by 74-001 is copied bit-for-bit into the offline kit; SHA256 in checksums file matches archive and `manifest.json` entry.
|
||||
- Kit manifest contains the attestation entry with UTC timestamp and root hash; promotion produces identical bytes across runs.
|
||||
- CI logs include the exportId and SHA256; failures stop the pipeline and do not overwrite prior artefacts.
|
||||
|
||||
## Handoff
|
||||
- Wire CI/packaging scripts in ExportCenter DevOps pipeline to consume the 74-001 export endpoint and assemble offline kit layout above.
|
||||
- Update Sprint 0162 Delivery Tracker entry P7 with status changes when implemented.
|
||||
@@ -0,0 +1,44 @@
|
||||
# Export Attestation Prep — PREP-EXPORT-ATTEST-75-001
|
||||
|
||||
Status: **Ready for implementation** (2025-11-20)
|
||||
Owners: Attestation Bundle Guild · CLI Attestor Guild
|
||||
Scope: Define CLI contract for verifying/importing attestation export bundles (from 74-002) in offline/air-gap environments.
|
||||
|
||||
## Dependencies
|
||||
- Attestation export bundle layout: `docs/modules/export-center/prep/2025-11-20-export-attest-74-001-prep.md` and CI/offline kit integration `...-74-002-prep.md`.
|
||||
- EvidenceLocker/Attestor verification library (`stella attest verify`).
|
||||
|
||||
## CLI experience
|
||||
- New command: `stella attest bundle verify --file export-attestation-bundle-v1.tgz`
|
||||
- Validates SHA256 against co-located `.sha256` file (see 74-002).
|
||||
- Runs DSSE verification using bundled statement/signature; prints subject digests, predicate type/version, and root hash.
|
||||
- Exit codes: 0 success, 2 checksum mismatch, 3 DSSE signature failure, 4 missing TSA/log when required, >4 unexpected error.
|
||||
- New command: `stella attest bundle import --file export-attestation-bundle-v1.tgz`
|
||||
- Performs verification first; then registers the attestation in the local/offline EvidenceLocker (when configured) and outputs new `attestationId`/`tenant` reference.
|
||||
- Supports `--tenant`, `--namespace` flags; defaults to current CLI profile.
|
||||
- No network calls beyond optional TSA/CT validations; provide `--offline` to skip.
|
||||
|
||||
## Determinism and I/O
|
||||
- CLI must avoid rewriting the archive; reads-only.
|
||||
- Output logs in JSON when `--output json` is passed, with stable key order:
|
||||
```json
|
||||
{
|
||||
"status": "verified",
|
||||
"exportId": "...",
|
||||
"attestationId": "...",
|
||||
"rootHash": "sha256:...",
|
||||
"subjects": ["sha256:..."],
|
||||
"predicateType": "slsa/v1",
|
||||
"bundlePath": "export-attestation-bundle-v1.tgz"
|
||||
}
|
||||
```
|
||||
- Human-readable output includes root hash, subject digests, predicate type/version, and trust root used.
|
||||
|
||||
## Acceptance criteria
|
||||
- CLI verifies bundles generated by 74-002 using only local artefacts; succeeds offline when `--offline` is used.
|
||||
- Import command registers attestation locally without modifying archive; errors if checksum/signature fail.
|
||||
- Exit codes and JSON schema documented for automation; tests cover checksum mismatch and invalid signature cases.
|
||||
|
||||
## Handoff
|
||||
- Implement commands in `src/Cli/StellaOps.Cli` (attestor plugin) and add docs/examples to `docs/modules/cli/artefacts/guardrails-artefacts-2025-11-19.md` or a new CLI guide.
|
||||
- Link back to this prep in Sprint 0162 Delivery Tracker entry P8.
|
||||
@@ -0,0 +1,35 @@
|
||||
# Export Attestation Prep — PREP-EXPORT-ATTEST-75-002
|
||||
|
||||
Status: **Ready for implementation** (2025-11-20)
|
||||
Owners: Exporter Service Guild
|
||||
Scope: Wire attestation export bundles (74-002) + CLI workflows (75-001) into full offline kit and mirror bundle distribution flows.
|
||||
|
||||
## Dependencies
|
||||
- 74-001/74-002 bundle + kit layout.
|
||||
- CLI verify/import contract: `docs/modules/export-center/prep/2025-11-20-export-attest-75-001-prep.md`.
|
||||
|
||||
## Distribution/kit contract
|
||||
- Place attestation bundles and checksum files into offline kit (same layout as 74-002) and publish to mirror locations used by ExportCenter air-gap profiles.
|
||||
- Provide `manifest-offline.json` entry per kit:
|
||||
```json
|
||||
{
|
||||
"kind": "attestation-kit",
|
||||
"kitVersion": "v1",
|
||||
"artifact": "attestations/export-attestation-bundle-v1.tgz",
|
||||
"checksum": "checksums/attestations/export-attestation-bundle-v1.tgz.sha256",
|
||||
"cliExample": "stella attest bundle verify --file attestations/export-attestation-bundle-v1.tgz",
|
||||
"importExample": "stella attest bundle import --file attestations/export-attestation-bundle-v1.tgz --offline",
|
||||
"rootHash": "sha256:...",
|
||||
"createdAt": "2025-11-20T00:00:00Z"
|
||||
}
|
||||
```
|
||||
- Copy the kit directory to mirror/air-gap repo: `mirror/export/attestations/{kitVersion}/` with same bytes; publish `manifest-offline.json` and `.sha256` for the manifest.
|
||||
|
||||
## Acceptance criteria
|
||||
- Offline kit includes attestation bundle + checksum + manifest entries; hashes match originals from 74-002.
|
||||
- Mirrors deliver identical bytes (bit-for-bit) across environments; manifests list CLI commands for operators.
|
||||
- No rebuild of attestation bundle during distribution; only copies allowed.
|
||||
|
||||
## Handoff
|
||||
- Implement packaging/copy steps in ExportCenter build pipeline and mirror publisher.
|
||||
- Update Sprint 0162 Delivery Tracker entry P9 when complete.
|
||||
@@ -0,0 +1,54 @@
|
||||
# ExportCenter OAS Prep — PREP-EXPORT-OAS-61-001
|
||||
|
||||
Status: **Ready for implementation** (2025-11-20)
|
||||
Owners: Exporter Service Guild · API Contracts Guild
|
||||
Scope: Freeze ExportCenter v1 OpenAPI surface (profiles/runs/downloads) with deterministic headers, ETag/versioning, and standard error envelope.
|
||||
|
||||
## Design targets
|
||||
- Cover the baseline export capabilities required for Wave 160.B: air-gap evidence exports, attestation exports, mirror/bootstrap exports, and discovery.
|
||||
- Keep payloads deterministic; avoid wall-clock dependence outside stamped fields returned by the service.
|
||||
- Provide strong cache/discovery signals: `ETag`, `Last-Modified`, `Cache-Control: private, must-revalidate`, plus `/.well-known/openapi` entry.
|
||||
|
||||
## Paths to include in v1 spec
|
||||
- `GET /.well-known/openapi` — returns OpenAPI document with `ETag` and `X-Export-Oas-Version` (value `v1`).
|
||||
- Evidence exports (portable bundles):
|
||||
- `POST /v1/exports/airgap/evidence/{bundleId}` → `202 Accepted` with `exportId`, `status=pending`.
|
||||
- `GET /v1/exports/airgap/evidence/{exportId}` → status document (`status`, `rootHash`, `artifactSha256`, `portableVersion`, `downloadUri`).
|
||||
- `GET /v1/exports/airgap/evidence/{exportId}/download` → `application/gzip`, filename `export-portable-bundle-v1.tgz`, `ETag` = archive SHA-256.
|
||||
- Attestation exports:
|
||||
- `POST /v1/exports/attestations/{attestationId}` → `202 Accepted` with `exportId`.
|
||||
- `GET /v1/exports/attestations/{exportId}` → status + `downloadUri`, `rootHash`, `statementDigest`.
|
||||
- `GET /v1/exports/attestations/{exportId}/download` → `application/gzip`, filename `export-attestation-bundle-v1.tgz`, `ETag` = archive SHA-256.
|
||||
- Mirror/bootstrap (profiles only, no payload schema change):
|
||||
- `GET /v1/exports/profiles` — lists available export profiles (e.g., `mirror`, `bootstrap`, `airgap-evidence`, `attestation`). Supports pagination (`limit`, `cursor`) and filtering by `kind`.
|
||||
- `GET /v1/exports/runs` — list export runs with status filters, tenant scoping, paging.
|
||||
- Observability hooks (metadata only):
|
||||
- `GET /v1/exports/runs/{exportId}/events` — optional timeline/event stream pointer (when notifications enabled). Can remain `x-stub: true` until envelopes land.
|
||||
|
||||
## Components
|
||||
- **Schemas**
|
||||
- `ExportStatus`: `{ exportId, profileId, status: pending|running|completed|failed, artifactSha256, rootHash, portableVersion?, attestationId?, bundleId?, createdAt, completedAt?, downloadUri }`
|
||||
- `ExportProfile`: `{ id, kind, description, version, retentionDays }`
|
||||
- `ErrorEnvelope`: `{ error: { code, message, correlationId, retryAfterSeconds? } }` with deterministic key order.
|
||||
- **Security**
|
||||
- OAuth2 client credentials; scopes: `export:write` (POST), `export:read` (GET/Download). Tenants enforced via claims.
|
||||
- **Headers**
|
||||
- `ETag` on all download/status responses; `Last-Modified` on status/download reflecting deterministic creation time.
|
||||
- Quota headers `X-Stella-Quota-*` retained for consistency with EvidenceLocker/ExportCenter.
|
||||
|
||||
## Versioning & determinism
|
||||
- OAS document served with `version: 1.0.0` and `x-stella-oas-revision` (UTC date string). No inline examples with non-deterministic timestamps; examples use `2025-01-01T00:00:00Z`.
|
||||
- All example hashes use fixed placeholder `sha256:0123...deadbeef` to keep docs repeatable.
|
||||
|
||||
## Deliverables
|
||||
- Publish OpenAPI YAML at `docs/modules/export-center/openapi/export-center.v1.yaml` matching the paths/schemas above.
|
||||
- Link the `.yaml` from Sprint 0162 Delivery Tracker P10 and set status to DONE once published.
|
||||
|
||||
## Acceptance criteria
|
||||
- All listed endpoints present in the YAML with request/response schemas and security scopes.
|
||||
- Deterministic examples (fixed timestamps/hashes) and `ETag`/`Last-Modified` response headers documented.
|
||||
- `/.well-known/openapi` discovery endpoint described with `ETag` and version headers.
|
||||
|
||||
## Next steps
|
||||
- Generate the YAML (can seed from EvidenceLocker/Orchestrator style) and check into `docs/modules/export-center/openapi/export-center.v1.yaml`.
|
||||
- Update SDK generator task (62-001) to depend on this OAS once merged.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Export OAS Discovery Prep — PREP-EXPORT-OAS-61-002-DEPENDS-ON-61-001
|
||||
|
||||
Status: Draft (2025-11-20)
|
||||
Owners: Exporter Service Guild
|
||||
Scope: Define the OpenAPI discovery endpoint once base OAS (61-001) is frozen.
|
||||
|
||||
## Requirements
|
||||
- Endpoint: `GET /.well-known/openapi` (and `.json` alias) returning latest Exporter OAS.
|
||||
- Headers: `ETag`, `Last-Modified`, `Cache-Control: public, max-age=300`; support `If-None-Match` for 304.
|
||||
- Body: JSON with fields `{version, oas_url, checksum_sha256, generated_at, profiles_supported}` plus embedded OAS or link.
|
||||
- Determinism: stable ordering of fields; checksum over canonical OAS JSON.
|
||||
|
||||
## Acceptance
|
||||
- Once 61-001 OAS is fixed, publish generated OAS path and checksum into this doc and `docs/modules/export-center/api.md`.
|
||||
- Add sample discovery response at `docs/events/samples/export-center.openapi.discovery@draft.json`.
|
||||
|
||||
## Handoff
|
||||
Use this as the prep artefact for PREP-EXPORT-OAS-61-002-DEPENDS-ON-61-001. Update checksums/links when 61-001 finalizes, then mark implementation DOING.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Export SDK Prep — PREP-EXPORT-OAS-62-001-DEPENDS-ON-61-002
|
||||
|
||||
Status: Draft (2025-11-20)
|
||||
Owners: Exporter Service Guild · SDK Generator Guild
|
||||
Scope: Capture SDK generation requirements once discovery endpoint (61-002) is live.
|
||||
|
||||
## Requirements
|
||||
- Inputs: stable OAS from 61-001, discovery metadata from 61-002.
|
||||
- SDKs: Go, Python, C#, TypeScript. Must include streaming helpers for export downloads and polling helpers for long-running export jobs.
|
||||
- Versioning: embed `x-sdk-version` matching OAS `version`; regenerate only on checksum change.
|
||||
- Tests: smoke tests per SDK calling stubbed endpoints; deterministic snapshots for generated code hashes.
|
||||
|
||||
## Acceptance
|
||||
- Record generated SDK artifact paths and checksums in this doc and `docs/modules/export-center/api.md`.
|
||||
- Provide sample snippet paths under `docs/modules/export-center/samples/sdk/` per language.
|
||||
|
||||
## Handoff
|
||||
Use this as the prep artefact for PREP-EXPORT-OAS-62-001-DEPENDS-ON-61-002. Update with actual checksums/paths after 61-002 and SDK generation are completed; then move implementation to DOING.
|
||||
@@ -0,0 +1,18 @@
|
||||
# EvidenceLocker Contract Blocker Prep — PREP-EXPORTER-SERVICE-EVIDENCELOCKER-GUILD-BL
|
||||
|
||||
Status: Draft (2025-11-20)
|
||||
Owners: Planning · Exporter Service Guild · EvidenceLocker Guild
|
||||
Scope: Document the blocker awaiting EvidenceLocker sealed bundle contract before ExportCenter implementation can proceed.
|
||||
|
||||
## Blocking items
|
||||
- Sealed bundle schema/hash and DSSE layout from EvidenceLocker (Sprint 161).
|
||||
- Sample sealed bundle + manifest checksum for DevPortal CLI dry run.
|
||||
- Trust-root publication path and rotation policy aligned with `docs/security/crypto-registry-decision-2025-11-18.md`.
|
||||
|
||||
## Ready-to-start criteria
|
||||
- Hash/version of sealed bundle schema recorded here and in Sprint 161 Decisions.
|
||||
- Sample bundle placed under `docs/samples/export-center/bundles/` with SHA256 + DSSE envelope.
|
||||
- Exporter service ingestion contract updated in `docs/modules/export-center/profiles.md`.
|
||||
|
||||
## Handoff
|
||||
Use this document as the prep artefact for PREP-EXPORTER-SERVICE-EVIDENCELOCKER-GUILD-BL. Update once EvidenceLocker provides schema hash and sample bundle; then unblock export tasks. If not available by the next checkpoint, keep dependent tasks BLOCKED and escalate via Sprint 160/161.
|
||||
Reference in New Issue
Block a user