Supabase Auth

repository·master·Indexed 25 days ago

https://github.com/supabase/auth

A user management and authentication server written in Go that powers Supabase features including JWT issuance, Row Level Security, and various sign-in methods such as email, magic links, and social providers. It supports extensive configuration via environment variables for database connections, JWT settings, SMTP email, SMS providers, and multiple external OAuth providers.

Tokens
10.5K
Snippets
39
Records
73
Agent score
82%

What's inside supabase-auth

  1. Backward compatibility guarantees

    master

    Supabase Auth follows Semantic Versioning. Note that Auth is not intended to be used as a Go library; there are no guarantees on backward API compatibility when used as a library.

    Patch Versions

    Guarantees include:

    • Database objects (tables, columns, indexes, functions).
    • REST API.
    • JWT structure.
    • Configuration.

    Note: Tables may add new columns, and JWTs may add new properties.

    Minor Versions

    Guarantees include:

    • REST API.
    • JWT structure.
    • Configuration.

    Note: Deprecated APIs or configurations may continue to work for a few releases. Significant schema changes or removal of JWT fields after deprecation are not guaranteed.

    Major Versions

    • No backward compatibility is guaranteed.
  2. Unsupported inherited features from GoTrue

    master

    The following features from the original Netlify GoTrue codebase are not supported by Supabase Auth and may be removed without notice:

    • Multi-tenancy via the instances table (GOTRUE_MULTI_INSTANCE_MODE).
    • System user (zero UUID user).
    • Super admin via the is_super_admin column.
    • Group information in JWTs via GOTRUE_JWT_ADMIN_GROUP_NAME and other configuration fields.
    • HS256 JWT signing (Asymmetric keys like RS256 are the default; HS256 is supported for compatibility but migration to asymmetric keys is recommended).
  3. Manage environment precedence and multiple environments

    master

    By default, existing environment variables take precedence over those loaded from a .env file. If you want to overwrite existing variables, use godotenv.Overload().

    A common pattern for managing multiple environments (development, test, production) is to use an environment variable like FOO_ENV to determine which .env file to load in a specific order.

    env := os.Getenv("FOO_ENV")
    if "" == env {
      env = "development"
    }
    
    // Loading order pattern:
    // 1. Load environment-specific local overrides
    godotenv.Load(".env." + env + ".local")
    // 2. Load general local overrides (if not in test)
    if "test" != env {
      godotenv.Load(".env.local")
    }
    // 3. Load environment-specific config
    godotenv.Load(".env." + env)
    // 4. Load the base .env file
    godotenv.Load()
  4. Quick Start: Local development with Docker

    master

    To run the entire Supabase Auth stack using Docker, follow these steps:

    1. Create a .env.docker file for your environment variables. Use example.docker.env as a template.
    2. Build the project: make build
    3. Start the development environment: make dev
    4. Verify that two containers are running (auth-auth-1 and auth-postgres-1) using docker ps.
    5. Confirm the service is running by visiting the health check endpoint: http://localhost:9999/health
    make build
    make dev
    docker ps
    # Visit http://localhost:9999/health to confirm
  5. Configure Auth via Environment Variables

    master
    Auth can be configured using a .env file, environment variables, or both. Environment variables are prefixed with GOTRUE_ and take precedence over values in a configuration file. For certain settings like PORT or DATABASE_URL, the GOTRUE_ prefix is not required.
  6. Rotate SAML SP signing and encryption keys with zero downtime

    master

    To rotate the SAML Service Provider (SP) signing and encryption keys without breaking existing sessions, follow a four-step process that utilizes a 'dual-key window'. This window allows Identity Providers (IdPs) to discover and cache the new certificate before the old one is decommissioned.

    Prerequisites

    • Access to the GoTrue environment variables or secrets store.
    • Ability to trigger a rolling restart or redeploy of GoTrue.
    • openssl installed locally.

    Step 1: Generate a new key

    Generate a PKCS#1 DER key encoded as standard Base64 (no line breaks):

    openssl genrsa 2048 | openssl rsa -outform DER | base64 | tr -d '\n'

    Requirement: RSA 2048 or larger, public exponent 65537.

    Step 2: Announce the new certificate (Dual-key window)

    Configure both the current key and the new key in your environment variables:

    GOTRUE_SAML_PRIVATE_KEY=<current key — unchanged>
    GOTRUE_SAML_PRIVATE_KEY_NEXT=<new key from Step 1>

    Redeploy GoTrue. During this phase, both certificates appear in the SAML metadata. If GOTRUE_SAML_ALLOW_ENCRYPTED_ASSERTIONS is enabled, GoTrue will automatically attempt decryption with the old key if the primary key fails.

    Verification: Check that the metadata contains 2 key descriptors:

    curl -s https://<your-domain>/auth/v1/sso/saml/metadata \
      | xmllint --xpath 'count(//md:KeyDescriptor[@use="signing"])' \
        --noout - 2>/dev/null
    # Expected: 2

    Step 3: Wait for IdP caches to drain

    Wait for the longest cache TTL among your IdPs. The minimum recommended wait is 1 hour (based on the cacheDuration=PT1H advertised in the metadata).

    Step 4: Promote the new key

    Swap the values so the new key becomes the primary, and clear the _NEXT variable:

    GOTRUE_SAML_PRIVATE_KEY=<new key from Step 1>
    GOTRUE_SAML_PRIVATE_KEY_NEXT=   # remove / clear

    Redeploy GoTrue. The metadata will now only show the new certificate.

    Verification: Check that the metadata contains 1 key descriptor:

    curl -s https://<your-domain>/auth/v1/sso/saml/metadata \
      | xmllint --xpath 'count(//md:KeyDescriptor[@use="signing"])' \
        --noout - 2>/dev/null
    # Expected: 1

    And verify the rotation status via the settings endpoint:

    curl -s https://<your-domain>/auth/v1/settings \
      | jq '.saml_private_key_next_configured'
    # Expected: false
  7. Use GoDotEnv as a library to load environment variables

    master

    To load variables from a .env file into your process's environment, use godotenv.Load(). By default, it looks for a file named .env in the current directory. You can also specify custom filenames or multiple files.

    Alternatively, you can use the autoload package to automatically load .env on import without calling Load() explicitly.

    package main
    
    import (
        "log"
        "os"
    
        "github.com/joho/godotenv"
    )
    
    func main() {
      // Loads .env from the current directory
      err := godotenv.Load()
      if err != nil {
        log.Fatal("Error loading .env file")
      }
    
      s3Bucket := os.Getenv("S3_BUCKET")
      secretKey := os.Getenv("SECRET_KEY")
    }
  8. Quick Start: Local development with Postgres

    master

    To run Supabase Auth locally using a standalone Postgres container, follow these steps:

    1. Create a .env file to store your custom environment variables. You can use example.env as a template.
    2. Start the local Postgres database: docker-compose -f docker-compose-dev.yml up postgres
    3. Build the auth binary: make build
    4. Execute the binary: ./auth
    docker-compose -f docker-compose-dev.yml up postgres
    make build
    ./auth
  9. Best practices for self-hosting Supabase Auth

    master

    When self-hosting Supabase Auth, follow these best practices to ensure stability and backward compatibility:

    1. Do not modify the schema managed by Auth. Refer to the migrations directory to see the managed schema.
    2. Do not rely on the database schema or data structure. Always use the provided Auth APIs and JWTs to retrieve user information.
    3. Always run Auth behind a TLS-capable proxy (e.g., a load balancer, CDN, or Nginx).
  10. Configure Database Connection

    master

    Settings for connecting to the underlying database.

    • GOTRUE_DB_DRIVER (required): Must be postgres.
    • DATABASE_URL or DB_DATABASE_URL (required): The connection string.
    • GOTRUE_DB_MAX_POOL_SIZE: Maximum open connections (defaults to 0/unlimited).
    • DB_NAMESPACE: A prefix added to all table names.

    Migrations: Migrations run automatically on startup. To run them manually:

    • Locally: ./auth migrate
    • Docker: docker run --rm auth gotrue migrate
    GOTRUE_DB_DRIVER=postgres
    DATABASE_URL=root@localhost/auth
  11. IdentitySchema: Understand linked identities

    master

    The IdentitySchema represents an identity linked to a user via an external provider (e.g., Google, GitHub).

    Key fields:

    • Id: The unique identity ID.
    • UserId: The ID of the user this identity belongs to.
    • Provider: The name of the provider.
    • Email: The email associated with this identity.
    • IdentityData: A map containing provider-specific data.