Skip to content

W3 — Flue gateway (productionize) to the resolved token seam - #491

Merged
ZIJ merged 3 commits into
flue-nativefrom
w3/gateway-productionize
Jul 7, 2026
Merged

W3 — Flue gateway (productionize) to the resolved token seam#491
ZIJ merged 3 commits into
flue-nativefrom
w3/gateway-productionize

Conversation

@ZIJ

@ZIJ ZIJ commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

W3 — Gateway (productionize) of the Flue-native buildout. Base = flue-native (feeds the evergreen #489). Buildout contract #1 / design 013 §4. cloudflare-workers/oc-gateway/.

A thin OC Worker over OpenRouter: verify a per-deploy token → lease-epoch fence → org+agt budget gate → inject the org's OR key → cache-safe + usage-accounted forward → sub-meter. Org-level spend stays on the org's single OR key → the existing model_meter → Autumn cron (nothing pushed to Autumn); the gateway only adds enforcement + per-session sub-metering.

Built to the RESOLVED token seam (option b + co-location refinement)

  • Token is per-DEPLOY {org, agt, iat, exp, ep?} — no sub:session, no bud. HS256 → EdDSA (Ed25519), alg-pinned; the minter (W7) holds the private key, the gateway only the public key.
  • Session identity rides the X-OC-Session header (Flue's static apiKey can't carry per-session data). Because Flue's provider registry is isolate-global and CF co-locates many session-DOs of one script per isolate, the header is best-effort: hard enforcement is at the race-free org+agt grain (from the token); the header is tracked-only, never gated (a co-location race must not wrongly 402 a legit session). Exact per-session enforcement is deferred to an upstream Flue per-request resolver (tracked ask, off the critical path).
  • SpendCounter DO (renamed from SessionBudget): generic µ$ counter + gate. HARD 402 at agt:${org}:${agt}; best-effort tracking at sess:${session}. Budget looked up server-side (provisioned or a gateway default) — never in the token.
  • DeployLease DO (new): per-(org,agt) lease-epoch floor. A token below the floor is fenced (401 token_superseded); the floor auto-rises on a higher-epoch (rotation) or via POST /admin/lease/bump (revoke without redeploy).
  • Org OR key from Infisical via the dedicated sessions-api seam (orgkey.ts; mirrors the edge's dedicated-secret key hand-off; TEST_OR_KEY override for the acceptance run).
  • usage:{include:true}; cache_control stripped for caching-unsafe models (claude-3-haiku → OR→Bedrock 400s; claude-haiku-4.5 works); cost extraction (JSON + SSE).

Note: this branch's prior commit (0b5f580) captured a mid-reshape snapshot (new token.ts + old index.ts) that does not compile; 78b0f7b completes the reshape into a consistent, compiling, green tree.

Verification

  • 31 vitest green — EdDSA/alg-pin/tamper/expired/missing-claims, SpendCounter gate+provision+idempotency, DeployLease fence+bump, org+agt hard enforcement, co-location (two sessions share the org+agt cap), per-session tracked-but-never-gated, cache_control strip, admin provision.
  • Live acceptance (real OpenRouter via wrangler dev, throwaway $1-capped OR key minted from the provisioning key and DELETEd after): a real claude-haiku-4.5 turn completed gateway → OpenRouter (200; model claude-4.5-haiku, cost echoed; no OR key / deploy token in the response); org+agt budget refused on-path (402 budget_exceeded, spent 0.000088 > budget 0.00001); a stale lease epoch was fenced (401 token_superseded); no-token + bad-admin-secret → 401.

Seam questions for the control plane (W1/W7)

  1. Org OR-key route (required to leave TEST_OR_KEY): sessions-api exposes POST {GATEWAY_ORKEY_URL} (dedicated bearer) → {key} = resolveManagedSecret for the org's active managed credential.
  2. Per-agent budget provisioning (optional): a per-(org,agt) cap other than AGENT_BUDGET_USD_DEFAULT via POST /admin/agent/budget.
  3. Lease epoch (ep) minting: W7 mints a monotonic per-(org,agt) ep into the deploy token so rotation auto-fences; a leaked token is revoked via POST /admin/lease/bump.

opencomputer = PR-only; do NOT merge (Igor merges).

🤖 Generated with Claude Code

ZIJ and others added 3 commits July 5, 2026 23:45
Productionizes the 1a spike (spike/oc-gateway, #486) into the flue-native
gateway per buildout contract #1 / design 013 §4. Thin OC Worker over
OpenRouter: verify a per-session token → epoch-fence + on-path budget gate
→ inject the org's OR key → cache-safe + usage-accounted forward →
sub-meter. Org spend stays on the org's single OR key → the existing
OpenRouter→Autumn cron (nothing pushed to Autumn); the gateway only adds
per-session sub-metering + enforcement.

What changed vs the spike:
- Token: HS256 → EdDSA (Ed25519). The minter holds the private key; the
  gateway holds only GATEWAY_TOKEN_PUBLIC_KEY (base64url raw). Alg pinned to
  EdDSA (rejects none/HS256 swaps).
- Lease-epoch fence (close the freeze-flags): the SessionBudget DO tracks a
  monotonic max_epoch; a token with a stale `ep` → 401 token_superseded; a
  newer epoch supersedes older in-flight tokens. DO-serialized.
- Org OR key from the credential store, not the KV/SPIKE stand-in: a
  dedicated internal sessions-api seam (mirrors the edge's dedicated-secret
  key hand-off), cached per-org in-isolate (60s). TEST_OR_KEY override for
  the acceptance run. The L3 route (resolveManagedSecret) is flagged for
  sessions-api.
- Prompt-caching safety: strip cache_control for caching-unsafe models
  (claude-3-haiku → Bedrock 400s) via an env-extensible denylist.
- Kept: usage:{include:true}, 402 budget_exceeded, metering by token.sub,
  the µ$ counter + /add idempotency on the OR generation id.

Tests: 23 green (vitest) — EdDSA/alg-pin/tamper/expired, SessionBudget
fence + budget + idempotency, cache_control strip, cost extraction, and the
full on-path flow through the real handler.

Live acceptance (2026-07-05, real OpenRouter via wrangler dev --local,
throwaway $1-capped OR key minted from the provisioning key and deleted
after): a real claude-haiku-4.5 turn completed gateway → OpenRouter (200,
no key in the response, token != key); per-session budget refused on-path
(402); cache_control stripped so claude-3-haiku succeeds via the gateway
where a direct OR call 400s; epoch fence returns 401 token_superseded.

Seam to confirm with the orchestrator (W1): EdDSA claim set + the mint side
(default: per-turn token via getApiKey). L3 seam to build: the internal
org-OR-key route. Not merged — Igor merges opencomputer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…oken, org+agt enforcement)

Reshapes the productionized gateway to the RESOLVED token seam (2026-07-05, option b) and
the co-location refinement, and lands a consistent, compiling tree. The prior commit
(0b5f580) captured a mid-reshape snapshot (new token.ts + old index.ts) that does not
compile; this commit completes the reshape. buildout contract #1 / design 013 §4.

Token seam (was per-session {sub,bud}; now per-DEPLOY):
- token.ts: claims are {org, agt, iat, exp, ep?} — no sub:session, no bud. EdDSA (Ed25519),
  alg-pinned; the minter (W7) holds the private key, the gateway only the public key.
  verifyDeployToken/mintDeployToken/DeployClaims.
- Session identity rides the X-OC-Session request header (Flue's static apiKey can't carry
  per-session data). It is BEST-EFFORT: Flue's provider registry is isolate-global and CF
  co-locates many session-DOs of one script per isolate, so per-session data injected via
  registerProvider races. Therefore hard enforcement is at the race-free org+agt grain.

Enforcement (co-location refinement):
- SpendCounter DO (renamed from SessionBudget; generic keyed µ$ counter + gate). HARD 402 at
  the org+agt grain (keyed agt:${org}:${agt}, from the token). Best-effort per-session
  tracking keyed sess:${X-OC-Session} — recorded for visibility, NEVER gated (a race must not
  wrongly 402 a legit session). Budget looked up server-side (provisioned or the gateway
  default), never carried in the token. Exact per-session enforcement is deferred to an
  upstream Flue per-request resolver (tracked ask, off the critical path).
- DeployLease DO (new): per-(org,agt) lease-epoch floor. A token below the floor is fenced
  (401 token_superseded); the floor auto-rises on a higher-epoch token (rotation) and via
  POST /admin/lease/bump (revoke without redeploy).
- Admin routes (guarded by GATEWAY_ADMIN_SECRET): /admin/agent/budget (provision org+agt cap),
  /admin/lease/bump (revoke).

Unchanged from the spike: org OR key from the dedicated sessions-api seam (orgkey.ts;
TEST_OR_KEY override), usage:{include:true}, cache_control strip for caching-unsafe models,
cost extraction (JSON+SSE), org spend stays on the existing OpenRouter→Autumn cron (gateway
pushes NOTHING to Autumn).

Tests: 31 green (vitest) — EdDSA/alg-pin/tamper/expired/missing-claims, SpendCounter
gate+provision+idempotency, DeployLease fence+bump, org+agt hard enforcement, co-location
(two sessions share the org+agt cap), per-session tracked-but-never-gated, cache_control
strip, admin provision.

Live acceptance (2026-07-06, real OpenRouter via wrangler dev, throwaway $1-capped OR key
minted from the provisioning key and DELETEd after): a real claude-haiku-4.5 turn completed
gateway → OpenRouter (200, model claude-4.5-haiku, cost echoed; no OR key / deploy token in
the response); org+agt budget refused on-path (402 budget_exceeded, spent 0.000088 >
budget 0.00001); a stale lease epoch was fenced (401 token_superseded); no-token and
bad-admin-secret → 401.

opencomputer = PR-only; do NOT merge (Igor merges). Base = flue-native, into #489.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​wrangler@​4.107.0981009296100

View full report

@2027-evals

2027-evals Bot commented Jul 7, 2026

Copy link
Copy Markdown

⚠️ Couldn't find a preview deployment for commit ef81aaa after 10 minutes.

2027 auto-runs evals against preview deployments of your docs. To enable this, install one of:

  • Mintlify — if you use Mintlify docs
  • Vercel — for Next.js / static sites
  • Netlify — for most static docs

Once a preview is deployed, open a new PR and we'll run the eval automatically.


Evaluating agent experience using 2027.dev · View dashboard

@ZIJ
ZIJ merged commit f2406d3 into flue-native Jul 7, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant