Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions apps/docs/content/guides/self-hosting/docker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,24 @@ The script generates a new password, updates all database roles, and modifies yo
sh run.sh recreate
```

### Rotating API keys

Unlike the managed platform, where you rotate keys from the Dashboard, self-hosted API keys live in your `.env` file. To rotate the publishable and secret keys (`SUPABASE_PUBLISHABLE_KEY` and `SUPABASE_SECRET_KEY`) without changing the asymmetric signing key pair, run:

```sh
sh utils/rotate-new-api-keys.sh --update-env
```

Then restart the services and update your applications with the new keys:

```sh
sh run.sh recreate
```

Use the publishable key in client apps and the secret key only in trusted server-side environments. Rotating these keys does not invalidate existing user session tokens. You can also set a custom value by editing `SUPABASE_PUBLISHABLE_KEY` or `SUPABASE_SECRET_KEY` in `.env` directly, then recreating the services.

For rotating versus fully regenerating the asymmetric key pair (which does affect active sessions), see [New API Keys and Asymmetric Authentication](/docs/guides/self-hosting/self-hosted-auth-keys#regenerating-asymmetric-key-pair).

### Configuring secrets

The `generate-keys.sh` script sets the following secrets automatically. You can also configure them manually in the `.env` file if needed:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Envoy is registered as the `api-gw` service and also exposes `envoy` and `kong`
Confirm the gateway is routing requests and enforcing API keys:

```sh
curl -i -H "apikey: your-service-role-key" http://<your-domain>/rest/v1/
curl -i -H "apikey: your-supabase-secret-key" http://<your-domain>/rest/v1/
```

A `200 OK` response from PostgREST confirms the gateway is up. A `401 Unauthorized` without the `apikey` header confirms enforcement is active.
Expand Down
6 changes: 3 additions & 3 deletions apps/docs/content/guides/self-hosting/self-hosted-oauth.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ sh run.sh recreate auth
Check that the provider is enabled:

```sh
curl -H 'apikey: your-anon-key' https://<your-domain>/auth/v1/settings
curl -H 'apikey: your-supabase-publishable-key' https://<your-domain>/auth/v1/settings
```

The response should include your provider under `external`:
Expand Down Expand Up @@ -350,9 +350,9 @@ You can test OAuth with the following minimal HTML page:
<script>
document.addEventListener('DOMContentLoaded', function () {
const SUPABASE_URL = 'https://<your-domain>'
const SUPABASE_ANON_KEY = 'your-anon-key'
const SUPABASE_PUBLISHABLE_KEY = 'your-supabase-publishable-key'

const supabase = window.supabase.createClient(SUPABASE_URL, SUPABASE_ANON_KEY)
const supabase = window.supabase.createClient(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY)

const button = document.getElementById('loginBtn')

Expand Down
39 changes: 15 additions & 24 deletions apps/docs/content/guides/self-hosting/self-hosted-saml-sso.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ You need:
- A running self-hosted Supabase instance (see the [setup guide](/docs/guides/self-hosting/docker))
- Open SSL installed (for key generation)
- Your IdP's SAML metadata URL or metadata XML
- The `SERVICE_ROLE_KEY` from your `.env` file (needed for admin API calls)
- Your project's secret key, `SUPABASE_SECRET_KEY`, from your `.env` file (needed for admin API calls)
- `API_EXTERNAL_URL` set to the publicly-accessible URL of your Supabase Auth service (e.g., `https://<your-domain>/auth/v1`). Used as the base for constructing the SAML Service Provider entity ID and ACS endpoint URL

## How SAML SSO works in Supabase
Expand Down Expand Up @@ -156,17 +156,16 @@ Key values in the metadata:

## Step 6: Register an identity provider

Use the Auth admin API to register your IdP. You need the `SERVICE_ROLE_KEY` for authentication.
Use the Auth admin API to register your IdP. You need your project's secret key, `SUPABASE_SECRET_KEY`, for authentication.

### Option A: Register with a metadata URL (recommended)

If your IdP provides a metadata URL, Auth will fetch and cache the metadata automatically and refresh it when it becomes stale:

