Skip to Content

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 schema51 tables, about 1,200 columns
Before9.79 s
After0.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 aal1 session up after a 403 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.