Skip to main content

Automatic auth catalog

Kurabase has a small, chain-backed, pseudonymous auth catalog. It is a convenience for application queries after a user has already authenticated; it is not an authentication provider, an authority registry, or evidence that a caller is authenticated.

System relations​

The current implementation exposes two reserved relations in the public SQL catalog:

RelationColumnsPurpose
kura_auth_usersid text primary keyOne canonical application user ID.
kura_auth_identitiesid text primary key, user_id text (FK to kura_auth_users.id), provider text, wallet_address textA deterministic identity record linked to that user. provider is wallet or privy.

kura_auth_identities.id is a deterministic hash of the provider, canonical user ID, and wallet address. It is an identifier for this catalog record, not an authentication credential. The catalog does not mint, validate, extend, or revoke sessions.

There is currently no auth schema or auth.* namespace. Use the exact relation names above. In particular, auth.uid() and auth.jwt() are SQL context helpers, not tables, views, or a Supabase Auth compatibility promise.

Bootstrap and compatibility​

At startup, only a gateway whose current on-chain grant is privileged creates the two relations. It creates both definitions atomically. An ordinary gateway only replays catalog metadata; it does not initialize it.

Startup is idempotent: when both relations already exist, Kurabase validates their reserved definitions and leaves the rows unchanged. If only one exists, or either definition was changed, startup fails rather than overwriting an occupied name. Operators retain administrative SQL control through the privileged gateway, but should treat these relation names and definitions as reserved system state.

Registration during session exchange​

Registration happens only after the gateway has verified an existing, independently signed user-session envelope. It uses that same user session for the resulting chain commit; it does not switch to a privileged execution path. Repeating the same successful exchange is idempotent (ON CONFLICT DO NOTHING).

Only these canonical forms are recorded:

Providerkura_auth_users.idCatalog record
WalletThe lower-case canonical EVM address, equal to the signing walletprovider = 'wallet', same lower-case address in wallet_address
Privy-attested identitydid:privy: followed by 1–128 ASCII letters, digits, _, or -provider = 'privy', with the verified session wallet in wallet_address

Other valid session subjects remain usable for RLS but are intentionally not cataloged. Arbitrary claims, email-like subjects, raw claims, access tokens, and identity tokens are never registered. A did:privy: test subject is only a strict pseudonymous format check; it is not live Privy verification.

For a live Privy flow, verify both token channels and issue the signed envelope through an external identity signer. The SDK then sends the envelope—not Privy tokens—to /auth/v1/session. See JavaScript SDK.

Application visibility and writes​

Both system relations enable RLS and have only an authenticated SELECT policy:

-- equivalent policies
USING (id = auth.uid()) -- kura_auth_users
USING (user_id = auth.uid()) -- kura_auth_identities

Consequently an authenticated user can read only their own catalog records; anonymous callers see none. REST client writes are not an application API for this catalog: there are no user INSERT, UPDATE, or DELETE policies. Attempts to insert are rejected, and update/delete requests cannot gain a permissive target through these SELECT-only policies. The session-exchange path is the sole automatic registration path.

This is access visibility, not confidentiality. All committed EVM cells, including the canonical IDs, deterministic hashes, provider labels, and wallet addresses in this catalog, are public-chain data. Do not use the catalog for email addresses, profiles, secrets, tokens, or any other confidential or personal data.

Current boundary​

The catalog is deliberately a narrow first slice. It does not provide a general auth.* API, user-management REST endpoints, a hosted identity provider, or native Privy token verification inside the gateway. Those remain separate provider and application responsibilities.