rcf-lite 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +2 -0
- package/bin/view-supervisor-child.mjs +0 -0
- package/blueprints/application-api-rest/README.md +40 -0
- package/blueprints/application-api-rest/assets/middleware/auth-classes.md +45 -0
- package/blueprints/application-api-rest/assets/openapi/openapi-skeleton.yaml +322 -0
- package/blueprints/application-api-rest/assets/sample-data/sample-resources.json +53 -0
- package/blueprints/application-api-rest/assets/samples/request-response-pairs.md +204 -0
- package/blueprints/application-api-rest/blueprint.json +265 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-301-application-api-rest-error-envelope.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-302-application-api-rest-auth-model.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-303-application-api-rest-api-versioning.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-304-application-api-rest-logging.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-305-application-api-rest-pagination.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-306-application-api-rest-idempotency.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-307-application-api-rest-openapi-generation.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-308-application-api-rest-rate-limiting.json +25 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-001.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-002.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-003.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-004.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-005.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-006.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-007.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-008.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-009.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-010.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-011.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-012.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-013.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-014.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-015.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-016.json +18 -0
- package/blueprints/application-api-rest/contributions/tacs/tac-301-application-api-rest-request-pipeline.json +48 -0
- package/blueprints/application-api-rest/contributions/tacs/tac-302-application-api-rest-auth-middleware.json +41 -0
- package/blueprints/application-api-rest/contributions/tacs/tac-303-application-api-rest-contract-surface.json +46 -0
- package/blueprints/application-api-rest/contributions/tacs/tac-304-application-api-rest-resource-layer.json +46 -0
- package/blueprints/application-api-rest/contributions/tacs/tac-305-application-api-rest-observability.json +40 -0
- package/blueprints/application-api-rest/contributions/tacs/tac-306-application-api-rest-operability.json +46 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2101.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2102.json +73 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2103.json +63 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2104.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2105.json +63 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2106.json +73 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2107.json +90 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2108.json +90 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2109.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2110.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2111.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2112.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2113.json +73 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2114.json +63 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2115.json +63 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2116.json +63 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2117.json +64 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2118.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2119.json +63 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2120.json +73 -0
- package/blueprints/application-api-rest/docs/topics.md +46 -0
- package/blueprints/application-api-rest/guide/application-api-rest.md +41 -0
- package/blueprints/application-spa/README.md +90 -0
- package/blueprints/application-spa/assets/component-specs/actions-and-text-inputs.md +36 -0
- package/blueprints/application-spa/assets/component-specs/data-display.md +19 -0
- package/blueprints/application-spa/assets/component-specs/feedback-and-status.md +27 -0
- package/blueprints/application-spa/assets/component-specs/overlays.md +23 -0
- package/blueprints/application-spa/assets/component-specs/selection-controls.md +23 -0
- package/blueprints/application-spa/assets/sample-data/sample-entities.json +41 -0
- package/blueprints/application-spa/assets/tokens/design-tokens.json +140 -0
- package/blueprints/application-spa/assets/tokens/theme.css +169 -0
- package/blueprints/application-spa/assets/viewports.md +18 -0
- package/blueprints/application-spa/assets/wireframes/dashboard.md +48 -0
- package/blueprints/application-spa/assets/wireframes/detail.md +40 -0
- package/blueprints/application-spa/assets/wireframes/empty.md +31 -0
- package/blueprints/application-spa/assets/wireframes/error.md +46 -0
- package/blueprints/application-spa/assets/wireframes/form.md +50 -0
- package/blueprints/application-spa/assets/wireframes/list.md +45 -0
- package/blueprints/application-spa/assets/wireframes/session-expired.md +35 -0
- package/blueprints/application-spa/assets/wireframes/sign-in.md +41 -0
- package/blueprints/application-spa/assets/wireframes/sign-out.md +32 -0
- package/blueprints/application-spa/blueprint.json +387 -0
- package/blueprints/application-spa/contributions/adrs/adr-201-application-spa-routing.json +25 -0
- package/blueprints/application-spa/contributions/adrs/adr-202-application-spa-theming.json +25 -0
- package/blueprints/application-spa/contributions/adrs/adr-203-application-spa-client-state.json +25 -0
- package/blueprints/application-spa/contributions/adrs/adr-204-application-spa-error-envelope.json +25 -0
- package/blueprints/application-spa/contributions/adrs/adr-205-application-spa-auth-model.json +25 -0
- package/blueprints/application-spa/contributions/adrs/adr-206-application-spa-iconography.json +13 -0
- package/blueprints/application-spa/contributions/adrs/adr-207-application-spa-motion.json +13 -0
- package/blueprints/application-spa/contributions/adrs/adr-208-application-spa-i18n.json +13 -0
- package/blueprints/application-spa/contributions/adrs/adr-209-application-spa-telemetry-naming.json +13 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-001.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-002.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-003.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-004.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-005.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-006.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-007.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-008.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-009.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-010.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-011.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-012.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-013.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-014.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-015.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-016.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-017.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-018.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-019.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-020.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-021.json +18 -0
- package/blueprints/application-spa/contributions/tacs/tac-201-application-spa-app-shell.json +45 -0
- package/blueprints/application-spa/contributions/tacs/tac-202-application-spa-theme-system.json +32 -0
- package/blueprints/application-spa/contributions/tacs/tac-203-application-spa-component-library.json +32 -0
- package/blueprints/application-spa/contributions/tacs/tac-204-application-spa-client-data-layer.json +27 -0
- package/blueprints/application-spa/contributions/tacs/tac-205-application-spa-forms-engine.json +27 -0
- package/blueprints/application-spa/contributions/tacs/tac-206-application-spa-telemetry.json +19 -0
- package/blueprints/application-spa/contributions/tacs/tac-207-application-spa-token-adherence-probe.json +57 -0
- package/blueprints/application-spa/contributions/tacs/tac-208-application-spa-icon-adherence-probe.json +56 -0
- package/blueprints/application-spa/contributions/tacs/tac-209-application-spa-csp-styled-adherence-probe.json +61 -0
- package/blueprints/application-spa/contributions/tacs/tac-210-application-spa-external-dependency-provisioning-probe.json +70 -0
- package/blueprints/application-spa/contributions/tacs/tac-211-application-spa-core-flow-e2e-probe.json +70 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1101.json +72 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1102.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1103.json +72 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1104.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1105.json +69 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1106.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1107.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1108.json +90 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1109.json +90 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1110.json +100 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1111.json +90 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1112.json +81 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1113.json +82 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1114.json +60 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1115.json +73 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1116.json +72 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1117.json +73 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1118.json +54 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1119.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1120.json +72 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1121.json +73 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1122.json +69 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1123.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1124.json +60 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1125.json +69 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1126.json +78 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1127.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1128.json +51 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1129.json +54 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1130.json +54 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1131.json +72 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1132.json +72 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1133.json +72 -0
- package/blueprints/application-spa/docs/topics.md +57 -0
- package/blueprints/application-spa/guide/application-spa.md +40 -0
- package/blueprints/ci-pipeline/README.md +49 -0
- package/blueprints/ci-pipeline/assets/ci-provider-examples/github-actions.yml +61 -0
- package/blueprints/ci-pipeline/assets/ci-provider-examples/notes.md +50 -0
- package/blueprints/ci-pipeline/assets/report-samples/per-gate.json +12 -0
- package/blueprints/ci-pipeline/assets/report-samples/pipeline.json +28 -0
- package/blueprints/ci-pipeline/blueprint.json +46 -0
- package/blueprints/ci-pipeline/contributions/adrs/adr-701-ci-pipeline-ci-gates.json +25 -0
- package/blueprints/ci-pipeline/contributions/adrs/adr-702-ci-pipeline-strict-coverage-gate.json +25 -0
- package/blueprints/ci-pipeline/contributions/adrs/adr-703-ci-pipeline-node-only-runner.json +25 -0
- package/blueprints/ci-pipeline/contributions/adrs/adr-704-ci-pipeline-report-shape.json +25 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-001.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-002.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-003.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-004.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-005.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-006.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-007.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-008.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-009.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-010.json +18 -0
- package/blueprints/ci-pipeline/contributions/tacs/tac-701-ci-pipeline-gate-runner.json +59 -0
- package/blueprints/ci-pipeline/contributions/tacs/tac-702-ci-pipeline-gate-report.json +32 -0
- package/blueprints/ci-pipeline/contributions/tacs/tac-703-ci-pipeline-aggregate-report.json +41 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6101.json +37 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6102.json +36 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6103.json +37 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6104.json +37 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6105.json +36 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6106.json +36 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6107.json +37 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6108.json +37 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6109.json +36 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6110.json +36 -0
- package/blueprints/ci-pipeline/docs/topics.md +49 -0
- package/blueprints/ci-pipeline/guide/ci-pipeline.md +79 -0
- package/blueprints/deploy-cloudflare-workers/README.md +63 -0
- package/blueprints/deploy-cloudflare-workers/assets/ci-workflows/build-and-upload.yml.md +109 -0
- package/blueprints/deploy-cloudflare-workers/assets/ci-workflows/promote.yml.md +120 -0
- package/blueprints/deploy-cloudflare-workers/assets/verification/served-surface-probes.md +90 -0
- package/blueprints/deploy-cloudflare-workers/assets/wrangler-samples/bootstrap-vs-steady-state.md +87 -0
- package/blueprints/deploy-cloudflare-workers/assets/wrangler-samples/preview-alias-shape.md +86 -0
- package/blueprints/deploy-cloudflare-workers/assets/wrangler-samples/wrangler-toml-shape.md +85 -0
- package/blueprints/deploy-cloudflare-workers/blueprint.json +48 -0
- package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1301-deploy-cloudflare-workers-deployment-target.json +30 -0
- package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1302-deploy-cloudflare-workers-default-vendor.json +35 -0
- package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1303-deploy-cloudflare-workers-preview-vs-production.json +30 -0
- package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1304-deploy-cloudflare-workers-rollback-is-promote.json +25 -0
- package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1305-deploy-cloudflare-workers-dev-mode-drift.json +25 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-001.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-002.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-003.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-004.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-005.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-006.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-007.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-008.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-009.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-010.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-011.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-012.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1301-deploy-cloudflare-workers-deploy-adapter.json +54 -0
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1302-deploy-cloudflare-workers-wrangler-manifest.json +45 -0
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1303-deploy-cloudflare-workers-preview-url-resolver.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1304-deploy-cloudflare-workers-promote-gate.json +57 -0
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1305-deploy-cloudflare-workers-served-surface-verifier.json +51 -0
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1306-deploy-cloudflare-workers-deploy-ci-workflows.json +64 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12101.json +54 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12102.json +45 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12103.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12104.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12105.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12106.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12107.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12108.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12109.json +47 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12110.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12111.json +45 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12112.json +46 -0
- package/blueprints/deploy-cloudflare-workers/docs/topics.md +46 -0
- package/blueprints/deploy-cloudflare-workers/guide/deploy-cloudflare-workers.md +74 -0
- package/blueprints/email-smtp-resend/README.md +45 -0
- package/blueprints/email-smtp-resend/assets/from-address-rotation-pattern.md +44 -0
- package/blueprints/email-smtp-resend/assets/resend-verification-pointer.md +25 -0
- package/blueprints/email-smtp-resend/assets/stub-adapter.md +65 -0
- package/blueprints/email-smtp-resend/blueprint.json +23 -0
- package/blueprints/email-smtp-resend/contributions/adrs/adr-401-email-smtp-resend-transport-choice.json +30 -0
- package/blueprints/email-smtp-resend/contributions/adrs/adr-402-email-smtp-resend-retry-and-backoff-posture.json +30 -0
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-001.json +18 -0
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-002.json +18 -0
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-003.json +18 -0
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-004.json +18 -0
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-005.json +18 -0
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-006.json +18 -0
- package/blueprints/email-smtp-resend/contributions/tacs/tac-401-email-smtp-resend-send-adapter.json +53 -0
- package/blueprints/email-smtp-resend/contributions/tacs/tac-402-email-smtp-resend-webhook-verifier.json +56 -0
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4101.json +45 -0
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4102.json +36 -0
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4103.json +45 -0
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4104.json +45 -0
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4105.json +36 -0
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4106.json +37 -0
- package/blueprints/email-smtp-resend/docs/topics.md +44 -0
- package/blueprints/email-smtp-resend/guide/email-smtp-resend.md +71 -0
- package/blueprints/observability-essentials/README.md +53 -0
- package/blueprints/observability-essentials/assets/probe-samples/liveness-body.json +4 -0
- package/blueprints/observability-essentials/assets/probe-samples/readiness-body.json +18 -0
- package/blueprints/observability-essentials/assets/status-page-samples/status-page-clean.html +22 -0
- package/blueprints/observability-essentials/assets/status-page-samples/status-page-with-notice.html +25 -0
- package/blueprints/observability-essentials/blueprint.json +54 -0
- package/blueprints/observability-essentials/contributions/adrs/adr-801-observability-essentials-health-probes.json +30 -0
- package/blueprints/observability-essentials/contributions/adrs/adr-802-observability-essentials-readiness-semantics.json +30 -0
- package/blueprints/observability-essentials/contributions/adrs/adr-803-observability-essentials-status-page-contract.json +30 -0
- package/blueprints/observability-essentials/contributions/adrs/adr-804-observability-essentials-probe-secrecy.json +25 -0
- package/blueprints/observability-essentials/contributions/adrs/adr-805-observability-essentials-notification-outcome-model.json +25 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-001.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-002.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-003.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-004.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-005.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-006.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-007.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-008.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-009.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-010.json +18 -0
- package/blueprints/observability-essentials/contributions/tacs/tac-801-observability-essentials-liveness-probe.json +32 -0
- package/blueprints/observability-essentials/contributions/tacs/tac-802-observability-essentials-readiness-probe.json +43 -0
- package/blueprints/observability-essentials/contributions/tacs/tac-803-observability-essentials-status-page.json +37 -0
- package/blueprints/observability-essentials/contributions/tacs/tac-804-observability-essentials-notification-outcome.json +42 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7101.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7102.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7103.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7104.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7105.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7106.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7107.json +46 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7108.json +47 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7109.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7110.json +46 -0
- package/blueprints/observability-essentials/docs/topics.md +57 -0
- package/blueprints/observability-essentials/guide/observability-essentials.md +68 -0
- package/blueprints/observability-probe-endpoints/README.md +53 -0
- package/blueprints/observability-probe-endpoints/assets/docker/dockerfile-healthcheck.md +19 -0
- package/blueprints/observability-probe-endpoints/assets/kubernetes/podspec-probes-separate-port.md +54 -0
- package/blueprints/observability-probe-endpoints/assets/kubernetes/podspec-probes.md +36 -0
- package/blueprints/observability-probe-endpoints/assets/load-balancer/health-check-config.md +23 -0
- package/blueprints/observability-probe-endpoints/assets/systemd/notify-service.md +30 -0
- package/blueprints/observability-probe-endpoints/assets/uptime-monitor/monitor-config.md +22 -0
- package/blueprints/observability-probe-endpoints/blueprint.json +44 -0
- package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1501-observability-probe-endpoints-health-probes.json +30 -0
- package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1502-observability-probe-endpoints-readiness-semantics.json +30 -0
- package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1503-observability-probe-endpoints-kubernetes-default.json +30 -0
- package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1504-observability-probe-endpoints-separate-port-option.json +30 -0
- package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1505-observability-probe-endpoints-external-response-secrecy.json +30 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-001.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-002.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-003.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-004.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-005.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-006.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-007.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-008.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1501-observability-probe-endpoints-profile-resolver.json +39 -0
- package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1502-observability-probe-endpoints-handler-set.json +40 -0
- package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1503-observability-probe-endpoints-listener-topology.json +51 -0
- package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1504-observability-probe-endpoints-non-http-adapters.json +39 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14101.json +46 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14102.json +46 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14103.json +46 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14104.json +45 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14105.json +46 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14106.json +45 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14107.json +45 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14108.json +46 -0
- package/blueprints/observability-probe-endpoints/docs/topics.md +51 -0
- package/blueprints/observability-probe-endpoints/guide/observability-probe-endpoints.md +83 -0
- package/blueprints/persistence-data-d1/README.md +50 -0
- package/blueprints/persistence-data-d1/assets/batch-usage/batch-atomicity-example.md +72 -0
- package/blueprints/persistence-data-d1/assets/facade-shape/facade-module-shape.md +115 -0
- package/blueprints/persistence-data-d1/assets/migration-shape/migration-file-shape.md +119 -0
- package/blueprints/persistence-data-d1/assets/wrangler-config/d1-binding-shape.md +93 -0
- package/blueprints/persistence-data-d1/blueprint.json +42 -0
- package/blueprints/persistence-data-d1/contributions/adrs/adr-1401-persistence-data-d1-store-model.json +30 -0
- package/blueprints/persistence-data-d1/contributions/adrs/adr-1402-persistence-data-d1-migration-discipline.json +30 -0
- package/blueprints/persistence-data-d1/contributions/adrs/adr-1403-persistence-data-d1-event-secrecy.json +25 -0
- package/blueprints/persistence-data-d1/contributions/adrs/adr-1404-persistence-data-d1-store-boundary.json +25 -0
- package/blueprints/persistence-data-d1/contributions/adrs/adr-1405-persistence-data-d1-recovery-model.json +30 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-001.json +18 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-002.json +18 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-003.json +18 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-004.json +18 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-005.json +18 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-006.json +18 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-007.json +18 -0
- package/blueprints/persistence-data-d1/contributions/tacs/tac-1401-persistence-data-d1-facade.json +51 -0
- package/blueprints/persistence-data-d1/contributions/tacs/tac-1402-persistence-data-d1-migration-catalog.json +31 -0
- package/blueprints/persistence-data-d1/contributions/tacs/tac-1403-persistence-data-d1-deploy-gate.json +38 -0
- package/blueprints/persistence-data-d1/contributions/tacs/tac-1404-persistence-data-d1-recovery-runner.json +39 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13101.json +45 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13102.json +45 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13103.json +46 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13104.json +45 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13105.json +45 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13106.json +46 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13107.json +38 -0
- package/blueprints/persistence-data-d1/docs/topics.md +59 -0
- package/blueprints/persistence-data-d1/guide/persistence-data-d1.md +77 -0
- package/blueprints/persistence-data-sqlite/README.md +50 -0
- package/blueprints/persistence-data-sqlite/assets/backup-procedures/hot-checkpoint-note.md +22 -0
- package/blueprints/persistence-data-sqlite/assets/backup-procedures/sqlite-file-copy.md +70 -0
- package/blueprints/persistence-data-sqlite/assets/schema-samples/catalog-file-layout.md +73 -0
- package/blueprints/persistence-data-sqlite/assets/schema-samples/migration-shape.md +76 -0
- package/blueprints/persistence-data-sqlite/blueprint.json +50 -0
- package/blueprints/persistence-data-sqlite/contributions/adrs/adr-601-persistence-data-sqlite-store-model.json +30 -0
- package/blueprints/persistence-data-sqlite/contributions/adrs/adr-602-persistence-data-sqlite-migration-discipline.json +30 -0
- package/blueprints/persistence-data-sqlite/contributions/adrs/adr-603-persistence-data-sqlite-event-secrecy.json +25 -0
- package/blueprints/persistence-data-sqlite/contributions/adrs/adr-604-persistence-data-sqlite-store-boundary.json +25 -0
- package/blueprints/persistence-data-sqlite/contributions/adrs/adr-605-persistence-data-sqlite-backup-model.json +25 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-001.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-002.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-003.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-004.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-005.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-006.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-007.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-008.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-009.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-010.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-011.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/tacs/tac-601-persistence-data-sqlite-store.json +57 -0
- package/blueprints/persistence-data-sqlite/contributions/tacs/tac-602-persistence-data-sqlite-migration-runner.json +34 -0
- package/blueprints/persistence-data-sqlite/contributions/tacs/tac-603-persistence-data-sqlite-migration-catalog.json +31 -0
- package/blueprints/persistence-data-sqlite/contributions/tacs/tac-604-persistence-data-sqlite-backup-runner.json +33 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5101.json +46 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5102.json +46 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5103.json +37 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5104.json +45 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5105.json +45 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5106.json +46 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5107.json +45 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5108.json +46 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5109.json +46 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5110.json +37 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5111.json +37 -0
- package/blueprints/persistence-data-sqlite/docs/topics.md +49 -0
- package/blueprints/persistence-data-sqlite/guide/persistence-data-sqlite.md +69 -0
- package/blueprints/security-auth-clerk/README.md +50 -0
- package/blueprints/security-auth-clerk/assets/authorisation/role-claim-mapping-sample.md +99 -0
- package/blueprints/security-auth-clerk/assets/middleware/node-middleware-shape.md +86 -0
- package/blueprints/security-auth-clerk/assets/wiring/clerk-provider-react.md +48 -0
- package/blueprints/security-auth-clerk/assets/wiring/clerk-provider-vue.md +41 -0
- package/blueprints/security-auth-clerk/blueprint.json +42 -0
- package/blueprints/security-auth-clerk/contributions/adrs/adr-1001-security-auth-clerk-auth-model.json +30 -0
- package/blueprints/security-auth-clerk/contributions/adrs/adr-1002-security-auth-clerk-middleware-boundary.json +25 -0
- package/blueprints/security-auth-clerk/contributions/adrs/adr-1003-security-auth-clerk-authorisation-adapter-contract.json +25 -0
- package/blueprints/security-auth-clerk/contributions/adrs/adr-1004-security-auth-clerk-claims-mapping-discipline.json +25 -0
- package/blueprints/security-auth-clerk/contributions/adrs/adr-1005-security-auth-clerk-session-lifecycle.json +25 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-001.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-002.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-003.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-004.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-005.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-006.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-007.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-008.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-009.json +18 -0
- package/blueprints/security-auth-clerk/contributions/tacs/tac-1001-security-auth-clerk-middleware.json +42 -0
- package/blueprints/security-auth-clerk/contributions/tacs/tac-1002-security-auth-clerk-authorisation-adapter.json +30 -0
- package/blueprints/security-auth-clerk/contributions/tacs/tac-1003-security-auth-clerk-session-verifier.json +38 -0
- package/blueprints/security-auth-clerk/contributions/tacs/tac-1004-security-auth-clerk-claims-mapper.json +22 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9101.json +46 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9102.json +38 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9103.json +46 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9104.json +46 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9105.json +36 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9106.json +36 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9107.json +37 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9108.json +36 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9109.json +36 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9110.json +37 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9111.json +36 -0
- package/blueprints/security-auth-clerk/docs/topics.md +56 -0
- package/blueprints/security-auth-clerk/guide/security-auth-clerk.md +71 -0
- package/blueprints/security-auth-keycloak/README.md +56 -0
- package/blueprints/security-auth-keycloak/assets/local-container/keycloak-bootstrap.md +54 -0
- package/blueprints/security-auth-keycloak/assets/middleware/verifier-wiring.md +93 -0
- package/blueprints/security-auth-keycloak/assets/mock-introspection/mock-introspection-shape.md +62 -0
- package/blueprints/security-auth-keycloak/assets/provider-router/router-shape.md +71 -0
- package/blueprints/security-auth-keycloak/assets/realm-skeleton/realm-config-shape.md +55 -0
- package/blueprints/security-auth-keycloak/blueprint.json +49 -0
- package/blueprints/security-auth-keycloak/contributions/adrs/adr-1201-security-auth-keycloak-auth-model.json +35 -0
- package/blueprints/security-auth-keycloak/contributions/adrs/adr-1202-security-auth-keycloak-verification-mode-choice.json +30 -0
- package/blueprints/security-auth-keycloak/contributions/adrs/adr-1203-security-auth-keycloak-provider-routing-seam.json +30 -0
- package/blueprints/security-auth-keycloak/contributions/adrs/adr-1204-security-auth-keycloak-session-vs-token-contract.json +25 -0
- package/blueprints/security-auth-keycloak/contributions/adrs/adr-1205-security-auth-keycloak-jwks-rotation-cache-lifetime.json +30 -0
- package/blueprints/security-auth-keycloak/contributions/adrs/adr-1206-security-auth-keycloak-refresh-and-sign-out-posture.json +25 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-001.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-002.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-003.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-004.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-005.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-006.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-007.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-008.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-009.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-010.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-011.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-012.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1201-security-auth-keycloak-discovery-client.json +51 -0
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1202-security-auth-keycloak-jwt-verifier.json +46 -0
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1203-security-auth-keycloak-introspection-client.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1204-security-auth-keycloak-provider-router.json +37 -0
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1205-security-auth-keycloak-role-adapter.json +32 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11101.json +47 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11102.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11103.json +36 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11104.json +36 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11105.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11106.json +46 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11107.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11108.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11109.json +37 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11110.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11111.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11112.json +37 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11113.json +36 -0
- package/blueprints/security-auth-keycloak/docs/topics.md +74 -0
- package/blueprints/security-auth-keycloak/guide/security-auth-keycloak.md +81 -0
- package/blueprints/security-auth-magic-link/README.md +46 -0
- package/blueprints/security-auth-magic-link/assets/email-templates/magic-link-email.md +44 -0
- package/blueprints/security-auth-magic-link/assets/email-templates/stub-adapter.md +55 -0
- package/blueprints/security-auth-magic-link/assets/principal-registry-samples/allow-list-file.md +46 -0
- package/blueprints/security-auth-magic-link/assets/principal-registry-samples/single-address.md +35 -0
- package/blueprints/security-auth-magic-link/blueprint.json +45 -0
- package/blueprints/security-auth-magic-link/contributions/adrs/adr-501-security-auth-magic-link-model.json +30 -0
- package/blueprints/security-auth-magic-link/contributions/adrs/adr-502-security-auth-magic-link-token-secrecy.json +25 -0
- package/blueprints/security-auth-magic-link/contributions/adrs/adr-503-security-auth-magic-link-anti-enumeration-budget.json +25 -0
- package/blueprints/security-auth-magic-link/contributions/adrs/adr-504-security-auth-magic-link-session-lifecycle.json +30 -0
- package/blueprints/security-auth-magic-link/contributions/adrs/adr-505-security-auth-magic-link-rate-limiting.json +25 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-001.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-002.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-003.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-004.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-005.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-006.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-007.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-008.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-009.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-010.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-011.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-501-security-auth-magic-link-manager.json +45 -0
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-502-security-auth-magic-link-session-manager.json +46 -0
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-503-security-auth-magic-link-login-routes.json +76 -0
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-504-security-auth-magic-link-email-delivery-adapter.json +26 -0
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-505-security-auth-magic-link-principal-registry.json +26 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3101.json +64 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3102.json +54 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3103.json +45 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3104.json +55 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3105.json +46 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3106.json +46 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3107.json +54 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3108.json +46 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3109.json +48 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3110.json +45 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3111.json +45 -0
- package/blueprints/security-auth-magic-link/docs/topics.md +45 -0
- package/blueprints/security-auth-magic-link/guide/security-auth-magic-link.md +65 -0
- package/blueprints/security-auth-oauth2/README.md +50 -0
- package/blueprints/security-auth-oauth2/assets/mock-provider/mock-oidc-shape.md +55 -0
- package/blueprints/security-auth-oauth2/assets/provider-selector/list-shape.md +27 -0
- package/blueprints/security-auth-oauth2/assets/providers/generic-oidc-discovery.md +31 -0
- package/blueprints/security-auth-oauth2/assets/providers/github-oauth2-only.md +31 -0
- package/blueprints/security-auth-oauth2/assets/providers/google-oidc.md +31 -0
- package/blueprints/security-auth-oauth2/assets/session-bridge/opaque-handle-shape.md +59 -0
- package/blueprints/security-auth-oauth2/blueprint.json +44 -0
- package/blueprints/security-auth-oauth2/contributions/adrs/adr-1101-security-auth-oauth2-auth-model.json +35 -0
- package/blueprints/security-auth-oauth2/contributions/adrs/adr-1102-security-auth-oauth2-provider-abstraction-contract.json +25 -0
- package/blueprints/security-auth-oauth2/contributions/adrs/adr-1103-security-auth-oauth2-pkce-discipline.json +25 -0
- package/blueprints/security-auth-oauth2/contributions/adrs/adr-1104-security-auth-oauth2-session-bridge-shape.json +25 -0
- package/blueprints/security-auth-oauth2/contributions/adrs/adr-1105-security-auth-oauth2-refresh-token-posture.json +25 -0
- package/blueprints/security-auth-oauth2/contributions/adrs/adr-1106-security-auth-oauth2-multi-provider-routing.json +25 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-001.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-002.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-003.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-004.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-005.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-006.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-007.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-008.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-009.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-010.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/tacs/tac-1101-security-auth-oauth2-flow-controller.json +61 -0
- package/blueprints/security-auth-oauth2/contributions/tacs/tac-1102-security-auth-oauth2-provider-adapter.json +33 -0
- package/blueprints/security-auth-oauth2/contributions/tacs/tac-1103-security-auth-oauth2-session-bridge.json +51 -0
- package/blueprints/security-auth-oauth2/contributions/tacs/tac-1104-security-auth-oauth2-provider-selector.json +29 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10101.json +47 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10102.json +45 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10103.json +36 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10104.json +36 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10105.json +55 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10106.json +45 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10107.json +46 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10108.json +46 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10109.json +37 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10110.json +37 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10111.json +28 -0
- package/blueprints/security-auth-oauth2/docs/topics.md +58 -0
- package/blueprints/security-auth-oauth2/guide/security-auth-oauth2.md +65 -0
- package/blueprints/security-secrets-management/README.md +48 -0
- package/blueprints/security-secrets-management/assets/cli-usage/agent-access-pattern.md +69 -0
- package/blueprints/security-secrets-management/assets/manifest-samples/environment-aware-example.md +33 -0
- package/blueprints/security-secrets-management/assets/manifest-samples/secrets-yaml-shape.md +74 -0
- package/blueprints/security-secrets-management/assets/ui-integration/three-way-choice.md +44 -0
- package/blueprints/security-secrets-management/blueprint.json +43 -0
- package/blueprints/security-secrets-management/contributions/adrs/adr-901-security-secrets-management-secrets-source.json +30 -0
- package/blueprints/security-secrets-management/contributions/adrs/adr-902-security-secrets-management-default-vendor.json +35 -0
- package/blueprints/security-secrets-management/contributions/adrs/adr-903-security-secrets-management-agent-access-discipline.json +25 -0
- package/blueprints/security-secrets-management/contributions/adrs/adr-904-security-secrets-management-dotenv-reflection.json +25 -0
- package/blueprints/security-secrets-management/contributions/adrs/adr-905-security-secrets-management-rotation-and-audit.json +30 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-001.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-002.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-003.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-004.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-005.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-006.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-007.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-008.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-009.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-010.json +18 -0
- package/blueprints/security-secrets-management/contributions/tacs/tac-901-security-secrets-management-manager-client.json +52 -0
- package/blueprints/security-secrets-management/contributions/tacs/tac-902-security-secrets-management-manifest.json +34 -0
- package/blueprints/security-secrets-management/contributions/tacs/tac-903-security-secrets-management-env-reflector.json +46 -0
- package/blueprints/security-secrets-management/contributions/tacs/tac-904-security-secrets-management-rotation-gate.json +57 -0
- package/blueprints/security-secrets-management/contributions/tacs/tac-905-security-secrets-management-agent-cli.json +59 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8101.json +46 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8102.json +45 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8103.json +37 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8104.json +45 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8105.json +55 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8106.json +46 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8107.json +46 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8108.json +45 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8109.json +46 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8110.json +45 -0
- package/blueprints/security-secrets-management/docs/topics.md +46 -0
- package/blueprints/security-secrets-management/guide/security-secrets-management.md +68 -0
- package/fixtures/canary-manifest.json +1 -101
- package/package.json +15 -9
- package/rcf/.identity/profile.md +37 -0
- package/rcf/knowledge/INDEX.md +12 -0
- package/rcf/knowledge/README.md +41 -0
- package/rcf/knowledge/docs/.gitkeep +0 -0
- package/rcf/knowledge/notes/.gitkeep +0 -0
- package/scripts/preinstall-node-check.mjs +61 -0
- package/src/blueprint/apply.js +12 -6
- package/src/blueprint/conflicts.js +8 -8
- package/src/blueprint/index.js +2 -1
- package/src/blueprint/list.js +60 -0
- package/src/blueprint/loader.js +26 -1
- package/src/blueprint/namespace.js +20 -16
- package/src/blueprint/shelf-resolver.js +173 -0
- package/src/blueprint/supersede.js +3 -2
- package/src/browser-verify/invariants.js +40 -0
- package/src/browser-verify/runner.js +2 -0
- package/src/cli/blueprint.js +53 -9
- package/src/cli/init.js +2 -0
- package/src/core/store/writer.js +64 -2
- package/src/setup/agent-setup.js +28 -10
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-901-security-secrets-management-secrets-source",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "A vendor-agnostic Secrets Manager, driven by a repo-root manifest, is the project's single source of truth for secret material",
|
|
8
|
+
"context": "Every non-trivial project depends on secret material: API keys for third-party vendors, database passwords, signing keys, session salts. The failure modes accumulate quietly: dependency shape lives in whichever file happened to read it, rotation policies are unenforced, laptop-local `.env` files diverge from the deployed environment, agent workflows echo values into transcripts that persist forever. A single source-of-truth model addresses the root cause: one manifest, one client, one audit stream, one boundary the vendor lives behind. This topic is scoped as a project-level global because a composing blueprint that holds a different opinion about the secrets source (a vendor-specific opinionated blueprint, a config-server pattern, a plaintext-committed pattern for a public reference project) needs to conflict here and be resolved by the operator.",
|
|
9
|
+
"decision": "The project's secrets source is a Secrets Manager client (TAC-901) reading a repo-root manifest (`secrets.yaml`, TAC-902) that declares every secret by name, per-environment path, owner, rotation-days budget, and required-or-optional. Values live only in the vendor the client resolves against; the manifest carries names and metadata only. Every runtime path that reads a secret value imports the Secrets Manager module and no other; every CI path that gates on secret age or shape reads the manifest and no other. The vendor is pluggable; the interface is not. The default vendor is named in ADR-902; alternatives supersede this ADR at the project level.",
|
|
10
|
+
"consequences": "One place to change vendors, one place to audit, one place to enforce least-privilege. The manifest becomes a piece of documentation the project maintains as part of its normal change flow, which is the intended cost. Rotation and access-audit surfaces exist because the client is the sole entry point. Composition with a blueprint that would import a vendor SDK directly conflicts here by design; the operator supersedes with a project-level ADR that either accepts the composed blueprint's shape or restates this one's.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Environment-variable-first with no manifest",
|
|
14
|
+
"summary": "Every module reads `process.env.X` (or the language equivalent); the shape of the dependency graph is whatever the code paths do.",
|
|
15
|
+
"reasonNotChosen": "This is the default state most projects drift into and the state this blueprint exists to end. Rotation is unenforced, dependency-shape drift goes unnoticed until a deploy breaks, and there is no audit surface for who read what."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Per-deployable manifest instead of a single repo-root manifest",
|
|
19
|
+
"summary": "Each deployable owns its own secrets file; there is no project-wide view.",
|
|
20
|
+
"reasonNotChosen": "The estate-wide view is the point. Rotation policies and least-privilege audits need one file to look at; per-deployable files split the truth and re-open the drift class."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "Vendor-committed opinionated blueprint (HashiCorp Vault only, or AWS Secrets Manager only)",
|
|
24
|
+
"summary": "Ship the blueprint tied to one specific vendor SDK; the manifest is that vendor's native shape.",
|
|
25
|
+
"reasonNotChosen": "Locks the project to a vendor at the blueprint layer, which the doctrine of round-2 refuses (vendor default belongs at ADR-902, contract belongs here). A composing blueprint or a project that wants a different vendor can only escape by removing this blueprint. Splitting the contract from the default keeps both moves available."
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
29
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
30
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-902-security-secrets-management-default-vendor",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "The default secrets vendor is SOPS with age keys; committed encrypted files plus a project-held age key",
|
|
8
|
+
"context": "ADR-901 fixes the contract; a project applying this blueprint still needs a working default vendor at day one. The rcf-lite tier this blueprint targets is small greenfield projects: a single deployable, one small team or one solo operator, no ops team standing by. A default vendor for that tier should ship with zero infrastructure to run, a small dependency footprint, an on-disk shape a human can read without a service running, and an integration surface a coding agent can use through a piped-stdin CLI without extra machinery. Larger deployments will supersede this decision; the point of a default is that day one works.",
|
|
9
|
+
"decision": "The default vendor is Mozilla SOPS with age keys. Encrypted value files live under a project-authored path (typically `secrets/<environment>/<name>.enc`) committed to the repo; the age private key that decrypts them is a per-machine key held out of the repo (developer laptop keyring, CI runner secret, deployment host key material). The vendor adapter shape is: `readMany` shells to `sops --decrypt` on the resolved path per entry; `lastRotatedAt` is read from a `sops-metadata:` block the encrypt operation stamps; `materialiseCredentials` is a no-op because the SOPS invocation itself relies on the caller's age key. The default is chosen because it makes the zero-infrastructure floor real: no server to run, no account to hold, no per-project vault to provision. Projects that outgrow the default supersede this ADR with a project-level ADR selecting a hosted or self-hosted alternative (see alternatives).",
|
|
10
|
+
"consequences": "The project ships with a working secrets flow on day one and does not force an ops decision before the first commit. The age key is now a first-class piece of operator state a project must manage (a key on every developer laptop, a key on every CI runner, a key on every host running the app); losing every copy of the key loses access to every committed encrypted file, which is a recoverable-by-rewrite problem for a project pre-launch and a recoverable-by-re-issue problem thereafter. The rotation-days gate reads a metadata block SOPS itself writes; a project that hand-edits the encrypted files bypasses the metadata and loses the gate's truth source. Composition with a vendor-specific superseding blueprint (Vault, AWS Secrets Manager, GCP Secret Manager, Doppler, Infisical) is a project-level ADR change and a vendor-adapter swap; the ADR-901 contract stays intact.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "HashiCorp Vault",
|
|
14
|
+
"summary": "Run a Vault server (self-hosted or Vault Cloud); the vendor adapter reads through the Vault HTTP API using an app-scoped token or an auth method.",
|
|
15
|
+
"reasonNotChosen": "Reserved as the primary promotion path for projects that outgrow the SOPS default. Vault is the reference open-source posture for organisations with dedicated ops capacity: dynamic secrets, richer audit, policy engine, mature rotation orchestration. The trade against SOPS is running the server (or paying for the hosted plan) and the operator learning curve; small greenfield rcf-lite projects rarely need that day one."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "AWS Secrets Manager / GCP Secret Manager / Azure Key Vault",
|
|
19
|
+
"summary": "Hosted per-cloud secrets managers; the vendor adapter reads through the cloud SDK using workload-identity credentials.",
|
|
20
|
+
"reasonNotChosen": "Ties the project to one cloud at the secrets layer; the doctrine of ADR-901 keeps the contract vendor-agnostic on purpose. Excellent choice for a project already committed to one cloud and using workload-identity; a project-level ADR supersede is the intended path there."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "Doppler / Infisical / other hosted third-party secrets services",
|
|
24
|
+
"summary": "Hosted vendor with a project workspace and per-environment scoping; the vendor adapter reads through the vendor's HTTP API using a service token.",
|
|
25
|
+
"reasonNotChosen": "Same trade as the cloud-native option: a fine promotion path for a project that wants a managed service without cloud lock-in, but not the zero-infrastructure day-one default. A project-level ADR supersedes this ADR when the operator adopts one."
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "Plaintext values in the repo",
|
|
29
|
+
"summary": "Commit secrets as plain files; ignore the encryption layer entirely.",
|
|
30
|
+
"reasonNotChosen": "Fails every requirement in this blueprint that touches secret secrecy. Named only to explain why 'just put the secret in a file' is not the same shape as SOPS+age."
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
34
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
35
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-903-security-secrets-management-agent-access-discipline",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Coding agents access secrets through the CLI with piped stdin only; secret bytes never appear in a chat transcript, log line, or committed file",
|
|
8
|
+
"context": "A coding agent that runs verbs, reads files, and captures its own tool output creates a large surface for secret material to land somewhere durable it should not be. Chat transcripts persist to model provider logs, session artefacts, and shared screenshots. Verbose tool logs land in the operator's terminal scrollback and in workspace backups. A `.env` file the agent generates in a scratch step ends up in git if a stray `git add` follows. The blueprint has to give agents an access path that is both usable (agents can wire the secret into the process that needs it) and safe (the bytes never traverse a surface the agent workflow persists).",
|
|
9
|
+
"decision": "Agents work with secrets through the Secrets CLI (TAC-905) using piped-stdin flow-through, never argv, never terminal-echoed output. `secrets read N` is called with stdout piped to the downstream consumer (a process being started, a temp file being materialised into a container secret volume, a Kubernetes secret being created); the value crosses one pipe and no more. `secrets put N` is called with stdin piped from the source of the new value (a clipboard reader, another `secrets read` in a rotation flow, a hardware token flow). The CLI refuses to echo a value to a TTY without an explicit `--show` flag, and the flag is honoured only when stdout is actually a TTY (not a captured stream). The CLI's own log stream runs through a redactor that replaces any bytes matching a resolved secret value with a fixed placeholder before emitting. Agent-authored code and configuration never store a secret value as a literal, an inlined constant, or a comment; every reference is by logical name through the client.",
|
|
10
|
+
"consequences": "Agent workflows compose secrets into running processes without the bytes crossing an observability surface the agent creates. The stdin-piped flow is unfamiliar to some tooling; projects wrap the pattern with small helper scripts (Node.js entry points that spawn a child process with the piped secret material as an environment variable set at spawn time and never printed) to keep the surface friendly. Human operators still have a debug path via `--show` on a real terminal, which is the one legitimate reason to look at a value with their own eyes. Nothing at this layer stops a human copying a value out of their own terminal; that class of leak requires an out-of-band delivery mode (see TAC-905 tradeoffs).",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Let the agent generate a `.env` file and reference it from process startup",
|
|
14
|
+
"summary": "The agent runs a reflector-like command that writes `.env` and the process reads from there.",
|
|
15
|
+
"reasonNotChosen": "The `.env` file is now on disk with secret bytes for the lifetime of the working tree, and the agent's transcript of the reflector command already contains everything an attacker needs to reproduce it. A piped-stdin invocation crosses fewer boundaries and leaves nothing on disk unless the operator's own tooling asks for it (that path is the env reflector, deliberately per-invocation-per-operator, not per-agent-step)."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Provide agents a mock-value adapter that returns placeholders for every secret",
|
|
19
|
+
"summary": "The agent works against a stub vendor that always returns strings like `<REDACTED>` and the real values are injected later by a human.",
|
|
20
|
+
"reasonNotChosen": "The stub adapter is a fine test-harness posture and does not need an ADR to authorise. It is not an access pattern for legitimate production wiring; the CLI's piped-stdin path is."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
24
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-904-security-secrets-management-dotenv-reflection",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "`.env` is an ephemeral regenerable reflection of the manifest, never the source of truth",
|
|
8
|
+
"context": "`.env` files have quietly become the de facto secrets store on many projects. Developers edit them by hand, tools like docker-compose and Node's dotenv library expect them at fixed paths, CI runners copy them around, and the file gets committed by accident on a regular schedule. Removing the `.env` entirely breaks a large amount of tooling that assumes its presence; keeping it as the source of truth reintroduces every failure mode this blueprint exists to end. The middle path is to keep the `.env` shape at the surface where tooling expects it and change its role from authoritative to reflective.",
|
|
9
|
+
"decision": "The `.env` file, when present at the repo root, is generated on demand from the Secrets Manager by the env reflector (TAC-903). Every run of `secrets reflect --deployable <id> --env <env>` overwrites the file atomically with the current vendor-resolved values for the target slice; nothing outside the reflector may write the file, and no runtime code reads the file to bypass the Secrets Manager client. The `.env` path is gitignored at project root by requirement (AC-8106-2) and the reflector refuses to run when it is not (defence against a mis-configured `.gitignore`). Per-environment reflection variants (`.env.dev`, `.env.ci`, `.env.live`) are selected by the `--env` flag; each variant is written and overwritten independently.",
|
|
10
|
+
"consequences": "Local tooling that expects `.env` keeps working; the developer runs the reflector and the file appears with values that match the current vendor state. The reflection is discardable at any moment (delete the file, rerun the reflector, get an identical result), which makes the file's ephemerality visible in the workflow. A stale `.env` from a week ago is a shape drift no one has to argue about; the reflector regenerates it. A CI job that needs a `.env` runs the reflector as a preamble; the file exists for the job's runtime and disappears with the runner. A process that reads `.env` directly at boot instead of the client is caught by the source-tree scan (AC-8106-3).",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "No `.env` at all; every consumer reads the client directly",
|
|
14
|
+
"summary": "Refuse to write a reflection; every tool that needs a value invokes the CLI or imports the client.",
|
|
15
|
+
"reasonNotChosen": "Purer but breaks a lot of tooling with hard-coded `.env` expectations (docker-compose, some Node frameworks' hot-reload modes, some IDE integrations). The reflector adds surface but keeps the ecosystem workable."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Commit an encrypted `.env` and decrypt in place",
|
|
19
|
+
"summary": "Ship the reflection encrypted at rest in the repo and decrypt to a plaintext `.env` at boot.",
|
|
20
|
+
"reasonNotChosen": "Overlaps the default vendor's own encrypt-and-commit posture (ADR-902's SOPS files) without adding anything; the plaintext `.env` still exists on disk during runtime and is now redundant with the encrypted store."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
24
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-905-security-secrets-management-rotation-and-audit",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Rotation-days budget enforced at CI; every secret access is audited; audit events carry metadata only",
|
|
8
|
+
"context": "Rotation policies that are not enforced quietly slip; audit trails that carry secret bytes turn every log store into a secrets store. Both problems have a fix at the boundary the Secrets Manager client already owns: the client is the sole reader of secret values, so it is the only place that can emit audit events truthfully, and the manifest is the sole declaration of rotation budgets, so CI has one file to enforce against.",
|
|
9
|
+
"decision": "Every fetch attempt on the Secrets Manager client emits exactly one structured audit event carrying `{ name, path, environment, principal, outcome, at }`; no field carries the secret value or a substring of it. The audit sink is pluggable behind the same discipline as the wire log; the blueprint fixes the SHAPE of the events, not the storage engine. CI runs the rotation gate (TAC-904) on every change; an entry whose `lastRotatedAt` is more than `rotationDays` in the past fails the run with `SECRETS_ROTATION_EXPIRED`; an entry with no vendor-reported `lastRotatedAt` fails with `SECRETS_ROTATION_UNKNOWN`. An operator-authored override file with an `expiresAt` timestamp is honoured for the named entry until the expiry passes; the override is itself audited every time it applies.",
|
|
10
|
+
"consequences": "Rotation cannot silently slip; a CI run is the place the project already gates every change through. Investigating an incident starts with the audit stream and stays there; the log store is safe to ship to a third party because it holds no credential material. The vendor becomes the truth source for rotation age; a vendor without native rotation metadata forces the project into a parallel side-file (an acknowledged trade in TAC-904). The override with an expiry keeps a legitimate mid-rotation change unblocked without opening a permanent bypass; the audited-every-time property makes an over-used override visible.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Hash the secret value into audit events for correlation",
|
|
14
|
+
"summary": "Emit a stable hash of the value so incident investigators can correlate 'this key was read here and here' without exposing the plaintext.",
|
|
15
|
+
"reasonNotChosen": "A hashed value still lets an attacker with log access confirm 'this hash is the hash for this secret', which is enough for correlation attacks on high-value keys. The event's `name` and `principal` already provide correlation; a hash adds risk without adding capability."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Rely on rotation announcements from the vendor rather than a CI gate",
|
|
19
|
+
"summary": "Subscribe to the vendor's rotation notification stream and act on drift asynchronously.",
|
|
20
|
+
"reasonNotChosen": "Async enforcement is a hope; a synchronous CI gate on every change is the place the project already fails on other drift classes (a lint error, a test failure, a schema mismatch). Enforcing at the same layer keeps the operator experience uniform."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "Rotate on every deploy",
|
|
24
|
+
"summary": "Every merge triggers a full rotation of every secret.",
|
|
25
|
+
"reasonNotChosen": "Amplifies blast radius on every deploy failure and makes the vendor's rotation quotas the pacing item. A rotation budget with a bounded override is the honest posture: rotate on the cadence the value's threat model actually needs."
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
29
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
30
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "security-secrets-management-REQ-001",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The repo-root secrets manifest is the single source of truth for what secrets exist",
|
|
5
|
+
"description": "A file named `secrets.yaml` at the repo root enumerates every secret the project depends on. Each entry declares a stable logical name, the path or reference the vendor uses to fetch the value, the owner, the rotation-days budget, the environment scope (declared as an environment-aware structure whose exact shape is elicited from the operator; the common default is `dev`, `ci`, `live`), and whether the secret is required or optional. Nothing outside the manifest may declare a secret dependency; a required secret referenced from code but absent from the manifest is a build refusal. Secret VALUES never appear in the manifest; only names, paths, and metadata.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "security",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "A scattered secret dependency graph is the failure mode this blueprint exists to end. If every code path names its own environment variable, no one knows what the project actually needs, rotation is guesswork, and a missing secret surfaces as a runtime null. A single manifest at a known path makes the dependency set legible to humans, to CI gates, to onboarding runs, and to the vendor-side least-privilege policy that grants access to exactly the declared set.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:security-secrets-management",
|
|
12
|
+
"category:01-manifest"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "security-secrets-management-REQ-002",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Secrets are read through one vendor-agnostic manager client interface",
|
|
5
|
+
"description": "The project imports a single Secrets Manager client that exposes the named verbs `get(name)`, `getRequired(name)`, `list()`, and `refresh()`. `get` returns the current value or null; `getRequired` throws a stable-coded error on absence; `list` returns the manifest-declared name set for this process; `refresh` re-reads every secret this process is authorised for. The client is the sole importer of the vendor binding on the boundary; no other module reaches for the vendor SDK, an environment variable, or a config file directly. The default vendor is named in ADR-902; the interface itself does not depend on which vendor is behind it.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "security",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "A vendor-agnostic port keeps the project free to change vendors under a passing test suite. It also removes the class of bugs where two modules read the same secret through two different code paths and disagree about whether it is set. One client, one boundary, one behaviour.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:security-secrets-management",
|
|
12
|
+
"category:02-client-contract"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "security-secrets-management-REQ-003",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Each process reads only the secrets its manifest slice declares (least-privilege)",
|
|
5
|
+
"description": "Each deployable in the project declares an explicit slice of the manifest it needs (by logical name). At boot the Secrets Manager client materialises credentials for exactly that slice and refuses to serve any other name for the lifetime of the process. A `get('X')` call for a name outside the declared slice throws a stable-coded refusal, even when `X` is a legal manifest entry for a different deployable. Vendor-side access policies are configured to grant this process's credentials read on exactly the declared slice and no other paths; the code-side refusal and the vendor-side deny are both required and both belong to the least-privilege posture.",
|
|
6
|
+
"category": "nonFunctional",
|
|
7
|
+
"domain": "security",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "A single credential that can read every secret in the project is one bug away from an all-secrets exposure. Slicing the read surface per process makes the blast radius of a code path that gets abused the size of that process's slice, not the size of the whole project.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:security-secrets-management",
|
|
12
|
+
"category:03-least-privilege"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "security-secrets-management-REQ-004",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Every access to secret material produces a durable audit event",
|
|
5
|
+
"description": "The Secrets Manager client emits a structured audit event on every fetch of a secret value: the logical name, the manifest path, the environment scope, the requesting principal (deployable name plus operator or agent id where applicable), the outcome (`served`, `refusedOutOfSlice`, `refusedAbsent`, `refusedRotationExpired`), and the wall-clock timestamp. The event never contains the secret value or any prefix or suffix of it. The audit sink is pluggable behind the same discipline as the wire log; the blueprint fixes the SHAPE of the events and the fields that must appear, not the storage engine.",
|
|
6
|
+
"category": "nonFunctional",
|
|
7
|
+
"domain": "security",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Rotation, incident response, and least-privilege verification all depend on being able to answer 'who read what, when'. A missing audit trail is the difference between 'we know the blast radius' and 'we hope the blast radius is small'. Keeping the value out of the event is the discipline that makes shipping the audit stream to a third-party log store safe.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:security-secrets-management",
|
|
12
|
+
"category:04-audit"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "security-secrets-management-REQ-005",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Coding agents work with secrets through a piped-stdin CLI; secret material never appears in a chat transcript, log line, or source-tree file",
|
|
5
|
+
"description": "A secrets CLI ships alongside the client. Every verb that would surface a secret VALUE accepts and produces that value only on stdin or stdout piped to a downstream consumer; the value never appears in a command argument, an environment variable printed at startup, a prompt echo, a chat transcript captured by any agent harness, or a log line the CLI itself writes. Agent-authored code and agent-authored configuration reference secrets by their logical name only. The CLI's structured output surface (`--json`, `--report`) enumerates names and metadata, never values. A verb that prints a value to a terminal is refused unless the process has an interactive TTY on stdout AND the operator has passed an explicit `--show` flag; the flag is deliberately not scriptable through an agent transcript.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "security",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "A secret that lands in an agent's transcript is a secret in every downstream copy of that transcript (session artefacts, workspace backups, model provider logs, human-shared screenshots). The stdin-piped posture is the only reliable way to keep secret bytes off the surfaces an agent-driven workflow creates. The `--show` interactive gate keeps the human debugging path open without becoming an agent scripting path.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:security-secrets-management",
|
|
12
|
+
"category:05-agent-access"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "security-secrets-management-REQ-006",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "`.env` files are ephemeral regenerable reflections of the manifest, never the source of truth",
|
|
5
|
+
"description": "A `.env` file, when it exists on a developer laptop or a CI runner, is a per-machine reflection generated on demand from the Secrets Manager by an env reflector command (`secrets reflect`). The reflector reads the current manifest slice for the target process, fetches the values, and writes them to the `.env` path atomically; a subsequent `secrets reflect` overwrites the file. The `.env` path is gitignored at project root; the manifest is committed. A process that reads `.env` directly at boot instead of going through the Secrets Manager client is a v1 policy violation caught by the source-tree scan the CI gate runs. The `.env` reflection is a convenience for local tooling that expects one; it is never the authoritative store, it is never rotated in-place, and it is discardable at any moment.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "security",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "`.env` files were invented as a laptop-local shim and have quietly become primary state on many projects, which is where rotation drift, uncommitted-secret-shape drift, and shared-laptop leaks begin. Recentring the manifest as the source of truth and demoting `.env` to a projection removes both classes of drift without breaking the local-dev flow developers already have muscle memory for.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:security-secrets-management",
|
|
12
|
+
"category:06-dotenv-reflection"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "security-secrets-management-REQ-007",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The manifest is environment-aware; the exact environment shape is elicited from the operator, not assumed",
|
|
5
|
+
"description": "Each manifest entry carries per-environment metadata: at minimum a path or reference the vendor resolves per environment, and optionally per-environment rotation and required-or-optional overrides. The set of environment names (for example `dev`, `ci`, `live`; or `dev`, `staging`, `prod`; or a project-specific list) is elicited from the operator at first apply, recorded in the manifest header, and enforced from then on. The Secrets Manager client resolves against exactly one environment per process, selected by an unambiguous boot input (a process-scoped variable or a boot flag), and a missing per-environment resolution for the active environment fails boot for a required secret and is served as null for an optional one.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "security",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Every project has a slightly different environment shape and forcing one on them is how the manifest becomes the thing developers work around instead of with. Eliciting the shape at apply time (and freezing it in the manifest header) keeps the manifest legible to a first-time reader and keeps the boot-time selection unambiguous.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:security-secrets-management",
|
|
12
|
+
"category:07-environment-aware"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "security-secrets-management-REQ-008",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The process fails to boot when a required secret is absent; degrades on an optional absent secret",
|
|
5
|
+
"description": "At boot the Secrets Manager client attempts to materialise every name in the declared slice. A `required: true` entry that cannot be resolved for the active environment aborts boot with a stable-coded error naming the logical name and the environment, and no partial start-up state is exposed on any port. A `required: false` entry that cannot be resolved is served as null; consumers that call `get` on an optional name handle the null branch. The failure mode is loud, early, and irreversible in-boot; there is no wait-and-retry loop that would leave the process half-alive with silently missing secrets.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "security",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "A process that starts with a required secret missing serves broken traffic while the operator hunts a null-pointer stack trace ten layers down. Failing at boot names the problem exactly once at exactly the right layer, and the operator moves straight to the manifest.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:security-secrets-management",
|
|
12
|
+
"category:08-fail-safe"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "security-secrets-management-REQ-009",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "CI fails a change when a secret has aged past its rotation-days budget",
|
|
5
|
+
"description": "A rotation gate runs in CI on every change. For each manifest entry with a `rotationDays` value, the gate compares the vendor-reported last-rotated timestamp against the current CI-run wall clock; a gap greater than `rotationDays` fails the run with a stable-coded error naming the logical name, the environment, the last-rotated timestamp, and the elapsed days. The gate has a documented override for a scheduled rotation window (an operator-authored justification file the gate reads with an expiry timestamp), and the override is itself audited. The gate runs on the manifest as-committed against the vendor as-configured; a required secret with no vendor-reported last-rotated timestamp fails the gate.",
|
|
6
|
+
"category": "nonFunctional",
|
|
7
|
+
"domain": "security",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Rotation policies that are not enforced are policies that quietly slip. CI is the gate every change already passes through, and failing on staleness turns 'we should rotate this' into 'this change cannot merge until we do'. The override with an expiry keeps a legitimate mid-rotation change unblocked without opening a permanent bypass.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:security-secrets-management",
|
|
12
|
+
"category:09-rotation-gate"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "security-secrets-management-REQ-010",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The operator picks one of three UI outcomes for the Secrets Management surface: integrate a Secrets page into an existing admin UI, adopt an admin-SPA blueprint, or decline a UI",
|
|
5
|
+
"description": "At apply the working agent elicits a three-way choice about the operator-facing Secrets Management surface: (a) integrate a Secrets Management page into an existing project admin UI, wired to the CLI's structured surface (names and metadata only; the page never renders a secret value); (b) adopt a separate admin-SPA blueprint (a future companion blueprint) that hosts the Secrets page as one of its screens; (c) decline a UI entirely and rely on the CLI plus the audit stream. The choice is recorded in the manifest header. When (a) is chosen the page's contract is fixed by TAC-905 (list, filter by environment, show last-rotated, request-rotation button that hands off to the operator's rotation procedure); the page implementation lives in the host project. When (b) is chosen the project applies the admin-SPA blueprint on top of this one and inherits the page from there. When (c) is chosen this blueprint contributes nothing to the operator UI surface and the CLI plus audit sink remain the whole story.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "security",
|
|
8
|
+
"priority": "should",
|
|
9
|
+
"rationale": "A UI over secret metadata (names, environments, ages, owners) is useful; a UI over secret values reintroduces the leakage class this blueprint spent nine requirements eliminating. Forcing every project onto a UI would add surface most rcf-lite projects do not need; forbidding one would push operators back to spreadsheets. Eliciting the choice at apply time keeps the blueprint honest across small and larger projects.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:security-secrets-management",
|
|
12
|
+
"category:10-ui-integration"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-901-security-secrets-management-manager-client",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Secrets Manager client",
|
|
8
|
+
"purpose": "The one place in the project that reads secret material. Loads the manifest slice for the current deployable at boot, materialises credentials for exactly that slice through a vendor adapter, exposes a fixed named-verb surface to callers, and emits an audit event on every fetch attempt. Every other module in the project reads secrets through this client; nothing else imports the vendor SDK.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Load the manifest for the repo root and pick out the slice for the boot-input deployable id (AC-8101-1, AC-8103-1).",
|
|
11
|
+
"Refuse `get`/`getRequired` for a name outside the declared slice with a stable-coded `SECRETS_OUT_OF_SLICE` error and no vendor call (AC-8101-2, AC-8103-1).",
|
|
12
|
+
"Materialise vendor credentials once at boot for exactly the declared slice; refuse boot on a required-absent secret with `SECRETS_REQUIRED_ABSENT` naming the logical name and active environment (AC-8102-2, AC-8108-1, AC-8107-3).",
|
|
13
|
+
"Serve `get(name)` from an in-memory cache; support `refresh()` as an atomic swap so a concurrent `get` never sees a mixed slice (AC-8102-3).",
|
|
14
|
+
"Emit exactly one structured audit event per fetch attempt, with fields `name`, `path`, `environment`, `principal`, `outcome`, `at`; no field may carry the secret value or a substring of it (AC-8104-1, AC-8104-2, AC-8104-3).",
|
|
15
|
+
"Select the active environment from an unambiguous boot input; refuse boot on ambiguous inputs with `SECRETS_ENV_AMBIGUOUS` (AC-8107-2).",
|
|
16
|
+
"Retry-once semantics at boot: a required-absent read is attempted once, not looped (AC-8108-3)."
|
|
17
|
+
],
|
|
18
|
+
"internalStructure": "One stateless class per process with an injected vendor adapter and an injected audit sink. The cache is a Map keyed by logical name and populated at boot; a refresh swaps a new Map in atomically. The vendor adapter is a project-authored module implementing the port defined in the interfaces block; the reference default vendor is named in ADR-902 and lives under the same package as this client.",
|
|
19
|
+
"interfaces": [
|
|
20
|
+
{
|
|
21
|
+
"name": "vendorAdapter",
|
|
22
|
+
"kind": "read-write-api",
|
|
23
|
+
"description": "Project-supplied vendor binding implementing `readMany({ paths, credentials, environment })` returning `{ [name]: { value, lastRotatedAt } }` or an entry-level not-found marker, and `materialiseCredentials({ slicePaths, environment })` returning per-slice credentials the vendor deny-by-default enforces."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "manifest",
|
|
27
|
+
"kind": "read-api",
|
|
28
|
+
"description": "The manifest loader (TAC-902) resolving the current deployable's slice, per-environment paths, and `required` flags."
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "auditSink",
|
|
32
|
+
"kind": "callback",
|
|
33
|
+
"description": "Structured-event sink invoked with `{ name, path, environment, principal, outcome, at }` on every fetch attempt; never invoked with the secret value."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "envSelector",
|
|
37
|
+
"kind": "read-api",
|
|
38
|
+
"description": "The boot-input resolver for the active environment: a process variable, a boot flag, or a project-authored selector. Returns exactly one environment string or refuses ambiguity."
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"dependencies": [
|
|
42
|
+
{
|
|
43
|
+
"name": "Secrets Manifest",
|
|
44
|
+
"kind": "tac",
|
|
45
|
+
"tacId": "TAC-902-security-secrets-management-manifest",
|
|
46
|
+
"description": "Upstream source of the declared slice and per-environment path map the client resolves at boot."
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"tradeoffs": "The client holds every declared value in memory for the lifetime of the process; a heap dump of a compromised process exposes the slice's cleartext. That trade means every read is a memory access rather than a vendor round trip, which is what makes the hot path affordable and what makes `refresh` cheap. Projects that want per-fetch vendor reads (short-lived credential floors, HSM-mediated flows) supply a vendor adapter whose `readMany` proxies to the vendor on every call and rely on the cache being a thin write-through layer.",
|
|
50
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
51
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
52
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-902-security-secrets-management-manifest",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Secrets manifest loader and validator",
|
|
8
|
+
"purpose": "Loads `secrets.yaml` at the repo root, validates its shape against the manifest schema, exposes the declared environment set, the declared deployable-to-slice map, and the per-entry per-environment path resolution. Every other component reads the manifest through this loader.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Read `secrets.yaml` from the repo root; refuse a missing file with a stable-coded `SECRETS_MANIFEST_MISSING` error naming the expected path.",
|
|
11
|
+
"Parse the YAML and validate against the schema: `environments` is a non-empty array of lower-kebab strings; each `secrets[]` entry has `name`, `paths`, `owner`, `rotationDays`, `required` (AC-8101-1).",
|
|
12
|
+
"Enforce that every entry's `paths` object key set equals `environments` exactly; refuse a partial entry with `SECRETS_ENV_PATH_MISSING` (AC-8107-1).",
|
|
13
|
+
"Refuse a `value` field on any entry (secret values never live in the manifest) with `SECRETS_MANIFEST_VALUE_FIELD`.",
|
|
14
|
+
"Resolve a deployable's slice: return the ordered array of manifest entries whose `deployables` list includes the queried deployable id (AC-8103-1).",
|
|
15
|
+
"Expose a lookup for a single entry by name so downstream tools (rotation gate, env reflector, CLI list surface) share one resolution path."
|
|
16
|
+
],
|
|
17
|
+
"internalStructure": "One pure module: a `loadManifest(rootPath)` function returning a frozen manifest object plus a set of typed accessors (`slicesFor(deployableId)`, `entryByName(name)`, `environments()`, `uiIntegrationMode()`). No I/O beyond the initial file read; no cache invalidation because the manifest is treated as a boot-time constant.",
|
|
18
|
+
"interfaces": [
|
|
19
|
+
{
|
|
20
|
+
"name": "fileSystem",
|
|
21
|
+
"kind": "read-api",
|
|
22
|
+
"description": "Project-supplied file reader accepting a repo-root-relative path and returning UTF-8 bytes; injected for test surface."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "yamlParser",
|
|
26
|
+
"kind": "read-api",
|
|
27
|
+
"description": "YAML parser accepting bytes and returning a plain object; injected so the project supplies its own dependency."
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"dependencies": [],
|
|
31
|
+
"tradeoffs": "The manifest is treated as boot-time immutable; a change to `secrets.yaml` requires a process restart to take effect. That trade removes a class of cache-invalidation bugs and keeps the audit-event trail truthful about which manifest version was in force. Projects that need hot-reload wire a file watcher that triggers a graceful restart, not an in-place manifest swap.",
|
|
32
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
33
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
34
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-903-security-secrets-management-env-reflector",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Env reflector",
|
|
8
|
+
"purpose": "Regenerates a `.env` file at the repo root from the current manifest slice and the vendor-resolved values, for the local developer tools that expect one. Runs on demand; overwrites atomically; never treats the resulting `.env` as authoritative.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Accept `--deployable <id>` and `--env <env>`; resolve the slice through TAC-902 and the values through TAC-901 (AC-8106-1).",
|
|
11
|
+
"Write the `.env` atomically: write to a temp file in the same directory and rename over the target so a partial write is never observable to a concurrent reader (AC-8106-1).",
|
|
12
|
+
"Refuse to run when the target `.env` path is not gitignored at the repo root; emit `SECRETS_DOTENV_NOT_IGNORED` naming the path (defence against a project that mis-configures `.gitignore`).",
|
|
13
|
+
"Never emit secret values to any surface other than the resulting file bytes; the command's own stdout, stderr, and audit event carry names and counts only.",
|
|
14
|
+
"Support per-environment reflection variants (`.env.dev`, `.env.ci`, `.env.live`) selected by the `--env` flag; when the same command is re-run with a different `--env` the previously-written variant is left untouched."
|
|
15
|
+
],
|
|
16
|
+
"internalStructure": "One stateless command handler. Composes the manifest loader (TAC-902), the Secrets Manager client (TAC-901), and a small `writeAtomic` utility. The output shape is a POSIX-style `KEY=value` file with values escaped for values containing whitespace, quotes, or newlines.",
|
|
17
|
+
"interfaces": [
|
|
18
|
+
{
|
|
19
|
+
"name": "fileSystem",
|
|
20
|
+
"kind": "read-write-api",
|
|
21
|
+
"description": "Project-supplied file reader-writer supporting temp-file creation and atomic rename."
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "gitignoreCheck",
|
|
25
|
+
"kind": "read-api",
|
|
26
|
+
"description": "Project-supplied predicate answering whether a given path is gitignored (usually a shell-out to `git check-ignore`)."
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"dependencies": [
|
|
30
|
+
{
|
|
31
|
+
"name": "Secrets Manager client",
|
|
32
|
+
"kind": "tac",
|
|
33
|
+
"tacId": "TAC-901-security-secrets-management-manager-client",
|
|
34
|
+
"description": "Source of the resolved values for the target slice."
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "Secrets Manifest",
|
|
38
|
+
"kind": "tac",
|
|
39
|
+
"tacId": "TAC-902-security-secrets-management-manifest",
|
|
40
|
+
"description": "Source of the deployable-to-slice map."
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"tradeoffs": "The reflector puts secret material on disk in a file most tooling has read access to. That trade is the cost of interoperability with the tools that expect a `.env`; the atomic-write plus gitignore-required-check plus explicit re-run posture keeps the reflection legible as ephemeral rather than authoritative. Projects that prefer never to touch disk (in-memory-only container starts) skip the reflector and let their tooling read from the client directly.",
|
|
44
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
45
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
46
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-904-security-secrets-management-rotation-gate",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Rotation gate",
|
|
8
|
+
"purpose": "CI-time enforcer of the rotation-days budget declared on each manifest entry. Reads the manifest, queries the vendor for the current per-entry `lastRotatedAt`, fails the CI run on any expired or unknown-age entry, honours a bounded override, and audits the outcome.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Read the manifest through TAC-902 and iterate every entry with a `rotationDays` value (AC-8109-1).",
|
|
11
|
+
"For each entry and each configured target environment, query the vendor adapter for the current `lastRotatedAt`; compare the elapsed days against `rotationDays`; fail with `SECRETS_ROTATION_EXPIRED` when elapsed > budget (AC-8109-1).",
|
|
12
|
+
"Fail with `SECRETS_ROTATION_UNKNOWN` when the vendor returns no `lastRotatedAt` for an entry, regardless of `required` (AC-8109-2).",
|
|
13
|
+
"Load the operator-authored override file when present; for a named entry with an unexpired override, skip the fail and emit a `SECRETS_ROTATION_OVERRIDE_APPLIED` audit event carrying the override author, expiry, and the wall-clock at gate time (AC-8109-3).",
|
|
14
|
+
"Refuse to accept an override without an `expiresAt` timestamp; the override is bounded by design.",
|
|
15
|
+
"Emit a `--report` structured summary listing every entry's environment, `lastRotatedAt`, elapsed days, budget, and outcome; the report never contains a secret value."
|
|
16
|
+
],
|
|
17
|
+
"internalStructure": "One stateless command handler runnable from any CI runner. Composes TAC-902 (manifest), the vendor adapter from TAC-901, and a small override reader. Wall-clock injected for test surface.",
|
|
18
|
+
"interfaces": [
|
|
19
|
+
{
|
|
20
|
+
"name": "vendorAdapter",
|
|
21
|
+
"kind": "read-api",
|
|
22
|
+
"description": "The same vendor binding the Secrets Manager client uses (TAC-901), scoped to a rotation-metadata read (no value fetch is required for the gate's own operation)."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "overrideStore",
|
|
26
|
+
"kind": "read-api",
|
|
27
|
+
"description": "Reads the operator-authored override file (project-authored path; a JSON or YAML file listing per-name `{ author, expiresAt, reason }` entries)."
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "clock",
|
|
31
|
+
"kind": "clock",
|
|
32
|
+
"description": "Injectable millisecond wall clock for the elapsed-days arithmetic."
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "auditSink",
|
|
36
|
+
"kind": "callback",
|
|
37
|
+
"description": "The same sink shape TAC-901 uses; the gate emits override-applied and rotation-expired events through it."
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"dependencies": [
|
|
41
|
+
{
|
|
42
|
+
"name": "Secrets Manifest",
|
|
43
|
+
"kind": "tac",
|
|
44
|
+
"tacId": "TAC-902-security-secrets-management-manifest",
|
|
45
|
+
"description": "Source of the entries the gate iterates over."
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "Secrets Manager client",
|
|
49
|
+
"kind": "tac",
|
|
50
|
+
"tacId": "TAC-901-security-secrets-management-manager-client",
|
|
51
|
+
"description": "Provider of the vendor adapter shape the gate re-uses for the rotation-metadata query."
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"tradeoffs": "The gate treats the vendor as the truth source for rotation age; a vendor with an unreliable `lastRotatedAt` field turns the gate into false positives. Projects on a vendor without native rotation metadata track rotation timestamps in a parallel side-file at the cost of an extra source of truth (accept the trade or supersede ADR-905 with a project-level ADR selecting a stricter posture).",
|
|
55
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
56
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
57
|
+
}
|