Keys are stored and retrievable now, so landing + docs no longer say
'shown once'. README setup applies migrations 0001-0003 in order, drops a
duplicate schema-isolation bullet, and documents key storage + workspace
minting.
Reconcile filtered app keys by the old "llmapikey:" prefix while mint now names
them "llmapikey/gh-<id>", so orphan/cost-leak detection silently missed every
new key. Centralize the prefix in lib/keys/key-name.js (KEY_NAME_PREFIX +
keyName) and use it in both mint and reconcile so they can't drift.
The column holds OpenRouter's delete handle (data.hash) used to revoke a key,
not a hash of the key. Migration 0003 renames the column; update repository,
admin revoke action, and the reconcile script.
Persist the raw key (migration 0002 adds openrouter_key) so users can copy it
again from the dashboard instead of a one-time-only reveal; admin console shows
the full key. Retain openrouter_key_hash for revocation. Keys remain in the
unexposed llmapikey schema (deny-all RLS, server-only direct connection).
- activate() stores the raw key; dashboard + generate-key return the full key.
- key-display warning updated (no longer shown-once).
- admin table renders the full key.
Node runner using the project's postgres dependency, for applying SQL
migrations where psql is unavailable. Reads POSTGRES_URL via --env-file;
runs the file in a single transaction.
Pass create-key workspace_id (from OPENROUTER_WORKSPACE_ID, defaulting to the
project workspace) so minted keys land in the intended workspace instead of the
management key's default. Rename key to non-PII llmapikey/gh-<id>.
- buildCreateKeyBody emits workspace_id only when set (omission keeps default).
- createKey threads workspaceId; mintAndPersist sources it from env.
- Test asserts workspace_id presence/omission; document the new env var.
Self-contained GitHub OAuth (Arctic) with a stateless HS256 signed-cookie
session (jose); Supabase is downgraded to the Postgres host only.
- Origin-derived callback (no redirect-uri env); read:user scope; access
token read once at callback and discarded (no token storage).
- CSRF via single-use state cookie; open-redirect guard on next.
- getCurrentGithubIdentity() now reads the session cookie, preserving the
numeric provider_id identity contract for admin/dashboard/mint.
- Remove @supabase/ssr + @supabase/supabase-js, middleware, and the
supabase-dependent rls test; delete lib/supabase clients.
- replace stale plan-reference comments with intent-describing ones
- move inline nav style to a .site-nav CSS class
- drop dummy placeholder return in generate-key resolveConflict