Skip to content

feat(web): safe operator-key access for headless product trials - #596

Open
drewstone wants to merge 1 commit into
mainfrom
feat/headless-api-key-client
Open

drewstone wants to merge 1 commit into
mainfrom
feat/headless-api-key-client

Conversation

@drewstone

@drewstone drewstone commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Purpose

Give headless product clients (including GTM's existing hosted business-trial recorder) a safe way to use an already-issued operator key without exporting a browser session. This belongs at the shared application boundary, not in a GTM-specific auth wrapper.

Implementation

  • Export createApiKeyFetch through the existing /web subpath; no new package, subpath, peer, workflow engine, auth issuer, or scheduler.
  • Trusted HTTPS origin and per-request secret resolver; explicit loopback HTTP opt-in for local tests.
  • Reject cross-origin/authority-relative paths, caller-controlled auth/cookie headers, redirects, and malformed credentials. Omit ambient cookies; preserve cancellation and HTTP responses.
  • No hidden retries. Lost write responses remain unresolved and require retained-state inspection. Adapter diagnostics do not disclose the supplied credential.
  • docs/api-key-client.md explains ownership, adoption, and security/release boundaries. Existing Hub and assistant clients remain unchanged: they target different protocols.

Verification actually executed

26/26 focused checks passed against the candidate source, including actual Node HTTP servers for authenticated POST/read and a redirect to another listener. Tests use the real fetch implementation for those two cases. A subsequent local recheck again passed 26/26, and the local source blob matches pushed blob 2c965d742f5587ef67ae74b233d76d5cfbd084ff.

Mutation control: changing redirect: 'manual' to follow fails 2/26 checks, including the redirect destination being reached. The destination assertion counts requests; it does not establish that the Authorization header was forwarded. Restoring the source passes 26/26.

Local environment has Node 22.16.0 and TypeScript but cannot resolve registry.npmjs.org. The test source was transpiled with TypeScript and its it import changed only in the temporary executable copy from Vitest to node:test; assertions and production module were unchanged. Full installed-dependency typecheck, build, package signoff, and live authenticated GTM/provider tests were not run. This is source review readiness, not production certification.

Consumer / scope

GTM #1093 consumes this addition in its hosted recorder, with a release-prerequisite check rather than an application-local copy. The consumer still needs the normally published package and generated dependency lock. Its server owns scope/expiry/workspace authorization and billing. API keys currently inherit account access, so live trials require a dedicated test identity, not the founder's account-wide key. Keep live Stripe and production outreach credentials out of that test identity.

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