Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: supabase/auth
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.180.0
Choose a base ref
...
head repository: supabase/auth
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v2.181.0
Choose a head ref
  • 20 commits
  • 64 files changed
  • 8 contributors

Commits on Sep 23, 2025

  1. feat: add after-user-created hook (#2169)

    This PR implements the `after-user-created` hook which runs whenever a
    new user has been successfully created.
    
    Summary:
    - Add `triggerAfterUserCreated` method to the `*API` object in
    `internal/api/hooks.go`
    - Update user creation paths to call `triggerAfterUserCreated` after a
    new user is persisted:
      - internal/api/anonymous.go
      - internal/api/external.go
      - internal/api/invite.go
      - internal/api/mail.go
      - internal/api/signup.go
      - internal/api/samlacs.go
      - internal/api/token_oidc.go
      - internal/api/web3.go
    - Extend `createAccountFromExternalIdentity` to return an
    `AccountLinkingDecision` to detect newly created accounts
    - Add full end-to-end verification of the new hook in
    `internal/api/e2e_test.go`
    
    Co-authored-by: Chris Stockton <[email protected]>
    cstockton and Chris Stockton authored Sep 23, 2025
    Configuration menu
    Copy the full SHA
    bd80df8 View commit details
    Browse the repository at this point in the history

Commits on Sep 24, 2025

  1. feat: webauthn support schema changes, update openapi.yaml (#2163)

    ## What kind of change does this PR introduce?
    
    Feature improvement / API cleanup
    
    ## What is the current behavior?
    
    - The API returns credential_creation_options and
    credential_request_options as separate fields at the root level,
    requiring clients to check which is null
    - OpenAPI spec doesn't match actual server output (missing publicKey
    wrapper that go-webauthn library adds)
    - Field naming inconsistent with W3C spec (web_authn vs standard
    webauthn)
    
    ## What is the new behavior?
    
    1. Challenge response structure changed to discriminated union:
    - Before: Check null fields {credential_creation_options?: ...,
    credential_request_options?: ...}
    - After: Single typed field {type: "create" | "request",
    credential_options: {publicKey: ...}}
    2. Verify request structure unified:
    - Before: {creation_response?: ..., assertion_response?: ...}
    - After: {type: "create" | "request", credential_response: ...}
    3. RPOrigins changed from comma-separated string to string array
    (matches go-webauthn v3 expectations)
    
    ## Additional context
    
    This makes the PR for the auth-js library easier.
    Bewinxed authored Sep 24, 2025
    Configuration menu
    Copy the full SHA
    68cb8d2 View commit details
    Browse the repository at this point in the history
  2. feat: add advisor to notify you when to double the max connection pool (

    #2167)
    
    Adds a simple advisor that emits a log message every hour, if the number
    of [DBStats](https://pkg.go.dev/database/sql#DBStats) samples exceeds:
    
    - 1/3 or more samples indicate more than 1ms wait for every millisecond
    in the sampling interval
    - 1/3 or more samples indicate 2 or more goroutines have been waiting to
    acquire a connection from the pool
    
    For instance, if you set `GOTRUE_DB_ADVISOR_SAMPLING_INTERVAL="100ms"`
    and `GOTRUE_DB_ADVISOR_OBSERVATION_INTERVAL="1s"` then:
    
    - There are 1000 / 100 = 10 samples
    - Every 100ms a sample is taken and the conditions are checked
    - Log message is emitted if either one of the conditions are met at most
    once per hour
    hf authored Sep 24, 2025
    Configuration menu
    Copy the full SHA
    a72f5d9 View commit details
    Browse the repository at this point in the history
  3. feat: support percentage based db limits with reload support (#2177)

    ## Summary
    Introduce a context aware DB dial path, a new `ConnPercentage` knob to
    cap Auth's share of Postgres connections, and background wiring to apply
    pool changes on config reloads.
    
    **Storage / DB**
    - Add `DialContext(ctx, *conf.GlobalConfiguration)` and keep `Dial(...)`
    as a thin wrapper. `serve` now passes its cancelable context so startup
    can't hang indefinitely.
    - `Connection` now keeps a handle to the underlying `*sql.DB` (via
    `popConnToStd`) when available.
    - New helpers:
    - `newConnectionDetails` and `applyDBDriver` to build
    `pop.ConnectionDetails` and derive driver when omitted.
    - `Connection.Copy()` to retain `sqldb` reference and updated locations
    that copy (`WithContext, Transaction)`.
    - Runtime tuning API: `(*Connection).ApplyConfig(ctx, cfg, le)` computes
    and applies connection limits to the underlying `*sql.DB`.
    - Fixed limits come from `MaxPoolSize`, `MaxIdlePoolSize`,
    `ConnMaxLifetime`, `ConnMaxIdleTime`.
    - If `ConnPercentage` is set (1-100), compute limits from `SHOW
    max_connections`, prefer percentage over fixed pool sizes, and set idle
    = open.
      - Retains previous behavior when `ConnPercentage` is `0`
      - No-op (and error) if `*sql.DB` is unavailable.
    
    **API worker**
    - `apiworker.New` now accepts the DB connection.
    - Split worker into three goroutines (via `errgroup`):
      - `configNotifier` fans out reload signals,
      - `templateWorker` refreshes template cache,
      - `dbWorker` applies DB connection limits on boot and each reload.
    
    **Serve**
    - Use `storage.DialContext(ctx, cfg)` and then `db =
    db.WithContext(ctx)` so the DB handle participates in request/trace
    context and shutdown.
    
    **Observability**
    - Add `observability.NewLogEntry(*logrus.Entry)` to construct chi
    middleware log entries.
    - Structured logs around applying DB limits.
    
    **Configuration knobs** (`GOTRUE_DB_*`)
    - `GOTRUE_DB_CONN_PERCENTAGE` (int, clamped to `[0,100]`):
      - `0` (default) disables percentage-based sizing.
      - `1-100` reserves that % of `max_connections` for the Auth server.
    
    **Tests**
    - `internal/storage/dial_test.go`
      - `DialContext` happy path and invalid driver/URL error path.
    - Reflection bridge to `*sql.DB` (`popConnToStd`) including
    `WithContext`-wrapped connection behavior.
    - `ApplyConfig` end-to-end: verify pool sizing and stats reflect limits.
      - Percentage math and precedence vs fixed pools across edge cases.
    - `internal/conf/configuration_test.go`
      - Validation clamps `ConnPercentage` to `[0,100]`.
    
    ## How it works
    In short if `GOTRUE_DB_CONN_PERCENTAGE=0`, we use the fixed
    `GOTRUE_DB_{MAX,CONN}_*` limits. If it's in the range `[1, 100]` we set
    percentage based limits derived from `SHOW max_connections` and ignore
    the fixed pool sizes.
    
    ### Deep Dive
    The startup sequence remains the same, trying to set it _before_ we
    returned from `DialContext` was a bit messy (chicken / egg: need a conn
    to setup a conn). I also didn't want to delay startup time during
    failure scenarios (db is unavailable, db is blocking, etc).
    
    So after `DialContext` we have a connection which is configured
    initially with only the existing DB settings:
    ```bash
    GOTRUE_DB_MAX_POOL_SIZE="50"
    GOTRUE_DB_MAX_IDLE_POOL_SIZE="10"
    GOTRUE_DB_CONN_MAX_IDLE_TIME="60s"
    GOTRUE_DB_CONN_MAX_LIFETIME="0"
    ```
    
    Next the server starts the `apiworker` which immediatelly creates a new
    [dbWorker](https://github.com/supabase/auth/pull/2177/files#diff-b20c1e9d1c21d077494cf5ff490de301a864d3d1812538cf594a687f620a7175R122)
    goroutine concurrently while the rest of the startup sequence continues.
    Before entering the config update loop the `dbWorker` will call the
    newly added
    [ApplyConfig(...)](https://github.com/supabase/auth/pull/2177/files#diff-5b7e4f0f03bfbc3a58168e58eb88386b9e683241c1ebcb57f6764c38308f2257R179)
    method on the `*storage.Connection`.
    
    The `ApplyConfig` method is where the logic for obtaining the best
    values to call the `sql.DB.Set*(...)` methods below lives:
    * [SetConnMaxIdleTime(d
    time.Duration)](https://pkg.go.dev/database/sql#DB.SetConnMaxIdleTime)
    * [SetConnMaxLifetime(d
    time.Duration)](https://pkg.go.dev/database/sql#DB.SetConnMaxLifetime)
    * [SetMaxIdleConns(n
    int)](https://pkg.go.dev/database/sql#DB.SetMaxIdleConns)
    * [SetMaxOpenConns(n
    int)](https://pkg.go.dev/database/sql#DB.SetMaxOpenConns)
    
    Right now
    [ApplyConfig](https://github.com/supabase/auth/blob/4b5bc8d08fb4fbdf778f504f226da29246d34e84/internal/storage/dial.go#L179)
    works like this:
    1. Checks that we were able to
    [reflect](https://github.com/supabase/auth/blob/4b5bc8d08fb4fbdf778f504f226da29246d34e84/internal/storage/dial.go#L140)
    a `*sql.DB` during `DialContext`, if not we do nothing since we can't
    call `sql.DB.Set*(...)`.
    * If we can't access *sql.DB or fetch max_connections, we leave the
    prior limits untouched and log a warning. Always all-or-nothing, no
    partial application of limits.
    2. Calls the new
    [getConnLimits](https://github.com/supabase/auth/blob/4b5bc8d08fb4fbdf778f504f226da29246d34e84/internal/storage/dial.go#L209)
    method.
    3. `getConnLimits` calls
    [newConnLimitsFromConfig](https://github.com/supabase/auth/blob/4b5bc8d08fb4fbdf778f504f226da29246d34e84/internal/storage/dial.go#L287)
    which returns a `ConnLimits` setup with `GOTRUE_DB_{MAX,CONN}_*`
    settings.
    4. Check if `GOTRUE_DB_CONN_PERCENTAGE` is zero, if so [it
    returns](https://github.com/supabase/auth/blob/4b5bc8d08fb4fbdf778f504f226da29246d34e84/internal/storage/dial.go#L218)
    the `GOTRUE_DB_{MAX,CONN}_*` from `newConnLimitsFromConfig`.
        * This means the limits are set exactly as they are today.
    5. Percentage config is non-zero so we make a call to
    [showMaxConns](https://github.com/supabase/auth/blob/4b5bc8d08fb4fbdf778f504f226da29246d34e84/internal/storage/dial.go#L266)
    which just returns an integer from `"SHOW max_connections;"`. In my
    testing this value always seems to be available for the auth server:
    	* This value cannot change without postgres restarts.
    	* Postgres will not start if it is 0.
    	* Being in recovery mode still shows the maximum connections.
    6. As long as `showMaxConns` does not return an error we attempt to
    apply percentage based connection limits in
    [applyPercentageLimits](https://github.com/supabase/auth/blob/4b5bc8d08fb4fbdf778f504f226da29246d34e84/internal/storage/dial.go#L235).
    7. If max conns is <= 0 we return [an
    error](https://github.com/supabase/auth/blob/4b5bc8d08fb4fbdf778f504f226da29246d34e84/internal/storage/dial.go#L245)
    which prevents any config changes from being applied. Leaving the
    connection in its prior state.
    * max_connections > 0 is guaranteed if postgres is running, this is a
    defensive check to prevent applying a clamp to 1 max conns on 0.
    8. We perform a simple [bounds
    check](https://github.com/supabase/auth/blob/4b5bc8d08fb4fbdf778f504f226da29246d34e84/internal/storage/dial.go#L252)
    and then set the [`MaxOpenConns` and
    `MaxIdleConns`](https://github.com/supabase/auth/blob/4b5bc8d08fb4fbdf778f504f226da29246d34e84/internal/storage/dial.go#L257)
    to the values derived from the `ConnPercentage` and `maxConns`.
    * Note that we preserve the existing behavior of IdleConns == MaxConns.
    I believe the aim is to minimize connection churn (latency) at the cost
    of more Postgres slots when idle. It's worth thinking about making this
    a bit more considerate in the future, something simple like (open/2) or
    more advanced heuristics using
    [sql.DBStats](https://pkg.go.dev/database/sql#DBStats).
    
    	```Go
    	pct := float64(dbCfg.ConnPercentage)
    	cl.MaxOpenConns = int(max(1, (pct/100)*float64(maxConns)))
    	cl.MaxIdleConns = cl.MaxOpenConns
    	```
    
    9. The values set from the call to `getConnLimits` are logged before
    being [applied via the
    `sql.DB.Set*(...)`](https://github.com/supabase/auth/blob/4b5bc8d08fb4fbdf778f504f226da29246d34e84/internal/storage/dial.go#L202)
    calls.
    
    We fail strictly and quickly on derivation errors to keep the last known
    good settings. By supporting config reloading my hope is that when under
    high load users may balance this setting without taking down the auth
    server. This tight feedback loop should help rule out (or resolve) the
    auth server as a potential root cause to connection timeouts and similar
    downstream effects.
    
    @stojan `apiworker` approach also gives a good place for your [stats
    tracking](#2167) to live, adding a
    simple ticker in the `dbWorker` to poll stats between config updates.
    This stats polling could be used to form additional heuristics in our
    connect limit tuning if we would like to explore that in the future. For
    example use the mean connection time as an additional weight to further
    increase the pool size.
    
    
    ## Some notes:
    I tested this extensively but please give a thorough review, I made some
    judgement calls on non-happy paths. I'm also not sure how reliable the
    sqldb reference is as it seems the composition of the *pop.Store can
    change based on inputs, context, dialect, driver, etc. The entire
    feature will not work if I can't reflect out the sqldb.
    
    ---------
    
    Co-authored-by: Chris Stockton <[email protected]>
    cstockton and Chris Stockton authored Sep 24, 2025
    Configuration menu
    Copy the full SHA
    1731466 View commit details
    Browse the repository at this point in the history

Commits on Sep 25, 2025

  1. feat: store latest challenge/attestation data (#2179)

    ## What kind of change does this PR introduce?
    
    Feature - Store WebAuthn challenge data for customer verification
    purposes
    
    ## What is the current behavior?
    
    Currently, WebAuthn challenge data (attestation/assertion responses) is
    not persisted after verification, making it impossible for customers to
    review or audit the WebAuthn authentication details.
    
    ## What is the new behavior?
    
    - Added `last_webauthn_challenge_data` JSONB column to `mfa_factors`
    table to store the latest challenge verification data
    - The system now stores the challenge, type (create/request), and parsed
    credential response after successful WebAuthn verification, THEN deletes
    the challenge like before.
    
    ## Additional context
    
    The structure for the JSONb would be like so, based on whether it's a
    `create` or `request` webauthn operation
    
    ```typescript
    type LastWebAuthnChallengeData = {
        challenge: ChallengeData,
    } & {
      type: "create"
      credential_response: ParsedCredentialCreationData
    } | {
      type: "request"
      credential_response: ParsedCredentialAssertionData
    }
    ```
    
    
    ---------
    
    Co-authored-by: Stojan Dimitrovski <[email protected]>
    Bewinxed and hf authored Sep 25, 2025
    Configuration menu
    Copy the full SHA
    01ebce1 View commit details
    Browse the repository at this point in the history

Commits on Sep 30, 2025

  1. feat: email address changed notification (#2181)

    This PR adds support for sending the user an email notification when
    their email has been changed.
    
    3 new environment variables are introduced:
    
    - `GOTRUE_MAILER_SUBJECTS_EMAIL_CHANGED_NOTIFICATION`: Email subject to
    use for password changed notification.
    - `GOTRUE_MAILER_TEMPLATES_EMAIL_CHANGED_NOTIFICATION`: The URL to
    specify a custom template.
    - `GOTRUE_MAILER_NOTIFICATIONS_EMAIL_CHANGED_ENABLED`: whether the
    notification is enabled or not.
    
    The feature is disabled by default. To enable it, the
    `GOTRUE_MAILER_NOTIFICATIONS_EMAIL_CHANGED_ENABLED` environment variable
    must be set to `true`.
    
    The default email will look as follows:
    
    <img width="956" height="461" alt="Screenshot 2025-09-26 at 15 28 18"
    src="https://github.com/user-attachments/assets/950812f5-5bfe-41ef-9368-9e479ab04f94"
    />
    fadymak authored Sep 30, 2025
    Configuration menu
    Copy the full SHA
    047f851 View commit details
    Browse the repository at this point in the history
  2. feat: MFA factor enrollment notifications (#2183)

    This PR adds support for sending email notifications to a user when a
    factor has been enrolled/unenrolled for their account.
    
    6 new environment variables are introduced:
    
    -
    `GOTRUE_MAILER_SUBJECTS_MFA_FACTOR_{ENROLLED|UNENROLLED}_NOTIFICATION`:
    Email subject to use for password changed notification.
    -
    `GOTRUE_MAILER_TEMPLATES_MFA_FACTOR_{ENROLLED|UNENROLLED}_NOTIFICATION`:
    The URL to specify a custom template.
    -
    `GOTRUE_MAILER_NOTIFICATIONS_MFA_FACTOR_{ENROLLED|UNENROLLED}_ENABLED`:
    whether the notification is enabled or not.
    
    The feature is disabled by default. To enable it, the
    `GOTRUE_MAILER_NOTIFICATIONS_MFA_FACTOR_{ENROLLED|UNENROLLED}_ENABLED`
    environment variable must be set to `true`.
    fadymak authored Sep 30, 2025
    Configuration menu
    Copy the full SHA
    53db712 View commit details
    Browse the repository at this point in the history

Commits on Oct 1, 2025

  1. feat: notify users when their phone number has changed (#2184)

    This PR adds support for sending the user an email notification when
    their phone number has been changed.
    
    3 new environment variables are introduced:
    
    - `GOTRUE_MAILER_SUBJECTS_PHONE_CHANGED_NOTIFICATION`: Email subject to
    use for phone changed notification.
    - `GOTRUE_MAILER_TEMPLATES_PHONE_CHANGED_NOTIFICATION`: The URL to
    specify a custom template.
    - `GOTRUE_MAILER_NOTIFICATIONS_PHONE_CHANGED_ENABLED`: whether the
    notification is enabled or not.
    
    The feature is disabled by default. To enable it, the
    `GOTRUE_MAILER_NOTIFICATIONS_PHONE_CHANGED_ENABLED` environment variable
    must be set to `true`.
    fadymak authored Oct 1, 2025
    Configuration menu
    Copy the full SHA
    21f3070 View commit details
    Browse the repository at this point in the history

Commits on Oct 7, 2025

  1. Configuration menu
    Copy the full SHA
    7d46936 View commit details
    Browse the repository at this point in the history
  2. feat: add support for account changes notifications in email send hook (

    #2192)
    
    Adds support for Account Changes Notifications in the `Send Email Hook`.
    fadymak authored Oct 7, 2025
    Configuration menu
    Copy the full SHA
    6b382ae View commit details
    Browse the repository at this point in the history

Commits on Oct 10, 2025

  1. docs: polish readme, update example.env, and gitignore (#2173)

    ## What kind of change does this PR introduce?
    
    Docs update / configuration cleanup
    
    ## What is the current behavior?
    
    * README contained inconsistent wording, capitalization, and formatting.
    * `example.env` provider sections weren’t fully normalized (e.g., brand
    naming).
    * `.idea` IDE files were not ignored, risking accidental commits.
    
    ## What is the new behavior?
    
    * README polished for clarity and consistency (terminology, grammar,
    branding).
    * `example.env` updated with cleaner provider sections and improved
    comments (e.g., explicit **Twitter (X)** naming).
    * `.gitignore` updated to exclude `.idea` directories.
    * Inherited features section: updated the outdated note on JWT signing.
    It now reflects current Supabase Auth behavior: asymmetric signing keys
    (RS256 by default, ECC/Ed25519 optional) are supported and recommended,
    while HS256 remains for compatibility.
    
    ## Additional context
    
    This PR improves documentation and developer ergonomics only. Read
    through the readme because I wanted to contribute to the project and
    just updated everything that didn't look right. No functional or runtime
    changes.
    
    ---------
    
    Co-authored-by: Chris Stockton <[email protected]>
    nicokempe and cstockton authored Oct 10, 2025
    Configuration menu
    Copy the full SHA
    7ff716b View commit details
    Browse the repository at this point in the history

Commits on Oct 13, 2025

  1. feat: properly handle redirect url fragments and unusual hostnames (#…

    …2200)
    
    Pattern matching should occur on the URL without the fragment. URLs with
    hostnames that are not usual (so having unicode characters) should be
    considered invalid.
    hf authored Oct 13, 2025
    Configuration menu
    Copy the full SHA
    aa0ac5b View commit details
    Browse the repository at this point in the history

Commits on Oct 20, 2025

  1. Configuration menu
    Copy the full SHA
    f805900 View commit details
    Browse the repository at this point in the history
  2. fix: gosec incorrectly warns about accessing signature[64] (#2222)

    Incorrectly identifies `[64]` as out-of-bounds access.
    hf authored Oct 20, 2025
    Configuration menu
    Copy the full SHA
    bca6626 View commit details
    Browse the repository at this point in the history
  3. feat: add .well-known/openid-configuration (#2197)

    Adds the `.well-known/openid-configuration` endpoint that serves a
    static response pointing to the `.well-known/jwks.json` URL.
    
    It's important to also have this, as AWS JWT Authorizers require the
    OpenID discovery URL, not just the `jwks.json`.
    
    
    https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-jwt-authorizer.html
    hf authored Oct 20, 2025
    Configuration menu
    Copy the full SHA
    9a8d0df View commit details
    Browse the repository at this point in the history

Commits on Oct 29, 2025

  1. fix(openapi): add missing OAuth client registration fields (#2227)

    adds missing OAuth client registration fields
    cemalkilic authored Oct 29, 2025
    Configuration menu
    Copy the full SHA
    cf39a8a View commit details
    Browse the repository at this point in the history
  2. feat: introduce v2 refresh token algorithm (#2216)

    Introduces v2 of a refresh token algorithm.
    
    **Goals**
    
    1. **Smaller disk size.** A common complaint with the `refresh_tokens`
    table is that it's huge and difficult to clean up without impacting IO
    performance.
    2. **Lighter on replication.** A lot of active users cause a lot of
    on-wire traffic for replication.
    3. **Easier to debug and analyze.** Refresh tokens are not transparent,
    and a recursive self-relationship is not easy to debug with difficult
    edge cases that are not local in time.
    
    **Configuration Options**
    
    | Config | Meaning |
    | --- | --- |
    | `GOTRUE_SECURITY_REFRESH_TOKEN_ALGORITHM_VERSION` | 0 or 1 for regular
    tokens, 2 for new tokens. This currently only applies on new sessions.
    Old sessions use old implementation. |
    | `GOTRUE_SECURITY_REFRESH_TOKEN_ALLOW_REUSE` | not secure, but allows
    any v2 refresh token to always be reused. |
    
    **Implementation**
    
    Refresh tokens now encode the session ID + counter value, which is then
    signed by a per-session HMAC key. By comparing the state in the session
    and the counter in the refresh token, we can identify whether a refresh
    token is being used properly or it's being reused. We can also identify
    what type of reuse is going on.
    
    If the refresh token counter is the previous refresh token, it means the
    client failed to save the last response. This is always allowed.
    
    If the refresh token counter is older than the previous refresh token,
    then it's being reused. Reuse is allowed only if the client is
    refreshing the same session within the
    `GOTRUE_SECURITY_REFRESH_TOKEN_REUSE_INTERVAL`.
    
    To ensure a non-synchronized client synchronizes to the correct refresh
    token state, the session's refresh token counter is incremented only on
    valid refresh token use.
    
    Please check the massive suite of tests (>700 LOC) which exercise every
    possible combination to ensure correctness of the algorithm. The
    coverage here is above 95% (of the lines that can be covered).
    
    **Observability and Debuging**
    
    Requests that create a session and refresh a session will now receive
    these response headers:
    
    | Header | Meaning |
    | --- | --- |
    | `sb-auth-user-id` | the user to which the session belongs |
    | `sb-auth-session-id` | the newly created or refreshed session |
    | `sb-auth-refresh-token-counter` | (v2 only) the refresh token's
    counter that is being returned |
    | `sb-auth-refresh-token-prefix` | (v1 only) the first 5 characters of
    the refresh token being returned |
    | `sb-auth-refresh-token-reuse-cause` | (v2 only) a comma separated list
    explaining what type of reuse was detected | `fail-to-save`,
    `concurrent-refresh`, `always-reuse` |
    | `sb-auth-refresh-token-rotation` | (v2 only) if the session is being
    terminated due to detected malicious refresh token reuse |
    hf authored Oct 29, 2025
    Configuration menu
    Copy the full SHA
    dea5b8e View commit details
    Browse the repository at this point in the history

Commits on Oct 30, 2025

  1. feat(oauthserver): add OAuth client admin update endpoint (#2231)

    ## Summary
    
    Adds a new admin endpoint to update existing OAuth client
    configurations. This enables administrators to modify OAuth client
    settings without having to delete and recreate clients.
    
      ## Changes
    
      ### New Endpoint
    - **PUT** `/admin/oauth/clients/{client_id}` - Update OAuth client
    configuration (admin only)
    
      ### Supported Update Fields
      - `redirect_uris` - Array of redirect URIs
    - `grant_types` - Array of grant types (`authorization_code`,
    `refresh_token`)
      - `client_name` - Human-readable client name
      - `client_uri` - Client application homepage URL
      - `logo_uri` - Client application logo URL
    
      ## Example Usage
    
      ```bash
      # Update client redirect URIs and name
    curl -X PUT
    https://your-project.supabase.co/admin/oauth/clients/{client_id} \
        -H "Authorization: Bearer {admin-token}" \
        -H "Content-Type: application/json" \
        -d '{
          "client_name": "Updated App Name",
          "redirect_uris": ["https://app.example.com/callback"]
        }'
    ```
    cemalkilic authored Oct 30, 2025
    Configuration menu
    Copy the full SHA
    6296a5a View commit details
    Browse the repository at this point in the history

Commits on Oct 31, 2025

  1. feat: add auth_migration annotation for the migrations (#2234)

    Adds `auth_migration` annotation for observability
    cemalkilic authored Oct 31, 2025
    Configuration menu
    Copy the full SHA
    b276d0b View commit details
    Browse the repository at this point in the history

Commits on Nov 4, 2025

  1. chore(master): release 2.181.0 (#2178)

    🤖 I have created a release *beep* *boop*
    ---
    
    
    ##
    [2.181.0](v2.180.0...v2.181.0)
    (2025-10-31)
    
    
    ### Features
    
    * add `.well-known/openid-configuration`
    ([#2197](#2197))
    ([9a8d0df](9a8d0df))
    * add `auth_migration` annotation for the migrations
    ([#2234](#2234))
    ([b276d0b](b276d0b))
    * add advisor to notify you when to double the max connection pool
    ([#2167](#2167))
    ([a72f5d9](a72f5d9))
    * add after-user-created hook
    ([#2169](#2169))
    ([bd80df8](bd80df8))
    * add support for account changes notifications in email send hook
    ([#2192](#2192))
    ([6b382ae](6b382ae))
    * email address changed notification
    ([#2181](#2181))
    ([047f851](047f851))
    * identity linked/unlinked notifications
    ([#2185](#2185))
    ([7d46936](7d46936))
    * introduce v2 refresh token algorithm
    ([#2216](#2216))
    ([dea5b8e](dea5b8e))
    * MFA factor enrollment notifications
    ([#2183](#2183))
    ([53db712](53db712))
    * notify users when their phone number has changed
    ([#2184](#2184))
    ([21f3070](21f3070))
    * **oauthserver:** add OAuth client admin update endpoint
    ([#2231](#2231))
    ([6296a5a](6296a5a))
    * properly handle redirect url fragments and unusual hostnames
    ([#2200](#2200))
    ([aa0ac5b](aa0ac5b))
    * store latest challenge/attestation data
    ([#2179](#2179))
    ([01ebce1](01ebce1))
    * support percentage based db limits with reload support
    ([#2177](#2177))
    ([1731466](1731466))
    * webauthn support schema changes, update openapi.yaml
    ([#2163](#2163))
    ([68cb8d2](68cb8d2))
    
    
    ### Bug Fixes
    
    * gosec incorrectly warns about accessing signature[64]
    ([#2222](#2222))
    ([bca6626](bca6626))
    * **openapi:** add missing OAuth client registration fields
    ([#2227](#2227))
    ([cf39a8a](cf39a8a))
    
    ---
    This PR was generated with [Release
    Please](https://github.com/googleapis/release-please). See
    [documentation](https://github.com/googleapis/release-please#release-please).
    
    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    github-actions[bot] authored Nov 4, 2025
    Configuration menu
    Copy the full SHA
    a6530d5 View commit details
    Browse the repository at this point in the history
Loading