Skip to content

Identity issuer setting (`app.identity_issuer`)

Supabase-auth identity_binding rows record an issuer string. It is disambiguating metadata — person resolution keys on provider + external_subject only — kept for a future with multiple auth sources of the same kind (second Supabase project, project migration).

The value is environment-owned. No issuer URL or environment-specific string lives in the repo; the single definition point is the SQL function public.identity_issuer() (created by the supabase_auth_hooks migration):

SELECT coalesce(nullif(current_setting('app.identity_issuer', true), ''), 'supabase')

Setting the value (operator, per environment)

Section titled “Setting the value (operator, per environment)”
ALTER DATABASE app SET app.identity_issuer = '<issuer-for-this-environment>';

Use the environment’s Supabase project URL (the GoTrue iss is <SUPABASE_URL>/auth/v1) or any stable identifier the operator prefers. New sessions pick the setting up immediately; already-open pooled sessions keep their startup value until they reconnect.

Where unset — dev and the podman-compose integration lane — the function falls back to the logical constant 'supabase', keeping those environments hermetic.

SELECT public.identity_issuer(); -- effective value
SELECT issuer, count(*) FROM identity_binding
WHERE provider = 'supabase-auth' GROUP BY issuer; -- what bindings carry
  • Changing the setting affects only new bindings; existing rows keep the issuer they were written with. Because resolution never keys on issuer, mixed historical values are harmless; backfill only if reporting needs uniformity.
  • Integration coverage: tests/integration/erasure-executor.integration.test.ts asserts the fallback and the override path (set_config transaction-local).