diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 2867c8a784..0000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,74 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -nationality, personal appearance, race, religion, or sexual identity and -orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or -advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at david@netlify.com. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d4da9761f9..91f8f504f0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,529 +1,59 @@ -# CONTRIBUTING +# Contributing to Auth -We would love to have contributions from each and every one of you in the community be it big or small and you are the ones who motivate us to do better than what we do today. +Thanks for your interest in improving Auth. Contributions of every size are welcome. Follow our [Code of Conduct](https://github.com/supabase/.github/blob/main/CODE_OF_CONDUCT.md). -## Code Of Conduct +## Before you start -Please help us keep all our projects open and inclusive. Kindly follow our [Code of Conduct](CODE_OF_CONDUCT.md) to keep the ecosystem healthy and friendly for all. +For anything beyond a trivial fix, open a [Discussion](https://github.com/supabase/supabase/discussions) before you start writing code. +Auth sits at the center of Supabase, and coordinating up front lets the team weigh in on the approach and line the work up with the rest of the project before effort is spent. -## Quick Start +Auth ships to a large and growing number of self-hosted and managed deployments. You cannot predict how any given project's database is configured or what has been customized, so schema changes and other risky changes carry outsized impact. Coordinate them early. -Auth has a development container setup that makes it easy to get started contributing. This setup only requires that [Docker](https://www.docker.com/get-started) is setup on your system. The development container setup includes a PostgreSQL container with migrations already applied and a container running GoTrue that will perform a hot reload when changes to the source code are detected. +Meaningful pull requests opened without a prior, agreed-upon Discussion may be closed or left stale until the work has been coordinated. This is not about turning contributors away, it is about making sure your time is well spent. -If you would like to run Auth locally or learn more about what these containers are doing for you, continue reading the [Setup and Tooling](#setup-and-tooling) section below. Otherwise, you can skip ahead to the [How To Verify that GoTrue is Available](#how-to-verify-that-auth-is-available) section to learn about working with and developing GoTrue. +You should understand your own changes and be able to explain what they do and how they interact with the rest of the system. -Before using the containers, you will need to make sure an `.env.docker` file exists by making a copy of `example.docker.env` and configuring it for your needs. The set of env vars in `example.docker.env` only contain the necessary env vars for auth to start in a docker environment. For the full list of env vars, please refer to `example.env` and copy over the necessary ones into your `.env.docker` file. +## Pull requests -The following are some basic commands. A full and up to date list of commands can be found in the project's `Makefile` or by running `make help`. +Follow these conventions when you open a pull request: -### Starting the containers - -Start the containers as described above in an attached state with log output. - -```bash -make dev -``` - -### Running tests in the containers - -Start the containers with a fresh database and run the project's tests. - -```bash -make docker-test -``` - -### Removing the containers - -Remove both containers and their volumes. This removes any data associated with the containers. - -```bash -make docker-clean -``` - -### Rebuild the containers - -Fully rebuild the containers without using any cached layers. - -```bash -make docker-build -``` - -## Setup and Tooling - -Auth -- as the name implies -- is a user registration and authentication API developed in [Go](https://go.dev). - -It connects to a [PostgreSQL](https://www.postgresql.org) database in order to store authentication data, [Soda CLI](https://gobuffalo.io/en/docs/db/toolbox) to manage database schema and migrations, -and runs inside a [Docker](https://www.docker.com/get-started) container. - -Therefore, to contribute to Auth you will need to install these tools. - -### Install Tools - -- Install [Go](https://go.dev) 1.22 - -```zsh -# Via Homebrew on macOS -brew install go@1.22 - -# Set the environment variable in the ~/.zshrc file -echo 'export PATH="/opt/homebrew/opt/go@1.22/bin:$PATH"' >> ~/.zshrc -``` - -- Install [Docker](https://www.docker.com/get-started) - -```zsh -# Via Homebrew on macOS -brew install docker -``` - -Or, if you prefer, download [Docker Desktop](https://www.docker.com/get-started). - -- Install [Soda CLI](https://gobuffalo.io/en/docs/db/toolbox) - -```zsh -# Via Homebrew on macOS -brew install gobuffalo/tap/pop -``` - -If you are on macOS Catalina you may [run into issues installing Soda with Brew](https://github.com/gobuffalo/homebrew-tap/issues/5). Do check your `GOPATH` and run - -`go build -o /bin/soda github.com/gobuffalo/pop/soda` to resolve. - -- Clone the Auth [repository](https://github.com/supabase/auth) - -```zsh -git clone https://github.com/supabase/auth -``` - -- (Optional, but recommended) Install [lefthook](https://github.com/evilmartians/lefthook) and activate the repo's git hooks. This mirrors CI's checks locally before each commit, so a mistake is caught early instead of failing CI. See `lefthook.yml` for the current list. - -```zsh -# See https://github.com/evilmartians/lefthook/blob/master/docs/install.md for all install methods -brew install lefthook - -# From the repo root, activate the hooks defined in lefthook.yml -make hooks -``` - -### Install Auth - -To begin installation, be sure to start from the root directory. - -- `cd auth` - -To complete installation, you will: - -- Install the PostgreSQL Docker image -- Create the DB Schema and Migrations -- Setup a local `.env` for environment variables -- Compile Auth -- Run the Auth binary executable - -#### Installation Steps - -1. Start Docker -2. To install the PostgreSQL Docker image, run: - -```zsh -# Builds the postgres image -docker-compose -f docker-compose-dev.yml build postgres - -# Runs the postgres container -docker-compose -f docker-compose-dev.yml up postgres -``` - -You should then see in Docker that `auth-postgres-1` is running on `port: 5432`. - -> **Important** If you happen to already have a local running instance of Postgres running on the port `5432` because you -> may have installed via [homebrew on macOS](https://formulae.brew.sh/formula/postgresql) then be certain to stop the process using: -> -> - `brew services stop postgresql` -> -> If you need to run the test environment on another port, you will need to modify several configuration files to use a different custom port. - -3. Next compile the Auth binary: - -When you fork a repository, GitHub does not automatically copy all the tags (tags are not included by default). To ensure the correct tag is set before building the binary, you need to fetch the tags from the upstream repository and push them to your fork. Follow these steps: - -```zsh -# Fetch the tags from the upstream repository -git fetch upstream --tags - -# Push the tags to your fork -git push origin --tags -``` - -Then build the binary by running: - -```zsh -make build -``` - -4. To setup the database schema via Soda, run: - -```zsh -make migrate_test -``` - -You should see log messages that indicate that the Auth migrations were applied successfully: - -```terminal -INFO[0000] Auth migrations applied successfully -DEBU[0000] after status -[POP] 2021/12/15 10:44:36 sql - SELECT EXISTS (SELECT schema_migrations.* FROM schema_migrations AS schema_migrations WHERE version = $1) | ["20210710035447"] -[POP] 2021/12/15 10:44:36 sql - SELECT EXISTS (SELECT schema_migrations.* FROM schema_migrations AS schema_migrations WHERE version = $1) | ["20210722035447"] -[POP] 2021/12/15 10:44:36 sql - SELECT EXISTS (SELECT schema_migrations.* FROM schema_migrations AS schema_migrations WHERE version = $1) | ["20210730183235"] -[POP] 2021/12/15 10:44:36 sql - SELECT EXISTS (SELECT schema_migrations.* FROM schema_migrations AS schema_migrations WHERE version = $1) | ["20210909172000"] -[POP] 2021/12/15 10:44:36 sql - SELECT EXISTS (SELECT schema_migrations.* FROM schema_migrations AS schema_migrations WHERE version = $1) | ["20211122151130"] -Version Name Status -20210710035447 alter_users Applied -20210722035447 adds_confirmed_at Applied -20210730183235 add_email_change_confirmed Applied -20210909172000 create_identities_table Applied -20211122151130 create_user_id_idx Applied -``` - -That lists each migration that was applied. Note: there may be more migrations than those listed. - -4. Create a `.env` file in the root of the project and copy the following config in [example.env](example.env). Set the values to GOTRUE_SMS_TEST_OTP_VALID_UNTIL in the `.env` file. - -5. In order to have Auth connect to your PostgreSQL database running in Docker, it is important to set a connection string like: - -``` -DATABASE_URL="postgres://supabase_auth_admin:root@localhost:5432/postgres" -``` - -> Important: Auth requires a set of SMTP credentials to run, you can generate your own SMTP credentials via an SMTP provider such as AWS SES, SendGrid, MailChimp, SendInBlue or any other SMTP providers. - -6. Then finally Start Auth -7. Verify that Auth is Available - -### Starting Auth - -Start Auth by running the executable: - -```zsh -./auth -``` - -This command will re-run migrations and then indicate that Auth has started: - -```zsh -INFO[0000] Auth API started on: localhost:9999 -``` - -### How To Verify that Auth is Available - -To test that your Auth is up and available, you can query the `health` endpoint at `http://localhost:9999/health`. You should see a response similar to: - -```json -{ - "description": "Auth is a user registration and authentication API", - "name": "Auth", - "version": "" -} -``` - -To see the current settings, make a request to `http://localhost:9999/settings` and you should see a response similar to: - -```json -{ - "external": { - "apple": false, - "azure": false, - "bitbucket": false, - "discord": false, - "github": false, - "gitlab": false, - "google": false, - "facebook": false, - "snapchat": false, - "spotify": false, - "slack": false, - "slack_oidc": false, - "twitch": true, - "twitter": false, - "email": true, - "phone": false, - "saml": false - }, - "external_labels": { - "saml": "auth0" - }, - "disable_signup": false, - "mailer_autoconfirm": false, - "phone_autoconfirm": false, - "sms_provider": "twilio" -} -``` - -## How to Use Admin API Endpoints - -To test the admin endpoints (or other api endpoints), you can invoke via HTTP requests. Using [Insomnia](https://insomnia.rest/products/insomnia) can help you issue these requests. - -You will need to know the `GOTRUE_JWT_SECRET` configured in the `.env` settings. - -Also, you must generate a JWT with the signature which has the `supabase_admin` role (or one that is specified in `GOTRUE_JWT_ADMIN_ROLES`). - -For example: - -```json -{ - "role": "supabase_admin" -} -``` - -You can sign this payload using the [JWT.io Debugger](https://jwt.io/#debugger-io) but make sure that `secret base64 encoded` is unchecked. - -Then you can use this JWT as a Bearer token for admin requests. - -### Create User (aka Sign Up a User) - -To create a new user, `POST /admin/users` with the payload: - -```json -{ - "email": "user@example.com", - "password": "12345678" -} -``` - -#### Request - -``` -POST /admin/users HTTP/1.1 -Host: localhost:9999 -User-Agent: insomnia/2021.7.2 -Content-Type: application/json -Authorization: Bearer -Accept: */* -Content-Length: 57 -``` - -#### Response - -And you should get a new user: - -```json -{ - "id": "e78c512d-68e4-482b-901b-75003e89acae", - "aud": "authenticated", - "role": "authenticated", - "email": "user@example.com", - "phone": "", - "app_metadata": { - "provider": "email", - "providers": ["email"] - }, - "user_metadata": {}, - "identities": null, - "created_at": "2021-12-15T12:40:03.507551-05:00", - "updated_at": "2021-12-15T12:40:03.512067-05:00" -} -``` - -### List/Find Users - -To create a new user, make a request to `GET /admin/users`. - -#### Request - -``` -GET /admin/users HTTP/1.1 -Host: localhost:9999 -User-Agent: insomnia/2021.7.2 -Authorization: Bearer -Accept: */\_ -``` - -#### Response - -The response from `/admin/users` should return all users: - -```json -{ - "aud": "authenticated", - "users": [ - { - "id": "b7fd0253-6e16-4d4e-b61b-5943cb1b2102", - "aud": "authenticated", - "role": "authenticated", - "email": "user+4@example.com", - "phone": "", - "app_metadata": { - "provider": "email", - "providers": ["email"] - }, - "user_metadata": {}, - "identities": null, - "created_at": "2021-12-15T12:43:58.12207-05:00", - "updated_at": "2021-12-15T12:43:58.122073-05:00" - }, - { - "id": "d69ae847-99be-4642-868f-439c2cdd9af4", - "aud": "authenticated", - "role": "authenticated", - "email": "user+3@example.com", - "phone": "", - "app_metadata": { - "provider": "email", - "providers": ["email"] - }, - "user_metadata": {}, - "identities": null, - "created_at": "2021-12-15T12:43:56.730209-05:00", - "updated_at": "2021-12-15T12:43:56.730213-05:00" - }, - { - "id": "7282cf42-344e-4474-bdf6-d48e4968a2e4", - "aud": "authenticated", - "role": "authenticated", - "email": "user+2@example.com", - "phone": "", - "app_metadata": { - "provider": "email", - "providers": ["email"] - }, - "user_metadata": {}, - "identities": null, - "created_at": "2021-12-15T12:43:54.867676-05:00", - "updated_at": "2021-12-15T12:43:54.867679-05:00" - }, - { - "id": "e78c512d-68e4-482b-901b-75003e89acae", - "aud": "authenticated", - "role": "authenticated", - "email": "user@example.com", - "phone": "", - "app_metadata": { - "provider": "email", - "providers": ["email"] - }, - "user_metadata": {}, - "identities": null, - "created_at": "2021-12-15T12:40:03.507551-05:00", - "updated_at": "2021-12-15T12:40:03.507554-05:00" - } - ] -} -``` - -### Running Database Migrations - -If you need to run any new migrations: - -```zsh -make migrate_test -``` - -## Testing - -Currently, we don't use a separate test database, so the same database created when installing Auth to run locally is used. - -The following commands should help in setting up a database and running the tests: - -```sh -# Runs the database in a docker container -$ docker-compose -f docker-compose-dev.yml up postgres - -# Applies the migrations to the database (requires soda cli) -$ make migrate_test - -# Executes the tests -$ make test -``` - -### Customizing the PostgreSQL Port - -if you already run PostgreSQL and need to run your database on a different, custom port, -you will need to make several configuration changes to the following files: - -In these examples, we change the port from 5432 to 7432. - -> Note: This is not recommended, but if you do, please do not check in changes. - -``` -// file: docker-compose-dev.yml -ports: - - 7432:5432 \ 👈 set the first value to your external facing port -``` - -The port you customize here can them be used in the subsequent configuration: - -``` -// file: database.yaml -test: -dialect: "postgres" -database: "postgres" -host: {{ envOr "POSTGRES_HOST" "127.0.0.1" }} -port: {{ envOr "POSTGRES_PORT" "7432" }} 👈 set to your port -``` - -``` -// file: test.env -DATABASE_URL="postgres://supabase_auth_admin:root@localhost:7432/postgres" 👈 set to your port -``` - -``` -// file: migrate.sh -export GOTRUE_DB_DATABASE_URL="postgres://supabase_auth_admin:root@localhost:7432/$DB_ENV" -``` - -## Helpful Docker Commands - -```zsh -# Command line into bash on the PostgreSQL container -docker exec -it auth-postgres-1 bash - -# Removes Container -docker container rm -f auth-postgres-1 - -# Removes volume -docker volume rm postgres_data -``` - -## Updating Package Dependencies +- Fork the repo and create your branch from `master`. +- Keep it small: one logical change per pull request. +- Add tests with your change. CI must be green. +- Reference the accepted Discussion or issue in the pull request description. -- `make deps` -- `go mod tidy` if necessary +### Writing a good pull request -## Submitting Pull Requests +A clear description speeds up review: -We actively welcome your pull requests. +- Explain why, not what. The diff shows what changed, the description should cover the motivation, the impact, and any tradeoffs or alternatives you weighed. +- Include verification steps: how you tested the change and how a reviewer can confirm it works. -- Fork the repo and create your branch from `master`. -- If you've added code that should be tested, add tests. -- If you've changed APIs, update the documentation. -- Ensure the test suite passes. -- Make sure your code lints. +### Schema and risky changes -### Checklist for Submitting Pull Requests +For the reasons above, schema changes and other risky changes get extra scrutiny. See also the [backward compatibility](README.md#backward-compatibility) guarantees. -- Is there a corresponding issue created for it? If so, please include it in the PR description so we can track / refer to it. -- Does your PR follow the [semantic-release commit guidelines](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines)? -- If the PR is a `feat`, an [RFC](https://github.com/supabase/rfcs) or a detailed description of the design implementation is required. The former (RFC) is preferred before starting on the PR. -- Are the existing tests passing? -- Have you written some tests for your PR? +- Prefer backward compatible, additive changes. A migration must run safely against an existing production database, and not just a fresh one. +- Do not assume data shape, size, or installed extensions. Avoid operations that take long locks or rewrite large tables. +- Include the `EXPLAIN` (or `EXPLAIN ANALYZE`) output for the affected queries so reviewers can see the query plan. -## Guidelines for Implementing Additional OAuth Providers +### Commit messages -> ⚠️ We won't be accepting any additional oauth / sms provider contributions for now because we intend to support these through webhooks or a generic provider in the future. +Pull request titles and commits must follow [Conventional Commits](https://www.conventionalcommits.org). For example: -Please ensure that an end-to-end test is done for the OAuth provider implemented. +- `feat: add support for OIDC sign-in` +- `fix: resolve race condition in token refresh` +- `docs: update OAuth configuration guide` +- `chore: upgrade dependencies` -An end-to-end test includes: +## Review -- Creating an application on the oauth provider site -- Generating your own client_id and secret -- Testing that `http://localhost:9999/authorize?provider=MY_COOL_NEW_PROVIDER` redirects you to the provider sign-in page -- The callback is handled properly -- Gotrue redirects to the `SITE_URL` or one of the URI's specified in the `URI_ALLOW_LIST` with the access_token, provider_token, expiry and refresh_token as query fragments +The Auth team (`@supabase/auth`) reviews and merges pull requests. We aim to respond promptly, but there is no guaranteed response time for community contributions. Address blocking review feedback before a change can be merged. -### Writing tests for the new OAuth provider implemented +## Development -Since implementing an additional OAuth provider consists of making api calls to an external api, we set up a mock server to attempt to mock the responses expected from the OAuth provider. +See [DEVELOPMENT.md](DEVELOPMENT.md) to build, run, and test Auth locally. ## License -By contributing to Auth, you agree that your contributions will be licensed -under its [MIT license](LICENSE). +By contributing to Auth, you agree that your contributions will be licensed under its [MIT license](LICENSE). diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000000..3dcd456db6 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,44 @@ +# Development + +How to build, run, and test Auth locally. + +## Prerequisites + +- [Go](https://go.dev) 1.27 +- [Docker](https://www.docker.com/get-started) + +## Quick start + +Run Postgres in a container and Auth on your host. This matches CI, which pins Go 1.27 in `go.mod`. + +```bash +# Create your local env file +cp example.env .env + +# Start Postgres in the background +docker compose -f docker-compose-dev.yml up -d postgres + +# Run Auth (applies migrations on startup) +go run . +``` + +Verify Auth is up: + +```bash +curl http://localhost:9999/health +``` + +## Going further + +Once Auth is running, these commands cover the rest of the workflow: + +- `make help` lists every available command; see the `Makefile` for details. +- `example.env` holds the full set of environment variables. +- Postgres must be running to run the tests: `go test ./...`. Scope with `-run`, for example `go test ./internal/api/... -run SCIM`. + +Optionally, install the git hooks so `gofmt` and the linters run before each commit. This requires [lefthook](https://github.com/evilmartians/lefthook): + +```bash +brew install lefthook +make hooks +``` diff --git a/LICENSE b/LICENSE index 56e5196da5..f4797abf98 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2025 Supabase +Copyright (c) 2021-2026 Supabase Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 7b103730b0..b5180554c6 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ -# Auth - Authentication and User Management by Supabase +# Auth: authentication and user management by Supabase [![Coverage Status](https://coveralls.io/repos/github/supabase/auth/badge.svg?branch=master)](https://coveralls.io/github/supabase/auth?branch=master) -Auth is a user management and authentication server written in Go that powers -[Supabase](https://supabase.com)'s features such as: +Auth is a user management and authentication server written in Go that powers [Supabase](https://supabase.com)'s features such as: - Issuing JWTs - Row Level Security with PostgREST @@ -11,66 +10,40 @@ Auth is a user management and authentication server written in Go that powers - Sign in with email, password, magic link, phone number - Sign in with external providers (Google, Apple, Facebook, Discord, ...) -It is originally based on the excellent -[GoTrue codebase by Netlify](https://github.com/netlify/gotrue), however both have diverged significantly in features and capabilities. +It was originally based on the [GoTrue codebase by Netlify](https://github.com/netlify/gotrue). +However, the two projects have since diverged significantly in features and capabilities. -If you wish to contribute to the project, please refer to the [contributing guide](/CONTRIBUTING.md). +To contribute to the project, see the [contributing guide](/CONTRIBUTING.md). -## Table of Contents +## Table of contents -- [Quick Start](#quick-start) -- [Running in Production](#running-in-production) +- [Quick start](#quick-start) +- [Running in production](#running-in-production) - [Configuration](#configuration) -- [Endpoints](#endpoints) +- [API](#api) -## Quick Start +## Quick start -Create a `.env` file to store your own custom environment variables. See [`example.env`](example.env) - -1. Start the local Postgres database in a Postgres container: `docker-compose -f docker-compose-dev.yml up postgres` -2. Build the auth binary: `make build` . You should see an output like this: - -```bash -go build -ldflags "-X github.com/supabase/auth/cmd.Version=`git rev-parse HEAD`" -GOOS=linux GOARCH=arm64 go build -ldflags "-X github.com/supabase/auth/cmd.Version=`git rev-parse HEAD`" -o gotrue-arm64 -``` - -3. Execute the auth binary: `./auth` - -### If you have Docker installed - -Create a `.env.docker` file to store your own custom env vars. See [`example.docker.env`](example.docker.env) - -1. `make build` -2. `make dev` -3. `docker ps` should show two Docker containers (`auth-auth-1` and `auth-postgres-1`) -4. That's it! Visit the [health check endpoint](http://localhost:9999/health) to confirm that auth is running. +To build, run, and test Auth locally, see [DEVELOPMENT.md](DEVELOPMENT.md). ## Running in production -Running an authentication server in production is not an easy feat. We -recommend using [Supabase Auth](https://supabase.com/auth) which gets regular -security updates. +Running an authentication server in production is hard. We recommend using [Supabase Auth](https://supabase.com/auth), which receives regular security updates. -Otherwise, please make sure you set up a process to promptly update to the -latest version. You can do that by following this repository, specifically the -[Releases](https://github.com/supabase/auth/releases) and [Security -Advisories](https://github.com/supabase/auth/security/advisories) sections. +Otherwise, set up a process to update promptly to the latest version. +Follow this repository, especially the [Releases](https://github.com/supabase/auth/releases) and [Security Advisories](https://github.com/supabase/auth/security/advisories) sections. ### Backward compatibility -Auth uses the [Semantic Versioning](https://semver.org) scheme. Here are some -further clarifications on backward compatibility guarantees: +Auth uses the [Semantic Versioning](https://semver.org) scheme. The following sections clarify its backward compatibility guarantees: **Go API compatibility** -Auth is not meant to be used as a Go library. There are no guarantees on -backward API compatibility when used this way regardless of which version -number changes. +Auth is not meant for use as a Go library. Auth does not guarantee backward API compatibility for this use, regardless of which version number changes. **Patch** -Changes to the patch version guarantees backward compatibility with: +Changes to the patch version guarantee backward compatibility with: - Database objects (tables, columns, indexes, functions). - REST API @@ -84,1330 +57,69 @@ Guaranteed examples: - An index will not be removed. - A uniqueness constraint will not be removed. - A REST API will not be removed. -- Parameters to REST APIs will work equivalently as before (or better, if a bug - has been fixed). +- Parameters to REST APIs will work equivalently as before. A bug fix might make them work better. - Configuration will not change. Not guaranteed examples: - A table may add new columns. - Columns in a table may be reordered. -- Non-unique constraints may be removed (database level checks, null, default - values). +- Non-unique constraints may be removed. Examples include database-level checks, null constraints, and default values. - JWT may add new properties. **Minor** -Changes to minor version guarantees backward compatibility with: +Changes to the minor version guarantee backward compatibility with: - REST API - JWT structure - Configuration -Exceptions to these guarantees will be made only when serious security issues -are found that can't be remedied in any other way. +We make exceptions to these guarantees only for serious security issues that have no other remedy. Guaranteed examples: -- Existing APIs may be deprecated but continue working for the next few minor - version releases. -- Configuration changes may become deprecated but continue working for the next - few minor version releases. -- Already issued JWTs will be accepted, but new JWTs may be with a different - structure (but usually similar). +- Existing APIs may be deprecated but continue working for the next few minor version releases. +- Configuration changes may become deprecated but continue working for the next few minor version releases. +- Already issued JWTs remain accepted. New JWTs may have a different structure, though usually similar to the old one. Not guaranteed examples: - Removal of JWT fields after a deprecation notice. - Removal of certain APIs after a deprecation notice. -- Removal of sign-in with external providers, after a deprecation notice. -- Deletion, truncation, significant schema changes to tables, indexes, views, - functions. +- Removal of sign-in with external providers after a deprecation notice. +- Deletion, truncation, significant schema changes to tables, indexes, views, functions. -We aim to provide a deprecation notice in execution logs for at least two major -version releases or two weeks if multiple releases go out. Compatibility will -be guaranteed while the notice is live. +We aim to provide a deprecation notice in execution logs for at least two major version releases or two weeks if multiple releases go out. We guarantee compatibility while the notice is live. **Major** -Changes to the major version do not guarantee any backward compatibility with -previous versions. +Changes to the major version do not guarantee any backward compatibility with previous versions. ### Inherited features -Certain inherited features from the Netlify codebase are not supported by -Supabase and they may be removed without prior notice in the future. This is a -comprehensive list of those features: +Supabase does not support certain features inherited from the Netlify codebase and may remove them without prior notice. The following is a comprehensive list of those features: -1. Multi-tenancy via the `instances` table i.e. `GOTRUE_MULTI_INSTANCE_MODE` - configuration parameter. -2. System user (zero UUID user). +1. Multi-tenancy via the `instances` table, that is the `GOTRUE_MULTI_INSTANCE_MODE` configuration parameter. +2. System user, identified by an all-zero UUID. 3. Super admin via the `is_super_admin` column. -4. Group information in JWTs via `GOTRUE_JWT_ADMIN_GROUP_NAME` and other - configuration fields. -5. JWT signing. Supabase Auth supports asymmetric keys (RS256 by default; - ECC/Ed25519 optional). HS256 is still supported for compatibility, but - migrating to asymmetric keys is recommended for easier validation and - rotation. Future deprecations will be announced in the changelog. See the - [JWT Signing Keys](https://supabase.com/docs/guides/auth/signing-keys) and - [JWTs guide](https://supabase.com/docs/guides/auth/jwts) for details. +4. Group information in JWTs via `GOTRUE_JWT_ADMIN_GROUP_NAME` and other configuration fields. +5. JWT signing. Supabase Auth supports asymmetric keys and uses RS256 by default. It also supports ECC and Ed25519 as optional algorithms. Auth still supports HS256 for compatibility, but migrating to asymmetric keys is recommended for easier validation and rotation. We announce future deprecations in the changelog. See the [JWT Signing Keys](https://supabase.com/docs/guides/auth/signing-keys) and [JWTs guide](https://supabase.com/docs/guides/auth/jwts) for details. -Note that this is not an exhaustive list and it may change. +This list is not exhaustive and may change. ### Best practices when self-hosting -These are some best practices to follow when self-hosting to ensure backward -compatibility with Auth: +Follow these best practices when self-hosting Auth to preserve backward compatibility: -1. Do not modify the schema managed by Auth. You can see all of the - migrations in the `migrations` directory. -2. Do not rely on the schema and the structure of data in the database. Always use - Auth APIs and JWTs to infer information about users. -3. Always run Auth behind a TLS-capable proxy such as a load balancer, CDN, - nginx or other similar software. +1. Do not modify the schema managed by Auth. See all migrations in the `migrations` directory. +2. Do not rely on the schema and the structure of data in the database. Always use Auth APIs and JWTs to infer information about users. +3. Always run Auth behind a TLS-capable proxy such as a load balancer, CDN, nginx, or similar software. ## Configuration -You may configure Auth using either a configuration file named `.env`, -environment variables, or a combination of both. Environment variables are prefixed with `GOTRUE_`, and will always have precedence over values provided via file. - -### Top-Level - -```properties -GOTRUE_SITE_URL=https://example.netlify.com/ -``` - -`SITE_URL` - `string` **required** - -The base URL your site is located at. Currently used in combination with other settings to construct URLs used in emails. Any URI that shares a host with `SITE_URL` is a permitted value for `redirect_to` params (see `/authorize` etc.). - -`URI_ALLOW_LIST` - `string` - -A comma-separated list of URIs (e.g. `"https://foo.example.com,https://*.foo.example.com,https://bar.example.com"`) which are permitted as valid `redirect_to` destinations. Defaults to []. Supports wildcard matching through globbing. e.g. `https://*.foo.example.com` will allow `https://a.foo.example.com` and `https://b.foo.example.com` to be accepted. Globbing is also supported on subdomains. e.g. `https://foo.example.com/*` will allow `https://foo.example.com/page1` and `https://foo.example.com/page2` to be accepted. - -For more common glob patterns, check out the [following link](https://pkg.go.dev/github.com/gobwas/glob#Compile). - -`OPERATOR_TOKEN` - `string` _Multi-instance mode only_ - -The shared secret with an operator (usually Netlify) for this microservice. Used to verify requests have been proxied through the operator and -the payload values can be trusted. - -`DISABLE_SIGNUP` - `bool` - -When signup is disabled the only way to create new users is through invites. Defaults to `false`, all signups enabled. - -`GOTRUE_EXTERNAL_EMAIL_ENABLED` - `bool` - -Use this to disable email signups (users can still use external OAuth providers to sign up / sign in) - -`GOTRUE_EXTERNAL_PHONE_ENABLED` - `bool` - -Use this to disable phone signups (users can still use external OAuth providers to sign up / sign in) - -`GOTRUE_RATE_LIMIT_HEADER` - `string` - -Header on which to rate limit the `/token` endpoint. This header is expected to be set by a trusted upstream proxy (such as Kong or Envoy). Headers such as `x-forwarded-for` are spoofable and can not be trusted for rate limiting when supplied directly by the client. - -`GOTRUE_RATE_LIMIT_EMAIL_SENT` - `string` - -Rate limit the number of emails sent per hour on the following endpoints: `/signup`, `/invite`, `/magiclink`, `/recover`, `/otp`, & `/user`. - -`GOTRUE_PASSWORD_MIN_LENGTH` - `int` - -Minimum password length, defaults to 6. - -`GOTRUE_PASSWORD_REQUIRED_CHARACTERS` - a string of character sets separated by `:`. A password must contain at least one character of each set to be accepted. To use the `:` character escape it with `\`. - -`GOTRUE_SECURITY_REFRESH_TOKEN_ROTATION_ENABLED` - `bool` - -If refresh token rotation is enabled, auth will automatically detect malicious attempts to reuse a revoked refresh token. When a malicious attempt is detected, GoTrue immediately revokes all tokens that descended from the offending token. - -`GOTRUE_SECURITY_REFRESH_TOKEN_REUSE_INTERVAL` - `string` - -This setting is only applicable if `GOTRUE_SECURITY_REFRESH_TOKEN_ROTATION_ENABLED` is enabled. The reuse interval for a refresh token allows for exchanging the refresh token multiple times during the interval to support concurrency or offline issues. During the reuse interval, auth will not consider using a revoked token as a malicious attempt and will simply return the child refresh token. - -Only the previous revoked token can be reused. Using an old refresh token way before the current valid refresh token will trigger the reuse detection. - -### API - -```properties -GOTRUE_API_HOST=localhost -PORT=9999 -API_EXTERNAL_URL=http://localhost:9999 -``` - -`API_HOST` - `string` - -Hostname to listen on. - -`PORT` (no prefix) / `API_PORT` - `number` - -Port number to listen on. Defaults to `8081`. - -`API_ENDPOINT` - `string` _Multi-instance mode only_ - -Controls what endpoint Netlify can access this API on. - -`API_EXTERNAL_URL` - `string` **required** - -The URL on which GoTrue might be accessed at. - -`REQUEST_ID_HEADER` - `string` - -If you wish to inherit a request ID from the incoming request, specify the name in this value. - -### Database - -```properties -GOTRUE_DB_DRIVER=postgres -DATABASE_URL=root@localhost/auth -``` - -`DB_DRIVER` - `string` **required** - -Chooses what dialect of database you want. Must be `postgres`. - -`DATABASE_URL` (no prefix) / `DB_DATABASE_URL` - `string` **required** - -Connection string for the database. - -`GOTRUE_DB_MAX_POOL_SIZE` - `int` - -Sets the maximum number of open connections to the database. Defaults to 0 which is equivalent to an "unlimited" number of connections. - -`DB_NAMESPACE` - `string` - -Adds a prefix to all table names. - -**Migrations Note** - -Migrations are applied automatically when you run `./auth`. However, you also have the option to rerun the migrations via the following methods: - -- If built locally: `./auth migrate` -- Using Docker: `docker run --rm auth gotrue migrate` - -### Logging - -```properties -LOG_LEVEL=debug # available without GOTRUE prefix (exception) -GOTRUE_LOG_FILE=/var/log/go/auth.log -``` - -`LOG_LEVEL` - `string` - -Controls what log levels are output. Choose from `panic`, `fatal`, `error`, `warn`, `info`, or `debug`. Defaults to `info`. - -`LOG_FILE` - `string` - -If you wish logs to be written to a file, set `log_file` to a valid file path. - -### Observability - -Auth has basic observability built in. It is able to export -[OpenTelemetry](https://opentelemetry.io) metrics and traces to a collector. - -#### Tracing - -To enable tracing configure these variables: - -`GOTRUE_TRACING_ENABLED` - `bool` - -`GOTRUE_TRACING_EXPORTER` - `string` only `opentelemetry` supported - -Make sure you also configure the [OpenTelemetry -Exporter](https://opentelemetry.io/docs/reference/specification/protocol/exporter/) -configuration for your collector or service. - -For example, if you use -[Honeycomb.io](https://docs.honeycomb.io/getting-data-in/opentelemetry/go-distro/#using-opentelemetry-without-the-honeycomb-distribution) -you should set these standard OpenTelemetry OTLP variables: - -``` -OTEL_SERVICE_NAME=auth -OTEL_EXPORTER_OTLP_PROTOCOL=grpc -OTEL_EXPORTER_OTLP_ENDPOINT=https://api.honeycomb.io:443 -OTEL_EXPORTER_OTLP_HEADERS="x-honeycomb-team=,x-honeycomb-dataset=auth" -``` - -#### Metrics - -To enable metrics configure these variables: - -`GOTRUE_METRICS_ENABLED` - `boolean` - -`GOTRUE_METRICS_EXPORTER` - `string` only `opentelemetry` and `prometheus` -supported - -Make sure you also configure the [OpenTelemetry -Exporter](https://opentelemetry.io/docs/reference/specification/protocol/exporter/) -configuration for your collector or service. - -If you use the `prometheus` exporter, the server host and port can be -configured using these standard OpenTelemetry variables: - -`OTEL_EXPORTER_PROMETHEUS_HOST` - IP address, default `0.0.0.0` - -`OTEL_EXPORTER_PROMETHEUS_PORT` - port number, default `9100` - -The metrics are exported on the `/` path on the server. - -If you use the `opentelemetry` exporter, the metrics are pushed to the -collector. - -For example, if you use -[Honeycomb.io](https://docs.honeycomb.io/getting-data-in/opentelemetry/go-distro/#using-opentelemetry-without-the-honeycomb-distribution) -you should set these standard OpenTelemetry OTLP variables: - -``` -OTEL_SERVICE_NAME=auth -OTEL_EXPORTER_OTLP_PROTOCOL=grpc -OTEL_EXPORTER_OTLP_ENDPOINT=https://api.honeycomb.io:443 -OTEL_EXPORTER_OTLP_HEADERS="x-honeycomb-team=,x-honeycomb-dataset=auth" -``` - -Note that Honeycomb.io requires a paid plan to ingest metrics. - -If you need to debug an issue with traces or metrics not being pushed, you can -set `DEBUG=true` to get more insights from the OpenTelemetry SDK. - -#### Custom resource attributes - -When using the OpenTelemetry tracing or metrics exporter you can define custom -resource attributes using the [standard `OTEL_RESOURCE_ATTRIBUTES` environment -variable](https://opentelemetry.io/docs/reference/specification/resource/sdk/#specifying-resource-information-via-an-environment-variable). - -A default attribute `auth.version` is provided containing the build version. - -#### Tracing HTTP routes - -All HTTP calls to the Auth API are traced. Routes use the parametrized -version of the route, and the values for the route parameters can be found as -the `http.route.params.` span attribute. - -For example, the following request: - -``` -GET /admin/users/4acde936-82dc-4552-b851-831fb8ce0927/ -``` - -will be traced as: - -``` -http.method = GET -http.route = /admin/users/{user_id} -http.route.params.user_id = 4acde936-82dc-4552-b851-831fb8ce0927 -``` - -#### Go runtime and HTTP metrics - -All of the Go runtime metrics are exposed. Some HTTP metrics are also collected -by default. - -### JSON Web Tokens (JWT) - -```properties -GOTRUE_JWT_SECRET=supersecretvalue -GOTRUE_JWT_EXP=3600 -GOTRUE_JWT_AUD=netlify -``` - -`JWT_SECRET` - `string` **required** - -The secret used to sign JWT tokens with. - -`JWT_EXP` - `number` - -How long tokens are valid for, in seconds. Defaults to 3600 (1 hour). - -`JWT_AUD` - `string` - -The default JWT audience. Use audiences to group users. - -`JWT_ADMIN_GROUP_NAME` - `string` - -The name of the admin group (if enabled). Defaults to `admin`. - -`JWT_DEFAULT_GROUP_NAME` - `string` - -The default group to assign all new users to. - -### External Authentication Providers - -We support `apple`, `azure`, `bitbucket`, `discord`, `facebook`, `figma`, `github`, `gitlab`, `google`, `keycloak`, `linkedin`, `notion`, `snapchat`, `spotify`, `slack`, `twitch`, `twitter` and `workos` for external authentication. - -Use the names as the keys underneath `external` to configure each separately. - -```properties -GOTRUE_EXTERNAL_GITHUB_ENABLED=true -GOTRUE_EXTERNAL_GITHUB_CLIENT_ID=myappclientid -GOTRUE_EXTERNAL_GITHUB_SECRET=clientsecretvaluessssh -GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI=http://localhost:3000/callback -``` - -No external providers are required, but you must provide the required values if you choose to enable any. - -`EXTERNAL_X_ENABLED` - `bool` - -Whether this external provider is enabled or not - -`EXTERNAL_X_CLIENT_ID` - `string` **required** - -The OAuth2 Client ID registered with the external provider. - -`EXTERNAL_X_SECRET` - `string` **required** - -The OAuth2 Client Secret provided by the external provider when you registered. - -`EXTERNAL_X_REDIRECT_URI` - `string` **required** - -The URI a OAuth2 provider will redirect to with the `code` and `state` values. - -`EXTERNAL_X_URL` - `string` - -The base URL used for constructing the URLs to request authorization and access tokens. Used by `gitlab` and `keycloak`. For `gitlab` it defaults to `https://gitlab.com`. For `keycloak` you need to set this to your instance, for example: `https://keycloak.example.com/realms/myrealm` - -#### Network hardening - -Configuring an external authentication provider causes Auth to make outbound HTTP requests to that provider's authorization, token, and userinfo endpoints. Configuring a provider either via `GOTRUE_EXTERNAL_*` settings or an admin API is an administrative action, and doing so implies trust in the hosts and URLs that will be contacted. - -The network Auth runs in should be hardened so these outbound connections cannot reach internal-only resources you don't want exposed, such as `localhost`/loopback addresses or cloud metadata endpoints (e.g. `169.254.169.254`). This matters most for providers with admin-configurable or discoverable endpoints (e.g. custom OAuth/OIDC providers), where a misconfigured or malicious URL could otherwise be used to reach internal infrastructure. - -#### Apple OAuth - -To try out external authentication with Apple locally, you will need to do the following: - -1. Remap localhost to \ in your `/etc/hosts` config. -2. Configure auth to serve HTTPS traffic over localhost by replacing `ListenAndServe` in [api.go](internal/api/api.go) with: - - ``` - func (a *API) ListenAndServe(hostAndPort string) { - log := logrus.WithField("component", "api") - path, err := os.Getwd() - if err != nil { - log.Println(err) - } - server := &http.Server{ - Addr: hostAndPort, - Handler: a.handler, - } - done := make(chan struct{}) - defer close(done) - go func() { - waitForTermination(log, done) - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - server.Shutdown(ctx) - }() - if err := server.ListenAndServeTLS("PATH_TO_CRT_FILE", "PATH_TO_KEY_FILE"); err != http.ErrServerClosed { - log.WithError(err).Fatal("http server listen failed") - } - } - ``` - -3. Generate the crt and key file. See [here](https://www.freecodecamp.org/news/how-to-get-https-working-on-your-local-development-environment-in-5-minutes-7af615770eec/) for more information. -4. Generate the `GOTRUE_EXTERNAL_APPLE_SECRET` by following this [post](https://medium.com/identity-beyond-borders/how-to-configure-sign-in-with-apple-77c61e336003)! - -### Email - -Sending email is not required, but highly recommended for password recovery. -If enabled, you must provide the required values below. - -```properties -GOTRUE_SMTP_HOST=smtp.mandrillapp.com -GOTRUE_SMTP_PORT=587 -GOTRUE_SMTP_USER=smtp-delivery@example.com -GOTRUE_SMTP_PASS=correcthorsebatterystaple -GOTRUE_SMTP_ADMIN_EMAIL=support@example.com -GOTRUE_MAILER_SUBJECTS_CONFIRMATION="Please confirm" -``` - -`SMTP_ADMIN_EMAIL` - `string` **required** - -The `From` email address for all emails sent. - -`SMTP_HOST` - `string` **required** - -The mail server hostname to send emails through. - -`SMTP_PORT` - `number` **required** - -The port number to connect to the mail server on. - -`SMTP_USER` - `string` - -If the mail server requires authentication, the username to use. - -`SMTP_PASS` - `string` - -If the mail server requires authentication, the password to use. - -`SMTP_MAX_FREQUENCY` - `number` - -Controls the minimum amount of time that must pass before sending another signup confirmation or password reset email. The value is the number of seconds. Defaults to 900 (15 minutes). - -`SMTP_SENDER_NAME` - `string` - -Sets the name of the sender. Defaults to the `SMTP_ADMIN_EMAIL` if not used. - -`MAILER_AUTOCONFIRM` - `bool` - -If you do not require email confirmation, you may set this to `true`. Defaults to `false`. - -`MAILER_OTP_EXP` - `number` - -Controls the duration an email link or OTP is valid for. - -`MAILER_URLPATHS_INVITE` - `string` - -URL path to use in the user invite email. Defaults to `/verify`. - -`MAILER_URLPATHS_CONFIRMATION` - `string` - -URL path to use in the signup confirmation email. Defaults to `/verify`. - -`MAILER_URLPATHS_RECOVERY` - `string` - -URL path to use in the password reset email. Defaults to `/verify`. - -`MAILER_URLPATHS_EMAIL_CHANGE` - `string` - -URL path to use in the email change confirmation email. Defaults to `/verify`. - -`MAILER_SUBJECTS_INVITE` - `string` - -Email subject to use for user invite. Defaults to `You've been invited`. - -`MAILER_SUBJECTS_CONFIRMATION` - `string` - -Email subject to use for signup confirmation. Defaults to `Confirm your email address`. - -`MAILER_SUBJECTS_RECOVERY` - `string` - -Email subject to use for password reset. Defaults to `Reset your password`. - -`MAILER_SUBJECTS_MAGIC_LINK` - `string` - -Email subject to use for magic link email. Defaults to `Your sign-in link`. - -`MAILER_SUBJECTS_EMAIL_CHANGE` - `string` - -Email subject to use for email change confirmation. Defaults to `Confirm your new email address`. - -`MAILER_SUBJECTS_REAUTHENTICATION` - `string` - -Email subject to use for reauthentication. Defaults to `{{ .Token }} is your verification code`. - -`MAILER_SUBJECTS_PASSWORD_CHANGED_NOTIFICATION` - `string` - -Email subject to use for password changed notification. Defaults to `Your password was changed`. - -`MAILER_SUBJECTS_EMAIL_CHANGED_NOTIFICATION` - `string` - -Email subject to use for email changed notification. Defaults to `Your email address was changed`. - -`GOTRUE_MAILER_SUBJECTS_PHONE_CHANGED_NOTIFICATION` - `string` - -Email subject to use for phone changed notification. Defaults to `Your phone number was changed`. - -`GOTRUE_MAILER_SUBJECTS_IDENTITY_LINKED_NOTIFICATION` - `string` - -Email subject to use for identity linked notification. Defaults to `A new sign-in method was linked to your account`. - -`GOTRUE_MAILER_SUBJECTS_IDENTITY_UNLINKED_NOTIFICATION` - `string` - -Email subject to use for identity unlinked notification. Defaults to `A sign-in method was removed from your account`. - -`GOTRUE_MAILER_SUBJECTS_MFA_FACTOR_ENROLLED_NOTIFICATION` - `string` - -Email subject to use for verification method added notification. Defaults to `A new verification method was added to your account`. - -`GOTRUE_MAILER_SUBJECTS_MFA_FACTOR_UNENROLLED_NOTIFICATION` - `string` - -Email subject to use for verification method removed notification. Defaults to `A verification method was removed from your account`. - -`MAILER_TEMPLATES_INVITE` - `string` - -URL path to an email template to use when inviting a user. (e.g. `https://www.example.com/path-to-email-template.html`) -`SiteURL`, `Email`, and `ConfirmationURL` variables are available. - -Default Content (if template is unavailable): - -```html -

