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
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ We'll be saving the Postgres documentation in Postgres, and ChatGPT will be retr
dark: '/docs/img/ai/chatgpt-plugins/chatgpt-plugin-scheme--dark.png',
}}

width={1196}
height={1194}
width={1196}
height={1194}
/>

### Step 1: Fork the ChatGPT Retrieval Plugin repository
Expand Down
29 changes: 26 additions & 3 deletions apps/docs/content/guides/auth/oauth-server/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,22 @@ Store the client secret securely. It will only be shown once. If you lose it, yo

</Admonition>

#### Token endpoint authentication method

When a client exchanges an authorization code or refreshes a token, it must authenticate with the token endpoint. The `token_endpoint_auth_method` controls how this authentication happens:

| Method | Description | Used by |
| --- | --- | --- |
| `none` | No client authentication. Only `client_id` is sent in the request body. | Public clients (required) |
| `client_secret_basic` | Client credentials sent via HTTP Basic auth (`Authorization: Basic <base64(client_id:client_secret)>`). **This is the default for confidential clients.** | Confidential clients |
| `client_secret_post` | Client credentials sent in the request body (`client_id` and `client_secret` as form parameters). | Confidential clients |

**Defaults:** Public clients default to `none`. Confidential clients default to `client_secret_basic` (per [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591#section-2)).

**Constraints:** Public clients must use `none`. Confidential clients cannot use `none`.

You can set this when registering a client via the dashboard or programmatically. See [OAuth Flows](/docs/guides/auth/oauth-server/oauth-flows#step-5-token-exchange) for examples of each method in action.

</TabPanel>
<TabPanel id="programmatically" label="Programmatically">

Expand Down Expand Up @@ -518,6 +534,8 @@ const { data, error } = await supabase.auth.admin.oauth.createClient({
name: 'My Third-Party App',
redirect_uris: ['https://my-app.com/auth/callback', 'https://my-app.com/auth/silent-callback'],
client_type: 'confidential',
// Optional: defaults to 'client_secret_basic' for confidential, 'none' for public
token_endpoint_auth_method: 'client_secret_basic',
})

if (error) {
Expand Down Expand Up @@ -548,7 +566,9 @@ response = supabase.auth.admin.oauth.create_client({
'https://my-app.com/auth/callback',
'https://my-app.com/auth/silent-callback'
],
'client_type': 'confidential'
'client_type': 'confidential',
# Optional: defaults to 'client_secret_basic' for confidential, 'none' for public
'token_endpoint_auth_method': 'client_secret_basic'
})

print('Client created:', response)
Expand All @@ -572,7 +592,8 @@ curl -X POST 'https://<project-ref>.supabase.co/auth/v1/admin/oauth/clients' \
"https://my-app.com/auth/callback",
"https://my-app.com/auth/silent-callback"
],
"client_type": "confidential"
"client_type": "confidential",
"token_endpoint_auth_method": "client_secret_basic"
}'
```

Expand All @@ -585,7 +606,8 @@ curl -X POST 'http://localhost:54321/auth/v1/admin/oauth/clients' \
-d '{
"name": "Local Dev App",
"redirect_uris": ["http://localhost:3000/auth/callback"],
"client_type": "confidential"
"client_type": "confidential",
"token_endpoint_auth_method": "client_secret_post"
}'
```

Expand All @@ -598,6 +620,7 @@ Response:
"name": "My Third-Party App",
"redirect_uris": ["https://my-app.com/auth/callback", "https://my-app.com/auth/silent-callback"],
"client_type": "confidential",
"token_endpoint_auth_method": "client_secret_basic",
"created_at": "2025-01-15T10:30:00.000Z"
}
```
Expand Down
101 changes: 96 additions & 5 deletions apps/docs/content/guides/auth/oauth-server/oauth-flows.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,11 @@ The error parameters allow clients to display relevant error messages to users:

### Step 5: Token exchange

The client exchanges the authorization code for tokens by making a POST request to the token endpoint:
The client exchanges the authorization code for tokens by making a POST request to the token endpoint. How the client authenticates depends on its `token_endpoint_auth_method` (set during [client registration](/docs/guides/auth/oauth-server/getting-started#token-endpoint-authentication-method)).

#### Public clients (`token_endpoint_auth_method: none`)

Public clients send only the `client_id` in the request body with no secret:

```bash
curl -X POST 'https://<project-ref>.supabase.co/auth/v1/oauth/token' \
Expand All @@ -242,7 +246,29 @@ curl -X POST 'https://<project-ref>.supabase.co/auth/v1/oauth/token' \
-d 'code_verifier=<code-verifier>'
```

For confidential clients (with client secret):
#### Confidential clients (`token_endpoint_auth_method: client_secret_basic`)

This is the **default** for confidential clients. Credentials are sent via the `Authorization` header using HTTP Basic authentication (base64-encoded `client_id:client_secret`):

```bash
curl -X POST 'https://<project-ref>.supabase.co/auth/v1/oauth/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-u '<client-id>:<client-secret>' \
-d 'grant_type=authorization_code' \
-d 'code=<authorization-code>' \
-d 'redirect_uri=<redirect-uri>' \
-d 'code_verifier=<code-verifier>'
```

<Admonition type="note">

The `-u` flag in cURL automatically encodes the credentials and sets the `Authorization: Basic <base64(client_id:client_secret)>` header. If you're not using cURL, you must base64-encode the `client_id:client_secret` string yourself.

</Admonition>

#### Confidential clients (`token_endpoint_auth_method: client_secret_post`)

Credentials are sent as form parameters in the request body:

```bash
curl -X POST 'https://<project-ref>.supabase.co/auth/v1/oauth/token' \
Expand All @@ -261,7 +287,37 @@ curl -X POST 'https://<project-ref>.supabase.co/auth/v1/oauth/token' \
// Retrieve the code verifier from storage
const codeVerifier = sessionStorage.getItem('code_verifier')

