Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
5 changes: 5 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Add 'documentation' to any change in apps/docs
# https://github.com/marketplace/actions/labeler
documentation:
- changed-files:
- any-glob-to-any-file: 'apps/docs/**/*'
16 changes: 16 additions & 0 deletions .github/workflows/label_prs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: 'Pull Request Labeler'

# only docs uses the labeler at the moment
on:
pull_request_target:
paths:
- 'apps/docs/**/*'

jobs:
labeler:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v6
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ export const auth: NavMenuConstant = {
enabled: allAuthProvidersEnabled,
},
{
name: 'Web3 (Sign in with Solana)',
name: 'Web3 (Ethereum or Solana)',
url: '/guides/auth/auth-web3',
enabled: allAuthProvidersEnabled,
},
Expand Down
6 changes: 3 additions & 3 deletions apps/docs/content/guides/ai.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,10 @@ export const integrations = [
href: 'https://supabase.com/customers/berriai',
},
{
name: 'Mendable switches from Pinecone to Supabase for PostgreSQL vector embeddings',
name: 'Firecrawl switches from Pinecone to Supabase for PostgreSQL vector embeddings',
description:
'How Mendable boosts efficiency and accuracy of chat powered search for documentation using Supabase with pgvector',
href: 'https://supabase.com/customers/mendableai',
'How Firecrawl boosts efficiency and accuracy of chat powered search for documentation using Supabase with pgvector',
href: 'https://supabase.com/customers/firecrawl',
},
{
name: 'Markprompt: GDPR-Compliant AI Chatbots for Docs and Websites',
Expand Down
97 changes: 92 additions & 5 deletions apps/docs/content/guides/auth/auth-web3.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,43 @@ subtitle: 'Use your Web3 wallet to authenticate users with Supabase'
Supported Web3 wallets:

- All Solana wallets
- Coming soon: All Ethereum wallets
- All Ethereum wallets

## How does it work?

Sign in with Web3 utilizes the [EIP 4361](https://eips.ethereum.org/EIPS/eip-4361) standard to authenticate wallet addresses off-chain. This standard is adopted by the Solana ecosystem with some minor differences from Ethereum.
Sign in with Web3 utilizes the [EIP 4361](https://eips.ethereum.org/EIPS/eip-4361) standard to authenticate wallet addresses off-chain. This standard is widely supported by the Ethereum and Solana ecosystems, making it the best choice for verifying wallet ownership.

Authentication works by asking the Web3 wallet application to sign a predefined message with the user's wallet. This message is parsed both by the Web3 wallet application and Supabase Auth to verify its validity and purpose, before creating a user account or session.

The Web3 wallet application uses the information contained in the message to provide the user with a confirmation dialog, asking whether they want to allow sign in with your project.
An example of such a message is:

Not all Web3 wallet applications show a dedicated confirmation dialog for these sign in messages. In that case the Web3 wallet shows a traditional message signature confirmation dialog.
```
example.com wants you to sign in with your Ethereum account:
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2

I accept the ExampleOrg Terms of Service: https://example.com/tos

URI: https://example.com/login
Version: 1
Chain ID: 1
Nonce: 32891756
Issued At: 2021-09-30T16:25:24Z
Resources:
- https://example.com/my-web2-claim.json
```

It defines the wallet address, timestamp, browser location where the sign-in occurred and includes a customizable statement (`I accept...`) which you can use to ask consent from the user.

Most Web3 wallets are able to recognize these messages and show a dedicated "Confirm Sign In" dialog validating and presenting the information in the message in a secure and responsible way to the user. Even if the wallet does not directly support these messages, it will use the message signature dialog instead.

Finally the Supabase Auth server validates both the message's contents and signature before issuing a valid [User session](/docs/guides/auth/sessions) to your application. Validation rules include:

- Message structure validation
- Cryptographic signature verification
- Timestamp validation, ensuring the signature was created within 10 minutes of the sign-in call
- URI and Domain validation, ensuring these match your server's defined [Redirect URLs](/docs/guides/auth/redirect-urls)

The wallet address is used as the identity identifier, and in the identity data you can also find the statement and additional metadata.

## Enable the Web3 provider

Expand All @@ -30,6 +56,9 @@ In the CLI add the following config to your `supabase/config.toml` file:
```toml
[auth.web3.solana]
enabled = true

[auth.web3.ethereum]
enabled = true
```

### Potential for abuse
Expand Down Expand Up @@ -63,7 +92,65 @@ For example if the user is signing in to the page `https://example.com/sign-in`

## Sign in with Ethereum

Sign in with Ethereum wallets is coming soon.
Ethereum defines the [`window.ethereum` global scope object](https://eips.ethereum.org/EIPS/eip-1193) that your app uses to interact with Ethereum Wallets. Additionally there is a [wallet discovery mechanism (EIP-6963)](https://eips.ethereum.org/EIPS/eip-6963) that your app can use to discover all of the available wallets on the user's browser.

To sign in a user with their Ethereum wallet make sure that the user has installed a wallet application. There are two ways to do this:

1. Detect the `window.ethereum` global scope object and ensure it's defined. This only works if your user has only one wallet installed on their browser.
2. Use the wallet discovery mechanism (EIP-6963) to ask the user to choose a wallet before they continue to sign in. Read [the MetaMask guide on the best way to support this](https://docs.metamask.io/wallet/tutorials/react-dapp-local-state).

<Tabs
scrollable
size="small"
type="underlined"
defaultActiveId="window"
queryGroup="ethWallet"
>

<TabPanel id="window" label="Ethereum Window API (EIP-1193)">

Use the following code to sign in a user, implicitly relying on the `window.ethereum` global scope wallet API:

```typescript
const { data, error } = await supabase.auth.signInWithWeb3({
chain: 'ethereum',
statement: 'I accept the Terms of Service at https://example.com/tos',
})
```

</TabPanel>

<TabPanel id="wallet" label="Ethereum Wallet API (EIP-6963)">

Once you've obtained a wallet using the wallet detection (EIP-6963) mechanism, you can pass the selected wallet to the Supabase JavaScript SDK to continue the sign-in process.

```typescript
const { data, error } = await supabase.auth.signInWithWeb3({
chain: 'ethereum',
statement: 'I accept the Terms of Service at https://example.com/tos',
wallet: selectedWallet, // obtain this using the EIP-6963 mechanism
})
```

An excellent guide on using the [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) mechanism is available by [MetaMask](https://docs.metamask.io/wallet/tutorials/react-dapp-local-state).

</TabPanel>

<TabPanel id="custom" label="Ethereum Message and Signature">

If your application relies on a custom Ethereum wallet API, you can pass a [Sign in with Ethereum (EIP-4361)](https://eips.ethereum.org/EIPS/eip-4361) message and signature to complete the sign in process.

```typescript
const { data, error } = await supabase.auth.signInWithWeb3({
chain: 'ethereum',
message: '<sign in with ethereum message>',
signature: '<hex of the ethereum signature over the message>',
})
```

</TabPanel>

</Tabs>

## Sign in with Solana

Expand Down
7 changes: 6 additions & 1 deletion apps/docs/content/guides/telemetry/metrics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Your project's metrics endpoint is accessible at `https://<project-ref>.supabase
Access to the endpoint is secured via HTTP Basic Auth:

- username: `service_role`
- password: the service role JWT from the [Supabase dashboard](/dashboard/project/_/settings/api-keys)
- password: the `service_role` API key or any other secret API key, get these from [Supabase dashboard](/dashboard/project/_/settings/api-keys)

You can also retrieve your service role key programmatically using the Management API:

Expand All @@ -43,6 +43,11 @@ curl -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \

<ProjectConfigVariables variable="url" />

```shell
curl <project-url>/customer/v1/privileged/metrics \
--user 'service_role:sb_secret_...'
```

```shell
curl <project-url>/customer/v1/privileged/metrics \
--user 'service_role:<service-role-jwt>'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16313,7 +16313,7 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
},
"isOptional": true,
"comment": {
"shortText": "Optional statement to include in the Sign in with Solana message. Must not include new line characters. Most wallets like Phantom **require specifying a statement!**"
"shortText": "Optional statement to include in the Sign in with Ethereum message. Must not include new line characters. Most wallets like Phantom **require specifying a statement!**"
}
},
{
Expand All @@ -16324,7 +16324,7 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
},
"isOptional": true,
"comment": {
"shortText": "Wallet interface to use. If not specified will default to \`window.solana\`."
"shortText": "Wallet interface to use. If not specified will default to \`window.ethereum\`."
}
}
]
Expand Down Expand Up @@ -16376,7 +16376,7 @@ exports[`TS type spec parsing > matches snapshot 1`] = `
"name": "Hex"
},
"comment": {
"shortText": "Ed25519 signature of the message."
"shortText": "Ethereum curve (secp256k1) signature of the message."
}
}
]
Expand Down
16 changes: 12 additions & 4 deletions apps/docs/spec/api_v1_openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -4846,7 +4846,8 @@
"type": "object",
"properties": { "id": { "type": "number" }, "username": { "type": "string" } },
"required": ["id", "username"]
}
},
"favorite": { "type": "boolean" }
},
"required": [
"id",
Expand All @@ -4858,7 +4859,8 @@
"description",
"project",
"owner",
"updated_by"
"updated_by",
"favorite"
]
}
},
Expand Down Expand Up @@ -4891,14 +4893,19 @@
"properties": { "id": { "type": "number" }, "username": { "type": "string" } },
"required": ["id", "username"]
},
"favorite": { "type": "boolean" },
"content": {
"type": "object",
"properties": {
"favorite": { "type": "boolean" },
"favorite": {
"type": "boolean",
"deprecated": true,
"description": "Deprecated: Rely on root-level favorite property instead."
},
"schema_version": { "type": "string" },
"sql": { "type": "string" }
},
"required": ["favorite", "schema_version", "sql"]
"required": ["schema_version", "sql"]
}
},
"required": [
Expand All @@ -4912,6 +4919,7 @@
"project",
"owner",
"updated_by",
"favorite",
"content"
]
},
Expand Down
9 changes: 8 additions & 1 deletion apps/docs/spec/common-client-libs-sections.json
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@
},
{
"id": "sign-in-with-id-token",
"title": "Sign in with ID Token",
"title": "Sign in with ID token (native sign-in)",
"slug": "auth-signinwithidtoken",
"product": "auth",
"type": "function"
Expand Down Expand Up @@ -490,6 +490,13 @@
"product": "auth",
"type": "function"
},
{
"id": "sign-in-with-web3",
"title": "Sign in a user through Web3 (Solana, Ethereum)",
"slug": "auth-signinwithweb3",
"product": "auth",
"type": "function"
},
{
"id": "get-claims",
"title": "Get user claims from verified JWT",
Expand Down
Loading
Loading