You've been invited

- -

You've been invited to create an account. Follow the link below to accept.

-

Accept invitation

-``` - -`MAILER_TEMPLATES_CONFIRMATION` - `string` - -URL path to an email template to use when confirming a signup. (e.g. `https://www.example.com/path-to-email-template.html`) -`SiteURL`, `Email`, and `ConfirmationURL` variables are available. - -Default Content (if template is unavailable): - -```html -

Confirm your email address

- -

Follow the link below to confirm this email address and finish signing up.

-

Confirm email address

-``` - -`MAILER_TEMPLATES_RECOVERY` - `string` - -URL path to an email template to use when resetting a password. (e.g. `https://www.example.com/path-to-email-template.html`) -`SiteURL`, `Email`, and `ConfirmationURL` variables are available. - -Default Content (if template is unavailable): - -```html -

Reset your password

- -

We received a request to reset your password. Follow the link below to choose a new one.

-

Reset password

-

If you didn't request this, you can safely ignore this email.

-``` - -`MAILER_TEMPLATES_MAGIC_LINK` - `string` - -URL path to an email template to use when sending magic link. (e.g. `https://www.example.com/path-to-email-template.html`) -`SiteURL`, `Email`, and `ConfirmationURL` variables are available. - -Default Content (if template is unavailable): - -```html -

