Everything runs on one Cloudflare account under the yuwakisa.com zone. Two independent monorepos, auth/ (identity) and jsonsolver/ (an SMT constraint-solving service), share only the auth service: jsonsolver never stores credentials, it verifies tokens that auth/ issues.
Cloudflare provides the edge (TLS and routing); auth/ provides identity. There is no Cloudflare Access anywhere.
Topology
Key: the Cloudflare pieces
Box colors in the diagrams: auth/ jsonsolver/ storage external or static site.
- Worker
- A small server-side program that runs on Cloudflare's network on each request. No servers to manage; it starts in milliseconds and runs close to the user. Every box above that says "Worker" is one.
- Durable Object (DO)
- A single named instance of a class (one per job, one per jsonsolver client) with its own private storage and a timer ("alarm"). All requests for that name go to the same instance, one at a time, so it is a safe place to keep counters and run a multi-step process.
- Container
- A regular Linux process image (here Node 22 + the Z3 solver) that a Durable Object starts on demand. Used for the heavy compute a Worker can't do.
- D1
- A SQLite database. Holds the structured records: users, sessions, OAuth clients, jobs, rulesets.
- R2
- File/blob storage (like Amazon S3), organised in buckets. Holds the bulky bytes: job payloads, results, ruleset source.
- Queue
- A message queue. The api Worker drops a job message on it; the solver Worker is handed each message and picks it up.
- Analytics Engine
- A write-heavy event log for metrics, queried later with SQL. Workers write events into it; nothing reads it on the request path.
- Service binding
- A direct, private call from one Worker to another inside Cloudflare. It never goes over the public internet, and nothing outside can use it.
- Custom domain / route
- Attaches a hostname (e.g.
auth.yuwakisa.com) to a Worker. Cloudflare handles DNS and the TLS certificate. - Pages / static assets
- Hosting for plain HTML, CSS and JS files. Pages deploys from a Git repo; a Worker can also serve files directly (that's how this page is served).
Signing in
Token formats
ID token: a JWT signed with EdDSA (Ed25519).
Access token: 01.<base64url(64-byte Ed25519 signature ‖ CBOR claims)>. The claims are integer-keyed CBOR: iss, sub, aud, exp, iat, kid, scope (keys 1 to 7). 01 is the version, which is the rotation lever.
Consumers verify with the public key published at /.well-known/jwks.json, so no secret is shared. The admin scope is granted only to the single is_admin user.
Solving a job
GET /v1/jobs/:id and receives status plus, for a finished job, the model or unsat core read from R2 results.Who can touch what
| Component | D1 | R2 | Queue | Durable Objects | Service bindings | Secrets |
|---|---|---|---|---|---|---|
| auth | auth | — | — | — | to bskyoidc (BSKYOIDC_SERVICE) | AUTH_SIGNING_KEY |
| bskyoidc | auth | — | — | — | — | holds auth’s public key; own AT Protocol client identity |
| auth-admin | auth only | — | — | — | none | none; no signing key |
| api (and its DOs) | jsonsolver | payloads, results, rulesets | producer | hosts PerJsonsolverClientGate, PerJobActor; binds SolverContainer | to auth (AUTH_SERVICE) | — |
| solver | none | none | consumer | hosts SolverContainer; binds PerJobActor, PerJsonsolverClientGate (only calls acceptJob) | — | — |
| Container | Nothing. Zero Cloudflare bindings: pure compute over bytes. | |||||
| admin | jsonsolver | rulesets only (not payloads or results) | — | — | to auth (AUTH_SERVICE), to api (API_SERVICE) | — |
| site | Static assets only. | |||||
The design goal is that “what can this component touch?” is answerable by inspection: a compromised admin Worker cannot reach customer payloads or results.
Status: not done yet
- jsonsolver admin MCP (
/mcp/*) and reports (/reports/*) are stubs. - jsonsolver admin does not yet gate its admin routes on the
adminscope. - Deferred in auth/: refresh tokens, password reset and email verification, MFA, rate limiting, client-credentials (machine-to-machine), live key rotation.
- Ruleset compile errors surface at solve time, not at upload.
Deploys
GitHub Actions deploy auth/ and jsonsolver/ on push to main, gated by a repository variable. The site Worker deploys manually with just deploy from site/. Cloudflare creates the DNS records and certificates for the custom domains.