docs/security-release.md
Rama main · réplica de lectura del repositorio original.
# Pre-release security hardening matrix
Reviewed for the `0.1.0-rc.3` closeout line on 2026-09-30.
This matrix records concrete pre-release controls. A checked item means the control exists in code/tests or is intentionally documented. Final stable-release readiness still depends on green PR CI and the owner's clean-install operator acceptance gate against the current candidate.
## Public transport and identity
- [x] HTTPS required for the supported public path.
- [x] OAuth/OIDC discovery validated before ChatGPT connection.
- [x] RFC 9728 protected-resource metadata published.
- [x] Dynamic Client Registration enabled only on the dedicated identity project.
- [x] PKCE S256 advertised and checked.
- [x] dedicated MCP resource audience required.
- [x] private RFC 7662 token introspection used by Gateway.
- [x] stable subject revalidated by Broker.
- [x] invalid/inactive access token rejected.
- [x] expired access token rejected by regression test.
- [x] wrong issuer rejected.
- [x] wrong audience rejected.
- [x] revoked/inactive access tokens are rejected from RFC 7662 introspection state; ZITADEL documents revoked tokens as inactive at introspection.
- [x] unauthenticated MCP returns fail-closed 401 with OAuth resource challenge.
- [x] DCR and OAuth endpoints have edge rate limiting.
- [x] application-level concurrent request ceiling exists (default 64; excess requests fail with HTTP 429).
- [x] MCP request bodies are capped at 1 MiB and Broker IPC decoding is capped at 2 MiB.
- [ ] E2E2 candidate pins ZITADEL API + Login V2 to patched `v4.19.4` with a persistent signing key of at least 32 characters. Promotion requires disposable integrated OAuth/HTTPS validation; the VPS version is not established by this candidate.
## Privilege boundary
- [x] Gateway runs non-root.
- [x] Gateway does not receive `/host`.
- [x] Gateway does not receive Docker socket.
- [x] Broker is local-only over Unix domain socket.
- [x] Broker validates Unix peer credentials with `SO_PEERCRED`.
- [x] package acceptance proves that a process with socket group access but the wrong UID is rejected before Broker request handling.
- [x] Broker owns privileged SQLite.
- [x] Broker re-authorizes subject + tool + resource + action.
- [x] Scoped is default.
- [x] Whole Host is a separate physical-mount decision.
- [x] Full is disabled by default.
- [x] unrestricted network remains separate from Full.
## Files, jobs and replay
- [x] path traversal negative tests.
- [x] symlink escape negative tests.
- [x] recursive removal does not follow symlink escapes.
- [x] move/rename through a symlink directory outside the root is denied.
- [x] concurrent file↔symlink swap attempts never return outside-root content.
- [x] hardlink unlink semantics are covered so removal inside an authorized root does not alter the outside hardlink name/content.
- [x] physical scope root canonicalization.
- [x] sandboxed scoped shell/jobs.
- [x] runtime/output/task/memory limits.
- [x] operation journal and idempotency semantics.
- [x] fencing-token resource locks.
- [x] revoke-all invalidates grants and pending approvals and cancels grant-backed jobs.
- [x] non-replay-safe operations are not blindly retried.
- [x] network allowlist mode fails closed in the sandbox until hostname/IP egress enforcement is implemented; unrestricted egress remains a separate explicit authority.
## Secrets, logs and privacy
- [x] repository secret scan with gitleaks.
- [x] repository-wide development-artifact sanitization guard.
- [x] gosec source scan.
- [x] govulncheck.
- [x] bounded Go fuzzing for secure filesystem root selection and policy parsing.
- [x] high-volume adversarial architecture simulation for grants, replay and locking.
- [x] image vulnerability scan with Trivy in package acceptance.
- [x] diagnostic bundle secret redaction and CI leakage checks.
- [x] first-party analytics/tracking absent.
- [x] bundled ZITADEL telemetry explicitly disabled.
- [x] user documentation forbids sharing VPS/SSH credentials.
- [x] privacy/data-location documentation exists.
## Release supply chain
- [x] SemVer `VERSION` file.
- [x] release tag must equal `v$VERSION`.
- [x] source release artifact has SHA-256 checksum.
- [x] GHCR release images build for amd64/arm64.
- [x] release images request BuildKit SBOM/provenance attestations.
- [x] the release workflow keyless-signs future release images and source artifacts with Sigstore/cosign using GitHub Actions OIDC, and immediately verifies the resulting signatures/bundles.
- [x] signing identity is bound to this repository's release workflow plus the GitHub Actions OIDC issuer; no long-lived private signing key is stored as a repository secret.
- [ ] already-published RC artifacts pre-dating this workflow remain unsigned; the next candidate must exercise the signing path before stable promotion.
## Maturity boundaries
- [x] Scoped is the supported product path.
- [x] real ChatGPT Web + integrated OAuth completion gate has been exercised.
- [x] Full/R5 is not presented as production-ready.
- [ ] long-running real-workload reliability remains a later R4 maturity requirement.
- [ ] final clean-install operator acceptance gate remains owner-operated and must pass before `v0.1.0` is frozen.