Your sign-in link

- -

Follow the link below to sign in. This link expires shortly and can only be used once.

-

Sign in

-``` - -`MAILER_TEMPLATES_EMAIL_CHANGE` - `string` - -URL path to an email template to use when confirming the change of an email address. (e.g. `https://www.example.com/path-to-email-template.html`) -`SiteURL`, `Email`, `NewEmail`, and `ConfirmationURL` variables are available. - -Default Content (if template is unavailable): - -```html -

Confirm your new email address

- -

Follow the link below to confirm {{ .NewEmail }} as your new email address.

-

Confirm new email address

-

If you didn't request this change, you can safely ignore this email.

-``` - -`MAILER_TEMPLATES_REAUTHENTICATION` - `string` - -URL path to an email template to use when reauthenticating a user. (e.g. `https://www.example.com/path-to-email-template.html`) -`Token` variable is available. - -Default Content (if template is unavailable): - -```html -

Your verification code

- -

Use the code below to verify your identity. It expires shortly.

-

{{ .Token }}

-``` - -`MAILER_TEMPLATES_PASSWORD_CHANGED_NOTIFICATION` - `string` - -URL path to an email template to use when notifying a user that their password has been changed. (e.g. `https://www.example.com/path-to-email-template.html`) -`Email` variables are available. - -Default Content (if template is unavailable): - -```html -

