Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ A Cloudflare Worker that proxies OpenPGP Web Key Directory (WKD) requests to Pro
## Architecture

Single-file Worker (`src/index.ts`) with no framework dependencies. Production
`DOMAINS` and routes stay in the Cloudflare dashboard. Do not put `DOMAINS`
in `wrangler.jsonc` `vars`. Tests set example domains in `vitest.config.ts`.
`DOMAINS` lives in `wrangler.jsonc` `vars`; change it via PR. Routes stay
in the Cloudflare dashboard. Tests set example domains in `vitest.config.ts`.
Local `wrangler dev` reads `.dev.vars`.

## Key Files

- `src/index.ts` - The entire Worker implementation
- `test/index.spec.ts` - Tests using `@cloudflare/vitest-pool-workers`
- `wrangler.jsonc` - Wrangler config (`keep_vars`, no routes, no `DOMAINS` var)
- `wrangler.jsonc` - Wrangler config (`vars.DOMAINS`, no routes, no `keep_vars`)
- `.github/workflows/deploy.yaml` - GitHub CI only: lint, test, `cf:check`

## Commands
Expand All @@ -47,21 +47,19 @@ Cloudflare Workers Builds owns production deploy from `main`. GitHub Actions
validates only. Do not run `wrangler deploy`, remote DNS writes, or use
`CLOUDFLARE_API_TOKEN` from GitHub or a Cloud Agent.

The Builds deploy command is `pnpm deploy:cloudflare` (`wrangler deploy --keep-vars`).
The Builds deploy command is `pnpm deploy:cloudflare`.
`workers_dev` is false and `route` / `routes` are omitted so dashboard routes stay.
`keep_vars` only preserves dashboard vars that are absent from `wrangler.jsonc`.
Do not commit `DOMAINS` in `vars`, including example values. This public
repo has no GitHub `DOMAINS` secret. Dashboard `DOMAINS` is the runtime
source.
`DOMAINS` lives in `wrangler.jsonc` `vars`; change it via PR. `keep_vars` is
not used: config owns plain vars.

Adding a domain is a workstation or dashboard procedure: update the `DOMAINS`
var, add the three route patterns, create the `openpgpkey` CNAME, and add a
root placeholder only when the zone has no A/AAAA/CNAME.
Adding a domain is a PR plus dashboard/DNS procedure: update `vars.DOMAINS`
in `wrangler.jsonc`, add the three route patterns, create the `openpgpkey` CNAME,
and add a root placeholder only when the zone has no A/AAAA/CNAME.

## Code Standards

- TypeScript strict mode with `noUncheckedIndexedAccess`
- No `any`, no `as` assertions, no `@ts-ignore`
- ESLint strict type-checked config
- 100% test coverage required
- All domains use example.com/org/net in tests (no real domains in source)
- Tests and local `.dev.vars` use example.com/org/net (no real domains there)
22 changes: 10 additions & 12 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ A Cloudflare Worker that proxies OpenPGP Web Key Directory (WKD) requests to Pro
## Architecture

Single-file Worker (`src/index.ts`) with no framework dependencies. Production
`DOMAINS` and routes stay in the Cloudflare dashboard. Do not put `DOMAINS`
in `wrangler.jsonc` `vars`. Tests set example domains in `vitest.config.ts`.
`DOMAINS` lives in `wrangler.jsonc` `vars`; change it via PR. Routes stay
in the Cloudflare dashboard. Tests set example domains in `vitest.config.ts`.
Local `wrangler dev` reads `.dev.vars`.

## Key Files

- `src/index.ts` - The entire Worker implementation
- `test/index.spec.ts` - Tests using `@cloudflare/vitest-pool-workers`
- `wrangler.jsonc` - Wrangler config (`keep_vars`, no routes, no `DOMAINS` var)
- `wrangler.jsonc` - Wrangler config (`vars.DOMAINS`, no routes, no `keep_vars`)
- `.github/workflows/deploy.yaml` - GitHub CI only: lint, test, `cf:check`

## Commands
Expand All @@ -36,21 +36,19 @@ Cloudflare Workers Builds owns production deploy from `main`. GitHub Actions
validates only. Do not run `wrangler deploy`, remote DNS writes, or use
`CLOUDFLARE_API_TOKEN` from GitHub or a Cloud Agent.

The Builds deploy command is `pnpm deploy:cloudflare` (`wrangler deploy --keep-vars`).
The Builds deploy command is `pnpm deploy:cloudflare`.
`workers_dev` is false and `route` / `routes` are omitted so dashboard routes stay.
`keep_vars` only preserves dashboard vars that are absent from `wrangler.jsonc`.
Do not commit `DOMAINS` in `vars`, including example values. This public
repo has no GitHub `DOMAINS` secret. Dashboard `DOMAINS` is the runtime
source.
`DOMAINS` lives in `wrangler.jsonc` `vars`; change it via PR. `keep_vars` is
not used: config owns plain vars.

