v0.1.95 — 4 Sep 2026
Action needed before you deploy. SSO auto-login now signs its handoff
token with a dedicated BUILDPAD_SSO_SECRET. Give the BuildPad platform the
same secret before this release goes out. Until both sides hold it,
POST /api/auth/sso answers 500. Password sign-in is not affected.
Added — SSO auto-login from the BuildPad platform
Who is affected: Deployments that sign users in from the BuildPad platform.
POST /api/auth/sso exchanges a short-lived handoff token for a session, so a
user who is already signed in to the platform does not sign in again. The login
page reads an sso_token query parameter, exchanges it, and removes it from the
URL. A refresh cannot resubmit the token, and the address bar stops holding a
live credential.
The endpoint protects the handoff in four ways:
- It accepts 10 requests per minute for each IP address.
- It refuses a token older than 5 minutes, whatever lifetime the token claims.
- It refuses a second exchange of the same token. The check is shared across the cluster, so a replay cannot land on another worker.
- It returns fixed error text. The messages from the auth service told a missing account apart from a blocked domain, and that text reached the browser.
The handoff is refused for a user with a verified MFA factor, because completing it would step around the second factor that the user asked for. Those users sign in with a password and then complete the code step. A failure to read the factor list also refuses the handoff. See Multi-Factor Authentication.
Changed — BUILDPAD_SSO_SECRET replaces the service role key for SSO
Who is affected: Deployments that use SSO auto-login. This needs a coordinated change on the platform side.
The handoff token was signed with SUPABASE_SERVICE_ROLE_KEY. Minting a login
needs the right to assert an email address. It does not need a credential that
bypasses row-level security on the whole database, and the two secrets had to
rotate together.
Signing now uses a dedicated BUILDPAD_SSO_SECRET. There is no fallback to the
old secret, because a fallback would keep the exposure open.
Performance — schema introspection no longer times out on large schemas
Who is affected: Deployments with large schemas. A few hundred columns was enough to reach the limit.
The two column-introspection functions ran four correlated subqueries for every
column returned, and each one re-joined the information_schema views from the
start. On a large schema this passed the statement timeout of the
authenticated and anon roles, and the request answered 500.
Both functions now compute the primary key, unique, foreign key, and index facts one time, and join the result onto the column list once.
| Benchmark schema | 51 tables, about 1,200 columns |
| Before | 9.79 s |
| After | 0.35 s |
The signatures, the returned columns, and the grants do not change. The
migration is 20260903000001_optimize_table_columns_functions.sql.
Fixed — foreign key reporting for composite and cross-schema keys
Who is affected: Anyone with a composite foreign key, or a foreign key that points at another schema.
Three defects in the same reporting path. Two of them are older than the change above, and came to light while the functions were rewritten.
- A composite foreign key returned one row for each pair of its columns. A three-column table answered with five rows, and two of them named the wrong referenced column.
- A composite foreign key paired its columns by constraint name alone, which
cannot express which referencing column maps to which referenced one. The
pairing now comes from
pg_constraint, where the two column lists are aligned by position. - A foreign key that pointed at another schema compared the schema of the referenced table against the schema of the constrained table. The key resolved to nothing, so the field reported no relation at all.
Fixed — a failed schema read is no longer cached as an empty result
When the column function failed, the relation resolver cached the empty field list for 60 seconds. An empty list is also what a collection with no columns returns, so the failure was invisible and repeated for a minute.
Documentation — Multi-Factor Authentication
MFA shipped in v0.1.94 with no public documentation. The Connect section now has a Multi-Factor Authentication page:
- the two-call enrollment flow, and what to show the user at each step
- how to step an
aal1session up after a403 MFA_REQUIRED, without signing the user out - the endpoint list, including the administrator-only status read
MFA_FORCE_ENABLED, and why static tokens are exempt from it- the SSO interaction described above
The Authentication page links to it, and MFA_REQUIRED is in its error table.
BUILDPAD_SSO_SECRET is documented on the
environment variables page.