Your password was changed

- -

The password for your account was recently changed.

-

If you didn't make this change, reset your password and contact support immediately.

-``` - -`GOTRUE_MAILER_NOTIFICATIONS_PASSWORD_CHANGED_ENABLED` - `bool` - -Whether to send a notification email when a user's password is changed. Defaults to `false`. - -`MAILER_TEMPLATES_EMAIL_CHANGED_NOTIFICATION` - `string` - -URL path to an email template to use when notifying a user that their email has been changed. (e.g. `https://www.example.com/path-to-email-template.html`) -`Email` and `OldEmail` variables are available. - -Default Content (if template is unavailable): - -```html -

Your email address was changed

- -

The email address for your account was changed from {{ .OldEmail }} to {{ .Email }}.

-

If you didn't make this change, contact support immediately.

-``` - -`GOTRUE_MAILER_NOTIFICATIONS_EMAIL_CHANGED_ENABLED` - `bool` - -Whether to send a notification email when a user's email is changed. Defaults to `false`. - -`GOTRUE_MAILER_TEMPLATES_PHONE_CHANGED_NOTIFICATION` - `string` - -URL path to an email template to use when notifying a user that their phone number has been changed. (e.g. `https://www.example.com/path-to-email-template.html`) -`Email`, `Phone`, and `OldPhone` variables are available. - -Default Content (if template is unavailable): - -```html -

Your phone number was changed

- -

The phone number for your account was changed from {{ .OldPhone }} to {{ .Phone }}.

-

If you didn't make this change, contact support immediately.

-``` - -`GOTRUE_MAILER_NOTIFICATIONS_PHONE_CHANGED_ENABLED` - `bool` - -Whether to send a notification email when a user's phone number is changed. Defaults to `false`. - -`GOTRUE_MAILER_TEMPLATES_IDENTITY_LINKED_NOTIFICATION` - `string` - -URL path to an email template to use when notifying a user that a sign-in method has been linked to their account. (e.g. `https://www.example.com/path-to-email-template.html`) -`Email` and `Provider` variables are available. - -Default Content (if template is unavailable): - -```html -

A new sign-in method was linked

- -

Your {{ .Provider }} account was linked as a new sign-in method for {{ .Email }}.

-

If you didn't make this change, contact support immediately.

-``` - -`GOTRUE_MAILER_NOTIFICATIONS_IDENTITY_LINKED_ENABLED` - `bool` - -Whether to send a notification email when a sign-in method is linked to a user's account. Defaults to `false`. - -`GOTRUE_MAILER_TEMPLATES_IDENTITY_UNLINKED_NOTIFICATION` - `string` - -URL path to an email template to use when notifying a user that a sign-in method has been removed from their account. (e.g. `https://www.example.com/path-to-email-template.html`) -`Email` and `Provider` variables are available. - -Default Content (if template is unavailable): - -```html -

A sign-in method was removed

- -

Your {{ .Provider }} account was removed as a sign-in method for {{ .Email }}.

-

If you didn't make this change, contact support immediately.

-``` - -`GOTRUE_MAILER_NOTIFICATIONS_IDENTITY_UNLINKED_ENABLED` - `bool` - -Whether to send a notification email when a sign-in method is removed from a user's account. Defaults to `false`. - -`GOTRUE_MAILER_TEMPLATES_MFA_FACTOR_ENROLLED_NOTIFICATION` - `string` - -URL path to an email template to use when notifying a user that a new verification method has been added to their account. (e.g. `https://www.example.com/path-to-email-template.html`) -`Email` and `FactorType` variables are available. - -Default Content (if template is unavailable): - -```html -

A new verification method was added

- -

Sign-in verification method {{ .FactorType }} was added to your account.

-

If you didn't make this change, contact support immediately.

-``` - -`GOTRUE_MAILER_NOTIFICATIONS_MFA_FACTOR_ENROLLED_ENABLED` - `bool` - -Whether to send a notification email when a new verification method is added to a user's account. Defaults to `false`. - -`GOTRUE_MAILER_TEMPLATES_MFA_FACTOR_UNENROLLED_NOTIFICATION` - `string` - -URL path to an email template to use when notifying a user that a verification method has been removed from their account. (e.g. `https://www.example.com/path-to-email-template.html`) -`Email` and `FactorType` variables are available. - -Default Content (if template is unavailable): - -```html -

A verification method was removed

- -

Sign-in verification method {{ .FactorType }} was removed from your account.

-

If you didn't make this change, contact support immediately.

