scripts/supabase/auth-config.json is the checked-in desired state that the daily drift
gate compares the live Supabase project against. It contains 8 values specific to this
instance, and nothing rewrites them on fork:
site_url https://scripthammer.com
uri_allow_list https://scripthammer.com,… (+www, +localhost)
smtp_host smtp.resend.com
smtp_user resend
smtp_admin_email noreply@scripthammer.com
smtp_sender_name ScriptHammer
external_github_client_id Ov23…
external_google_client_id 988747852237-….apps.googleusercontent.com
scripts/rebrand.sh does not mention this file. So a fork inherits ScriptHammer's identity as
its declared correct configuration, and auth-config-drift.yml — which runs daily and on
every push to main — then reports drift against values that were never theirs. The fork's
options are to fix it by hand or to stop believing the gate.
None of these are secrets. Client ids appear in every authorize URL the browser is
redirected to, which is where tests/e2e/utils/oauth-validity.ts reads them from; gitleaks
scans clean. The problem is not confidentiality, it is that instance identity is baked into a
file forks are meant to reuse.
Why not simply move them to env vars
Because that breaks what the gate is for. It compares LIVE prod against a value pinned in the
repo. If the expected value came from the runner's environment, both sides could drift
together and the check could never fire — and #287 is exactly "prod drifted while every test
stayed green". A pinned literal is what makes drift detectable at all.
Proposed
${VAR:-default} interpolation in the loader, which is the pattern CLAUDE.md already
prescribes for committed files:
- Keeps a pinned default, so ScriptHammer's own gate still detects real drift.
- Lets a fork declare its own expectation in CI without editing the file.
- An unset var in a fork falls back to the ScriptHammer default and the gate fails loudly,
which is the correct outcome — it tells them to configure, rather than passing silently.
set-auth-config.ts does no interpolation today (process.env is read only for secrets and
the API token), so this is a real change, not a config edit.
Then teach scripts/rebrand.sh about this file, the same way #659 taught it about branding
assets after CRUDkit's monogram shipped to a live client site.
Related
scripts/supabase/auth-config.jsonis the checked-in desired state that the daily driftgate compares the live Supabase project against. It contains 8 values specific to this
instance, and nothing rewrites them on fork:
scripts/rebrand.shdoes not mention this file. So a fork inherits ScriptHammer's identity asits declared correct configuration, and
auth-config-drift.yml— which runs daily and onevery push to main — then reports drift against values that were never theirs. The fork's
options are to fix it by hand or to stop believing the gate.
None of these are secrets. Client ids appear in every authorize URL the browser is
redirected to, which is where
tests/e2e/utils/oauth-validity.tsreads them from; gitleaksscans clean. The problem is not confidentiality, it is that instance identity is baked into a
file forks are meant to reuse.
Why not simply move them to env vars
Because that breaks what the gate is for. It compares LIVE prod against a value pinned in the
repo. If the expected value came from the runner's environment, both sides could drift
together and the check could never fire — and #287 is exactly "prod drifted while every test
stayed green". A pinned literal is what makes drift detectable at all.
Proposed
${VAR:-default}interpolation in the loader, which is the pattern CLAUDE.md alreadyprescribes for committed files:
which is the correct outcome — it tells them to configure, rather than passing silently.
set-auth-config.tsdoes no interpolation today (process.envis read only for secrets andthe API token), so this is a real change, not a config edit.
Then teach
scripts/rebrand.shabout this file, the same way #659 taught it about brandingassets after CRUDkit's monogram shipped to a live client site.
Related
the gate to cover OAuth, so that moving
oauth-csrf.spec.tsto a weekly hosted lane wouldnot delete the only check that prod's ids are real.