Adding a domain is a workstation or dashboard procedure: update the `DOMAINS`
var, add the three route patterns, create the `openpgpkey` CNAME, and add a
root placeholder only when the zone has no A/AAAA/CNAME.
Adding a domain is a PR plus dashboard/DNS procedure: update `vars.DOMAINS`
in `wrangler.jsonc`, add the three route patterns, create the `openpgpkey` CNAME,
and add a root placeholder only when the zone has no A/AAAA/CNAME.

## Code Standards

- TypeScript strict mode with `noUncheckedIndexedAccess`
- No `any`, no `as` assertions, no `@ts-ignore`
- ESLint strict type-checked config
- 100% test coverage required
- All domains use example.com/org/net in tests (no real domains in source)
- Tests and local `.dev.vars` use example.com/org/net (no real domains there)
29 changes: 14 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ This Worker intercepts those requests via Cloudflare route patterns and proxies

- Supports unlimited custom domains via a single environment variable
- Handles both WKD direct (subdomain) and advanced (`.well-known` path) methods
- Dashboard-managed routes and `DOMAINS` so real domains stay out of this public repo
- Dashboard-managed routes; `DOMAINS` lives in `wrangler.jsonc` vars (change via PR)
- One-time DNS setup for `openpgpkey.*` subdomains
- 100% test coverage with Cloudflare Workers vitest integration
- Full observability: structured logging, traces, and logpush
Expand All @@ -40,10 +40,9 @@ In the Cloudflare dashboard, open Worker `wkd-proxy-worker` → Settings →
Builds and connect this repository. Production branch: `main`. Deploy
command: `pnpm deploy:cloudflare`. Leave non-production branch builds off.

Set the Worker runtime variable `DOMAINS` in Settings → Variables to a
comma-separated list of your custom domains. That list stays in the
Cloudflare dashboard. This public repository has no GitHub secret or
variable for `DOMAINS`, and GitHub Actions has no Cloudflare deploy token.
`DOMAINS` lives in `wrangler.jsonc` `vars` as a comma-separated list of
custom domains. Change that list via pull request. GitHub Actions has no
Cloudflare deploy token.

### 4. Add routes and DNS once

Expand All @@ -60,10 +59,10 @@ has no A, AAAA, or CNAME (common for email-only domains), add proxied
placeholders `192.0.2.1` and `100::` so Cloudflare can intercept
`.well-known` requests. Existing website records stay untouched.

`wrangler.jsonc` sets `workers_dev = false` and `keep_vars = true` and
omits `routes` and `vars`. Wrangler still applies any `vars` that are in
the config, so example `DOMAINS` must not appear there. Tests and local
dev supply example domains separately.
`wrangler.jsonc` sets `workers_dev = false` and omits `routes`, so
dashboard routes stay. `DOMAINS` lives in `vars` and is the runtime
source. Tests and local `wrangler dev` still supply example domains
separately.

### 5. Push to Deploy

Expand Down Expand Up @@ -99,9 +98,9 @@ pnpm run lint # ESLint strict type-checked
## How Deployment Works

GitHub Actions validates the pull request. Cloudflare Workers Builds deploys
from `main` with `pnpm deploy:cloudflare`. That command is
`wrangler deploy --keep-vars`. Dashboard routes stay because `routes` is
omitted. Production `DOMAINS` stays because it is not in `wrangler.jsonc`.
from `main` with `pnpm deploy:cloudflare`. Dashboard routes stay because
`routes` is omitted. Production `DOMAINS` comes from `wrangler.jsonc`
`vars`.

The Worker only intercepts the three WKD route patterns. Other hostname
traffic is unchanged.
Expand All @@ -113,13 +112,13 @@ That org-required workflow uses hosted runners and no MNPPI secrets.

## Adding or Removing Domains

1. Update the Worker `DOMAINS` variable in the Cloudflare dashboard.
1. Update `vars.DOMAINS` in `wrangler.jsonc` and open a pull request.
2. Add or remove the three route patterns for that domain.
3. Add or delete the `openpgpkey.*` CNAME. Add a root placeholder only when
the zone has no A, AAAA, or CNAME.

Do not put real domains in git, in `wrangler.jsonc` `vars`, or in GitHub
Actions secrets. Production `DOMAINS` is a Cloudflare dashboard variable.
Do not put `DOMAINS` in GitHub Actions secrets. Routes stay
dashboard-managed. Production `DOMAINS` is the `wrangler.jsonc` `vars` list.

## Prerequisites

Expand Down
4 changes: 3 additions & 1 deletion wrangler.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"main": "src/index.ts",
"compatibility_date": "2025-03-16",
"workers_dev": false,
"keep_vars": true,
"vars": {
"DOMAINS": "marinerpoint.net,mnppi.org,mnppi.com,uihq.com,twintechhomes.com,seekthechurch.org,zuricert.com,opelyx.com,pyndale.com",
},
"logpush": true,
"observability": {
"enabled": true,
Expand Down
Loading