-``` - -`GOTRUE_MAILER_NOTIFICATIONS_MFA_FACTOR_UNENROLLED_ENABLED` - `bool` - -Whether to send a notification email when a verification method is removed from a user's account. Defaults to `false`. - -### Phone Auth - -`SMS_AUTOCONFIRM` - `bool` - -If you do not require phone confirmation, you may set this to `true`. Defaults to `false`. - -`SMS_MAX_FREQUENCY` - `number` - -Controls the minimum amount of time that must pass before sending another SMS OTP. The value is the number of seconds. Defaults to 60 (1 minute). - -`SMS_OTP_EXP` - `number` - -Controls the duration an SMS OTP is valid for. - -`SMS_OTP_LENGTH` - `number` - -Controls the number of digits of the SMS OTP sent. - -`SMS_PROVIDER` - `string` - -Available options are: `twilio`, `messagebird`, `textlocal`, and `vonage` - -Then you can use your [twilio credentials](https://www.twilio.com/docs/usage/requests-to-twilio#credentials): - -- `SMS_TWILIO_ACCOUNT_SID` -- `SMS_TWILIO_AUTH_TOKEN` -- `SMS_TWILIO_MESSAGE_SERVICE_SID` - can be set to your twilio sender mobile number - -Or Messagebird credentials, which can be obtained in the [Dashboard](https://dashboard.messagebird.com/en/developers/access): - -- `SMS_MESSAGEBIRD_ACCESS_KEY` - your Messagebird access key -- `SMS_MESSAGEBIRD_ORIGINATOR` - SMS sender (your Messagebird phone number with + or company name) - -### CAPTCHA - -- If enabled, CAPTCHA will check the request body for the `captcha_token` field and make a verification request to the CAPTCHA provider. - -`SECURITY_CAPTCHA_ENABLED` - `string` - -Whether captcha middleware is enabled - -`SECURITY_CAPTCHA_PROVIDER` - `string` - -for now the only options supported are: hCaptcha and Turnstile - -- `SECURITY_CAPTCHA_SECRET` - `string` -- `SECURITY_CAPTCHA_TIMEOUT` - `string` - -Retrieve from hcaptcha or turnstile account - -### Reauthentication - -`SECURITY_UPDATE_PASSWORD_REQUIRE_REAUTHENTICATION` - `bool` - -Enforce reauthentication on password update. - -### Anonymous Sign-Ins - -`GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED` - `bool` - -Use this to enable/disable anonymous sign-ins. - -### IP address forwarding - -`GOTRUE_SECURITY_SB_FORWARDED_FOR_ENABLED` - `bool` - -Enable IP address forwarding using the `Sb-Forwarded-For` HTTP request header. When enabled, Auth will parse the first value of this header as an IP address and use it for IP address tracking and rate limiting. Make sure this header is fully trusted before enabling this feature by only passing it from trustworthy clients or proxies. - -## Endpoints - -Auth exposes the following endpoints: - -### **GET /settings** - -Returns the publicly available settings for this auth instance. - -```json -{ - "external": { - "apple": true, - "azure": true, - "bitbucket": true, - "discord": true, - "facebook": true, - "figma": true, - "github": true, - "gitlab": true, - "google": true, - "keycloak": true, - "linkedin": true, - "notion": true, - "slack": true, - "snapchat": true, - "spotify": true, - "twitch": true, - "twitter": true, - "workos": true - }, - "disable_signup": false, - "autoconfirm": false -} -``` - -### **POST, PUT /admin/users/** - -Creates (POST) or Updates (PUT) the user based on the `user_id` specified. The `ban_duration` field accepts the following time units: "ns", "us", "ms", "s", "m", "h". See [`time.ParseDuration`](https://pkg.go.dev/time#ParseDuration) for more details on the format used. - -```js -headers: -{ - "Authorization": "Bearer eyJhbGciOiJI...M3A90LCkxxtX9oNP9KZO" // requires a role claim that can be set in the GOTRUE_JWT_ADMIN_ROLES env var -} - -body: -{ - "role": "test-user", - "email": "email@example.com", - "phone": "12345678", - "password": "secret", // only if type = signup - "email_confirm": true, - "phone_confirm": true, - "user_metadata": {}, - "app_metadata": {}, - "ban_duration": "24h" or "none" // to unban a user -} -``` - -### **POST /admin/generate_link** - -Returns the corresponding email action link based on the type specified. Among other things, the response also contains the query params of the action link as separate JSON fields for convenience (along with the email OTP from which the corresponding token is generated). - -```js -headers: -{ - "Authorization": "Bearer eyJhbGciOiJI...M3A90LCkxxtX9oNP9KZO" // admin role required -} - -body: -{ - "type": "signup" or "magiclink" or "recovery" or "invite" or "email_change_current" or "email_change_new", - "email": "email@example.com", - "password": "secret", // only if type = signup - "data": { - ... - }, // only if type = signup - "redirect_to": "https://supabase.io" // Redirect URL to send the user to after an email action. Defaults to SITE_URL. - -} -``` - -Returns - -```js -{ - "action_link": "http://localhost:9999/verify?token=TOKEN&type=TYPE&redirect_to=REDIRECT_URL", - "email_otp": "EMAIL_OTP", - "hashed_token": "TOKEN", - "verification_type": "TYPE", - "redirect_to": "REDIRECT_URL", - ... -} -``` - -### **POST /signup** - -Register a new user with an email and password. - -```json -{ - "email": "email@example.com", - "password": "secret" -} -``` - -returns: - -```js -{ - "id": "11111111-2222-3333-4444-5555555555555", - "email": "email@example.com", - "confirmation_sent_at": "2016-05-15T20:49:40.882805774-07:00", - "created_at": "2016-05-15T19:53:12.368652374-07:00", - "updated_at": "2016-05-15T19:53:12.368652374-07:00" -} - -// if sign up is a duplicate then faux data will be returned -// as to not leak information about whether a given email -// has an account with your service or not -``` - -Register a new user with a phone number and password. - -```js -{ - "phone": "12345678", // follows the E.164 format - "password": "secret" -} -``` - -Returns: - -```js -{ - "id": "11111111-2222-3333-4444-5555555555555", // if duplicate sign up, this ID will be faux - "phone": "12345678", - "confirmation_sent_at": "2016-05-15T20:49:40.882805774-07:00", - "created_at": "2016-05-15T19:53:12.368652374-07:00", - "updated_at": "2016-05-15T19:53:12.368652374-07:00" -} -``` - -if AUTOCONFIRM is enabled and the sign up is a duplicate, then the endpoint will return: - -```json -{ - "code": 400, - "msg": "User already registered" -} -``` - -### **POST /resend** - -Allows a user to resend an existing signup, sms, email_change or phone_change OTP. - -```json -{ - "email": "user@example.com", - "type": "signup" -} -``` - -```json -{ - "phone": "12345678", - "type": "sms" -} -``` - -returns: - -```json -{ - "message_id": "msgid123456" -} -``` - -### **POST /invite** - -Invites a new user with an email. -This endpoint requires the `service_role` or `supabase_admin` JWT set as an Auth Bearer header: - -e.g. - -```js -headers: { - "Authorization" : "Bearer eyJhbGciOiJI...M3A90LCkxxtX9oNP9KZO" -} -``` - -```json -{ - "email": "email@example.com" -} -``` - -Returns: - -```json -{ - "id": "11111111-2222-3333-4444-5555555555555", - "email": "email@example.com", - "confirmation_sent_at": "2016-05-15T20:49:40.882805774-07:00", - "created_at": "2016-05-15T19:53:12.368652374-07:00", - "updated_at": "2016-05-15T19:53:12.368652374-07:00", - "invited_at": "2016-05-15T19:53:12.368652374-07:00" -} -``` - -### **POST /verify** - -Verify a registration or a password recovery. Type can be `signup`, `recovery`, `invite`, `magiclink`, `email_change`, `sms`, or `phone_change` -and the `token` is a token returned from either `/signup` or `/recover`. - -```json -{ - "type": "signup", - "token": "confirmation-code-delivered-in-email" -} -``` - -`password` is required for signup verification if no existing password exists. - -Returns: - -```json -{ - "access_token": "jwt-token-representing-the-user", - "token_type": "bearer", - "expires_in": 3600, - "refresh_token": "a-refresh-token", - "type": "signup | recovery | invite | magiclink | email_change | sms | phone_change" -} -``` - -Verify a phone signup or SMS OTP. Type should be set to `sms`. - -```json -{ - "type": "sms", - "token": "confirmation-otp-delivered-in-sms", - "redirect_to": "https://supabase.io", - "phone": "phone-number-sms-otp-was-delivered-to" -} -``` - -Returns: - -```json -{ - "access_token": "jwt-token-representing-the-user", - "token_type": "bearer", - "expires_in": 3600, - "refresh_token": "a-refresh-token" -} -``` - -### **GET /verify** - -Verify a registration or a password recovery. Type can be `signup`, `recovery`, `magiclink`, `invite`, or `email_change` -and the `token` is a token returned from either `/signup` or `/recover` or `/magiclink`. - -query params: - -```json -{ - "type": "signup", - "token": "confirmation-code-delivered-in-email", - "redirect_to": "https://supabase.io" -} -``` - -User will be logged in and redirected to: - -``` -SITE_URL/#access_token=jwt-token-representing-the-user&token_type=bearer&expires_in=3600&refresh_token=a-refresh-token&type=invite -``` - -Your app should detect the query params in the fragment and use them to set the session (supabase-js does this automatically) - -You can use the `type` param to redirect the user to a password set form in the case of `invite` or `recovery`, -or show an account confirmed/welcome message in the case of `signup`, or direct them to some additional onboarding flow - -### **POST /otp** - -One-Time-Password. Will deliver a magic link or SMS OTP to the user depending on whether the request body contains an "email" or "phone" key. - -If `"create_user": true`, user will not be automatically signed up if the user doesn't exist. - -```js -{ - "phone": "12345678" // follows the E.164 format - "create_user": true -} -``` - -OR - -```js -// exactly the same as /magiclink -{ - "email": "email@example.com" - "create_user": true -} -``` - -Returns: - -```json -{} -``` - -### **POST /magiclink** (recommended to use /otp instead. See above.) - -Magic Link. Will deliver a link (e.g. `/verify?type=magiclink&token=fgtyuf68ddqdaDd`) to the user based on -email address which they can use to redeem an access_token. - -By default Magic Links can only be sent once every 60 seconds - -```json -{ - "email": "email@example.com" -} -``` - -Returns: - -```json -{} -``` - -When the magic link is clicked, it will redirect to `#access_token=x&refresh_token=y&expires_in=z&token_type=bearer&type=magiclink` (see `/verify` above) - -### **POST /recover** - -Password recovery. Will deliver a password recovery mail to the user based on -email address. - -By default recovery links can only be sent once every 60 seconds - -```json -{ - "email": "email@example.com" -} -``` - -Returns: - -```json -{} -``` - -### **POST /token** - -This is an OAuth2 endpoint that currently implements -the password and refresh_token grant types - -query params: - -``` -?grant_type=password -``` - -body: - -```js -// Email login -{ - "email": "name@domain.com", - "password": "somepassword" -} - -// Phone login -{ - "phone": "12345678", - "password": "somepassword" -} -``` - -or - -query params: - -``` -grant_type=refresh_token -``` - -body: - -```json -{ - "refresh_token": "a-refresh-token" -} -``` - -Once you have an access token, you can access the methods requiring authentication -by settings the `Authorization: Bearer YOUR_ACCESS_TOKEN_HERE` header. - -Returns: - -```json -{ - "access_token": "jwt-token-representing-the-user", - "token_type": "bearer", - "expires_in": 3600, - "refresh_token": "a-refresh-token" -} -``` - -### **GET /user** - -Get the JSON object for the logged in user (requires authentication) - -Returns: - -```json -{ - "id": "11111111-2222-3333-4444-5555555555555", - "email": "email@example.com", - "confirmation_sent_at": "2016-05-15T20:49:40.882805774-07:00", - "created_at": "2016-05-15T19:53:12.368652374-07:00", - "updated_at": "2016-05-15T19:53:12.368652374-07:00" -} -``` - -### **PUT /user** - -Update a user (Requires authentication). Apart from changing email/password, this -method can be used to set custom user data. Changing the email will result in a magic link being sent out. - -```json -{ - "email": "new-email@example.com", - "password": "new-password", - "phone": "+123456789", - "data": { - "key": "value", - "number": 10, - "admin": false - } -} -``` - -Returns: - -```json -{ - "id": "11111111-2222-3333-4444-5555555555555", - "email": "email@example.com", - "email_change_sent_at": "2016-05-15T20:49:40.882805774-07:00", - "phone": "+123456789", - "phone_change_sent_at": "2016-05-15T20:49:40.882805774-07:00", - "created_at": "2016-05-15T19:53:12.368652374-07:00", - "updated_at": "2016-05-15T19:53:12.368652374-07:00" -} -``` - -If `GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_REAUTHENTICATION` is enabled, the user will need to reauthenticate first. - -```json -{ - "password": "new-password", - "nonce": "123456" -} -``` - -### **GET /reauthenticate** - -Sends a nonce to the user's email (preferred) or phone. This endpoint requires the user to be logged in / authenticated first. The user needs to have either an email or phone number for the nonce to be sent successfully. - -```js -headers: { - "Authorization" : "Bearer eyJhbGciOiJI...M3A90LCkxxtX9oNP9KZO" -} -``` - -### **POST /logout** - -Logout a user (Requires authentication). - -This will revoke all refresh tokens for the user. Remember that the JWT tokens -will still be valid for stateless auth until they expire. - -### **GET /authorize** - -Get access_token from external oauth provider - -query params: - -``` -provider=apple | azure | bitbucket | discord | facebook | figma | github | gitlab | google | keycloak | linkedin | notion | slack | snapchat | spotify | twitch | twitter | workos - -scopes= -``` - -Redirects to provider and then to `/callback` - -For Apple-specific setup see: - -### **GET /callback** +Configure Auth using a configuration file, environment variables, or a combination of both. See [configuration.md](docs/configuration.md) for the full list of settings, organized by area: top-level, API, database, logging, observability, JWT, external authentication providers, SAML single sign-on, email, phone auth, CAPTCHA, reauthentication, anonymous sign-ins, and IP address forwarding. -External provider should redirect to this endpoint +## API -Redirects to `#access_token=&refresh_token=&provider_token=&expires_in=3600&provider=` -If additional scopes were requested then `provider_token` will be populated, you can use this to fetch additional data from the provider or interact with their services +Auth exposes a REST API. See [openapi.yaml](openapi.yaml) for the full, codegen-verified reference of every endpoint, and [docs/api.md](docs/api.md) for behavior notes that the spec alone doesn't cover, such as session delivery and token lifetime. diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000000..6736b9fac6 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,744 @@ +# Configuration + +Configure Auth using a configuration file named `.env`, environment variables, or both. + +## Server + +### General + +```properties +GOTRUE_SITE_URL=https://example.netlify.com/ +``` + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_SITE_URL` | `string` | required | The base URL of your site. Auth uses it, combined with other settings, to construct URLs for emails. Auth also accepts a `redirect_to` value whose scheme, host, and port all match `GOTRUE_SITE_URL`. The port need not match for loopback addresses, per RFC 8252. To permit other destinations, add them to `GOTRUE_URI_ALLOW_LIST`. | +| `GOTRUE_URI_ALLOW_LIST` | `string` | optional (default `[]`) | A comma-separated list of URIs permitted as valid `redirect_to` destinations, for example `"https://foo.example.com,https://*.foo.example.com,https://bar.example.com"`.

Supports wildcard matching through globbing. `https://*.foo.example.com` allows `https://a.foo.example.com` and `https://b.foo.example.com`. Globbing also works on paths: `https://foo.example.com/*` allows `https://foo.example.com/page1` and `https://foo.example.com/page2`. For more glob patterns, see the [glob package documentation](https://pkg.go.dev/github.com/gobwas/glob#Compile). | +| `GOTRUE_OPERATOR_TOKEN` | `string` | optional, multi-instance mode only | The shared secret with an operator, usually Netlify, for this microservice. Auth uses it to verify that the operator proxied the request and that the payload values can be trusted. | + +### API + +```properties +GOTRUE_API_HOST=localhost +PORT=9999 +API_EXTERNAL_URL=http://localhost:9999 +``` + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `API_EXTERNAL_URL` (no prefix) | `string` | required | The URL on which Auth is accessible. | +| `GOTRUE_API_HOST` | `string` | optional | Hostname to listen on. | +| `GOTRUE_API_PORT` / `PORT` (no prefix) | `number` | `8081` | Port number to listen on. | +| `GOTRUE_API_ENDPOINT` | `string` | optional, multi-instance mode only | Controls what endpoint Netlify can access this API on. | +| `GOTRUE_API_REQUEST_ID_HEADER` | `string` | optional | The name of the header Auth reads an inherited request ID from on the incoming request. | +| `GOTRUE_API_MAX_REQUEST_DURATION` | `duration` | `10s` | The maximum time a single API request may take before Auth cancels it. | + +### Database + +```properties +GOTRUE_DB_DRIVER=postgres +DATABASE_URL=root@localhost/auth +``` + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_DB_DRIVER` | `string` | required | The database dialect. Must be `postgres`. | +| `GOTRUE_DB_DATABASE_URL` / `DATABASE_URL` (no prefix) | `string` | required | Connection string for the database. | +| `DB_NAMESPACE` (no prefix) | `string` | `auth` | A prefix added to all table names. | +| `GOTRUE_DB_MAX_POOL_SIZE` | `int` | `0` (unlimited connections) | The maximum number of open connections to the database. | +| `GOTRUE_DB_MAX_IDLE_POOL_SIZE` | `int` | optional | The maximum number of idle connections to keep in the pool. | +| `GOTRUE_DB_CONN_PERCENTAGE` | `int` | optional | The percentage (1-100) of available database connections Auth may use. Values outside the range are clamped. | +| `GOTRUE_DB_CONN_MAX_LIFETIME` | `duration` | optional | The maximum time a connection may be reused before it is closed. | +| `GOTRUE_DB_CONN_MAX_IDLE_TIME` | `duration` | optional | The maximum time a connection may sit idle before it is closed. | +| `GOTRUE_DB_HEALTH_CHECK_PERIOD` | `duration` | optional | How often the pool checks the health of idle connections. | +| `GOTRUE_DB_MIGRATIONS_PATH` | `string` | `./migrations` | The path to the migrations directory. | +| `GOTRUE_DB_CLEANUP_ENABLED` | `bool` | `false` | Whether Auth periodically cleans up expired rows, such as stale sessions and tokens. | +| `GOTRUE_DB_ADVISOR_ENABLED` | `bool` | `true` | Whether the database advisor, which samples query performance, is enabled. | +| `GOTRUE_DB_ADVISOR_SAMPLING_INTERVAL` | `duration` | `200ms` | How often the advisor samples query activity. | +| `GOTRUE_DB_ADVISOR_OBSERVATION_INTERVAL` | `duration` | `20s` | How often the advisor reports its observations. | + +**Migrations** + +Auth applies migrations automatically when you run `./auth`. You can also rerun the migrations directly: + +- If built locally: `./auth migrate` +- Using Docker: `docker run --rm auth auth migrate` + +### Logging + +```properties +GOTRUE_LOG_LEVEL=debug +GOTRUE_LOG_FILE=/var/log/go/auth.log +``` + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_LOG_LEVEL` | `string` | `info` | The log level Auth outputs. Choose from `panic`, `fatal`, `error`, `warn`, `info`, or `debug`. | +| `GOTRUE_LOG_FILE` | `string` | optional | A file path to write logs to. | +| `GOTRUE_LOG_SQL` | `string` | optional | The log level for SQL queries. | +| `GOTRUE_LOG_TSFORMAT` | `string` | optional | The timestamp format for log entries. | +| `GOTRUE_LOG_DISABLE_COLORS` | `bool` | `false` | Whether to disable ANSI colors in console log output. | +| `GOTRUE_LOG_QUOTE_EMPTY_FIELDS` | `bool` | `false` | Whether to quote empty fields in log output. | +| `GOTRUE_LOG_FIELDS` | `string` (JSON) | optional, advanced | Default fields added to every log entry, as a JSON object. | + +### Audit log + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_AUDIT_LOG_DISABLE_POSTGRES` | `bool` | `false` | When `true`, Auth stops writing audit log entries to Postgres. | + +### CORS + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_CORS_ALLOWED_HEADERS` | `string` | optional | A comma-separated list of extra request headers to allow, added to the built-in defaults. | + +### Profiler + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_PROFILER_ENABLED` | `bool` | `false` | Whether the pprof profiling server is enabled. | +| `GOTRUE_PROFILER_HOST` | `string` | `localhost` | Host the profiling server binds to. | +| `GOTRUE_PROFILER_PORT` | `string` | `9998` | Port the profiling server binds to. | + +### User search indexes + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_INDEX_WORKER_ENSURE_USER_SEARCH_INDEXES_EXIST` | `bool` | `false` | When `true`, Auth always creates the user-search indexes, ignoring the threshold. | +| `GOTRUE_INDEX_WORKER_MAX_USERS_THRESHOLD` | `int` | `0` | When greater than 0, Auth creates the indexes only if the user count is at or below this threshold. `0` disables the progressive rollout. Has no effect when the setting above is `true`. | + +### Configuration reloading + +These startup values control runtime configuration reloads. They take effect only when you provide the `--config-dir` flag, and they stay fixed across reloads. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_RELOADING_NOTIFY_ENABLED` | `bool` | `true` | Whether Auth watches the config directory for changes using filesystem notifications. | +| `GOTRUE_RELOADING_POLLERENABLED` | `bool` | `false` | Whether Auth falls back to filesystem polling when notifications are unavailable. | +| `GOTRUE_RELOADING_POLLER_INTERVAL` | `duration` | `10s` | How often to poll the filesystem when polling is used. | +| `GOTRUE_RELOADING_SIGNAL_ENABLED` | `bool` | `false` | Whether Auth reloads the config when it receives the configured signal. | +| `GOTRUE_RELOADING_SIGNAL_NUMBER` | `int` | `10` | The signal number that triggers a reload. `10` is `SIGUSR1` on Linux. | +| `GOTRUE_RELOADING_GRACE_PERIOD_INTERVAL` | `duration` | `5s` | How much idle time must pass after a burst of changes before Auth reloads, so a burst triggers a single reload. | + +## Observability + +Auth has basic observability built in. It can export [OpenTelemetry](https://opentelemetry.io) metrics and traces to a collector. + +### Tracing + +To enable tracing, configure these variables. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_TRACING_ENABLED` | `bool` | `false` | Whether tracing is enabled. | +| `GOTRUE_TRACING_EXPORTER` | `string` | `opentelemetry` | Only `opentelemetry` is supported. | +| `GOTRUE_TRACING_SERVICE_NAME` | `string` | `gotrue` | The service name reported in traces. | +| `GOTRUE_TRACING_HOST` | `string` | optional | The tracing collector host. | +| `GOTRUE_TRACING_PORT` | `string` | optional | The tracing collector port. | +| `GOTRUE_TRACING_TAGS` | `string` | optional | Comma-separated `key:value` tags added to traces. | +| `OTEL_EXPORTER_OTLP_PROTOCOL` (no prefix) | `string` | `http/protobuf` | The OTLP exporter protocol, for example `grpc`. | + +You must also configure the [OpenTelemetry exporter](https://opentelemetry.io/docs/reference/specification/protocol/exporter/) for your collector or service. + +For example, if you use [Honeycomb.io](https://docs.honeycomb.io/getting-data-in/opentelemetry/go-distro/#using-opentelemetry-without-the-honeycomb-distribution), set these standard OpenTelemetry OTLP variables: + +``` +OTEL_SERVICE_NAME=auth +OTEL_EXPORTER_OTLP_PROTOCOL=grpc +OTEL_EXPORTER_OTLP_ENDPOINT=https://api.honeycomb.io:443 +OTEL_EXPORTER_OTLP_HEADERS="x-honeycomb-team=,x-honeycomb-dataset=auth" +``` + +### Metrics + +To enable metrics, configure these variables. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_METRICS_ENABLED` | `bool` | `false` | Whether metrics are enabled. | +| `GOTRUE_METRICS_EXPORTER` | `string` | `opentelemetry` | Only `opentelemetry` and `prometheus` are supported. | +| `OTEL_EXPORTER_PROMETHEUS_HOST` (no prefix) | IP address | `0.0.0.0` | The server host to bind the `prometheus` exporter to. | +| `OTEL_EXPORTER_PROMETHEUS_PORT` (no prefix) | port number | `9100` | The server port to bind the `prometheus` exporter to. | + +You must also configure the [OpenTelemetry exporter](https://opentelemetry.io/docs/reference/specification/protocol/exporter/) for your collector or service. If you use the `prometheus` exporter, Auth serves the metrics at the `/` path on the server. + +If you use the `opentelemetry` exporter, Auth pushes the metrics to the collector. + +### Custom resource attributes + +When using the OpenTelemetry tracing or metrics exporter you can define custom resource attributes using the [standard `OTEL_RESOURCE_ATTRIBUTES` environment variable](https://opentelemetry.io/docs/reference/specification/resource/sdk/#specifying-resource-information-via-an-environment-variable). + +Auth provides a default attribute, `auth.version`, containing the build version. + +### Tracing HTTP routes + +Auth traces all HTTP calls to its API. It records each route in parametrized form and records each parameter value as the `http.route.params.` span attribute. + +For example, the following request: + +``` +GET /admin/users/4acde936-82dc-4552-b851-831fb8ce0927/ +``` + +is traced as: + +``` +http.method = GET +http.route = /admin/users/{user_id} +http.route.params.user_id = 4acde936-82dc-4552-b851-831fb8ce0927 +``` + +### Go runtime and HTTP metrics + +Auth exposes all Go runtime metrics. It also collects some HTTP metrics by default. + +## Authentication + +### Sign-up + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_DISABLE_SIGNUP` | `bool` | `false` | When `true`, invites become the only way to create new users. When `false`, all signups are enabled. | +| `GOTRUE_EXTERNAL_EMAIL_ENABLED` | `bool` | `true` | Set to `false` to disable email signups. Users can still use external OAuth providers to sign up or sign in. | +| `GOTRUE_EXTERNAL_EMAIL_MAGIC_LINK_ENABLED` | `bool` | `true` | Whether magic-link sign-in over email is enabled. | +| `GOTRUE_EXTERNAL_EMAIL_AUTHORIZED_ADDRESSES` | `string` | optional | A comma-separated allowlist of email addresses permitted to sign up. When unset, any address may sign up. | +| `GOTRUE_EXTERNAL_PHONE_ENABLED` | `bool` | `false` | Set to `true` to enable phone signups. Phone signups are disabled by default. | + +### JSON Web Tokens (JWT) + +```properties +GOTRUE_JWT_SECRET=supersecretvalue +GOTRUE_JWT_EXP=3600 +GOTRUE_JWT_AUD=netlify +``` + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_JWT_SECRET` | `string` | required | The secret used to sign JWT tokens with. | +| `GOTRUE_JWT_EXP` | `number` | `3600` (1 hour) | How long, in seconds, tokens remain valid. | +| `GOTRUE_JWT_AUD` | `string` | optional | The default JWT audience. Use audiences to group users. | +| `GOTRUE_JWT_ADMIN_GROUP_NAME` | `string` | `admin` | The name of the admin group, if enabled. | +| `GOTRUE_JWT_ADMIN_ROLES` | `string` | `service_role,supabase_admin` | A comma-separated list of roles treated as admin. | +| `GOTRUE_JWT_DEFAULT_GROUP_NAME` | `string` | optional | The default group for all new users. | +| `GOTRUE_JWT_ISSUER` | `string` | optional | The `iss` claim to set on issued tokens. | +| `GOTRUE_JWT_KEY_ID` | `string` | optional | The `kid` for the signing key derived from `GOTRUE_JWT_SECRET`. | +| `GOTRUE_JWT_KEYS` | `string` (JSON) | optional, advanced | A JSON array of JWKs used for signing and verification. When set, it takes the place of `GOTRUE_JWT_SECRET`. | +| `GOTRUE_JWT_VALID_METHODS` | `string` | optional, advanced | A comma-separated list of accepted signing algorithms. Derived from the configured keys when unset. | + +### External authentication providers + +Auth supports `apple`, `azure`, `bitbucket`, `discord`, `facebook`, `figma`, `fly`, `github`, `gitlab`, `google`, `kakao`, `keycloak`, `linkedin`, `linkedin_oidc`, `notion`, `slack`, `slack_oidc`, `snapchat`, `spotify`, `twitch`, `twitter`, `vercel_marketplace`, `workos`, `x`, and `zoom` for external authentication. + +Use the provider name as the key underneath `external` to configure each one separately. + +```properties +GOTRUE_EXTERNAL_GITHUB_ENABLED=true +GOTRUE_EXTERNAL_GITHUB_CLIENT_ID=myappclientid +GOTRUE_EXTERNAL_GITHUB_SECRET=clientsecretvaluessssh +GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI=http://localhost:3000/callback +``` + +External providers are optional, but each one you enable needs its required values. Replace `X` in the variable names below with the uppercased provider name, for example `GOTRUE_EXTERNAL_GITHUB_ENABLED`. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_EXTERNAL_X_ENABLED` | `bool` | optional | Whether this external provider is enabled. | +| `GOTRUE_EXTERNAL_X_CLIENT_ID` | `string` | required if enabled | The OAuth2 client ID registered with the external provider. Accepts a comma-separated list to allow more than one client ID. | +| `GOTRUE_EXTERNAL_X_SECRET` | `string` | required if enabled | The OAuth2 client secret the external provider issued when you registered. | +| `GOTRUE_EXTERNAL_X_REDIRECT_URI` | `string` | required if enabled | The URI an OAuth2 provider redirects to with the `code` and `state` values. | +| `GOTRUE_EXTERNAL_X_URL` | `string` | required for `keycloak` | The base URL used to construct the authorization and access token URLs. Used by `gitlab` and `keycloak`. For `gitlab` it is optional and defaults to `https://gitlab.com`. For `keycloak` it is required: set it to your instance, for example `https://keycloak.example.com/realms/myrealm`. | +| `GOTRUE_EXTERNAL_X_API_URL` | `string` | optional | Overrides the userinfo/API base URL for the provider, when it differs from the authorization URL. | +| `GOTRUE_EXTERNAL_X_EMAIL_OPTIONAL` | `bool` | optional | When `true`, Auth allows sign-in even if the provider returns no email address. | +| `GOTRUE_EXTERNAL_X_SKIP_NONCE_CHECK` | `bool` | optional | When `true`, Auth skips nonce verification during OIDC token validation. Nonce verification helps prevent replay attacks; only disable it when necessary. | + +#### Shared provider settings + +These apply across providers rather than to a single one. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_EXTERNAL_REDIRECTURL` | `string` | optional | The default redirect URL used after an external sign-in. | +| `GOTRUE_EXTERNAL_IOS_BUNDLE_ID` | `string` | optional | The iOS bundle identifier accepted for native Apple sign-in. | +| `GOTRUE_EXTERNAL_ALLOWED_ID_TOKEN_ISSUERS` | `string` | `https://appleid.apple.com,https://accounts.google.com` | A comma-separated list of issuers accepted for ID-token sign-in. | +| `GOTRUE_EXTERNAL_FLOW_STATE_EXPIRY_DURATION` | `duration` | `300s` | How long a PKCE flow state remains valid. Values below `300s` are raised to `300s`. | +| `GOTRUE_EXTERNAL_OIDC_PROVIDER_CACHE_TTL` | `duration` | `1h` | How long Auth caches OIDC discovery documents. | + +#### Network hardening + +Configuring an external authentication provider causes Auth to make outbound HTTP requests to that provider's authorization, token, and userinfo endpoints. Configuring a provider, either through `GOTRUE_EXTERNAL_*` settings or an admin API, is an administrative action, and doing so implies trust in the hosts and URLs Auth will contact. + +Harden the network Auth runs in so these outbound connections cannot reach internal-only resources you don't want exposed, such as `localhost`/loopback addresses or cloud metadata endpoints such as `169.254.169.254`. This matters most for providers with admin-configurable or discoverable endpoints, such as custom OAuth or OIDC providers, where a misconfigured or malicious URL could otherwise reach internal infrastructure. + +#### Apple OAuth + +To try external authentication with Apple locally, do the following: + +1. Remap `localhost` to a custom hostname in your `/etc/hosts` config. +2. Serve your local Auth instance over HTTPS. Use a local tunnel such as [ngrok](https://ngrok.com) and point `API_EXTERNAL_URL` at the tunnel's HTTPS URL. +3. Generate the `GOTRUE_EXTERNAL_APPLE_SECRET` by following this [post](https://medium.com/identity-beyond-borders/how-to-configure-sign-in-with-apple-77c61e336003). + +### Custom OAuth providers + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_CUSTOM_OAUTH_ENABLED` | `bool` | `true` | Whether custom OAuth and OIDC providers are enabled. | +| `GOTRUE_CUSTOM_OAUTH_MAX_PROVIDERS` | `int` | `0` (unlimited) | The maximum number of custom providers that can be configured. | +| `GOTRUE_CUSTOM_OAUTH_EXTERNAL_URL` | `string` | optional | Overrides the external URL advertised for custom provider callbacks. | + +### OAuth server + +Auth can act as an OAuth 2.0 authorization server. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_OAUTH_SERVER_ENABLED` | `bool` | `false` | Whether the OAuth authorization server is enabled. | +| `GOTRUE_OAUTH_SERVER_ALLOW_DYNAMIC_REGISTRATION` | `bool` | optional | Whether dynamic client registration is allowed. | +| `GOTRUE_OAUTH_SERVER_AUTHORIZATION_PATH` | `string` | optional | The path served for the authorization endpoint. | +| `GOTRUE_OAUTH_SERVER_AUTHORIZATION_TTL` | `duration` | `10m` | How long an authorization code remains valid. | +| `GOTRUE_OAUTH_SERVER_DEFAULT_SCOPE` | `string` | `email` | The default scope granted when none is requested. | + +### Web3 (wallet) sign-in + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_EXTERNAL_WEB3_SOLANA_ENABLED` | `bool` | optional | Whether Sign in with Solana is enabled. | +| `GOTRUE_EXTERNAL_WEB3_SOLANA_MAXIMUM_VALIDITY_DURATION` | `duration` | `10m` | How long a signed Solana message remains valid. | +| `GOTRUE_EXTERNAL_WEB3_ETHEREUM_ENABLED` | `bool` | optional | Whether Sign in with Ethereum is enabled. | +| `GOTRUE_EXTERNAL_WEB3_ETHEREUM_MAXIMUM_VALIDITY_DURATION` | `duration` | `10m` | How long a signed Ethereum message remains valid. | + +### SAML single sign-on + +```properties +GOTRUE_SAML_ENABLED=true +GOTRUE_SAML_PRIVATE_KEY= +``` + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_SAML_ENABLED` | `bool` | `false` | Whether SAML SSO support is enabled. | +| `GOTRUE_SAML_PRIVATE_KEY` | `string` | required if enabled | The active signing and decryption key. PKCS#1 DER format, Base64-encoded. Must be RSA 2048 or larger with the 65537 public exponent. | +| `GOTRUE_SAML_PRIVATE_KEY_NEXT` | `string` | optional | An incoming key for zero-downtime key rotation. Advertised in SAML metadata alongside `GOTRUE_SAML_PRIVATE_KEY` and used as a decryption fallback. See the [SAML SP key rotation runbook](saml_key_rotation.md) for the full rotation procedure. | +| `GOTRUE_SAML_ALLOW_ENCRYPTED_ASSERTIONS` | `bool` | optional | Whether Auth accepts encrypted SAML assertions from the identity provider. | +| `GOTRUE_SAML_RELAY_STATE_VALIDITY_PERIOD` | `duration` | `2m` | How long a SAML `RelayState` value remains valid. | +| `GOTRUE_SAML_EXTERNAL_URL` | `string` | optional | Overrides the URL Auth advertises for the SAML SP entity ID and endpoints, if it differs from `API_EXTERNAL_URL`. | +| `GOTRUE_SAML_RATE_LIMIT_ASSERTION` | `float` | `15` | Maximum SAML assertions accepted per 5 minutes per client IP. | + +### Phone auth + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_SMS_AUTOCONFIRM` | `bool` | `false` | Set to `true` if you do not require phone confirmation. | +| `GOTRUE_SMS_MAX_FREQUENCY` | `duration` | `1m` | The minimum time between one SMS OTP and the next, for example `1m` or `60s`. | +| `GOTRUE_SMS_OTP_EXP` | `number` | `60` | How long an SMS OTP remains valid, in seconds. | +| `GOTRUE_SMS_OTP_LENGTH` | `number` | `6` | The number of digits of the SMS OTP sent. | +| `GOTRUE_SMS_PROVIDER` | `string` | optional | Available options are `twilio`, `twilio_verify`, `messagebird`, `textlocal`, and `vonage`. | +| `GOTRUE_SMS_TEMPLATE` | `string` | optional | The message template for the OTP SMS. The `{{ .Code }}` variable is available. | +| `GOTRUE_SMS_TEST_OTP` | `string` | optional | A comma-separated list of `phone:code` pairs that bypass the provider and always verify, for testing. | +| `GOTRUE_SMS_TEST_OTP_VALID_UNTIL` | `time` | optional | The timestamp after which the test OTPs stop working. | +| `GOTRUE_SMS_TWILIO_ACCOUNT_SID` | `string` | required for Twilio | Your [Twilio account SID](https://www.twilio.com/docs/usage/requests-to-twilio#credentials). | +| `GOTRUE_SMS_TWILIO_AUTH_TOKEN` | `string` | required for Twilio | Your [Twilio auth token](https://www.twilio.com/docs/usage/requests-to-twilio#credentials). | +| `GOTRUE_SMS_TWILIO_MESSAGE_SERVICE_SID` | `string` | required for Twilio | Your Twilio message service SID. Can be set to your Twilio sender mobile number. | +| `GOTRUE_SMS_TWILIO_CONTENT_SID` | `string` | optional | The Twilio content template SID, when using content templates. | +| `GOTRUE_SMS_TWILIO_VERIFY_ACCOUNT_SID` | `string` | required for Twilio Verify | Your Twilio account SID for the Verify service. | +| `GOTRUE_SMS_TWILIO_VERIFY_AUTH_TOKEN` | `string` | required for Twilio Verify | Your Twilio auth token for the Verify service. | +| `GOTRUE_SMS_TWILIO_VERIFY_MESSAGE_SERVICE_SID` | `string` | required for Twilio Verify | Your Twilio Verify service SID. | +| `GOTRUE_SMS_MESSAGEBIRD_ACCESS_KEY` | `string` | required for Messagebird | Your Messagebird access key. Find it in the [Messagebird dashboard](https://dashboard.messagebird.com/en/developers/access). | +| `GOTRUE_SMS_MESSAGEBIRD_ORIGINATOR` | `string` | required for Messagebird | The SMS sender: your Messagebird phone number with `+`, or a company name. | +| `GOTRUE_SMS_TEXTLOCAL_API_KEY` | `string` | required for Textlocal | Your Textlocal API key. | +| `GOTRUE_SMS_TEXTLOCAL_SENDER` | `string` | required for Textlocal | Your Textlocal sender ID. | +| `GOTRUE_SMS_VONAGE_API_KEY` | `string` | required for Vonage | Your Vonage API key. | +| `GOTRUE_SMS_VONAGE_API_SECRET` | `string` | required for Vonage | Your Vonage API secret. | +| `GOTRUE_SMS_VONAGE_FROM` | `string` | required for Vonage | The Vonage sender phone number or name. | + +### Multi-factor authentication (MFA) + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_MFA_CHALLENGE_EXPIRY_DURATION` | `float` | `300` | How long, in seconds, an MFA challenge remains valid. Values below `300` are raised to `300`. | +| `GOTRUE_MFA_FACTOR_EXPIRY_DURATION` | `duration` | `300s` | How long an unverified factor remains before expiry. Values below `300s` are raised to `300s`. | +| `GOTRUE_MFA_MAX_ENROLLED_FACTORS` | `float` | `10` | The maximum number of factors a user may enroll. | +| `GOTRUE_MFA_MAX_VERIFIED_FACTORS` | `int` | `10` | The maximum number of verified factors a user may have. | +| `GOTRUE_MFA_RATE_LIMIT_CHALLENGE_AND_VERIFY` | `float` | `15` | Maximum challenge and verify attempts per minute per client IP. | +| `GOTRUE_MFA_TOTP_ENROLL_ENABLED` | `bool` | `true` | Whether users may enroll a TOTP factor. | +| `GOTRUE_MFA_TOTP_VERIFY_ENABLED` | `bool` | `true` | Whether users may verify with a TOTP factor. | +| `GOTRUE_MFA_PHONE_ENROLL_ENABLED` | `bool` | `false` | Whether users may enroll a phone factor. | +| `GOTRUE_MFA_PHONE_VERIFY_ENABLED` | `bool` | `false` | Whether users may verify with a phone factor. | +| `GOTRUE_MFA_PHONE_OTP_LENGTH` | `int` | `6` | The number of digits in the phone MFA OTP. | +| `GOTRUE_MFA_PHONE_MAX_FREQUENCY` | `duration` | `1m` | The minimum time between one phone MFA message and the next. | +| `GOTRUE_MFA_PHONE_TEMPLATE` | `string` | optional | The message template for the phone MFA OTP. The `{{ .Code }}` variable is available. | +| `GOTRUE_MFA_WEB_AUTHN_ENROLL_ENABLED` | `bool` | `false` | Whether users may enroll a WebAuthn factor. | +| `GOTRUE_MFA_WEB_AUTHN_VERIFY_ENABLED` | `bool` | `false` | Whether users may verify with a WebAuthn factor. | +| `GOTRUE_MFA_RECOVERY_CODES_ENROLL_ENABLED` | `bool` | `false` | Whether recovery codes may be generated. | +| `GOTRUE_MFA_RECOVERY_CODES_VERIFY_ENABLED` | `bool` | `false` | Whether recovery codes may be used to verify. | +| `GOTRUE_MFA_RECOVERY_CODES_COUNT` | `int` | `10` | The number of recovery codes generated. Must be 4-16 when enabled. | +| `GOTRUE_MFA_RECOVERY_CODES_CODE_LENGTH` | `int` | `16` | The length of each recovery code. Must be 13-32 when enabled. | +| `GOTRUE_MFA_RECOVERY_CODES_MAX_VERIFY_ATTEMPTS` | `int` | `5` | The maximum failed verification attempts. Must be 3-15 when enabled. | +| `GOTRUE_MFA_RECOVERY_CODES_LOCKOUT_DURATION` | `duration` | `15m` | How long a user is locked out after too many failed attempts. Must be between `1m` and `24h` when enabled. | + +### WebAuthn + +Required when WebAuthn MFA or passkeys are enabled. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_WEBAUTHN_RP_ID` | `string` | required if enabled | The relying party ID, usually your site's domain. | +| `GOTRUE_WEBAUTHN_RP_DISPLAY_NAME` | `string` | required if enabled | The relying party display name shown to users. | +| `GOTRUE_WEBAUTHN_RP_ORIGINS` | `string` | required if enabled | A comma-separated list of allowed origins. | +| `GOTRUE_WEBAUTHN_CHALLENGE_EXPIRY_DURATION` | `duration` | `5m` | How long a WebAuthn challenge remains valid. | + +### Passkeys + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_PASSKEY_ENABLED` | `bool` | `false` | Whether passkey sign-in is enabled. Requires the WebAuthn settings above. | +| `GOTRUE_PASSKEY_MAX_PASSKEYS_PER_USER` | `int` | `10` | The maximum number of passkeys a user may register. | + +### Sessions + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_SESSIONS_TIMEBOX` | `duration` | optional | The maximum lifetime of a session, after which it ends regardless of activity. Must be positive when set. | +| `GOTRUE_SESSIONS_INACTIVITY_TIMEOUT` | `duration` | optional | How long a session may be idle before it ends. Must be positive when set. | +| `GOTRUE_SESSIONS_ALLOW_LOW_AAL` | `duration` | optional | How long a session may keep a low assurance level before MFA is required. Must be positive when set. | +| `GOTRUE_SESSIONS_SINGLE_PER_USER` | `bool` | optional | When `true`, each user may have only one active session. | +| `GOTRUE_SESSIONS_TAGS` | `string` | optional | A comma-separated list of tags applied to sessions. | + +### Auth hooks + +Each hook points at a Postgres function (`pg-functions://...`) or an HTTPS endpoint. Replace `HOOK` below with one of `MFA_VERIFICATION_ATTEMPT`, `PASSWORD_VERIFICATION_ATTEMPT`, `CUSTOM_ACCESS_TOKEN`, `SEND_EMAIL`, `SEND_SMS`, `BEFORE_USER_CREATED`, or `AFTER_USER_CREATED`. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_HOOK_HOOK_ENABLED` | `bool` | optional | Whether this hook is enabled. | +| `GOTRUE_HOOK_HOOK_URI` | `string` | required if enabled | The hook target. `pg-functions:///` or an `https://` URL. `http://` is allowed only for localhost. | +| `GOTRUE_HOOK_HOOK_SECRETS` | `string` | required for HTTP hooks | Pipe-separated webhook signing secrets, for example `v1,whsec_...|v1a,whpk_...`. | + +### Anonymous sign-ins + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED` | `bool` | `false` | Enable or disable anonymous sign-ins. | + +### Experimental + +These settings may change or be removed in a future release. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_EXPERIMENTAL_SCIM_ENABLED` | `bool` | `false` | Gates the `/scim/v2` router. | +| `GOTRUE_EXPERIMENTAL_CURSOR_PAGINATION_ENABLED` | `bool` | `false` | Enables cursor-based pagination for the admin user list endpoint. | +| `GOTRUE_EXPERIMENTAL_CREATE_EMAIL_IDENTITY_ON_PASSWORD_SET_ENABLED` | `bool` | `false` | Creates a missing email identity when a password is added to an account that had none. | +| `GOTRUE_EXPERIMENTAL_PROVIDER_LINKING_DOMAINS` | `string` | optional | A comma-separated list of `provider=domain` pairs. Providers mapped to the same domain link to one another but stay isolated from the default email-linked pool, for example `custom:github=social,custom:google=social`. | +| `GOTRUE_EXPERIMENTAL_PROVIDERS_WITH_OWN_LINKING_DOMAIN` | `string` | deprecated | Use `GOTRUE_EXPERIMENTAL_PROVIDER_LINKING_DOMAINS` instead. A comma-separated list of providers that do not participate in email-similarity linking. | + +## Email + +Sending email is not required, but is highly recommended for password recovery. If you enable it, provide the values below. + +```properties +GOTRUE_SMTP_HOST=smtp.mandrillapp.com +GOTRUE_SMTP_PORT=587 +GOTRUE_SMTP_USER=smtp-delivery@example.com +GOTRUE_SMTP_PASS=correcthorsebatterystaple +GOTRUE_SMTP_ADMIN_EMAIL=support@example.com +GOTRUE_MAILER_SUBJECTS_CONFIRMATION="Please confirm" +``` + +### Delivery (SMTP) + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_SMTP_HOST` | `string` | optional | The mail server hostname to send emails through. When unset, Auth skips sending email. | +| `GOTRUE_SMTP_PORT` | `number` | `587` | The port number for connecting to the mail server. | +| `GOTRUE_SMTP_USER` | `string` | optional | If the mail server requires authentication, the username to use. | +| `GOTRUE_SMTP_PASS` | `string` | optional | If the mail server requires authentication, the password to use. | +| `GOTRUE_SMTP_ADMIN_EMAIL` | `string` | optional | The `From` email address for all emails sent. | +| `GOTRUE_SMTP_SENDER_NAME` | `string` | optional | The display name for the `From` address. When unset, the address has no display name. | +| `GOTRUE_SMTP_MAX_FREQUENCY` | `duration` | `1m` | The minimum time between a signup confirmation or password reset email and the next, for example `1m` or `60s`. | +| `GOTRUE_SMTP_HEADERS` | `string` (JSON) | optional | Extra headers to add to every email, as a JSON object of header name to list of values. Invalid JSON is ignored. | +| `GOTRUE_SMTP_LOGGING_ENABLED` | `bool` | `false` | Whether Auth logs SMTP activity. | + +### Message behavior + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_MAILER_AUTOCONFIRM` | `bool` | `false` | Set to `true` if you do not require email confirmation. | +| `GOTRUE_MAILER_ALLOW_UNVERIFIED_EMAIL_SIGN_INS` | `bool` | `false` | When `true`, users may sign in before confirming their email. Cannot be combined with `GOTRUE_MAILER_AUTOCONFIRM`. | +| `GOTRUE_MAILER_SECURE_EMAIL_CHANGE_ENABLED` | `bool` | `true` | When `true`, changing an email requires confirmation from both the old and new address. | +| `GOTRUE_MAILER_OTP_EXP` | `number` | `86400` (1 day) | How long an email link or OTP remains valid. | +| `GOTRUE_MAILER_OTP_LENGTH` | `int` | `6` | The number of digits in an email OTP. | +| `GOTRUE_MAILER_URLPATHS_INVITE` | `string` | `/verify` | URL path to use in the user invite email. | +| `GOTRUE_MAILER_URLPATHS_CONFIRMATION` | `string` | `/verify` | URL path to use in the signup confirmation email. | +| `GOTRUE_MAILER_URLPATHS_RECOVERY` | `string` | `/verify` | URL path to use in the password reset email. | +| `GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE` | `string` | `/verify` | URL path to use in the email change confirmation email. | +| `GOTRUE_MAILER_EXTERNAL_HOSTS` | `string` | optional | A comma-separated allowlist of hosts permitted in email redirect links. | +| `GOTRUE_MAILER_EMAIL_BACKGROUND_SENDING` | `bool` | `false` | When `true`, Auth sends email in the background rather than during the request. | +| `GOTRUE_MAILER_EMAIL_VALIDATION_EXTENDED` | `bool` | `false` | When `true`, Auth performs extended validation of recipient email addresses. | +| `GOTRUE_MAILER_EMAIL_VALIDATION_SERVICE_URL` | `string` | optional | The URL of an external email validation service. | +| `GOTRUE_MAILER_EMAIL_VALIDATION_SERVICE_HEADERS` | `string` (JSON) | optional | Headers for the validation service, as a JSON object of header name to list of values. | +| `GOTRUE_MAILER_EMAIL_VALIDATION_BLOCKED_MX` | `string` (JSON) | optional | A JSON array of MX hostnames whose domains are rejected. | +| `GOTRUE_MAILER_TEMPLATE_MAX_SIZE` | `int` | `1000000` | The maximum number of bytes read from a remote template endpoint. | +| `GOTRUE_MAILER_TEMPLATE_MAX_AGE` | `duration` | `10m` | How long a fetched template is used before it is considered stale. | +| `GOTRUE_MAILER_TEMPLATE_RETRY_INTERVAL` | `duration` | `10s` | The time between retries after a failed template reload. | +| `GOTRUE_MAILER_TEMPLATE_RELOADING_ENABLED` | `bool` | `false` | Whether templates reload in the background to avoid blocking requests. | +| `GOTRUE_MAILER_TEMPLATE_RELOADING_MAX_IDLE` | `duration` | `20m` | The maximum idle time before background template reloading stops. | + +### Subjects + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_MAILER_SUBJECTS_INVITE` | `string` | `You've been invited` | Email subject to use for user invite. | +| `GOTRUE_MAILER_SUBJECTS_CONFIRMATION` | `string` | `Confirm your email address` | Email subject to use for signup confirmation. | +| `GOTRUE_MAILER_SUBJECTS_RECOVERY` | `string` | `Reset your password` | Email subject to use for password reset. | +| `GOTRUE_MAILER_SUBJECTS_MAGIC_LINK` | `string` | `Your sign-in link` | Email subject to use for magic link email. | +| `GOTRUE_MAILER_SUBJECTS_EMAIL_CHANGE` | `string` | `Confirm your new email address` | Email subject to use for email change confirmation. | +| `GOTRUE_MAILER_SUBJECTS_REAUTHENTICATION` | `string` | `{{ .Token }} is your verification code` | Email subject to use for reauthentication. | +| `GOTRUE_MAILER_SUBJECTS_PASSWORD_CHANGED_NOTIFICATION` | `string` | `Your password was changed` | Email subject to use for password changed notification. | +| `GOTRUE_MAILER_SUBJECTS_EMAIL_CHANGED_NOTIFICATION` | `string` | `Your email address was changed` | Email subject to use for email changed notification. | +| `GOTRUE_MAILER_SUBJECTS_PHONE_CHANGED_NOTIFICATION` | `string` | `Your phone number was changed` | Email subject to use for phone changed notification. | +| `GOTRUE_MAILER_SUBJECTS_IDENTITY_LINKED_NOTIFICATION` | `string` | `A new sign-in method was linked to your account` | Email subject to use for identity linked notification. | +| `GOTRUE_MAILER_SUBJECTS_IDENTITY_UNLINKED_NOTIFICATION` | `string` | `A sign-in method was removed from your account` | Email subject to use for identity unlinked notification. | +| `GOTRUE_MAILER_SUBJECTS_MFA_FACTOR_ENROLLED_NOTIFICATION` | `string` | `A new verification method was added to your account` | Email subject to use for verification method added notification. | +| `GOTRUE_MAILER_SUBJECTS_MFA_FACTOR_UNENROLLED_NOTIFICATION` | `string` | `A verification method was removed from your account` | Email subject to use for verification method removed notification. | + +### Templates + +Each value is a URL path to an email template. Default content, used when the template is unavailable, is shown under "Default template content". + +| Variable | Type | Default/Required | Available variables | +| --- | --- | --- | --- | +| `GOTRUE_MAILER_TEMPLATES_INVITE` | `string` | optional | `SiteURL`, `Email`, `ConfirmationURL` | +| `GOTRUE_MAILER_TEMPLATES_CONFIRMATION` | `string` | optional | `SiteURL`, `Email`, `ConfirmationURL` | +| `GOTRUE_MAILER_TEMPLATES_RECOVERY` | `string` | optional | `SiteURL`, `Email`, `ConfirmationURL` | +| `GOTRUE_MAILER_TEMPLATES_MAGIC_LINK` | `string` | optional | `SiteURL`, `Email`, `ConfirmationURL` | +| `GOTRUE_MAILER_TEMPLATES_EMAIL_CHANGE` | `string` | optional | `SiteURL`, `Email`, `NewEmail`, `ConfirmationURL` | +| `GOTRUE_MAILER_TEMPLATES_REAUTHENTICATION` | `string` | optional | `Token` | +| `GOTRUE_MAILER_TEMPLATES_PASSWORD_CHANGED_NOTIFICATION` | `string` | optional | `Email` | +| `GOTRUE_MAILER_TEMPLATES_EMAIL_CHANGED_NOTIFICATION` | `string` | optional | `Email`, `OldEmail` | +| `GOTRUE_MAILER_TEMPLATES_PHONE_CHANGED_NOTIFICATION` | `string` | optional | `Email`, `Phone`, `OldPhone` | +| `GOTRUE_MAILER_TEMPLATES_IDENTITY_LINKED_NOTIFICATION` | `string` | optional | `Email`, `Provider` | +| `GOTRUE_MAILER_TEMPLATES_IDENTITY_UNLINKED_NOTIFICATION` | `string` | optional | `Email`, `Provider` | +| `GOTRUE_MAILER_TEMPLATES_MFA_FACTOR_ENROLLED_NOTIFICATION` | `string` | optional | `Email`, `FactorType` | +| `GOTRUE_MAILER_TEMPLATES_MFA_FACTOR_UNENROLLED_NOTIFICATION` | `string` | optional | `Email`, `FactorType` | + +### Notifications + +Account-change notification emails are off by default. Enable the ones you want. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_MAILER_NOTIFICATIONS_PASSWORD_CHANGED_ENABLED` | `bool` | `false` | Whether to send a notification email when a user's password changes. | +| `GOTRUE_MAILER_NOTIFICATIONS_EMAIL_CHANGED_ENABLED` | `bool` | `false` | Whether to send a notification email when a user's email changes. | +| `GOTRUE_MAILER_NOTIFICATIONS_PHONE_CHANGED_ENABLED` | `bool` | `false` | Whether to send a notification email when a user's phone number changes. | +| `GOTRUE_MAILER_NOTIFICATIONS_IDENTITY_LINKED_ENABLED` | `bool` | `false` | Whether to send a notification email when a sign-in method is linked to a user's account. | +| `GOTRUE_MAILER_NOTIFICATIONS_IDENTITY_UNLINKED_ENABLED` | `bool` | `false` | Whether to send a notification email when a sign-in method is removed from a user's account. | +| `GOTRUE_MAILER_NOTIFICATIONS_MFA_FACTOR_ENROLLED_ENABLED` | `bool` | `false` | Whether to send a notification email when a new verification method is added to a user's account. | +| `GOTRUE_MAILER_NOTIFICATIONS_MFA_FACTOR_UNENROLLED_ENABLED` | `bool` | `false` | Whether to send a notification email when a verification method is removed from a user's account. | + +### Default template content + +Used when the corresponding `GOTRUE_MAILER_TEMPLATES_*` variable is unset. + +`GOTRUE_MAILER_TEMPLATES_INVITE` + +```html +

You've been invited

+ +

You've been invited to create an account. Follow the link below to accept.

+

Accept invitation

+``` + +`GOTRUE_MAILER_TEMPLATES_CONFIRMATION` + +```html +

Confirm your email address

+ +

Follow the link below to confirm this email address and finish signing up.

+

Confirm email address

+``` + +`GOTRUE_MAILER_TEMPLATES_RECOVERY` + +```html +

Reset your password

+ +

We received a request to reset your password. Follow the link below to choose a new one.

+

Reset password

+

If you didn't request this, you can safely ignore this email.

+``` + +`GOTRUE_MAILER_TEMPLATES_MAGIC_LINK` + +```html +

Your sign-in link

+ +

Follow the link below to sign in. This link expires shortly and can only be used once.

+

Sign in

+``` + +`GOTRUE_MAILER_TEMPLATES_EMAIL_CHANGE` + +```html +

Confirm your new email address

+ +

Follow the link below to confirm {{ .NewEmail }} as your new email address.

+

Confirm new email address

+

If you didn't request this change, you can safely ignore this email.

+``` + +`GOTRUE_MAILER_TEMPLATES_REAUTHENTICATION` + +```html +

Your verification code

+ +

Use the code below to verify your identity. It expires shortly.

+

{{ .Token }}

+``` + +`GOTRUE_MAILER_TEMPLATES_PASSWORD_CHANGED_NOTIFICATION` + +```html +

Your password was changed

+ +

The password for your account was recently changed.

+

If you didn't make this change, reset your password and contact support immediately.

+``` + +`GOTRUE_MAILER_TEMPLATES_EMAIL_CHANGED_NOTIFICATION` + +```html +

Your email address was changed

+ +

The email address for your account was changed from {{ .OldEmail }} to {{ .Email }}.

+

If you didn't make this change, contact support immediately.

+``` + +`GOTRUE_MAILER_TEMPLATES_PHONE_CHANGED_NOTIFICATION` + +```html +

Your phone number was changed

+ +

The phone number for your account was changed from {{ .OldPhone }} to {{ .Phone }}.

+

If you didn't make this change, contact support immediately.

+``` + +`GOTRUE_MAILER_TEMPLATES_IDENTITY_LINKED_NOTIFICATION` + +```html +

A new sign-in method was linked

+ +

Your {{ .Provider }} account was linked as a new sign-in method for {{ .Email }}.

+

If you didn't make this change, contact support immediately.

+``` + +`GOTRUE_MAILER_TEMPLATES_IDENTITY_UNLINKED_NOTIFICATION` + +```html +

A sign-in method was removed

+ +

Your {{ .Provider }} account was removed as a sign-in method for {{ .Email }}.

+

If you didn't make this change, contact support immediately.

+``` + +`GOTRUE_MAILER_TEMPLATES_MFA_FACTOR_ENROLLED_NOTIFICATION` + +```html +

A new verification method was added

+ +

Sign-in verification method {{ .FactorType }} was added to your account.

+

If you didn't make this change, contact support immediately.

+``` + +`GOTRUE_MAILER_TEMPLATES_MFA_FACTOR_UNENROLLED_NOTIFICATION` + +```html +

A verification method was removed

+ +

Sign-in verification method {{ .FactorType }} was removed from your account.

+

If you didn't make this change, contact support immediately.

+``` + +## Security + +### Passwords + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_PASSWORD_MIN_LENGTH` | `int` | `6` | Minimum password length. Values below `6` are raised to `6`. | +| `GOTRUE_PASSWORD_REQUIRED_CHARACTERS` | `string` | optional | A string of character sets separated by `:`. A password must contain at least one character of each set to be accepted. To use the `:` character, escape it with `\`. | +| `GOTRUE_PASSWORD_HIBP_ENABLED` | `bool` | optional | Whether passwords are checked against the Have I Been Pwned database. | +| `GOTRUE_PASSWORD_HIBP_FAIL_CLOSED` | `bool` | optional | When `true`, Auth rejects the password if the HIBP check cannot complete. | +| `GOTRUE_PASSWORD_HIBP_USER_AGENT` | `string` | `https://github.com/supabase/gotrue` | The `User-Agent` sent to the HIBP API. | +| `GOTRUE_PASSWORD_HIBP_BLOOM_ENABLED` | `bool` | optional | Whether a local bloom filter caches pwned passwords. | +| `GOTRUE_PASSWORD_HIBP_BLOOM_ITEMS` | `uint` | `100000` | The expected number of items in the bloom filter. | +| `GOTRUE_PASSWORD_HIBP_BLOOM_FALSE_POSITIVES` | `float` | `0.0000099` | The target false-positive rate for the bloom filter. | + +### Rate limiting + +Rate limits are applied per client IP. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_RATE_LIMIT_HEADER` | `string` | optional | Header on which to rate limit the `/token` endpoint. A trusted upstream proxy, such as Kong or Envoy, must set this header. Headers such as `x-forwarded-for` are spoofable. Do not trust them for rate limiting when a client supplies them directly. | +| `GOTRUE_RATE_LIMIT_EMAIL_SENT` | `Rate` | `30` (per hour) | Emails sent per hour on `/signup`, `/invite`, `/magiclink`, `/recover`, `/otp`, and `/user`. Accepts a plain number of events per hour, or a burst syntax of `events/duration`, for example `30/1h`. | +| `GOTRUE_RATE_LIMIT_SMS_SENT` | `Rate` | `30` (per hour) | SMS messages sent per hour. Accepts the same syntax as `GOTRUE_RATE_LIMIT_EMAIL_SENT`. | +| `GOTRUE_RATE_LIMIT_OTP` | `float` | `30` | OTP-related requests per 5 minutes (`/signup`, `/magiclink`, `/recover`, `/otp`, `/user`, resend). | +| `GOTRUE_RATE_LIMIT_VERIFY` | `float` | `30` | Verify requests per 5 minutes. | +| `GOTRUE_RATE_LIMIT_TOKEN_REFRESH` | `float` | `150` | Token refresh requests per 5 minutes. | +| `GOTRUE_RATE_LIMIT_SSO` | `float` | `30` | SSO requests per 5 minutes. | +| `GOTRUE_RATE_LIMIT_ANONYMOUS_USERS` | `float` | `30` | Anonymous sign-ins per hour. | +| `GOTRUE_RATE_LIMIT_WEB3` | `float` | `30` | Web3 sign-ins per 5 minutes. | +| `GOTRUE_RATE_LIMIT_PASSKEY` | `float` | `30` | Passkey authentications per 5 minutes. | +| `GOTRUE_RATE_LIMIT_O_AUTH_DYNAMIC_CLIENT_REGISTER` | `float` | `10` | Dynamic OAuth client registrations per 5 minutes. | + +### Refresh tokens + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_SECURITY_REFRESH_TOKEN_ROTATION_ENABLED` | `bool` | `true` | When enabled, Auth detects attempts to reuse a revoked refresh token. When it detects a reuse attempt, Auth revokes all tokens descended from the offending token. | +| `GOTRUE_SECURITY_REFRESH_TOKEN_REUSE_INTERVAL` | `int` | optional | The interval length in seconds. Applies only when `GOTRUE_SECURITY_REFRESH_TOKEN_ROTATION_ENABLED` is enabled.

The reuse interval for a refresh token allows exchanging the refresh token multiple times during the interval, to support concurrency or offline use. During the reuse interval, Auth does not treat reuse of a revoked token as a reuse attempt, and returns the child refresh token instead.

Auth allows reuse of only the previous revoked token. Using an older refresh token triggers reuse detection. | +| `GOTRUE_SECURITY_REFRESH_TOKEN_ALLOW_REUSE` | `bool` | optional | When `true`, Auth does not treat refresh token reuse as an attack. | +| `GOTRUE_SECURITY_REFRESH_TOKEN_ALGORITHM_VERSION` | `int` | optional | The refresh token algorithm version. Must be 0, 1, or 2. | +| `GOTRUE_SECURITY_REFRESH_TOKEN_UPGRADE_PERCENTAGE` | `int` | optional | The percentage (0-100) of tokens upgraded to the newer algorithm during a rollout. | + +### CAPTCHA + +If enabled, Auth checks the request body for the `captcha_token` field and makes a verification request to the CAPTCHA provider. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_SECURITY_CAPTCHA_ENABLED` | `bool` | `false` | Whether the CAPTCHA middleware is enabled. | +| `GOTRUE_SECURITY_CAPTCHA_PROVIDER` | `string` | `hcaptcha` | Auth currently supports only `hcaptcha` and `turnstile`. | +| `GOTRUE_SECURITY_CAPTCHA_SECRET` | `string` | required if enabled | Retrieve this from your hCaptcha or Turnstile account. | +| `GOTRUE_SECURITY_CAPTCHA_TIMEOUT` | `duration` | `10s` | The HTTP client timeout for the CAPTCHA verification request. | + +### Reauthentication + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_REAUTHENTICATION` | `bool` | optional | Enforce reauthentication on password update. | +| `GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_CURRENT_PASSWORD` | `bool` | optional | Require the current password when updating the password. | + +### Account linking + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_SECURITY_MANUAL_LINKING_ENABLED` | `bool` | `false` | Whether the manual identity linking API is enabled. | + +### Database encryption + +Once `GOTRUE_SECURITY_DB_ENCRYPTION_ENCRYPT` is `true`, Auth encrypts certain columns with the provided key. Setting it back to `false` stops further encryption, but the key must remain in the decryption keys so existing data stays readable. + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_SECURITY_DB_ENCRYPTION_ENCRYPT` | `bool` | optional | Whether column encryption is enabled. | +| `GOTRUE_SECURITY_DB_ENCRYPTION_ENCRYPTION_KEY_ID` | `string` | required if encrypting | The ID of the active encryption key. | +| `GOTRUE_SECURITY_DB_ENCRYPTION_ENCRYPTION_KEY` | `string` | required if encrypting | The active 256-bit key, Base64 raw-URL encoded. | +| `GOTRUE_SECURITY_DB_ENCRYPTION_DECRYPTION_KEYS` | `string` | required if encrypting | A comma-separated list of `key_id:key` pairs used to decrypt existing data. Must contain the active key. | + +### IP address forwarding + +| Variable | Type | Default/Required | Description | +| --- | --- | --- | --- | +| `GOTRUE_SECURITY_SB_FORWARDED_FOR_ENABLED` | `bool` | `false` | Enable IP address forwarding using the `Sb-Forwarded-For` HTTP request header. When enabled, Auth parses the first value of this header as an IP address and uses it for IP address tracking and rate limiting.

Before enabling this feature, make sure only trustworthy clients or proxies can set this header. |