Desired DNS for bounded.tools (incl. trust.bounded.tools), applied to Cloudflare with a
reviewer-gated, OIDC-brokered workflow. Public on purpose: DNS records are publicly resolvable
anyway, so nothing here is secret — and a public repo gets GitHub's required-reviewers
environment protection for free (it needs GitHub Enterprise on private repos).
state/bounded.tools.dns.jsonis the source of truth for the zone's DNS. Edit it via PRs.apply.mjsreconciles live Cloudflare DNS toward that state. Dry-run by default; a real apply needsapply=true, and deletes also needallow_delete=true.- The diff is value-aware — it reconciles each
(type, name)group by content, so multi-value records (dual MX, multiple TXT) are handled correctly. Covered byapply.test.mjs.
- Dispatch the
applyworkflow. A plain run is a dry-run — it prints the plan and changes nothing. - To execute, dispatch with
apply=true. That run enters thecloudflare-applyEnvironment, which is configured with required reviewers — so it pends for approval. - On approval, the run proceeds. No Cloudflare secret is stored: a short-lived, zone-scoped token
is minted just-in-time by the OIDC broker, which grants
DNS:Editonly because the approved run carries theenvironment=cloudflare-applyclaim. A dry-run gets read-only.
- Environment: Settings → Environments → create
cloudflare-apply→ add Required reviewers (free on a public repo). - Repo variables:
CF_BROKER_URL— this zone's cf-oidc-token-broker endpoint, pinned tobounded-systems/deployand thebounded.toolszone.CLOUDFLARE_ACCOUNT_ID— the Cloudflare account.GH_AUDIENCE(optional) — the OIDC audience the broker expects (defaultcf-oidc-token-broker).
- Broker config (deploy a broker instance for this repo):
GH_OWNER=bounded-systems,GH_REPOSITORY=bounded-systems/deploy,EDIT_WORKFLOW_REF=bounded-systems/deploy/.github/workflows/apply.yml@refs/heads/main,EDIT_ENVIRONMENT=cloudflare-apply, andCF_ZONE_IDS= thebounded.toolszone id.
apply.mjs doesn't yet send MX priority (the desired state doesn't capture it) — fine for the
current records, but capture priority before adding/creating MX records.