rcf-lite 0.23.0 → 0.25.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 +29 -0
- package/blueprints/application-account-settings/docs/topics.md +10 -1
- package/blueprints/application-admin-console/CHANGELOG.md +12 -0
- package/blueprints/application-admin-console/blueprint.json +34 -1
- package/blueprints/application-admin-console/contributions/adrs/adr-2214-application-admin-console-consume-zero-trust-gate.json +25 -0
- package/blueprints/application-admin-console/contributions/requirements/application-admin-console-req-014.json +17 -0
- package/blueprints/application-admin-console/contributions/tacs/tac-2214-application-admin-console-access-gated-signin-surface.json +32 -0
- package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21815.json +27 -0
- package/blueprints/application-admin-console/contributions/user-stories/application-admin-console-us-21816.json +27 -0
- package/blueprints/application-admin-console/docs/topics.md +10 -1
- package/blueprints/application-admin-console/guide/application-admin-console.md +24 -0
- package/blueprints/application-admin-console/probe-packs/application-admin-console.pack.mjs +26 -1
- package/blueprints/application-api-rest/docs/topics.md +10 -1
- package/blueprints/application-charts/docs/topics.md +10 -1
- package/blueprints/application-dashboard/docs/topics.md +10 -1
- package/blueprints/application-datatable/docs/topics.md +10 -1
- package/blueprints/application-empty-error-states/docs/topics.md +10 -1
- package/blueprints/application-error-handling/docs/topics.md +10 -1
- package/blueprints/application-file-upload/docs/topics.md +10 -1
- package/blueprints/application-forms-wizard/docs/topics.md +10 -1
- package/blueprints/application-notifications-in-app/docs/topics.md +10 -1
- package/blueprints/application-onboarding-tour/docs/topics.md +10 -1
- package/blueprints/application-spa/docs/topics.md +10 -1
- package/blueprints/delivery-ci-workflows/docs/topics.md +10 -1
- package/blueprints/deploy-cloudflare-workers/docs/topics.md +10 -1
- package/blueprints/deploy-hetzner-server/CHANGELOG.md +34 -0
- package/blueprints/deploy-hetzner-server/README.md +202 -0
- package/blueprints/deploy-hetzner-server/blueprint.json +233 -0
- package/blueprints/deploy-hetzner-server/contributions/adrs/adr-3801-deploy-hetzner-server-cloud-host-contract.json +14 -0
- package/blueprints/deploy-hetzner-server/contributions/adrs/adr-3802-deploy-hetzner-server-snapshot-cadence.json +14 -0
- package/blueprints/deploy-hetzner-server/contributions/adrs/adr-3803-deploy-hetzner-server-provisioning-tool.json +20 -0
- package/blueprints/deploy-hetzner-server/contributions/adrs/adr-3804-deploy-hetzner-server-hardening-baseline.json +14 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/cloud-init-render-lint.mjs +64 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/hcloud-dry-run-mock.mjs +116 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/manifest-schema-validate.mjs +180 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/probe-utils.mjs +106 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/real-account-cloud-init-hardened.mjs +63 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/real-account-snapshot-on-demand.mjs +60 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/real-account-throwaway-server-provision.mjs +58 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/run-cloud-init-render-lint.mjs +9 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/run-hcloud-dry-run-mock.mjs +9 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/run-manifest-schema-validate.mjs +9 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/run-real-account-cloud-init-hardened.mjs +9 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/run-real-account-snapshot-on-demand.mjs +9 -0
- package/blueprints/deploy-hetzner-server/contributions/probes/run-real-account-throwaway-server-provision.mjs +9 -0
- package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-001.json +18 -0
- package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-002.json +18 -0
- package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-003.json +18 -0
- package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-004.json +18 -0
- package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-005.json +18 -0
- package/blueprints/deploy-hetzner-server/contributions/requirements/deploy-hetzner-server-req-006.json +18 -0
- package/blueprints/deploy-hetzner-server/contributions/schemas/hetzner-server.schema.json +108 -0
- package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3801-deploy-hetzner-server-provisioner.json +27 -0
- package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3802-deploy-hetzner-server-manifest-schema.json +26 -0
- package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3803-deploy-hetzner-server-cloud-init-template.json +26 -0
- package/blueprints/deploy-hetzner-server/contributions/tacs/tac-3804-deploy-hetzner-server-firewall-shape.json +25 -0
- package/blueprints/deploy-hetzner-server/contributions/templates/cloud-init.yaml.tmpl +93 -0
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37101.json +24 -0
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37102.json +24 -0
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37103.json +25 -0
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37104.json +24 -0
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37105.json +24 -0
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37106.json +25 -0
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37107.json +24 -0
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37108.json +24 -0
- package/blueprints/deploy-hetzner-server/contributions/user-stories/deploy-hetzner-server-us-37109.json +24 -0
- package/blueprints/deploy-hetzner-server/docs/topics.md +48 -0
- package/blueprints/deploy-hetzner-server/guide/deploy-hetzner-server.md +180 -0
- package/blueprints/edge-cloudflare-access/CHANGELOG.md +23 -0
- package/blueprints/edge-cloudflare-access/README.md +141 -0
- package/blueprints/edge-cloudflare-access/blueprint.json +197 -0
- package/blueprints/edge-cloudflare-access/contributions/adrs/adr-3501-edge-cloudflare-access-jwt-gate.json +14 -0
- package/blueprints/edge-cloudflare-access/contributions/adrs/adr-3502-edge-cloudflare-access-identity-provider.json +25 -0
- package/blueprints/edge-cloudflare-access/contributions/adrs/adr-3503-edge-cloudflare-access-policy-scope.json +12 -0
- package/blueprints/edge-cloudflare-access/contributions/adrs/adr-3504-edge-cloudflare-access-audit-retention.json +12 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/admin-console-gate-surface.mjs +100 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/audit-event-secrecy.mjs +70 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/jwt-validator-fixture.mjs +63 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/jwt-validator-reject.mjs +95 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/probe-utils.mjs +90 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/real-account-gated-url.mjs +65 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/run-admin-console-gate-surface.mjs +5 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/run-audit-event-secrecy.mjs +5 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/run-jwt-validator-fixture.mjs +5 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/run-jwt-validator-reject.mjs +5 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/run-real-account-gated-url.mjs +5 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/run-wrangler-seam.mjs +5 -0
- package/blueprints/edge-cloudflare-access/contributions/probes/wrangler-seam.mjs +203 -0
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-001.json +17 -0
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-002.json +17 -0
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-003.json +17 -0
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-004.json +17 -0
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-005.json +17 -0
- package/blueprints/edge-cloudflare-access/contributions/requirements/edge-cloudflare-access-req-006.json +18 -0
- package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3501-edge-cloudflare-access-jwt-validator.json +31 -0
- package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3502-edge-cloudflare-access-application-declaration.json +33 -0
- package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3503-edge-cloudflare-access-policy-shape.json +25 -0
- package/blueprints/edge-cloudflare-access/contributions/tacs/tac-3504-edge-cloudflare-access-audit-sink.json +25 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34101.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34102.json +28 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34103.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34104.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34105.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34106.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34107.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34108.json +27 -0
- package/blueprints/edge-cloudflare-access/contributions/user-stories/edge-cloudflare-access-us-34109.json +27 -0
- package/blueprints/edge-cloudflare-access/docs/topics.md +71 -0
- package/blueprints/edge-cloudflare-access/guide/edge-cloudflare-access.md +180 -0
- package/blueprints/edge-cloudflare-rate-limiting/CHANGELOG.md +10 -0
- package/blueprints/edge-cloudflare-rate-limiting/README.md +73 -0
- package/blueprints/edge-cloudflare-rate-limiting/blueprint.json +174 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/adrs/adr-3701-edge-cloudflare-rate-limiting-throttle-contract.json +14 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/adrs/adr-3702-edge-cloudflare-rate-limiting-layering.json +14 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/adrs/adr-3703-edge-cloudflare-rate-limiting-manifest-shape.json +14 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/adrs/adr-3704-edge-cloudflare-rate-limiting-drift-audit-cadence.json +14 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/event-secrecy.mjs +104 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/manifest-presence.mjs +95 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/manifest-schema-validate.mjs +130 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/probe-utils.mjs +111 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/real-account-burst-and-429.mjs +104 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/run-event-secrecy.mjs +5 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/run-manifest-presence.mjs +5 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/run-manifest-schema-validate.mjs +5 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/probes/run-real-account-burst-and-429.mjs +5 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-001.json +17 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-002.json +17 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-003.json +17 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-004.json +17 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/requirements/edge-cloudflare-rate-limiting-req-005.json +17 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/schemas/rate-limit-rule.schema.json +67 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3701-edge-cloudflare-rate-limiting-manifest-schema.json +31 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3702-edge-cloudflare-rate-limiting-management-surface-doc.json +25 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/tacs/tac-3703-edge-cloudflare-rate-limiting-drift-audit-runner.json +26 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36101.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36102.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36103.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36104.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36105.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36106.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36107.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/contributions/user-stories/edge-cloudflare-rate-limiting-us-36108.json +27 -0
- package/blueprints/edge-cloudflare-rate-limiting/docs/topics.md +71 -0
- package/blueprints/edge-cloudflare-rate-limiting/guide/edge-cloudflare-rate-limiting.md +88 -0
- package/blueprints/edge-cloudflare-tunnel/CHANGELOG.md +13 -0
- package/blueprints/edge-cloudflare-tunnel/README.md +257 -0
- package/blueprints/edge-cloudflare-tunnel/blueprint.json +168 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/adrs/adr-4001-edge-cloudflare-tunnel-ingress-bridge-contract.json +23 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/adrs/adr-4002-edge-cloudflare-tunnel-connector-runtime.json +19 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/adrs/adr-4003-edge-cloudflare-tunnel-hostname-mode.json +19 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/probes/aud-presence-check.mjs +114 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/probes/cloudflared-config-lint.mjs +80 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/probes/manifest-schema-validate.mjs +234 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/probes/probe-utils.mjs +231 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/probes/real-account-connector-healthy.mjs +54 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/probes/real-account-tunnel-hostname-routes.mjs +73 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-aud-presence-check.mjs +4 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-cloudflared-config-lint.mjs +4 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-manifest-schema-validate.mjs +4 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-real-account-connector-healthy.mjs +4 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/probes/run-real-account-tunnel-hostname-routes.mjs +4 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/probes/tunnel-manifest.schema.json +55 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-001.json +18 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-002.json +18 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-003.json +18 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-004.json +18 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/requirements/edge-cloudflare-tunnel-req-005.json +18 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4001-edge-cloudflare-tunnel-connector-shape.json +26 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4002-edge-cloudflare-tunnel-manifest-schema.json +26 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/tacs/tac-4003-edge-cloudflare-tunnel-access-binding.json +25 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39101.json +24 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39102.json +24 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39103.json +24 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39104.json +24 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39105.json +24 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39106.json +24 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39107.json +24 -0
- package/blueprints/edge-cloudflare-tunnel/contributions/user-stories/edge-cloudflare-tunnel-us-39108.json +24 -0
- package/blueprints/edge-cloudflare-tunnel/docs/topics.md +72 -0
- package/blueprints/edge-cloudflare-tunnel/guide/edge-cloudflare-tunnel.md +204 -0
- package/blueprints/edge-cloudflare-turnstile/CHANGELOG.md +20 -0
- package/blueprints/edge-cloudflare-turnstile/README.md +95 -0
- package/blueprints/edge-cloudflare-turnstile/blueprint.json +161 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/adrs/adr-3601-edge-cloudflare-turnstile-verifier-contract.json +14 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/adrs/adr-3602-edge-cloudflare-turnstile-widget-mode.json +14 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/adrs/adr-3603-edge-cloudflare-turnstile-refuse-shape.json +14 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/event-secrecy.mjs +51 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/guard-shape-scan.mjs +48 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/probe-utils.mjs +139 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/run-event-secrecy.mjs +5 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/run-guard-shape-scan.mjs +5 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/run-secret-shape-scan.mjs +5 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/run-siteverify-fixture.mjs +5 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/secret-shape-scan.mjs +77 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/probes/siteverify-fixture.mjs +53 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-001.json +17 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-002.json +17 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-003.json +17 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-004.json +17 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/requirements/edge-cloudflare-turnstile-req-005.json +17 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3601-edge-cloudflare-turnstile-widget-mount.json +26 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3602-edge-cloudflare-turnstile-server-verifier.json +36 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/tacs/tac-3603-edge-cloudflare-turnstile-magic-link-hook.json +25 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35101.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35102.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35103.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35104.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35105.json +36 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35106.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35107.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/contributions/user-stories/edge-cloudflare-turnstile-us-35108.json +27 -0
- package/blueprints/edge-cloudflare-turnstile/docs/topics.md +71 -0
- package/blueprints/edge-cloudflare-turnstile/guide/edge-cloudflare-turnstile.md +104 -0
- package/blueprints/edge-cloudflare-turnstile/probe-packs/edge-cloudflare-turnstile.pack.mjs +146 -0
- package/blueprints/email-smtp-resend/docs/topics.md +10 -1
- package/blueprints/jobs-background/docs/topics.md +10 -1
- package/blueprints/messaging-queue-cloudflare/docs/topics.md +10 -1
- package/blueprints/object-storage-s3/docs/topics.md +10 -1
- package/blueprints/observability-essentials/docs/topics.md +10 -1
- package/blueprints/observability-logging/docs/topics.md +10 -1
- package/blueprints/observability-probe-endpoints/docs/topics.md +10 -1
- package/blueprints/persistence-data-d1/docs/topics.md +10 -1
- package/blueprints/persistence-data-postgres/docs/topics.md +10 -1
- package/blueprints/persistence-data-sqlite/docs/topics.md +10 -1
- package/blueprints/platform-cloudflare-cron-triggers/CHANGELOG.md +22 -0
- package/blueprints/platform-cloudflare-cron-triggers/README.md +117 -0
- package/blueprints/platform-cloudflare-cron-triggers/blueprint.json +85 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/adrs/adr-3301-platform-cloudflare-cron-triggers-scheduled-trigger-contract.json +14 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/adrs/adr-3302-platform-cloudflare-cron-triggers-dispatcher-mode.json +14 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/adrs/adr-3303-platform-cloudflare-cron-triggers-skew-tolerance-default.json +14 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/dispatcher-routing.mjs +64 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/event-secrecy.mjs +100 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/probe-utils.mjs +70 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/real-account-scheduled-smoke.mjs +100 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-dispatcher-routing.mjs +5 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-event-secrecy.mjs +5 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-real-account-scheduled-smoke.mjs +5 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-skew-tolerance.mjs +5 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/run-wrangler-test-scheduled.mjs +5 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/skew-tolerance.mjs +130 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/probes/wrangler-test-scheduled.mjs +129 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-001.json +17 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-002.json +17 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-003.json +17 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/requirements/platform-cloudflare-cron-triggers-req-004.json +17 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3301-platform-cloudflare-cron-triggers-scheduled-handler.json +22 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3302-platform-cloudflare-cron-triggers-expression-router.json +22 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/tacs/tac-3303-platform-cloudflare-cron-triggers-event-sink.json +21 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32101.json +25 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32102.json +34 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32103.json +34 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32104.json +34 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32105.json +25 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32106.json +25 -0
- package/blueprints/platform-cloudflare-cron-triggers/contributions/user-stories/platform-cloudflare-cron-triggers-us-32107.json +25 -0
- package/blueprints/platform-cloudflare-cron-triggers/docs/topics.md +74 -0
- package/blueprints/platform-cloudflare-cron-triggers/guide/platform-cloudflare-cron-triggers.md +119 -0
- package/blueprints/platform-cloudflare-durable-objects/CHANGELOG.md +23 -0
- package/blueprints/platform-cloudflare-durable-objects/README.md +200 -0
- package/blueprints/platform-cloudflare-durable-objects/blueprint.json +243 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3401-platform-cloudflare-durable-objects-single-cell-contract.json +14 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3402-platform-cloudflare-durable-objects-websocket-hub-contract.json +14 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3403-platform-cloudflare-durable-objects-storage-backend.json +14 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3404-platform-cloudflare-durable-objects-migrations-shape.json +14 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/adrs/adr-3405-platform-cloudflare-durable-objects-hibernation-posture.json +14 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/alarm-fires-once.mjs +63 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/namespace-facade-ready.mjs +60 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/probe-utils.mjs +105 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/real-account-storage-smoke.mjs +58 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-alarm-fires-once.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-namespace-facade-ready.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-real-account-storage-smoke.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-single-cell-concurrent-increment.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-sole-reader-scan.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-storage-round-trip.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-websocket-hub-broadcast.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/run-wrangler-seam.mjs +5 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/single-cell-concurrent-increment.mjs +56 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/sole-reader-scan.mjs +117 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/storage-round-trip.mjs +87 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/websocket-hub-broadcast.mjs +112 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/probes/wrangler-seam.mjs +257 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-001.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-002.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-003.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-004.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-005.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-006.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-007.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/requirements/platform-cloudflare-durable-objects-req-008.json +17 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3401-platform-cloudflare-durable-objects-namespace-facade.json +31 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3402-platform-cloudflare-durable-objects-single-cell-shape.json +30 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3403-platform-cloudflare-durable-objects-alarm-handler.json +29 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3404-platform-cloudflare-durable-objects-websocket-hub.json +31 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/tacs/tac-3405-platform-cloudflare-durable-objects-event-sink.json +24 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33101.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33102.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33103.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33104.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33105.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33106.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33107.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33108.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33109.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33110.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33111.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33112.json +27 -0
- package/blueprints/platform-cloudflare-durable-objects/contributions/user-stories/platform-cloudflare-durable-objects-us-33113.json +25 -0
- package/blueprints/platform-cloudflare-durable-objects/docs/topics.md +76 -0
- package/blueprints/platform-cloudflare-durable-objects/guide/platform-cloudflare-durable-objects.md +237 -0
- package/blueprints/platform-cloudflare-kv/CHANGELOG.md +21 -0
- package/blueprints/platform-cloudflare-kv/README.md +159 -0
- package/blueprints/platform-cloudflare-kv/blueprint.json +87 -0
- package/blueprints/platform-cloudflare-kv/contributions/adrs/adr-3201-platform-cloudflare-kv-key-value-store-contract.json +14 -0
- package/blueprints/platform-cloudflare-kv/contributions/adrs/adr-3202-platform-cloudflare-kv-default-cache-ttl.json +14 -0
- package/blueprints/platform-cloudflare-kv/contributions/adrs/adr-3203-platform-cloudflare-kv-key-naming-convention.json +14 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/cache-aside-hit-then-miss.mjs +82 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/event-secrecy.mjs +102 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/facade-round-trip.mjs +92 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/list-with-prefix.mjs +52 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/probe-utils.mjs +73 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/real-account-eventual-consistency-smoke.mjs +102 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/run-cache-aside-hit-then-miss.mjs +5 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/run-event-secrecy.mjs +5 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/run-facade-round-trip.mjs +5 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/run-list-with-prefix.mjs +5 -0
- package/blueprints/platform-cloudflare-kv/contributions/probes/run-real-account-eventual-consistency-smoke.mjs +5 -0
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-001.json +18 -0
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-002.json +18 -0
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-003.json +18 -0
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-004.json +18 -0
- package/blueprints/platform-cloudflare-kv/contributions/requirements/platform-cloudflare-kv-req-005.json +18 -0
- package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3201-platform-cloudflare-kv-facade.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3202-platform-cloudflare-kv-cache-aside.json +26 -0
- package/blueprints/platform-cloudflare-kv/contributions/tacs/tac-3203-platform-cloudflare-kv-event-sink.json +25 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31101.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31102.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31103.json +36 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31104.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31105.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31106.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31107.json +27 -0
- package/blueprints/platform-cloudflare-kv/contributions/user-stories/platform-cloudflare-kv-us-31108.json +27 -0
- package/blueprints/platform-cloudflare-kv/docs/topics.md +74 -0
- package/blueprints/platform-cloudflare-kv/guide/platform-cloudflare-kv.md +138 -0
- package/blueprints/platform-docker-compose-host/CHANGELOG.md +12 -0
- package/blueprints/platform-docker-compose-host/README.md +76 -0
- package/blueprints/platform-docker-compose-host/blueprint.json +209 -0
- package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3901-platform-docker-compose-host-contract.json +14 -0
- package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3902-platform-docker-compose-host-reverse-proxy.json +14 -0
- package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3903-platform-docker-compose-host-reject-coolify.json +14 -0
- package/blueprints/platform-docker-compose-host/contributions/adrs/adr-3904-platform-docker-compose-host-log-driver.json +14 -0
- package/blueprints/platform-docker-compose-host/contributions/probes/caddyfile-validate.mjs +108 -0
- package/blueprints/platform-docker-compose-host/contributions/probes/compose-config-lint.mjs +231 -0
- package/blueprints/platform-docker-compose-host/contributions/probes/probe-utils.mjs +185 -0
- package/blueprints/platform-docker-compose-host/contributions/probes/real-account-minimal-stack-up.mjs +41 -0
- package/blueprints/platform-docker-compose-host/contributions/probes/real-account-reload-burst.mjs +36 -0
- package/blueprints/platform-docker-compose-host/contributions/probes/run-caddyfile-validate.mjs +5 -0
- package/blueprints/platform-docker-compose-host/contributions/probes/run-compose-config-lint.mjs +5 -0
- package/blueprints/platform-docker-compose-host/contributions/probes/run-real-account-minimal-stack-up.mjs +5 -0
- package/blueprints/platform-docker-compose-host/contributions/probes/run-real-account-reload-burst.mjs +5 -0
- package/blueprints/platform-docker-compose-host/contributions/probes/run-secrets-as-files-scan.mjs +5 -0
- package/blueprints/platform-docker-compose-host/contributions/probes/secrets-as-files-scan.mjs +116 -0
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-001.json +18 -0
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-002.json +18 -0
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-003.json +18 -0
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-004.json +18 -0
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-005.json +18 -0
- package/blueprints/platform-docker-compose-host/contributions/requirements/platform-docker-compose-host-req-006.json +18 -0
- package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3901-platform-docker-compose-host-compose-layout.json +26 -0
- package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3902-platform-docker-compose-host-secrets-mount.json +26 -0
- package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3903-platform-docker-compose-host-healthcheck-lint.json +26 -0
- package/blueprints/platform-docker-compose-host/contributions/tacs/tac-3904-platform-docker-compose-host-reverse-proxy-artefact.json +26 -0
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38101.json +24 -0
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38102.json +24 -0
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38103.json +24 -0
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38104.json +24 -0
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38105.json +25 -0
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38106.json +24 -0
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38107.json +24 -0
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38108.json +24 -0
- package/blueprints/platform-docker-compose-host/contributions/user-stories/platform-docker-compose-host-us-38109.json +24 -0
- package/blueprints/platform-docker-compose-host/docs/topics.md +71 -0
- package/blueprints/platform-docker-compose-host/guide/platform-docker-compose-host.md +94 -0
- package/blueprints/security-auth-clerk/docs/topics.md +10 -1
- package/blueprints/security-auth-keycloak/docs/topics.md +10 -1
- package/blueprints/security-auth-magic-link/docs/topics.md +10 -1
- package/blueprints/security-auth-oauth2/docs/topics.md +10 -1
- package/blueprints/security-secrets-management/docs/topics.md +10 -1
- package/fixtures/canary-manifest.json +9 -9
- package/package.json +1 -1
- package/rcf/adrs/adr-2214-application-admin-console-consume-zero-trust-gate.json +13 -0
- package/rcf/adrs/adr-3501-edge-cloudflare-access-jwt-gate.json +13 -0
- package/rcf/adrs/adr-3502-edge-cloudflare-access-identity-provider.json +13 -0
- package/rcf/adrs/adr-3503-edge-cloudflare-access-policy-scope.json +13 -0
- package/rcf/adrs/adr-3504-edge-cloudflare-access-audit-retention.json +13 -0
- package/rcf/adrs/adr-3601-edge-cloudflare-turnstile-verifier-contract.json +13 -0
- package/rcf/adrs/adr-3602-edge-cloudflare-turnstile-widget-mode.json +13 -0
- package/rcf/adrs/adr-3603-edge-cloudflare-turnstile-refuse-shape.json +13 -0
- package/rcf/adrs/adr-3701-edge-cloudflare-rate-limiting-throttle-contract.json +13 -0
- package/rcf/adrs/adr-3702-edge-cloudflare-rate-limiting-layering.json +13 -0
- package/rcf/adrs/adr-3703-edge-cloudflare-rate-limiting-manifest-shape.json +13 -0
- package/rcf/adrs/adr-3704-edge-cloudflare-rate-limiting-drift-audit-cadence.json +13 -0
- package/rcf/adrs/adr-3801-deploy-hetzner-server-cloud-host-contract.json +13 -0
- package/rcf/adrs/adr-3802-deploy-hetzner-server-snapshot-cadence.json +13 -0
- package/rcf/adrs/adr-3803-deploy-hetzner-server-provisioning-tool.json +13 -0
- package/rcf/adrs/adr-3804-deploy-hetzner-server-hardening-baseline.json +13 -0
- package/rcf/adrs/adr-3901-platform-docker-compose-host-contract.json +13 -0
- package/rcf/adrs/adr-3902-platform-docker-compose-host-reverse-proxy.json +13 -0
- package/rcf/adrs/adr-3903-platform-docker-compose-host-reject-coolify.json +13 -0
- package/rcf/adrs/adr-3904-platform-docker-compose-host-log-driver.json +13 -0
- package/rcf/adrs/adr-4001-edge-cloudflare-tunnel-ingress-bridge-contract.json +13 -0
- package/rcf/adrs/adr-4002-edge-cloudflare-tunnel-connector-runtime.json +13 -0
- package/rcf/adrs/adr-4003-edge-cloudflare-tunnel-hostname-mode.json +13 -0
- package/rcf/code-nodes/cn-230.json +13 -0
- package/rcf/code-nodes/cn-231.json +14 -0
- package/rcf/code-nodes/cn-232.json +13 -0
- package/rcf/code-nodes/cn-233.json +14 -0
- package/rcf/code-nodes/cn-234.json +13 -0
- package/rcf/code-nodes/cn-260.json +21 -0
- package/rcf/code-nodes/cn-261.json +14 -0
- package/rcf/code-nodes/cn-262.json +18 -0
- package/rcf/code-nodes/cn-263.json +12 -0
- package/rcf/code-nodes/cn-264.json +13 -0
- package/rcf/code-nodes/cn-265.json +15 -0
- package/rcf/code-nodes/cn-266.json +12 -0
- package/rcf/code-nodes/cn-267.json +12 -0
- package/rcf/code-nodes/cn-290.json +21 -0
- package/rcf/code-nodes/cn-291.json +12 -0
- package/rcf/code-nodes/cn-292.json +13 -0
- package/rcf/code-nodes/cn-293.json +13 -0
- package/rcf/code-nodes/cn-294.json +13 -0
- package/rcf/code-nodes/cn-295.json +12 -0
- package/rcf/code-nodes/cn-296.json +12 -0
- package/rcf/code-nodes/cn-297.json +12 -0
- package/rcf/code-nodes/cn-298.json +12 -0
- package/rcf/code-nodes/cn-299.json +12 -0
- package/rcf/code-nodes/cn-300.json +12 -0
- package/rcf/code-nodes/cn-301.json +14 -0
- package/rcf/code-nodes/cn-302.json +12 -0
- package/rcf/code-nodes/cn-303.json +12 -0
- package/rcf/code-nodes/cn-304.json +21 -0
- package/rcf/code-nodes/cn-320.json +20 -0
- package/rcf/code-nodes/cn-321.json +14 -0
- package/rcf/code-nodes/cn-350.json +19 -0
- package/rcf/code-nodes/cn-380.json +19 -0
- package/rcf/code-nodes/cn-410.json +20 -0
- package/rcf/code-nodes/cn-440.json +20 -0
- package/rcf/code-nodes/cn-470.json +19 -0
- package/rcf/fbs/fbs-070.json +24 -0
- package/rcf/fbs/fbs-080.json +24 -0
- package/rcf/fbs/fbs-090.json +24 -0
- package/rcf/fbs/fbs-100.json +23 -0
- package/rcf/fbs/fbs-101.json +16 -0
- package/rcf/fbs/fbs-110.json +23 -0
- package/rcf/fbs/fbs-120.json +22 -0
- package/rcf/fbs/fbs-130.json +23 -0
- package/rcf/fbs/fbs-140.json +23 -0
- package/rcf/fbs/fbs-150.json +22 -0
- package/rcf/requirements/req-050.json +18 -0
- package/rcf/requirements/req-051.json +18 -0
- package/rcf/requirements/req-052.json +18 -0
- package/rcf/requirements/req-053.json +18 -0
- package/rcf/requirements/req-054.json +18 -0
- package/rcf/requirements/req-060.json +20 -0
- package/rcf/requirements/req-061.json +18 -0
- package/rcf/requirements/req-062.json +20 -0
- package/rcf/requirements/req-063.json +20 -0
- package/rcf/requirements/req-070.json +18 -0
- package/rcf/requirements/req-071.json +18 -0
- package/rcf/requirements/req-072.json +18 -0
- package/rcf/requirements/req-073.json +18 -0
- package/rcf/requirements/req-074.json +18 -0
- package/rcf/requirements/req-075.json +18 -0
- package/rcf/requirements/req-076.json +18 -0
- package/rcf/requirements/req-077.json +18 -0
- package/rcf/requirements/req-080.json +18 -0
- package/rcf/requirements/req-081.json +18 -0
- package/rcf/requirements/req-082.json +18 -0
- package/rcf/requirements/req-083.json +18 -0
- package/rcf/requirements/req-084.json +18 -0
- package/rcf/requirements/req-085.json +18 -0
- package/rcf/requirements/req-086.json +18 -0
- package/rcf/requirements/req-090.json +44 -0
- package/rcf/requirements/req-091.json +53 -0
- package/rcf/requirements/req-092.json +32 -0
- package/rcf/requirements/req-093.json +52 -0
- package/rcf/requirements/req-094.json +32 -0
- package/rcf/requirements/req-100.json +13 -0
- package/rcf/requirements/req-101.json +13 -0
- package/rcf/requirements/req-102.json +13 -0
- package/rcf/requirements/req-103.json +13 -0
- package/rcf/requirements/req-104.json +13 -0
- package/rcf/requirements/req-110.json +58 -0
- package/rcf/requirements/req-111.json +32 -0
- package/rcf/requirements/req-112.json +42 -0
- package/rcf/requirements/req-113.json +33 -0
- package/rcf/requirements/req-114.json +20 -0
- package/rcf/requirements/req-115.json +38 -0
- package/rcf/requirements/req-120.json +20 -0
- package/rcf/requirements/req-121.json +20 -0
- package/rcf/requirements/req-122.json +20 -0
- package/rcf/requirements/req-123.json +42 -0
- package/rcf/requirements/req-124.json +27 -0
- package/rcf/requirements/req-125.json +20 -0
- package/rcf/requirements/req-130.json +32 -0
- package/rcf/requirements/req-131.json +54 -0
- package/rcf/requirements/req-132.json +27 -0
- package/rcf/requirements/req-133.json +20 -0
- package/rcf/requirements/req-134.json +42 -0
- package/rcf/tacs/tac-2214-application-admin-console-access-gated-signin-surface.json +15 -0
- package/rcf/tacs/tac-3501-edge-cloudflare-access-jwt-validator.json +15 -0
- package/rcf/tacs/tac-3502-edge-cloudflare-access-application-declaration.json +15 -0
- package/rcf/tacs/tac-3503-edge-cloudflare-access-policy-shape.json +15 -0
- package/rcf/tacs/tac-3504-edge-cloudflare-access-audit-sink.json +15 -0
- package/rcf/tacs/tac-3601-edge-cloudflare-turnstile-widget-mount.json +15 -0
- package/rcf/tacs/tac-3602-edge-cloudflare-turnstile-server-verifier.json +15 -0
- package/rcf/tacs/tac-3603-edge-cloudflare-turnstile-magic-link-hook.json +15 -0
- package/rcf/tacs/tac-3701-edge-cloudflare-rate-limiting-manifest-schema.json +16 -0
- package/rcf/tacs/tac-3702-edge-cloudflare-rate-limiting-management-surface-doc.json +15 -0
- package/rcf/tacs/tac-3703-edge-cloudflare-rate-limiting-drift-audit-runner.json +16 -0
- package/rcf/tacs/tac-3801-deploy-hetzner-server-provisioner.json +17 -0
- package/rcf/tacs/tac-3802-deploy-hetzner-server-manifest-schema.json +17 -0
- package/rcf/tacs/tac-3803-deploy-hetzner-server-cloud-init-template.json +17 -0
- package/rcf/tacs/tac-3804-deploy-hetzner-server-firewall-shape.json +16 -0
- package/rcf/tacs/tac-3901-platform-docker-compose-host-compose-layout.json +17 -0
- package/rcf/tacs/tac-3902-platform-docker-compose-host-secrets-mount.json +17 -0
- package/rcf/tacs/tac-3903-platform-docker-compose-host-healthcheck-lint.json +17 -0
- package/rcf/tacs/tac-3904-platform-docker-compose-host-reverse-proxy-artefact.json +17 -0
- package/rcf/tacs/tac-4001-edge-cloudflare-tunnel-connector-shape.json +17 -0
- package/rcf/tacs/tac-4002-edge-cloudflare-tunnel-manifest-schema.json +17 -0
- package/rcf/tacs/tac-4003-edge-cloudflare-tunnel-access-binding.json +16 -0
- package/rcf/test-suites/ts-052.json +58 -8
- package/rcf/test-suites/ts-080.json +22 -0
- package/rcf/test-suites/ts-081.json +22 -0
- package/rcf/test-suites/ts-082.json +30 -0
- package/rcf/test-suites/ts-083.json +22 -0
- package/rcf/test-suites/ts-084.json +30 -0
- package/rcf/test-suites/ts-085.json +22 -0
- package/rcf/test-suites/ts-086.json +22 -0
- package/rcf/test-suites/ts-087.json +22 -0
- package/rcf/test-suites/ts-090.json +22 -0
- package/rcf/test-suites/ts-091.json +22 -0
- package/rcf/test-suites/ts-092.json +22 -0
- package/rcf/test-suites/ts-093.json +30 -0
- package/rcf/test-suites/ts-094.json +30 -0
- package/rcf/test-suites/ts-095.json +30 -0
- package/rcf/test-suites/ts-096.json +22 -0
- package/rcf/test-suites/ts-100.json +22 -0
- package/rcf/test-suites/ts-101.json +22 -0
- package/rcf/test-suites/ts-102.json +22 -0
- package/rcf/test-suites/ts-103.json +22 -0
- package/rcf/test-suites/ts-104.json +22 -0
- package/rcf/test-suites/ts-105.json +22 -0
- package/rcf/test-suites/ts-106.json +22 -0
- package/rcf/test-suites/ts-107.json +22 -0
- package/rcf/test-suites/ts-108.json +22 -0
- package/rcf/test-suites/ts-109.json +22 -0
- package/rcf/test-suites/ts-110.json +22 -0
- package/rcf/test-suites/ts-111.json +22 -0
- package/rcf/test-suites/ts-112.json +22 -0
- package/rcf/test-suites/ts-113.json +22 -0
- package/rcf/test-suites/ts-114.json +22 -0
- package/rcf/test-suites/ts-115.json +22 -0
- package/rcf/test-suites/ts-116.json +22 -0
- package/rcf/test-suites/ts-117.json +22 -0
- package/rcf/test-suites/ts-118.json +22 -0
- package/rcf/test-suites/ts-119.json +30 -0
- package/rcf/test-suites/ts-120.json +22 -0
- package/rcf/test-suites/ts-121.json +22 -0
- package/rcf/test-suites/ts-122.json +22 -0
- package/rcf/test-suites/ts-123.json +22 -0
- package/rcf/test-suites/ts-124.json +22 -0
- package/rcf/test-suites/ts-125.json +22 -0
- package/rcf/test-suites/ts-126.json +22 -0
- package/rcf/test-suites/ts-127.json +22 -0
- package/rcf/test-suites/ts-130.json +22 -0
- package/rcf/test-suites/ts-131.json +22 -0
- package/rcf/test-suites/ts-132.json +22 -0
- package/rcf/test-suites/ts-133.json +22 -0
- package/rcf/test-suites/ts-134.json +22 -0
- package/rcf/test-suites/ts-135.json +22 -0
- package/rcf/test-suites/ts-136.json +22 -0
- package/rcf/test-suites/ts-137.json +22 -0
- package/rcf/test-suites/ts-140.json +86 -0
- package/rcf/test-suites/ts-150.json +86 -0
- package/rcf/test-suites/ts-160.json +78 -0
- package/rcf/user-stories/us-10001.json +23 -0
- package/rcf/user-stories/us-10101.json +23 -0
- package/rcf/user-stories/us-10201.json +23 -0
- package/rcf/user-stories/us-10301.json +23 -0
- package/rcf/user-stories/us-10401.json +23 -0
- package/rcf/user-stories/us-10601.json +23 -0
- package/rcf/user-stories/us-10701.json +23 -0
- package/rcf/user-stories/us-10801.json +23 -0
- package/rcf/user-stories/us-11001.json +23 -0
- package/rcf/user-stories/us-11101.json +23 -0
- package/rcf/user-stories/us-11102.json +24 -0
- package/rcf/user-stories/us-11201.json +23 -0
- package/rcf/user-stories/us-11202.json +23 -0
- package/rcf/user-stories/us-11301.json +24 -0
- package/rcf/user-stories/us-11401.json +23 -0
- package/rcf/user-stories/us-11402.json +23 -0
- package/rcf/user-stories/us-11501.json +23 -0
- package/rcf/user-stories/us-12001.json +23 -0
- package/rcf/user-stories/us-12101.json +23 -0
- package/rcf/user-stories/us-12102.json +23 -0
- package/rcf/user-stories/us-12201.json +23 -0
- package/rcf/user-stories/us-12202.json +24 -0
- package/rcf/user-stories/us-12301.json +23 -0
- package/rcf/user-stories/us-12401.json +23 -0
- package/rcf/user-stories/us-12402.json +23 -0
- package/rcf/user-stories/us-12501.json +23 -0
- package/rcf/user-stories/us-13001.json +23 -0
- package/rcf/user-stories/us-13002.json +23 -0
- package/rcf/user-stories/us-13101.json +23 -0
- package/rcf/user-stories/us-13102.json +23 -0
- package/rcf/user-stories/us-13201.json +23 -0
- package/rcf/user-stories/us-13301.json +23 -0
- package/rcf/user-stories/us-13302.json +23 -0
- package/rcf/user-stories/us-13401.json +23 -0
- package/rcf/user-stories/us-5001.json +27 -0
- package/rcf/user-stories/us-5002.json +27 -0
- package/rcf/user-stories/us-5101.json +36 -0
- package/rcf/user-stories/us-5102.json +27 -0
- package/rcf/user-stories/us-5201.json +36 -0
- package/rcf/user-stories/us-5301.json +27 -0
- package/rcf/user-stories/us-5302.json +27 -0
- package/rcf/user-stories/us-5401.json +27 -0
- package/rcf/user-stories/us-6001.json +27 -0
- package/rcf/user-stories/us-6002.json +27 -0
- package/rcf/user-stories/us-6003.json +27 -0
- package/rcf/user-stories/us-6101.json +36 -0
- package/rcf/user-stories/us-6201.json +36 -0
- package/rcf/user-stories/us-6301.json +36 -0
- package/rcf/user-stories/us-6302.json +27 -0
- package/rcf/user-stories/us-7001.json +27 -0
- package/rcf/user-stories/us-7002.json +27 -0
- package/rcf/user-stories/us-7101.json +27 -0
- package/rcf/user-stories/us-7201.json +27 -0
- package/rcf/user-stories/us-7301.json +27 -0
- package/rcf/user-stories/us-7401.json +27 -0
- package/rcf/user-stories/us-7402.json +27 -0
- package/rcf/user-stories/us-7501.json +27 -0
- package/rcf/user-stories/us-7601.json +27 -0
- package/rcf/user-stories/us-7701.json +27 -0
- package/rcf/user-stories/us-8001.json +24 -0
- package/rcf/user-stories/us-8002.json +24 -0
- package/rcf/user-stories/us-8003.json +24 -0
- package/rcf/user-stories/us-8101.json +24 -0
- package/rcf/user-stories/us-8201.json +24 -0
- package/rcf/user-stories/us-8301.json +24 -0
- package/rcf/user-stories/us-8401.json +24 -0
- package/rcf/user-stories/us-8501.json +24 -0
- package/rcf/user-stories/us-8502.json +24 -0
- package/rcf/user-stories/us-8601.json +24 -0
- package/rcf/user-stories/us-8602.json +24 -0
- package/rcf/user-stories/us-9001.json +27 -0
- package/rcf/user-stories/us-9002.json +27 -0
- package/rcf/user-stories/us-9101.json +27 -0
- package/rcf/user-stories/us-9102.json +27 -0
- package/rcf/user-stories/us-9201.json +27 -0
- package/rcf/user-stories/us-9301.json +27 -0
- package/rcf/user-stories/us-9302.json +27 -0
- package/rcf/user-stories/us-9401.json +27 -0
- package/releases/releases.yaml +21 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "deploy-hetzner-server-US-37104",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "deploy-hetzner-server-REQ-003",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Cloud-init template renders the six hardening baseline blocks",
|
|
8
|
+
"asA": "developer whose project provisions Hetzner servers that face the public internet",
|
|
9
|
+
"iWant": "the shipped cloud-init template to render YAML that lands SSH key-only, root disabled, UFW default-deny incoming, DOCKER-USER iptables chain, fail2ban SSH jail and unattended-upgrades on every server",
|
|
10
|
+
"soThat": "I inherit the six-block hardening baseline declaratively without hand-authoring per host",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-37104-1",
|
|
14
|
+
"description": "cloud-init-render-lint.mjs renders the template with the fixture manifest and asserts each of the six baseline blocks (SSH key-only, root disabled, UFW default-deny incoming, DOCKER-USER iptables chain, fail2ban SSH jail, unattended-upgrades) appears in the rendered YAML by grep; a mutation SIMULATE_HARDENING_DRIFT=true removes the unattended-upgrades block and the probe FAILS with a message naming the missing line.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"scope": "runtime"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"tacIds": [
|
|
20
|
+
"TAC-3803-deploy-hetzner-server-cloud-init-template"
|
|
21
|
+
],
|
|
22
|
+
"createdAt": "2026-09-08T00:00:00.000Z",
|
|
23
|
+
"updatedAt": "2026-09-08T00:00:00.000Z"
|
|
24
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "deploy-hetzner-server-US-37105",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "deploy-hetzner-server-REQ-003",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Provisioned server is hardened at runtime as the rendered cloud-init promised",
|
|
8
|
+
"asA": "operator running Hetzner servers provisioned by this blueprint",
|
|
9
|
+
"iWant": "the running server to refuse root ssh, refuse password auth, run UFW default-deny incoming, hold the DOCKER-USER chain and run unattended-upgrades",
|
|
10
|
+
"soThat": "I can trust the cloud-init contract without ssh-in-and-check on every server",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-37105-1",
|
|
14
|
+
"description": "real-account-cloud-init-hardened.mjs (accountBound: true, skipped without CI_HAS_HETZNER_ACCOUNT) waits for cloud-init status --wait on the throwaway server, then ssh-checks the six baseline blocks and asserts each check passes; failure names the missing block. Teardown via destroy.mjs runs regardless.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"scope": "runtime"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"tacIds": [
|
|
20
|
+
"TAC-3803-deploy-hetzner-server-cloud-init-template"
|
|
21
|
+
],
|
|
22
|
+
"createdAt": "2026-09-08T00:00:00.000Z",
|
|
23
|
+
"updatedAt": "2026-09-08T00:00:00.000Z"
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "deploy-hetzner-server-US-37106",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "deploy-hetzner-server-REQ-004",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Firewall rule shape restricts SSH to nominated prefixes, permits 80/443, denies all else",
|
|
8
|
+
"asA": "operator running Hetzner servers that face the public internet",
|
|
9
|
+
"iWant": "the firewall rule set carried in hetzner/servers/name.json to permit 22 only from an operator-nominated set of source-prefix ranges, permit 80 and 443 from any source for the reverse proxy, and deny all other inbound; the provisioner applies the rules at provision time",
|
|
10
|
+
"soThat": "I inherit a documented least-privilege firewall shape on every server without opening ssh to the world",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-37106-1",
|
|
14
|
+
"description": "manifest-schema-validate.mjs asserts every fixture manifest carries a firewallRules array matching the shape (22 permitted only from a nonempty list of source-prefix ranges with no 0.0.0.0/0; 80 and 443 permitted from 0.0.0.0/0; no other inbound rule); an induced defect (a manifest that opens 22 to 0.0.0.0/0) FAILS schema validation with a message naming the offending rule.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"scope": "runtime"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"tacIds": [
|
|
20
|
+
"TAC-3802-deploy-hetzner-server-manifest-schema",
|
|
21
|
+
"TAC-3804-deploy-hetzner-server-firewall-shape"
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-09-08T00:00:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-08T00:00:00.000Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "deploy-hetzner-server-US-37107",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "deploy-hetzner-server-REQ-005",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Snapshot cadence is elicited (weekly default, daily and off alternatives) and validated on the manifest",
|
|
8
|
+
"asA": "operator whose project takes recovery-point snapshots on Hetzner Cloud",
|
|
9
|
+
"iWant": "the elicited snapshot cadence value on hetzner/servers/name.json to match the shipped enum {weekly, daily, off}, with weekly the recommended default per ADR-3802",
|
|
10
|
+
"soThat": "I have one project-wide answer for how often each server snapshots",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-37107-1",
|
|
14
|
+
"description": "manifest-schema-validate.mjs asserts every fixture manifest carries snapshotCadence with a value in the shipped enum {weekly, daily, off}; a manifest missing the field FAILS schema validation naming the missing field.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"scope": "runtime"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"tacIds": [
|
|
20
|
+
"TAC-3802-deploy-hetzner-server-manifest-schema"
|
|
21
|
+
],
|
|
22
|
+
"createdAt": "2026-09-08T00:00:00.000Z",
|
|
23
|
+
"updatedAt": "2026-09-08T00:00:00.000Z"
|
|
24
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "deploy-hetzner-server-US-37108",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "deploy-hetzner-server-REQ-005",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Snapshot-on-demand fires a tagged snapshot and emits hetznerSnapshotTaken",
|
|
8
|
+
"asA": "operator whose project needs an on-demand recovery point at any moment",
|
|
9
|
+
"iWant": "the snapshot-on-demand verb on the provisioner to shell to hcloud image create-image (or the raw-api equivalent) and tag the snapshot with server name and wall-clock time; hetznerSnapshotTaken carries snapshot id and time",
|
|
10
|
+
"soThat": "I have a documented on-demand recovery point at any moment without a manual dashboard visit",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-37108-1",
|
|
14
|
+
"description": "real-account-snapshot-on-demand.mjs (accountBound: true, skipped without CI_HAS_HETZNER_ACCOUNT) fires the snapshot verb on the throwaway server, then asserts hcloud image list --type=snapshot --output json shows a snapshot tagged with the server name and current wall-clock time; hetznerSnapshotTaken event carries snapshot id and time. Teardown via destroy.mjs.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"scope": "runtime"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"tacIds": [
|
|
20
|
+
"TAC-3801-deploy-hetzner-server-provisioner"
|
|
21
|
+
],
|
|
22
|
+
"createdAt": "2026-09-08T00:00:00.000Z",
|
|
23
|
+
"updatedAt": "2026-09-08T00:00:00.000Z"
|
|
24
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "deploy-hetzner-server-US-37109",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "deploy-hetzner-server-REQ-006",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Four lifecycle events fire with metadata-only payloads and no event body carries a secret",
|
|
8
|
+
"asA": "operator whose observability sink carries the Hetzner lifecycle trail",
|
|
9
|
+
"iWant": "the provisioner facade to fire the four lifecycle events (provisionerReady, hetznerServerProvisioned, hetznerSnapshotTaken, hetznerServerDestroyed) with metadata-only payloads and no secret content",
|
|
10
|
+
"soThat": "the observability sink carries the operational trail without ever leaking a token or an ssh key",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-37109-1",
|
|
14
|
+
"description": "hcloud-dry-run-mock.mjs drives every lifecycle event through the facade against a mocked hcloud shim; the accumulated event stream carries only the metadata fields named on REQ-006; a mutation SIMULATE_EVENT_SECRECY_LEAK=true injects the token into the hetznerServerProvisioned payload and the probe FAILS with a defensive-fake finding naming the leaked field.",
|
|
15
|
+
"testable": true,
|
|
16
|
+
"scope": "runtime"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"tacIds": [
|
|
20
|
+
"TAC-3801-deploy-hetzner-server-provisioner"
|
|
21
|
+
],
|
|
22
|
+
"createdAt": "2026-09-08T00:00:00.000Z",
|
|
23
|
+
"updatedAt": "2026-09-08T00:00:00.000Z"
|
|
24
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# deploy-hetzner-server topics
|
|
2
|
+
|
|
3
|
+
Shelf registry of global ADR topics and shelf-band anchors relevant
|
|
4
|
+
to `deploy-hetzner-server` v1.0.0.
|
|
5
|
+
|
|
6
|
+
## Global topics minted by this blueprint
|
|
7
|
+
|
|
8
|
+
| Topic | ADR | Meaning |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| `linuxCloudHostContract` | `ADR-3801` | The Hetzner Cloud VM as the shipped `cloudHost` shape. A future non-Hetzner sibling (Vultr, DigitalOcean, Fly.io) contributes the same topic string with a different provider and forces a deliberate conflict per the round-2 pattern. |
|
|
11
|
+
| `snapshotAndBackupCadence` | `ADR-3802` | Weekly snapshot as the shipped default, daily and off alternatives, Hetzner-managed backups as an elicited paid opt-in at approximately 20 percent of monthly server price. |
|
|
12
|
+
|
|
13
|
+
## Shelf id band and suffix block
|
|
14
|
+
|
|
15
|
+
| Blueprint | US band | ADR/TAC suffix block | Status | Global topics |
|
|
16
|
+
|---|---|---|---|---|
|
|
17
|
+
| application-datatable | 17101-17899 | 18xx | shipped v1.0.0 | none |
|
|
18
|
+
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
19
|
+
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
20
|
+
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
21
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.1.0 | `adminConsoleSignInSurface` |
|
|
22
|
+
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
23
|
+
| application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
|
|
24
|
+
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
25
|
+
| application-account-settings | 25101-25899 | 26xx | shipped v1.0.0 | none |
|
|
26
|
+
| application-onboarding-tour | 26101-26899 | 27xx | shipped v1.0.0 | none |
|
|
27
|
+
| persistence-data-postgres | 27101-27899 | 28xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
|
|
28
|
+
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
29
|
+
| messaging-queue-cloudflare | 29101-29899 | 30xx | shipped v1.0.0 | `deliverySemantics` |
|
|
30
|
+
| jobs-background | 30101-30899 | 31xx | shipped v1.0.0 | `backgroundJobModel` |
|
|
31
|
+
| platform-cloudflare-kv | 31101-31899 | 32xx | shipped v1.0.0 | `keyValueStoreContract` |
|
|
32
|
+
| platform-cloudflare-cron-triggers | 32101-32899 | 33xx | shipped v1.0.0 | `scheduledTriggerContract` |
|
|
33
|
+
| platform-cloudflare-durable-objects | 33101-33899 | 34xx | shipped v1.0.0 | `strongConsistencyCellContract`, `websocketHubContract` |
|
|
34
|
+
| edge-cloudflare-access | 34101-34899 | 35xx | shipped v1.0.0 | `edgeAuthenticationGate` |
|
|
35
|
+
| edge-cloudflare-turnstile | 35101-35899 | 36xx | shipped v1.0.0 | `humanVerificationGate` |
|
|
36
|
+
| edge-cloudflare-rate-limiting | 36101-36899 | 37xx | shipped v1.0.0 | `edgeThrottleContract` |
|
|
37
|
+
| deploy-hetzner-server | 37101-37899 | 38xx | shipped v1.0.0 | `linuxCloudHostContract`, `snapshotAndBackupCadence` |
|
|
38
|
+
| platform-docker-compose-host | 38101-38899 | 39xx | shipped v1.0.0 | `containerHostContract` |
|
|
39
|
+
| edge-cloudflare-tunnel | 39101-39899 | 40xx | shipped v1.0.0 | `edgeIngressBridge` |
|
|
40
|
+
|
|
41
|
+
The shelf-wide band registry lives in `packages/rcf-lite/docs/blueprint-authoring.md` section 5.
|
|
42
|
+
|
|
43
|
+
## Cross-references
|
|
44
|
+
|
|
45
|
+
- `security-secrets-management` (v1.0.1): the provisioner facade reads `HETZNER_ACCOUNT_API_KEY` through the applied secrets facade. The facade is the sole reader; every other module in the applying project imports the facade and never dereferences the token.
|
|
46
|
+
- `deploy-cloudflare-workers` (v1.2.0): sibling in the `deploy-*` family. The family enforces one-target-per-project at apply time (a project applying both refuses with `deploy-family-multiple-targets`).
|
|
47
|
+
- Round-7 T-2 `platform-docker-compose-host`: composes on `capabilities: [cloudHost]`; ships the compose runtime on the Hetzner host this blueprint provisions.
|
|
48
|
+
- Round-7 T-3 `edge-cloudflare-tunnel`: composes on `cloudHost` (systemd unit shape) or on `containerHost` (compose service shape); either shape bridges the Hetzner host to the Cloudflare edge without opening origin ports.
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# deploy-hetzner-server guide
|
|
2
|
+
|
|
3
|
+
Practical guide for the operator applying `deploy-hetzner-server`
|
|
4
|
+
v1.0.0. Covers manifest authoring, the two provisioner paths, the
|
|
5
|
+
hardening baseline, snapshot posture, elicitation shortcuts, and
|
|
6
|
+
the runtime probe rig.
|
|
7
|
+
|
|
8
|
+
## Prerequisites
|
|
9
|
+
|
|
10
|
+
- A Hetzner Cloud project and API token. The token binds to one
|
|
11
|
+
project; a fresh throwaway project keeps the blast radius small
|
|
12
|
+
during onboarding.
|
|
13
|
+
- `hcloud` on `PATH` when `provisioning-tool` is `hcloud`. Install:
|
|
14
|
+
Homebrew `brew install hcloud` on macOS, or download the OS/arch
|
|
15
|
+
tarball from https://github.com/hetznercloud/cli/releases/latest,
|
|
16
|
+
verify against `checksums.txt`, drop the binary on `PATH`. Skip
|
|
17
|
+
the install when `provisioning-tool` is `raw-api`; the provisioner
|
|
18
|
+
reaches the REST API directly.
|
|
19
|
+
- `security-secrets-management` applied so the facade reads
|
|
20
|
+
`HETZNER_ACCOUNT_API_KEY` from the operator's vault of choice.
|
|
21
|
+
|
|
22
|
+
## Authoring `hetzner/servers/<name>.json`
|
|
23
|
+
|
|
24
|
+
Every server declaration lives at
|
|
25
|
+
`hetzner/servers/<server-name>.json` and validates against the
|
|
26
|
+
shipped `hetzner-server.schema.json`. The fixture manifest at
|
|
27
|
+
`packages/rcf-lite/test/fixtures/hetzner-throwaway-server/hetzner/servers/ci-throwaway.json`
|
|
28
|
+
is the canonical example. Copy it and edit:
|
|
29
|
+
|
|
30
|
+
```jsonc
|
|
31
|
+
{
|
|
32
|
+
"name": "ops-01",
|
|
33
|
+
"serverType": "cx33",
|
|
34
|
+
"location": "fsn1",
|
|
35
|
+
"image": "ubuntu-24.04",
|
|
36
|
+
"sshKeyIds": ["dave-ed25519", "baz-yubikey"],
|
|
37
|
+
"networkId": null,
|
|
38
|
+
"firewallId": null,
|
|
39
|
+
"cloudInitPath": "hetzner/servers/rendered/ops-01.cloud-init.yaml",
|
|
40
|
+
"labels": {
|
|
41
|
+
"role": "ops-host",
|
|
42
|
+
"blueprint": "deploy-hetzner-server"
|
|
43
|
+
},
|
|
44
|
+
"firewallRules": [
|
|
45
|
+
{ "name": "ssh", "protocol": "tcp", "port": 22, "direction": "in", "sourceIps": ["203.0.113.0/24"] },
|
|
46
|
+
{ "name": "http", "protocol": "tcp", "port": 80, "direction": "in", "sourceIps": ["0.0.0.0/0", "::/0"] },
|
|
47
|
+
{ "name": "https", "protocol": "tcp", "port": 443, "direction": "in", "sourceIps": ["0.0.0.0/0", "::/0"] }
|
|
48
|
+
],
|
|
49
|
+
"snapshotCadence": "weekly",
|
|
50
|
+
"hetznerManagedBackups": false
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The manifest-schema-validate probe refuses on missing required
|
|
55
|
+
fields and on a rule set that opens 22 to `0.0.0.0/0`.
|
|
56
|
+
|
|
57
|
+
## Rendering cloud-init
|
|
58
|
+
|
|
59
|
+
Point `cloudInitPath` at a rendered file the provisioner uploads
|
|
60
|
+
with `--user-data-from-file`. The fixture renderer at
|
|
61
|
+
`packages/rcf-lite/test/fixtures/hetzner-throwaway-server/src/cloud-init-renderer.mjs`
|
|
62
|
+
consumes the shipped template with two placeholders:
|
|
63
|
+
|
|
64
|
+
- `{{name}}` (the manifest name)
|
|
65
|
+
- `{{sshAuthorizedKeysBlock}}` (the ssh-authorized_keys entries per
|
|
66
|
+
`sshKeyIds`)
|
|
67
|
+
|
|
68
|
+
An applying project runs the renderer at manifest edit time (a git
|
|
69
|
+
pre-commit hook, or a `pnpm build:cloud-init` script) and commits
|
|
70
|
+
the rendered YAML alongside the manifest.
|
|
71
|
+
|
|
72
|
+
## Six hardening baseline blocks (ADR-3804)
|
|
73
|
+
|
|
74
|
+
The rendered YAML lands the six blocks per the estate baseline at
|
|
75
|
+
`operator/knowledge/systems/environments/hetzner-cloud/overview.md`
|
|
76
|
+
Security posture baseline and the Debian unattended-upgrades wiki
|
|
77
|
+
at https://wiki.debian.org/UnattendedUpgrades.
|
|
78
|
+
|
|
79
|
+
1. SSH key-only. `PasswordAuthentication no`.
|
|
80
|
+
2. Root disabled. `PermitRootLogin no`.
|
|
81
|
+
3. UFW default-deny incoming. `ufw allow 22/tcp 80/tcp 443/tcp`.
|
|
82
|
+
4. DOCKER-USER iptables chain. Drops non-conforming egress from
|
|
83
|
+
containers before Docker rules apply.
|
|
84
|
+
5. fail2ban SSH jail on port 22. `maxretry 5`, `bantime 3600`.
|
|
85
|
+
6. `unattended-upgrades` on for security-only updates
|
|
86
|
+
(`Unattended-Upgrade::Automatic-Reboot "false"`).
|
|
87
|
+
|
|
88
|
+
Deviation costs an ADR at the applying project level; the shipped
|
|
89
|
+
lint refuses on drift.
|
|
90
|
+
|
|
91
|
+
## When to reach for hcloud vs raw-api
|
|
92
|
+
|
|
93
|
+
- `hcloud` (default). Choose it when the operator laptop and CI
|
|
94
|
+
runner can install the binary. Small, self-documenting, JSON
|
|
95
|
+
output on `--output json`; the vendor updates it in step with the
|
|
96
|
+
API. Docs: https://github.com/hetznercloud/cli.
|
|
97
|
+
- `raw-api`. Choose it when a container base image cannot install
|
|
98
|
+
`hcloud` (Alpine minimal builds, a locked-down runtime). The
|
|
99
|
+
provisioner reaches the REST endpoints directly per
|
|
100
|
+
https://docs.hetzner.cloud/. Vendor SLAs cover the API; the local
|
|
101
|
+
CLI is a convenience layer.
|
|
102
|
+
|
|
103
|
+
The facade shape is identical on both paths so switching is a one
|
|
104
|
+
elicit change.
|
|
105
|
+
|
|
106
|
+
## When to reach for `cx23` vs `cx33`
|
|
107
|
+
|
|
108
|
+
- `cx23` (default). Two vCPU, 4 GB RAM, 40 GB SSD. Approximately
|
|
109
|
+
EUR 4.15/month. Fine for the docker-compose stack that ops-01
|
|
110
|
+
runs (fewer than ten containers, each below 300 MB RSS).
|
|
111
|
+
- `cx33`. Two vCPU, 8 GB RAM, 80 GB SSD. Approximately EUR
|
|
112
|
+
7.99/month. Reach when the compose stack holds a Postgres, a
|
|
113
|
+
Grafana, or any container that regularly touches 1 GB RSS.
|
|
114
|
+
- `cx43`. Four vCPU, 16 GB RAM. Reach for a home for the
|
|
115
|
+
`platform-cloudflare-durable-objects` self-hosted mode or a
|
|
116
|
+
Postgres + Grafana + Loki triad.
|
|
117
|
+
- `cpx*`. AMD EPYC. Faster per vCPU; slightly more expensive.
|
|
118
|
+
- `cax*`. ARM64. Choose when every runtime component has an ARM
|
|
119
|
+
build (Node, Postgres, cloudflared, most caddy modules do).
|
|
120
|
+
|
|
121
|
+
Vendor pricing:
|
|
122
|
+
https://docs.hetzner.com/cloud/servers/overview.
|
|
123
|
+
|
|
124
|
+
## Snapshot cadence choices (ADR-3802)
|
|
125
|
+
|
|
126
|
+
- `weekly` (default). One snapshot every Sunday at 02:00 local. On
|
|
127
|
+
a `cx23`, adds approximately EUR 0.005/month in snapshot storage.
|
|
128
|
+
- `daily`. Higher recovery-point objective. On a `cx23`, adds
|
|
129
|
+
approximately EUR 0.035/month.
|
|
130
|
+
- `off`. No automatic snapshot. Choose only when Hetzner-managed
|
|
131
|
+
backups are opted-in AND the application layer takes its own
|
|
132
|
+
logical backups on cadence.
|
|
133
|
+
|
|
134
|
+
Hetzner-managed backups are a separately elicited paid opt-in at
|
|
135
|
+
approximately 20 percent of monthly server price (on a `cx23`,
|
|
136
|
+
approximately EUR 0.80/month). They compose with the scheduled
|
|
137
|
+
snapshot runner; both fire independently.
|
|
138
|
+
Vendor pricing:
|
|
139
|
+
https://docs.hetzner.com/cloud/servers/backups-snapshots/overview.
|
|
140
|
+
|
|
141
|
+
## Snapshot-on-demand
|
|
142
|
+
|
|
143
|
+
Fire a snapshot manually from the applying project's CLI:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
node ./scripts/snapshot.mjs --server ops-01
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The script imports the provisioner facade, calls `takeSnapshot`,
|
|
150
|
+
and emits `hetznerSnapshotTaken` on the injected sink. The account-
|
|
151
|
+
bound probe `real-account-snapshot-on-demand` covers the same shape.
|
|
152
|
+
|
|
153
|
+
## The shared throwaway-server fixture
|
|
154
|
+
|
|
155
|
+
Every real-account probe runs against a throwaway `cx23` in `fsn1`
|
|
156
|
+
provisioned from the fixture manifest. Fixture location:
|
|
157
|
+
`packages/rcf-lite/test/fixtures/hetzner-throwaway-server/`. Cost
|
|
158
|
+
ceiling: EUR 0.006/hour per run; destroy runs in `always()`; nightly
|
|
159
|
+
`sweep-orphans` cron collects any leak on a 60-minute label-age
|
|
160
|
+
cutoff.
|
|
161
|
+
|
|
162
|
+
Round-7 T-2 (`platform-docker-compose-host`) and T-3
|
|
163
|
+
(`edge-cloudflare-tunnel`) EXTEND this fixture rather than shipping
|
|
164
|
+
a second copy. T-2 mounts the docker + compose verbs on the same
|
|
165
|
+
throwaway server after cloud-init seals the baseline; T-3 mounts
|
|
166
|
+
`cloudflared` on the runtime T-2 stands up.
|
|
167
|
+
|
|
168
|
+
## Standards trace
|
|
169
|
+
|
|
170
|
+
Every URL fetched 200 in the ratifying pass before the T-1 PR.
|
|
171
|
+
|
|
172
|
+
- Hetzner Cloud API https://docs.hetzner.cloud/
|
|
173
|
+
- Hetzner Cloud CLI https://github.com/hetznercloud/cli
|
|
174
|
+
- Hetzner Cloud servers overview https://docs.hetzner.com/cloud/servers/overview
|
|
175
|
+
- Hetzner Cloud firewalls overview https://docs.hetzner.com/cloud/firewalls/overview/
|
|
176
|
+
- Hetzner Cloud backups-and-snapshots overview https://docs.hetzner.com/cloud/servers/backups-snapshots/overview
|
|
177
|
+
- Hetzner Cloud networks overview https://docs.hetzner.com/cloud/networks/overview/
|
|
178
|
+
- Hetzner community basic-cloud-config tutorial https://community.hetzner.com/tutorials/basic-cloud-config
|
|
179
|
+
- cloud-init https://cloudinit.readthedocs.io/en/latest/
|
|
180
|
+
- Debian unattended-upgrades wiki https://wiki.debian.org/UnattendedUpgrades
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `edge-cloudflare-access` are recorded here. The shape follows Keep a Changelog and Semantic Versioning per the blueprint authoring standard.
|
|
4
|
+
|
|
5
|
+
## 1.0.0 (2026-09-07)
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- v1.0.0 mint of the `edge-cloudflare-access` blueprint, category `edge`, capabilities `["zeroTrustGate"]`. Ships a shipped JWT validator middleware that is the sole reader of the `Cf-Access-Jwt-Assertion` header per REQ-001, an Access application declaration surface with elicited hostname or self-hosted-app id, an elicited policy shape from the enum (email-domain, service-token-only, service-token-plus-email-domain, group-membership), a metadata-only audit event contract per REQ-004, and a break-glass posture per REQ-005 with an elicited service-auth pair for CI-signed automation.
|
|
10
|
+
- 6 REQs (`edge-cloudflare-access-REQ-001..006`), 9 USs (`edge-cloudflare-access-US-34101..34109`), 4 TACs (`TAC-3501` JWT validator, `TAC-3502` Access application declaration, `TAC-3503` policy shape enum, `TAC-3504` audit sink), 4 ADRs (`ADR-3501` scope-global on new topic `edgeAuthenticationGate` with `standardsTraceClause: Cloudflare Access policy actions and rule selectors`; `ADR-3502` identity provider elicited with `recommendedDefault: null`; `ADR-3503` policy scope elicited with `recommendedDefault: application-level`; `ADR-3504` audit retention delegated to the applied logging companion with sentinel clause).
|
|
11
|
+
- 6 Node-only probes under `contributions/probes/`: `jwt-validator-fixture` (fixture-signed JWT validates and principal reduces to `{email, sub, groups}` on request.auth), `jwt-validator-reject` (three subcases: missing header, expired exp, mis-signed each return 401 with one metadata-only audit event), `admin-console-gate-surface` (extended admin-console fixture flips its sign-in surface per applied capability set; covers `AC-34108-1`), `audit-event-secrecy` (5 pass + 5 reject runs produce 10 metadata-only records with no forbidden substrings, no token slices, no header names beyond `path`), `real-account-gated-url` (`accountBound: true`; records `accountBoundSkipped: true` in CI without `CI_HAS_CLOUDFLARE_ACCOUNT` per spec section 3.5) and `wrangler-seam` (drives `wrangler dev --local` on the fixture; `/protected` returns HTTP 401 on the shipped validator's missing-header reject path; `/health` returns HTTP 200 exempt; warn semantics per section 3.1 pass-with-skip if wrangler is missing or fails to bind).
|
|
12
|
+
- 6 elicited parameters on `blueprint.json`: `access-application-host` (or `access-selfhosted-app-id`, exactly one required), `access-audience`, `access-jwks-url`, `access-policy-shape` (enum default `email-domain`), `access-bypass-service-auth-id` (blank disables break-glass).
|
|
13
|
+
- `suggestedCompanions`: `logging` (for the metadata-only audit sink retention), `errorHandling` (for the validator failure boundary) and `secretsManagement` (for the paired break-glass service-auth secret).
|
|
14
|
+
- Ships the shared `cf-edge` sample-app fixture at `packages/rcf-lite/test/fixtures/cf-edge/` (T-4 mints it per spec section 3.3). The fixture ships the applied Worker (`src/index.mjs`), the JWT validator (`src/jwt-validator.mjs`, sole reader of the `Cf-Access-Jwt-Assertion` header), a dependency-free RS256 fixture-JWT signer (`test/jwt-signer.mjs`) and a local JWKS server (`test/jwks-server.mjs`). No new rcf-lite runtime dependency (Node's built-in `crypto` module signs and verifies).
|
|
15
|
+
- Extends `packages/rcf-lite/test/fixtures/probe-pack-application-admin-console/` with a `/admin/sign-in` route rendering the Access-gated surface (with `?caps=zeroTrustGate`) or the local-login surface (without). The extension rides `application-admin-console` v1.1.0.
|
|
16
|
+
- Anatomy test at `packages/rcf-lite/test/blueprint/edge-cloudflare-access-anatomy.test.js` covers `TS-110..119` on the T-4 chain slice (blueprint shape, contributions cross-check, JWT validator behaviour, sole-reader guarantee, audit-event secrecy, break-glass posture, admin-console composition, fixture files, ADR bodies and clauses, guide sections and vendor URL).
|
|
17
|
+
|
|
18
|
+
### Known limitations
|
|
19
|
+
|
|
20
|
+
- The `real-account-gated-url` probe records `accountBoundSkipped: true` and aggregates to `pass` when `CI_HAS_CLOUDFLARE_ACCOUNT` or `CF_ACCESS_HOST` are unset (spec section 3.5 pass-with-skip). Full mechanism reach requires a CI environment with both env vars set and a deployed hostname behind an issued Zero Trust policy.
|
|
21
|
+
- The v1.0.0 boundary defers per-path policy scope authoring, group-membership rule authoring and identity-provider federation to v1.1.0. The shipped validator observes the JWT's `groups` claim but does not enforce policy on it (the Cloudflare edge enforces before the request reaches the origin Worker); a future minor could ship a group-membership refinement.
|
|
22
|
+
- The `wrangler-seam` probe warns (never fails) when `wrangler` is not installed under `packages/rcf-lite/test/fixtures/cf-edge/node_modules/.bin/wrangler`; a handler thrown at the workerd boundary is a genuine fail per the round-6 T-3 gate directive.
|
|
23
|
+
- The Access-gated sign-in surface on `application-admin-console` v1.1.0 shows a placeholder principal email in the fixture (supplied via `?principalEmail=` or `ADMIN_CONSOLE_PRINCIPAL_EMAIL` env var). In a real deployment the principal reads from `request.auth.email` the JWT validator attaches; the fixture does not embed the validator (it renders the surface).
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# edge-cloudflare-access
|
|
2
|
+
|
|
3
|
+
A rcf-lite blueprint that ships an opinionated wiring for Cloudflare
|
|
4
|
+
Access as the edge authentication gate on a Workers project. One
|
|
5
|
+
JWT validator middleware sits at the top of every fetch handler,
|
|
6
|
+
verifies the JWT Cloudflare Access mints against the JWKS the
|
|
7
|
+
service publishes, and reduces the principal onto `request.auth` as
|
|
8
|
+
`{email, sub, groups}`. Every audit event carries only
|
|
9
|
+
`{email, outcome, timestamp, path}`; no token slice, no header
|
|
10
|
+
value beyond `path` ever leaves the validator boundary.
|
|
11
|
+
|
|
12
|
+
- Version: `1.0.0`
|
|
13
|
+
- Category: `edge`
|
|
14
|
+
- Capabilities: `["zeroTrustGate"]`
|
|
15
|
+
- Suggested companions: `logging`, `errorHandling`, `secretsManagement`
|
|
16
|
+
|
|
17
|
+
## When to reach for it
|
|
18
|
+
|
|
19
|
+
- Any Cloudflare Workers project that needs an authenticated edge
|
|
20
|
+
(only authenticated principals reach the origin Worker).
|
|
21
|
+
- Any project that has adopted the Zero Trust posture and wants a
|
|
22
|
+
vendor-neutral seam (`request.auth`) between the edge and the
|
|
23
|
+
downstream handler.
|
|
24
|
+
- Compose with `application-admin-console` v1.1.0 for the Access-gated
|
|
25
|
+
sign-in surface (round-4 T-4 capability-minor pattern).
|
|
26
|
+
|
|
27
|
+
## The six REQs
|
|
28
|
+
|
|
29
|
+
| REQ | What |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| `edge-cloudflare-access-REQ-001` | The JWT validator is the sole reader of the `Cf-Access-Jwt-Assertion` header and reduces the principal onto `request.auth`. |
|
|
32
|
+
| `edge-cloudflare-access-REQ-002` | An Access application is declared with an elicited hostname or self-hosted-app id and an elicited policy shape from the enum. |
|
|
33
|
+
| `edge-cloudflare-access-REQ-003` | The operator issues a Zero Trust policy via the guide's dashboard walk-through or the alternative API path. |
|
|
34
|
+
| `edge-cloudflare-access-REQ-004` | The audit event carries only `{email, outcome, timestamp, path}` with no token value or headers. |
|
|
35
|
+
| `edge-cloudflare-access-REQ-005` | Break-glass posture: an elicited bypass-service-auth pair authenticates CI automation. |
|
|
36
|
+
| `edge-cloudflare-access-REQ-006` | Composition with `application-admin-console` v1.1.0: the sign-in surface flips per applied capability set. |
|
|
37
|
+
|
|
38
|
+
## The wired shape
|
|
39
|
+
|
|
40
|
+
The validator is the one place the `Cf-Access-Jwt-Assertion` header
|
|
41
|
+
is read. Consumers reach the reduced principal via `request.auth`.
|
|
42
|
+
The public surface is:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
createAccessValidator({ env, eventSink, fetch?, clock?, bypassServiceAuth? })
|
|
46
|
+
-> { validate, middleware }
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Where `env` carries the elicited `ACCESS_JWKS_URL` and `ACCESS_AUDIENCE`.
|
|
50
|
+
The `middleware(request, envSwitches?)` returns either
|
|
51
|
+
`{rejected: true, response, outcome}` for a 401 rejection or
|
|
52
|
+
`{rejected: false, outcome}` after attaching `request.auth` in place.
|
|
53
|
+
|
|
54
|
+
## Elicited parameters
|
|
55
|
+
|
|
56
|
+
- `access-application-host` OR `access-selfhosted-app-id`: pick
|
|
57
|
+
exactly one at apply. The dashboard walk-through follows the
|
|
58
|
+
hostname path when the first is set and the self-hosted-app id
|
|
59
|
+
path when the second is set.
|
|
60
|
+
- `access-audience`: the JWT audience tag the Access policy issues
|
|
61
|
+
the validator refuses tokens whose `aud` claim does not match.
|
|
62
|
+
- `access-jwks-url`: the JWKS endpoint URL the validator fetches.
|
|
63
|
+
Cloudflare Access publishes this at
|
|
64
|
+
`https://<team>.cloudflareaccess.com/cdn-cgi/access/certs`.
|
|
65
|
+
- `access-policy-shape` (default `email-domain`): one of
|
|
66
|
+
`email-domain`, `service-token-only`,
|
|
67
|
+
`service-token-plus-email-domain`, `group-membership`. Drives
|
|
68
|
+
the guide walk-through and the API alternative.
|
|
69
|
+
- `access-bypass-service-auth-id`: leave blank to disable
|
|
70
|
+
break-glass. When set, the paired secret is delegated to the
|
|
71
|
+
applied `secretsManagement` companion via
|
|
72
|
+
`security-secrets-management`.
|
|
73
|
+
|
|
74
|
+
## The six probes
|
|
75
|
+
|
|
76
|
+
The probes live under `contributions/probes/`. Each has a matching
|
|
77
|
+
`run-<probe-name>.mjs` shim that writes a per-blueprint report to
|
|
78
|
+
`.rcf/reports/blueprints/edge-cloudflare-access/<probe-name>.json`
|
|
79
|
+
under the fixture root.
|
|
80
|
+
|
|
81
|
+
| Probe | anchorAcId | accountBound | What it covers |
|
|
82
|
+
| --- | --- | --- | --- |
|
|
83
|
+
| `jwt-validator-fixture.mjs` | `AC-34101-1` | false | Fixture-signed JWT validates; principal reduces to `{email, sub, groups}` on request.auth; one audit event with `outcome: validated` and allowed keys only. |
|
|
84
|
+
| `jwt-validator-reject.mjs` | `AC-34102-1` | false | Three subcases: missing header, expired exp, mis-signed each return HTTP 401 with exactly one audit event whose keys are drawn from the allowed set; outcomes: `missing`, `expired`, `invalid`. |
|
|
85
|
+
| `admin-console-gate-surface.mjs` | `AC-34108-1` | false | The extended admin-console fixture flips the sign-in surface: with `?caps=zeroTrustGate` it renders `[data-surface=access-gated]`; without it renders `[data-surface=local-login]`. Mutually exclusive on both branches. |
|
|
86
|
+
| `audit-event-secrecy.mjs` | `AC-34106-1` | false | After 5 pass + 5 reject runs, the audit sink holds 10 metadata-only records; the serialised sink contains no substring of any JWT (or its segments) and no header names beyond `path`. |
|
|
87
|
+
| `real-account-gated-url.mjs` | `AC-34109-1` | true | Fetch against a scheduled Access-configured hostname (`CF_ACCESS_HOST`) with `CI_HAS_CLOUDFLARE_ACCOUNT=true` follows the redirect chain to a `<team>.cloudflareaccess.com` URL. Records `accountBoundSkipped: true` without both env vars (pass-with-skip). |
|
|
88
|
+
| `wrangler-seam.mjs` | `AC-34101-1` | false | Spawns `wrangler dev --local` on the cf-edge fixture. `/protected` returns HTTP 401 on the shipped validator's missing-header reject path (workerd boundary); `/health` returns HTTP 200 exempt. Warn semantics per section 3.1 pass-with-skip if wrangler is missing or fails to bind; a handler thrown at the workerd boundary is a fail. |
|
|
89
|
+
|
|
90
|
+
## Mechanism-reach note
|
|
91
|
+
|
|
92
|
+
- `AC-34101-1` (fixture JWT validate) and `AC-34102-1` (reject) are
|
|
93
|
+
covered by the in-process probes plus the wrangler-seam probe
|
|
94
|
+
under workerd.
|
|
95
|
+
- `AC-34103-1` (sole-reader guarantee) is covered by the anatomy
|
|
96
|
+
test that greps `src/**/*.mjs` for the header string.
|
|
97
|
+
- `AC-34104-1` (Access application declaration) is covered by the
|
|
98
|
+
anatomy test that reads `blueprint.json` for the elicits[] shape.
|
|
99
|
+
- `AC-34105-1` (guide dashboard walk-through and API alternative)
|
|
100
|
+
is covered by the anatomy test that greps the shipped guide file
|
|
101
|
+
for the two section headings and the vendor URL.
|
|
102
|
+
- `AC-34106-1` (audit metadata secrecy) is covered by the
|
|
103
|
+
`audit-event-secrecy` probe.
|
|
104
|
+
- `AC-34107-1` (break-glass posture) is covered by the anatomy
|
|
105
|
+
test that drives the validator with an elicited pair.
|
|
106
|
+
- `AC-34108-1` (admin-console composition) is covered by the
|
|
107
|
+
`admin-console-gate-surface` probe (both branches) and by the
|
|
108
|
+
shipped `application-admin-console.pack.mjs` pack check
|
|
109
|
+
`AC-21815-1` (Playwright-driven on the extended fixture).
|
|
110
|
+
- `AC-34109-1` (real-account gated URL) is covered by the
|
|
111
|
+
`real-account-gated-url` probe (skipped in CI without both env
|
|
112
|
+
vars per section 3.5).
|
|
113
|
+
|
|
114
|
+
## Two-line gate-reviewer boot
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
cd packages/rcf-lite/test/fixtures/cf-edge
|
|
118
|
+
pnpm install --ignore-workspace
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Then run every probe:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
node ../../../../../blueprints/edge-cloudflare-access/contributions/probes/run-jwt-validator-fixture.mjs
|
|
125
|
+
node ../../../../../blueprints/edge-cloudflare-access/contributions/probes/run-jwt-validator-reject.mjs
|
|
126
|
+
node ../../../../../blueprints/edge-cloudflare-access/contributions/probes/run-audit-event-secrecy.mjs
|
|
127
|
+
node ../../../../../blueprints/edge-cloudflare-access/contributions/probes/run-admin-console-gate-surface.mjs
|
|
128
|
+
node ../../../../../blueprints/edge-cloudflare-access/contributions/probes/run-real-account-gated-url.mjs
|
|
129
|
+
node ../../../../../blueprints/edge-cloudflare-access/contributions/probes/run-wrangler-seam.mjs
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Each probe prints a report envelope and writes it to
|
|
133
|
+
`.rcf/reports/blueprints/edge-cloudflare-access/<probe-name>.json`.
|
|
134
|
+
|
|
135
|
+
## Composition companion
|
|
136
|
+
|
|
137
|
+
- `application-admin-console` v1.1.0 consumes `zeroTrustGate`
|
|
138
|
+
optionally: the admin-console's sign-in surface renders
|
|
139
|
+
Access-gated when `zeroTrustGate` is in the applied set (and
|
|
140
|
+
falls back to `security-auth-*` local login otherwise). The
|
|
141
|
+
v1.1.0 minor rides this PR (round-4 T-4 capability-minor pattern).
|