Clerk
You can enable the Clerk wrapper right from the Supabase dashboard.
Open wrapper in dashboardClerk is a complete suite of embeddable UIs, flexible APIs, and admin dashboards to authenticate and manage users.
The Clerk Wrapper is a WebAssembly(Wasm) foreign data wrapper which allows you to read data from Clerk for use within your Postgres database.
Available Versions#
| Version | Wasm Package URL | Checksum | Required Wrappers Version |
|---|---|---|---|
| 0.2.2 | https://github.com/supabase/wrappers/releases/download/wasm_clerk_fdw_v0.2.2/clerk_fdw.wasm | tbd | >=0.5.0 |
| 0.2.1 | https://github.com/supabase/wrappers/releases/download/wasm_clerk_fdw_v0.2.1/clerk_fdw.wasm | 100f3f105e7e6dab92c433b2da6bec98fafeccd0304e6efaf3780d0a8cae30ec | >=0.5.0 |
| 0.2.0 | https://github.com/supabase/wrappers/releases/download/wasm_clerk_fdw_v0.2.0/clerk_fdw.wasm | 89337bb11779d4d654cd3e54391aabd02509d213db6995f7dd58951774bf0e37 | >=0.5.0 |
| 0.1.0 | https://github.com/supabase/wrappers/releases/download/wasm_clerk_fdw_v0.1.0/clerk_fdw.wasm | 613be26b59fa4c074e0b93f0db617fcd7b468d4d02edece0b1f85fdb683ebdc4 | >=0.4.0 |
Preparation#
Before you can query Clerk, you need to enable the Wrappers extension and store your credentials in Postgres.
Enable Wrappers#
Make sure the wrappers extension is installed on your database:
1create extension if not exists wrappers with schema extensions;Enable the Clerk Wrapper#
Enable the Wasm foreign data wrapper:
1create foreign data wrapper wasm_wrapper2 handler wasm_fdw_handler3 validator wasm_fdw_validator;Store your credentials (optional)#
By default, Postgres stores FDW credentials inside pg_catalog.pg_foreign_server in plain text. Anyone with access to this table will be able to view these credentials. Wrappers is designed to work with Vault, which provides an additional level of security for storing credentials. We recommend using Vault to store your credentials.
1-- Save your Clerk API key in Vault and retrieve the created `key_id`2select vault.create_secret(3 '<Clerk API key>', -- Clerk API key4 'clerk',5 'Clerk API key for Wrappers'6);Connecting to Clerk#
We need to provide Postgres with the credentials to access Clerk and any additional options. We can do this using the create server command:
1create server clerk_server2 foreign data wrapper wasm_wrapper3 options (4 fdw_package_url 'https://github.com/supabase/wrappers/releases/download/wasm_clerk_fdw_v0.2.2/clerk_fdw.wasm',5 fdw_package_name 'supabase:clerk-fdw',6 fdw_package_version '0.2.2',7 fdw_package_checksum 'tbd',8 api_url 'https://api.clerk.com/v1', -- optional9 api_key_id '<key_ID>' -- The Key ID from above.10 );Note the fdw_package_* options are required, which specify the Wasm package metadata. You can get the available package version list from above.
Create a schema#
We recommend creating a schema to hold all the foreign tables:
1create schema if not exists clerk;Options#
The full list of foreign table options are below:
object- Object name in Clerk, required.
Supported objects are listed below:
| Object name |
|---|
| allowlist_identifiers |
| billing_payment_attempts |
| billing_plans |
| billing_statement |
| billing_statements |
| billing_subscription_items |
| blocklist_identifiers |
| domains |
| invitations |
| jwt_templates |
| oauth_applications |
| organizations |
| organization_billing_subscriptions |
| organization_invitations |
| organization_memberships |
| redirect_urls |
| saml_connections |
| user_billing_subscriptions |
| users |
Entities#
We can use SQL import foreign schema to import foreign table definitions from Clerk.
For example, using below SQL can automatically create foreign tables in the clerk schema.
1-- create all the foreign tables2import foreign schema clerk from server clerk_server into clerk;34-- or, create selected tables only5import foreign schema clerk6 limit to ("users", "organizations")7 from server clerk_server into clerk;89-- or, create all foreign tables except selected tables10import foreign schema clerk11 except ("users")12 from server clerk_server into clerk;Allow-list#
This is a list of all identifiers allowed to sign up to an instance.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| allowlist_identifiers | ✅ | ✅ | ❌ | ✅ | ❌ |
Usage#
1create foreign table clerk.allowlist_identifiers (2 id text,3 invitation_id text,4 identifier text,5 identifier_type text,6 instance_id text,7 created_at timestamp,8 updated_at timestamp,9 attrs jsonb10)11 server clerk_server12 options (13 object 'allowlist_identifiers',14 rowid_column 'id'15 );Notes#
- The
attrscolumn contains additional attributes in JSON format
Block-list#
This is a list of all identifiers which are not allowed to access an instance.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| blocklist_identifiers | ✅ | ✅ | ❌ | ✅ | ❌ |
Usage#
1create foreign table clerk.blocklist_identifiers (2 id text,3 identifier text,4 identifier_type text,5 instance_id text,6 created_at timestamp,7 updated_at timestamp,8 attrs jsonb9)10 server clerk_server11 options (12 object 'blocklist_identifiers',13 rowid_column 'id'14 );Notes#
- The
attrscolumn contains additional attributes in JSON format
Domains#
This is a list of all domains for an instance.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| domains | ✅ | ❌ | ✅ | ✅ | ❌ |
Usage#
1create foreign table clerk.domains (2 id text,3 name text,4 is_satellite boolean,5 frontend_api_url text,6 accounts_portal_url text,7 attrs jsonb8)9 server clerk_server10 options (11 object 'domains',12 rowid_column 'id'13 );Notes#
- The
attrscolumn contains additional attributes in JSON format
Invitations#
This is a list of all non-revoked invitations for your application.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| invitations | ✅ | ✅ | ❌ | ❌ | ❌ |
Usage#
1create foreign table clerk.invitations (2 id text,3 email_address text,4 url text,5 revoked boolean,6 status text,7 expires_at timestamp,8 created_at timestamp,9 updated_at timestamp,10 attrs jsonb11)12 server clerk_server13 options (14 object 'invitations',15 rowid_column 'id'16 );Notes#
- The
attrscolumn contains additional attributes in JSON format
JWT Templates#
This is a list of all JWT templates.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| jwt_templates | ✅ | ✅ | ✅ | ✅ | ❌ |
Usage#
1create foreign table clerk.jwt_templates (2 id text,3 name text,4 lifetime bigint,5 allowed_clock_skew bigint,6 custom_signing_key boolean,7 signing_algorithm text,8 created_at timestamp,9 updated_at timestamp,10 attrs jsonb11)12 server clerk_server13 options (14 object 'jwt_templates',15 rowid_column 'id'16 );Notes#
- The
attrscolumn contains additional attributes in JSON format - Single-item retrieval is supported via
WHERE id = 'xxx'clause, which fetches fromGET /jwt_templates/{template_id}endpoint
OAuth Applications#
This is a list of OAuth applications for an instance.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| oauth_applications | ✅ | ✅ | ✅ | ✅ | ❌ |
Usage#
1create foreign table clerk.oauth_applications (2 id text,3 name text,4 instance_id text,5 client_id text,6 public boolean,7 scopes text,8 created_at timestamp,9 updated_at timestamp,10 attrs jsonb11)12 server clerk_server13 options (14 object 'oauth_applications',15 rowid_column 'id'16 );Notes#
- The
attrscolumn contains additional attributes in JSON format - Single-item retrieval is supported via
WHERE id = 'xxx'clause, which fetches fromGET /oauth_applications/{oauth_application_id}endpoint
Organizations#
This is a list of organizations for an instance.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| organizations | ✅ | ✅ | ✅ | ✅ | ❌ |
Usage#
1create foreign table clerk.organizations (2 id text,3 name text,4 slug text,5 created_at timestamp,6 updated_at timestamp,7 attrs jsonb8)9 server clerk_server10 options (11 object 'organizations',12 rowid_column 'id'13 );Notes#
- The
attrscolumn contains additional attributes in JSON format - Single-item retrieval is supported via
WHERE id = 'xxx'clause, which fetches fromGET /organizations/{organization_id}endpoint
Organization Invitations#
This is a list of organization invitations for an instance.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| organization_invitations | ✅ | ❌ | ❌ | ❌ | ❌ |
Usage#
1create foreign table clerk.organization_invitations (2 id text,3 email_address text,4 role text,5 role_name text,6 organization_id text,7 status text,8 created_at timestamp,9 updated_at timestamp,10 attrs jsonb11)12 server clerk_server13 options (14 object 'organization_invitations'15 );Notes#
- The
attrscolumn contains additional attributes in JSON format
Organization Memberships#
This is a list of organization user memberships for an instance.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| organization_memberships | ✅ | ❌ | ❌ | ❌ | ❌ |
Usage#
1create foreign table clerk.organization_memberships (2 id text,3 role text,4 role_name text,5 created_at timestamp,6 updated_at timestamp,7 attrs jsonb8)9 server clerk_server10 options (11 object 'organization_memberships'12 );Notes#
- The
attrscolumn contains additional attributes in JSON format - Single-item retrieval is supported via
WHERE id = 'xxx'clause, which fetches fromGET /oauth_applications/{oauth_application_id}endpoint
Redirect URLs#
This is a list of all whitelisted redirect urls for the instance.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| redirect_urls | ✅ | ✅ | ❌ | ✅ | ❌ |
Usage#
1create foreign table clerk.redirect_urls (2 id text,3 url text,4 created_at timestamp,5 updated_at timestamp,6 attrs jsonb7)8 server clerk_server9 options (10 object 'redirect_urls',11 rowid_column 'id'12 );Notes#
- The
attrscolumn contains additional attributes in JSON format - Single-item retrieval is supported via
WHERE id = 'xxx'clause, which fetches fromGET /redirect_urls/{id}endpoint
SAML Connections#
This is a list of SAML Connections for an instance.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| saml_connections | ✅ | ✅ | ✅ | ✅ | ❌ |
Usage#
1create foreign table clerk.saml_connections (2 id text,3 name text,4 domain text,5 active boolean,6 provider text,7 user_count bigint,8 created_at timestamp,9 updated_at timestamp,10 attrs jsonb11)12 server clerk_server13 options (14 object 'saml_connections',15 rowid_column 'id'16 );Notes#
- The
attrscolumn contains additional attributes in JSON format - Single-item retrieval is supported via
WHERE id = 'xxx'clause, which fetches fromGET /saml_connections/{saml_connection_id}endpoint
Users#
This is a list of all users.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| users | ✅ | ✅ | ✅ | ✅ | ❌ |
Usage#
1create foreign table clerk.users (2 id text,3 external_id text,4 username text,5 first_name text,6 last_name text,7 created_at timestamp,8 updated_at timestamp,9 attrs jsonb10)11 server clerk_server12 options (13 object 'users',14 rowid_column 'id'15 );Notes#
- The
attrscolumn contains additional attributes in JSON format - Single-item retrieval is supported via
WHERE id = 'xxx'clause, which fetches fromGET /users/{user_id}endpoint
User Billing Subscriptions#
This retrieves the billing subscription for a specific user.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| users/billing/subscription | ✅ | ❌ | ❌ | ❌ | ❌ |
Usage#
1create foreign table clerk.user_billing_subscriptions (2 user_id text,3 id text,4 status text,5 payer_id text,6 created_at timestamp,7 updated_at timestamp,8 attrs jsonb9)10 server clerk_server11 options (12 object 'users/billing/subscription'13 );Notes#
- The
attrscolumn contains additional attributes in JSON format - The query must specify
user_idin the WHERE clause
Organization Billing Subscriptions#
This retrieves the billing subscription for a specific organization.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| organizations/billing/subscription | ✅ | ❌ | ❌ | ❌ | ❌ |
Usage#
1create foreign table clerk.organization_billing_subscriptions (2 organization_id text,3 id text,4 status text,5 payer_id text,6 created_at timestamp,7 updated_at timestamp,8 attrs jsonb9)10 server clerk_server11 options (12 object 'organizations/billing/subscription'13 );Notes#
- The
attrscolumn contains additional attributes in JSON format - The query must specify
organization_idin the WHERE clause
Billing Plans#
This is a list of all billing plans.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| billing/plans | ✅ | ❌ | ❌ | ❌ | ❌ |
Usage#
1create foreign table clerk.billing_plans (2 id text,3 name text,4 description text,5 slug text,6 is_default boolean,7 is_recurring boolean,8 attrs jsonb9)10 server clerk_server11 options (12 object 'billing/plans'13 );Notes#
- The
attrscolumn contains additional attributes in JSON format
Billing Subscription Items#
This is a list of all billing subscription items.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| billing/subscription_items | ✅ | ❌ | ❌ | ❌ | ❌ |
Usage#
1create foreign table clerk.billing_subscription_items (2 id text,3 status text,4 plan_id text,5 plan_period text,6 payer_id text,7 is_free_trial boolean,8 created_at timestamp,9 updated_at timestamp,10 attrs jsonb11)12 server clerk_server13 options (14 object 'billing/subscription_items'15 );Notes#
- The
attrscolumn contains additional attributes in JSON format
Billing Statements#
This is a list of all billing statements.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| billing/statements | ✅ | ❌ | ❌ | ❌ | ❌ |
Usage#
1create foreign table clerk.billing_statements (2 id text,3 status text,4 timestamp timestamp,5 attrs jsonb6)7 server clerk_server8 options (9 object 'billing/statements'10 );Notes#
- The
attrscolumn contains additional attributes in JSON format
Billing Statement#
This retrieves a specific billing statement by ID.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| billing/statement | ✅ | ❌ | ❌ | ❌ | ❌ |
Usage#
1create foreign table clerk.billing_statement (2 statement_id text,3 id text,4 status text,5 timestamp timestamp,6 attrs jsonb7)8 server clerk_server9 options (10 object 'billing/statement'11 );Notes#
- The
attrscolumn contains additional attributes in JSON format - The query must specify
statement_idin the WHERE clause
Billing Payment Attempts#
This retrieves payment attempts for a specific billing statement.
Ref: Clerk API docs
Operations#
| Object | Select | Insert | Update | Delete | Truncate |
|---|---|---|---|---|---|
| billing/payment_attempts | ✅ | ❌ | ❌ | ❌ | ❌ |
Usage#
1create foreign table clerk.billing_payment_attempts (2 statement_id text,3 id text,4 status text,5 created_at timestamp,6 updated_at timestamp,7 attrs jsonb8)9 server clerk_server10 options (11 object 'billing/payment_attempts'12 );Notes#
- The
attrscolumn contains additional attributes in JSON format - The query must specify
statement_idin the WHERE clause
Query Pushdown Support#
where clause pushdown#
This FDW supports where id = 'xxx' clause pushdown for the following objects:
- users
- organizations
- jwt_templates
- oauth_applications
- saml_connections
- redirect_urls
For example:
1-- Fetches from GET /users/user_xxx (single API call)2select * from clerk.users where id = 'user_xxx';Parameterized endpoints#
Some endpoints require specific qualifiers in the WHERE clause:
| Object | Required qualifier |
|---|---|
| user_billing_subscriptions | user_id |
| organization_billing_subscriptions | organization_id |
| billing_statement | statement_id |
| billing_payment_attempts | statement_id |
For example:
1-- Fetches from GET /users/{user_id}/billing/subscription2select * from clerk.user_billing_subscriptions where user_id = 'user_xxx';Supported Data Types#
| Postgres Data Type | Clerk Data Type |
|---|---|
| boolean | Boolean |
| bigint | Number |
| double precision | Number |
| text | String |
| timestamp | Time |
| jsonb | Json |
The Clerk API uses JSON formatted data, please refer to Clerk Backend API docs for more details.
Limitations#
This section describes important limitations and considerations when using this FDW:
- Large result sets may experience slower performance due to full data transfer requirement
- Materialized views using these foreign tables may fail during logical backups
Examples#
Below are some examples on how to use Clerk foreign tables.
Basic example#
This example will create a "foreign table" inside your Postgres database and query its data.
1create foreign table clerk.users (2 id text,3 external_id text,4 username text,5 first_name text,6 last_name text,7 created_at timestamp,8 updated_at timestamp,9 attrs jsonb10)11 server clerk_server12 options (13 object 'users',14 rowid_column 'id'15 );1617-- query all users (fetches from GET /users)18select * from clerk.users;1920-- retrieve a specific user by ID (fetches from GET /users/{user_id})21select * from clerk.users where id = 'user_xxx';attrs is a special column which stores all the object attributes in JSON format, you can extract any attributes needed from it. See more examples below.
Query JSON attributes#
1-- extract all email addresses from user2select3 u.id,4 e->>'email_address' as email5from clerk.users u6 cross join json_array_elements((attrs->'email_addresses')::json) e;Data Modify Examples#
Some tables support INSERT, UPDATE, and DELETE operations. Use the attrs JSONB column to provide the request body:
1-- Create a new user2INSERT INTO clerk.users (attrs) VALUES ('{"email_address": ["user@example.com"], "password": "secure123"}');34-- Update a user (requires rowid_column 'id')5UPDATE clerk.users SET attrs = '{"first_name": "John", "last_name": "Doe"}' WHERE id = 'user_xxx';67-- Delete a user (requires rowid_column 'id')8DELETE FROM clerk.users WHERE id = 'user_xxx';910-- Create a new organization11INSERT INTO clerk.organizations (attrs) VALUES ('{"name": "My Organization", "slug": "my-org"}');1213-- Update an organization14UPDATE clerk.organizations SET attrs = '{"name": "Updated Name"}' WHERE id = 'org_xxx';1516-- Delete an organization17DELETE FROM clerk.organizations WHERE id = 'org_xxx';Billing examples#
1-- Query all billing plans2SELECT * FROM clerk.billing_plans;34-- Query all billing statements5SELECT * FROM clerk.billing_statements;67-- Query all billing subscription items8SELECT * FROM clerk.billing_subscription_items;910-- Query a specific statement (requires WHERE clause)11SELECT * FROM clerk.billing_statement WHERE statement_id = 'stmt_xxx';1213-- Query payment attempts for a statement (requires WHERE clause)14SELECT * FROM clerk.billing_payment_attempts WHERE statement_id = 'stmt_xxx';1516-- Query subscription for a specific user (requires WHERE clause)17SELECT * FROM clerk.user_billing_subscriptions WHERE user_id = 'user_xxx';1819-- Query subscription for a specific organization (requires WHERE clause)20SELECT * FROM clerk.organization_billing_subscriptions WHERE organization_id = 'org_xxx';2122-- Retrieve a single user by ID (fetches from GET /users/{user_id})23SELECT * FROM clerk.users WHERE id = 'user_xxx';2425-- Retrieve a single organization by ID (fetches from GET /organizations/{organization_id})26SELECT * FROM clerk.organizations WHERE id = 'org_xxx';2728-- Retrieve a single JWT template by ID (fetches from GET /jwt_templates/{template_id})29SELECT * FROM clerk.jwt_templates WHERE id = 'tmpl_xxx';3031-- Retrieve a single OAuth application by ID (fetches from GET /oauth_applications/{oauth_application_id})32SELECT * FROM clerk.oauth_applications WHERE id = 'oauth_xxx';3334-- Retrieve a single SAML connection by ID (fetches from GET /saml_connections/{saml_connection_id})35SELECT * FROM clerk.saml_connections WHERE id = 'samlconn_xxx';3637-- Retrieve a single redirect URL by ID (fetches from GET /redirect_urls/{id})38SELECT * FROM clerk.redirect_urls WHERE id = 'redir_xxx';