Skip to content

feat(e2e): mint a gateway token locally with one browser login - #1355

Closed
johncwaters wants to merge 1 commit into
mainfrom
johnw/local-gateway-mint
Closed

johncwaters wants to merge 1 commit into
mainfrom
johnw/local-gateway-mint

Conversation

@johncwaters

@johncwaters johncwaters commented Sep 24, 2026 •

Copy link
Copy Markdown

Problem

Feedback wanted: ready to merge. Approve or request changes.

  • Should the mint script live in scripts/ as a .no-jest dev tool, or under e2e-harness/?
  • Is refusing to write when the minted token's team differs from PROJECT_ID the right call, rather than recording whichever project was picked on the consent screen?

Headless and e2e runs need an already-issued AI gateway token in WIZARD_CI_GATEWAY_TOKEN_FILE, and there is no way to get one locally except borrowing CI's. The wizard-workbench team wants the workbench to be easier for agents to run, and a one-time browser login that is then cached is the closest we can get today: the mint endpoint only accepts a wizard-app OAuth token (phs_ and phx_ keys were tried and refused).

Companion PR: PostHog/wizard-workbench#4191, which calls this script and caches the token.

Changes

  • scripts/mint-gateway-token.no-jest.ts (pnpm mint-gateway-token): reads PROGRAM, PROJECT_ID, TOKEN_FILE; runs the same OAuth login and gatewayAuth mint the interactive wizard uses; writes the token and a <file>.json sidecar (program, verified project, gateway URL, refresh time, token SHA-256).
  • Writes happen only when the minted team matches PROJECT_ID, through 0600 temp files (O_EXCL|O_NOFOLLOW) renamed into place, and only when every directory on the path is a real directory no other account can write or redirect.
  • docs/local-dev.md: how to mint a token locally.
  • .no-jest scripts are stripped from dist, so nothing ships.

Test plan

  • Minted real tokens for posthog-integration on project 483112: file and sidecar 0600, verified project, sidecar hash matches the token.
  • wizard-workbench e2e (basic-integration/django/django3-saas, basic-integration/next-js/15-app-router-saas) against this branch: the agent run completes through the gateway with the minted token.
  • npx tsc --noEmit -p . clean. The repo's tsconfig and ESLint skip scripts/, so the script was also type-checked with a temporary config.
  • Reviewed over three rounds by the Claude review lanes and a Codex security pass; the last round's ancestor-directory check had no review after it.

Unrelated, seen during testing: on main the e2e result JSON records a screen path ending at outro and skillsComplete: false, although the captured frames reach keep-skills, so the workbench's keep-skills checks fail on main.

LLM context

Written with Claude Code; security review also by Codex (gpt-6-astra).

Headless and e2e runs need an already-issued AI gateway token in
WIZARD_CI_GATEWAY_TOKEN_FILE, and the only way to get one locally was to
borrow CI's. `pnpm mint-gateway-token` runs the same OAuth login and mint
the interactive wizard uses, then writes the token plus a sidecar
(program, verified project, gateway URL, refresh time, token SHA-256) so
a runner such as wizard-workbench can reuse it until it expires.

The mint writes only after the token's team matches PROJECT_ID, and only
through 0600 temp files renamed into a directory chain that no other
account can redirect, because the file holds a live bearer.

Constraint: the mint endpoint accepts only a wizard-app OAuth token, so one browser login per mint is unavoidable
Rejected: phs_ project secret key as the gateway token | gateway answers 402 admission rejected
Confidence: medium
Scope-risk: narrow
Not-tested: the last review round's fix (full ancestor-chain check) had no review after it; exercised by a live mint on the default path
@github-actions

Copy link
Copy Markdown

🧙 Wizard CI

Run the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands:

Test all apps:

  • /wizard-ci all

Test all apps in a directory:

  • /wizard-ci ai-observability
  • /wizard-ci basic-integration
  • /wizard-ci feature-flags
  • /wizard-ci mcp-analytics
  • /wizard-ci replay-vision
  • /wizard-ci revenue
  • /wizard-ci self-driving
  • /wizard-ci warehouse
  • /wizard-ci warehouse-seeded

Test an individual app:

  • /wizard-ci ai-observability/anthropic
  • /wizard-ci ai-observability/google-adk
  • /wizard-ci ai-observability/groq
Show more apps
  • /wizard-ci ai-observability/manual-capture
  • /wizard-ci ai-observability/openai
  • /wizard-ci ai-observability/openai-agents
  • /wizard-ci ai-observability/opentelemetry
  • /wizard-ci ai-observability/vercel-ai
  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/flutter
  • /wizard-ci basic-integration/javascript-node
  • /wizard-ci basic-integration/javascript-web
  • /wizard-ci basic-integration/laravel
  • /wizard-ci basic-integration/next-js
  • /wizard-ci basic-integration/nuxt
  • /wizard-ci basic-integration/python
  • /wizard-ci basic-integration/rails
  • /wizard-ci basic-integration/react-native
  • /wizard-ci basic-integration/react-router
  • /wizard-ci basic-integration/sveltekit
  • /wizard-ci basic-integration/swift
  • /wizard-ci basic-integration/tanstack-router
  • /wizard-ci basic-integration/tanstack-start
  • /wizard-ci basic-integration/vue
  • /wizard-ci feature-flags/django
  • /wizard-ci feature-flags/next-js
  • /wizard-ci mcp-analytics/custom-dispatcher
  • /wizard-ci mcp-analytics/typescript-sdk
  • /wizard-ci replay-vision/javascript-node
  • /wizard-ci replay-vision/next-js
  • /wizard-ci replay-vision/react-vite
  • /wizard-ci revenue/stripe
  • /wizard-ci self-driving/astro
  • /wizard-ci self-driving/fastapi
  • /wizard-ci self-driving/nuxt
  • /wizard-ci self-driving/react-router
  • /wizard-ci self-driving/sveltekit
  • /wizard-ci warehouse/monorepo-env
  • /wizard-ci warehouse/multi-source-next
  • /wizard-ci warehouse/stripe-node
  • /wizard-ci warehouse/zero-source
  • /wizard-ci warehouse-seeded/next-stripe
  • /wizard-ci warehouse-seeded/next-stripe-declined

Test against a Context Mill branch:

  • /wizard-ci all context-mill:my-branch

Add context-mill:<branch> to any command above to pin the Context Mill branch. It defaults to main.

Results will be posted here when complete.

@johncwaters

Copy link
Copy Markdown
Author

Closing: a public mint-to-file script makes pulling a raw gateway token trivial for anyone, so it won't ship. Local e2e will use an employee-held token instead (see PostHog/wizard-workbench#4191).

@johncwaters
johncwaters deleted the johnw/local-gateway-mint branch September 24, 2026 18:49
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