// Exchange code for tokens
// --- Public clients (token_endpoint_auth_method: none) ---
const response = await fetch(`https://<project-ref>.supabase.co/auth/v1/oauth/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'authorization_code',
code: authorizationCode,
client_id: '<client-id>',
redirect_uri: '<redirect-uri>',
code_verifier: codeVerifier,
}),
})

// --- Confidential clients (token_endpoint_auth_method: client_secret_basic) ---
const response = await fetch(`https://<project-ref>.supabase.co/auth/v1/oauth/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Basic ' + btoa('<client-id>:<client-secret>'),
},
body: new URLSearchParams({
grant_type: 'authorization_code',
code: authorizationCode,
redirect_uri: '<redirect-uri>',
code_verifier: codeVerifier,
}),
})

// --- Confidential clients (token_endpoint_auth_method: client_secret_post) ---
const response = await fetch(`https://<project-ref>.supabase.co/auth/v1/oauth/token`, {
method: 'POST',
headers: {
Expand All @@ -271,6 +327,7 @@ const response = await fetch(`https://<project-ref>.supabase.co/auth/v1/oauth/to
grant_type: 'authorization_code',
code: authorizationCode,
client_id: '<client-id>',
client_secret: '<client-secret>',
redirect_uri: '<redirect-uri>',
code_verifier: codeVerifier,
}),
Expand Down Expand Up @@ -377,7 +434,9 @@ Clients should refresh access tokens when:

### Refresh request

Make a POST request to the token endpoint with the refresh token:
Make a POST request to the token endpoint with the refresh token. The client authenticates the same way as during the [token exchange](#step-5-token-exchange), based on its `token_endpoint_auth_method`.

#### Public clients (`token_endpoint_auth_method: none`)

```bash
curl -X POST 'https://<project-ref>.supabase.co/auth/v1/oauth/token' \
Expand All @@ -387,7 +446,17 @@ curl -X POST 'https://<project-ref>.supabase.co/auth/v1/oauth/token' \
-d 'client_id=<client-id>'
```

For confidential clients:
#### Confidential clients (`token_endpoint_auth_method: client_secret_basic`)

```bash
curl -X POST 'https://<project-ref>.supabase.co/auth/v1/oauth/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-u '<client-id>:<client-secret>' \
-d 'grant_type=refresh_token' \
-d 'refresh_token=<refresh-token>'
```

#### Confidential clients (`token_endpoint_auth_method: client_secret_post`)

```bash
curl -X POST 'https://<project-ref>.supabase.co/auth/v1/oauth/token' \
Expand All @@ -401,6 +470,7 @@ curl -X POST 'https://<project-ref>.supabase.co/auth/v1/oauth/token' \
#### Example in JavaScript

```javascript
// Public clients (token_endpoint_auth_method: none)
async function refreshAccessToken(refreshToken) {
const response = await fetch(`https://<project-ref>.supabase.co/auth/v1/oauth/token`, {
method: 'POST',
Expand All @@ -420,6 +490,27 @@ async function refreshAccessToken(refreshToken) {

return await response.json()
}

// Confidential clients (token_endpoint_auth_method: client_secret_basic)
async function refreshAccessTokenConfidential(refreshToken) {
const response = await fetch(`https://<project-ref>.supabase.co/auth/v1/oauth/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Basic ' + btoa('<client-id>:<client-secret>'),
},
body: new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: refreshToken,
}),
})

if (!response.ok) {
throw new Error('Failed to refresh token')
}

return await response.json()
}
```

### Refresh response
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/guides/auth/social-login/auth-google.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Supabase Auth needs a few scopes granting access to profile data of your end use

- `openid` (add manually)
- `.../auth/userinfo.email` (added by default)
- `...auth/userinfo.profile` (added by default)
- `.../auth/userinfo.profile` (added by default)

If you add more scopes, especially those on the sensitive or restricted list your application might be subject to verification which may take a long time.

Expand Down
6 changes: 3 additions & 3 deletions apps/docs/content/guides/database/connection-management.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ These numbers are generalizations and depends on other Supabase products that yo
<Image
alt="Database client connections chart"

src={{
src={{
dark: '/docs/img/database/reports/db-connections-chart-dark.png',
light: '/docs/img/database/reports/db-connections-chart-light.png',
}}
width={2062}
height={608}
width={2062}
height={608}
/>

For Teams and Enterprise plans, Supabase provides Advanced Telemetry charts directly within the Dashboard. The `Database client connections` chart displays historical connection data broken down by connection type:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ Wrappers introduce some new terminology and different workflows.
<Image
alt="Foreign Data Wrappers (FDW)"

src={{
src={{
dark: '/docs/img/database/foreign-data-wrappers/extracting-data.png',
light: '/docs/img/database/foreign-data-wrappers/extracting-data--light.png',
}}
width={1600}
height={929}
width={1600}
height={929}
/>

### Remote servers
Expand Down Expand Up @@ -117,12 +117,12 @@ select cron.schedule(
<Image
alt="FDW with pg_cron"

src={{
src={{
dark: '/docs/img/database/foreign-data-wrappers/extracting-data-pgcron.png',
light: '/docs/img/database/foreign-data-wrappers/extracting-data-pgcron--light.png',
}}
width={1600}
height={929}
width={1600}
height={929}
/>

This process can be taxing on your database if you are moving large amounts of data. Often, it's better to use an external tool for batch ETL, such as [Fivetran](https://fivetran.com/) or [Airbyte](https://airbyte.io/).
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/guides/database/orioledb.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ To get started with OrioleDB you need to [create a new Supabase project](/dashbo
}}
className="max-w-[550px] !mx-auto border rounded-md"

width={1376}
height={2034}
width={1376}
height={2034}
/>

### Creating tables
Expand Down
6 changes: 3 additions & 3 deletions apps/docs/content/guides/database/postgres/indexes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ Here is a simplified diagram of the index we just created (note that in practice
<Image
alt="B-Tree index example in Postgres"

src={{
src={{
dark: '/docs/img/database/managing-indexes/creating-indexes.png',
light: '/docs/img/database/managing-indexes/creating-indexes--light.png',
}}
width={1600}
height={1091}
width={1600}
height={1091}
/>

You can see that in any large data set, traversing the index to locate a given value can be done in much less operations (O(log n)) than compared to scanning the table one value at a time from top to bottom (O(n)).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ To monitor your replication pipelines:
alt="Destinations List"
src="/docs/img/database/replication/replication-destinations-list.png"

width={3560}
height={2146}
width={3560}
height={2146}
/>

#### Pipeline states
Expand All @@ -50,8 +50,8 @@ For detailed information about a specific pipeline, click **View status** on the
alt="Pipeline Status View"
src="/docs/img/database/replication/replication-view-status.png"

width={3560}
height={2146}
width={3560}
height={2146}
/>

#### Replication lag metrics
Expand Down Expand Up @@ -82,8 +82,8 @@ Table errors occur during the copy phase and affect individual tables. These err
alt="Table Error Details"
src="/docs/img/database/replication/replication-pipeline-table-error.png"

width={3560}
height={2146}
width={3560}
height={2146}
/>

**Viewing table error details:**
Expand All @@ -110,8 +110,8 @@ When a pipeline error occurs, you'll receive an email notification immediately.
alt="Pipeline Error Details"
src="/docs/img/database/replication/replication-pipeline-error.png"

width={3560}
height={2146}
width={3560}
height={2146}
/>

**Viewing pipeline error details:**
Expand Down
Loading
Loading