```sh
curl -X POST 'http://<your-domain>/auth/v1/admin/sso/providers' \
-H 'Authorization: Bearer your-service-role-key' \
-H 'Content-Type: application/json' \
-H 'apikey: your-service-role-key' \
-H 'apikey: your-supabase-secret-key' \
-d '{
"type": "saml",
"metadata_url": "https://idp.example.com/saml/metadata",
Expand All @@ -190,9 +189,8 @@ If you have the IdP metadata as an XML string:

```sh
curl -X POST 'http://<your-domain>/auth/v1/admin/sso/providers' \
-H 'Authorization: Bearer your-service-role-key' \
-H 'Content-Type: application/json' \
-H 'apikey: your-service-role-key' \
-H 'apikey: your-supabase-secret-key' \
-d '{
"type": "saml",
"metadata_xml": "<EntityDescriptor ...>...</EntityDescriptor>",
Expand Down Expand Up @@ -384,41 +382,36 @@ Mapped attributes are stored in the user's `raw_user_meta_data` and are availabl

```sh
curl 'http://<your-domain>/auth/v1/admin/sso/providers' \
-H 'Authorization: Bearer your-service-role-key' \
-H 'apikey: your-service-role-key'
-H 'apikey: your-supabase-secret-key'
```

Filter by resource ID using exact match:

```sh
curl 'http://<your-domain>/auth/v1/admin/sso/providers?resource_id=my-idp' \
-H 'Authorization: Bearer your-service-role-key' \
-H 'apikey: your-service-role-key'
-H 'apikey: your-supabase-secret-key'
```

or prefix match:

```sh
curl 'http://<your-domain>/auth/v1/admin/sso/providers?resource_id_prefix=prod-' \
-H 'Authorization: Bearer your-service-role-key' \
-H 'apikey: your-service-role-key'
-H 'apikey: your-supabase-secret-key'
```

### Get a specific provider

```sh
curl 'http://<your-domain>/auth/v1/admin/sso/providers/{provider_id}' \
-H 'Authorization: Bearer your-service-role-key' \
-H 'apikey: your-service-role-key'
-H 'apikey: your-supabase-secret-key'
```

### Update a provider

```sh
curl -X PUT 'http://<your-domain>/auth/v1/admin/sso/providers/{provider_id}' \
-H 'Authorization: Bearer your-service-role-key' \
-H 'Content-Type: application/json' \
-H 'apikey: your-service-role-key' \
-H 'apikey: your-supabase-secret-key' \
-d '{
"domains": ["example.com", "subsidiary.com"],
"attribute_mapping": {
Expand All @@ -435,18 +428,16 @@ curl -X PUT 'http://<your-domain>/auth/v1/admin/sso/providers/{provider_id}' \

```sh
curl -X PUT 'http://<your-domain>/auth/v1/admin/sso/providers/{provider_id}' \
-H 'Authorization: Bearer your-service-role-key' \
-H 'Content-Type: application/json' \
-H 'apikey: your-service-role-key' \
-H 'apikey: your-supabase-secret-key' \
-d '{ "disabled": true }'
```

### Delete a provider

```sh
curl -X DELETE 'http://<your-domain>/auth/v1/admin/sso/providers/{provider_id}' \
-H 'Authorization: Bearer your-service-role-key' \
-H 'apikey: your-service-role-key'
-H 'apikey: your-supabase-secret-key'
```

## Client-side integration
Expand All @@ -456,7 +447,7 @@ curl -X DELETE 'http://<your-domain>/auth/v1/admin/sso/providers/{provider_id}'
```js
import { createClient } from '@supabase/supabase-js'

const supabase = createClient('http://<your-domain>', 'your-anon-key')
const supabase = createClient('http://<your-domain>', 'your-supabase-publishable-key')

// Option 1: SSO by email domain
const { data, error } = await supabase.auth.signInWithSSO({
Expand All @@ -483,7 +474,7 @@ By domain:
```sh
curl -X POST 'http://<your-domain>/auth/v1/sso' \
-H 'Content-Type: application/json' \
-H 'apikey: your-anon-key' \
-H 'apikey: your-supabase-publishable-key' \
-d '{
"domain": "example.com",
"skip_http_redirect": true
Expand All @@ -495,7 +486,7 @@ By provider ID:
```sh
curl -X POST 'http://<your-domain>/auth/v1/sso' \
-H 'Content-Type: application/json' \
-H 'apikey: your-anon-key' \
-H 'apikey: your-supabase-publishable-key' \
-d '{
"provider_id": "d3f5a1b2-...",
"skip_http_redirect": true
Expand Down Expand Up @@ -523,7 +514,7 @@ To verify the session was created:
```sh
curl 'http://<your-domain>/auth/v1/user' \
-H 'Authorization: Bearer user-session-token' \
-H 'apikey: your-anon-key'
-H 'apikey: your-supabase-publishable-key'
```

The response should include `app_metadata.provider: "sso:saml"` and any mapped attributes in `user_metadata`.
Expand Down
Loading