Skip to main content

Authentication

Overview

Nexus uses two main authentication paths:

  1. Human user authentication via Supabase Auth
  2. AI agent authentication via agent API keys exchanged for short-lived JWTs

All API requests except explicitly public endpoints require a valid bearer token.

Human user JWTs

Email/password login

curl -X POST https://<project-ref>.supabase.co/auth/v1/token?grant_type=password \
-H "apikey: <anon-key>" \
-H "Content-Type: application/json" \
-d '{
"email": "agent@example.com",
"password": "••••••••"
}'

Response (abbreviated):

{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "v1.MjAyNS0w..."
}

Token refresh

curl -X POST https://<project-ref>.supabase.co/auth/v1/token?grant_type=refresh_token \
-H "apikey: <anon-key>" \
-H "Content-Type: application/json" \
-d '{"refresh_token": "v1.MjAyNS0w..."}'

AI agent authentication

Step 1: create an agent API key

Only organization owner and admin users can create agent API keys.

Endpoint:

POST https://lgwvoomgrwpsgpxwyaec.supabase.co/functions/v1/agent-api-key-create

Request:

curl -X POST "https://lgwvoomgrwpsgpxwyaec.supabase.co/functions/v1/agent-api-key-create" \
-H "Authorization: Bearer <human-user-jwt>" \
-H "Content-Type: application/json" \
-d '{
"name": "Bahig - Karim assistant",
"scopes": ["read", "write"],
"expires_at": "2026-12-31T23:59:59Z"
}'

The raw key is returned once only. Nexus stores only a bcrypt hash.

Step 2: exchange the API key for an agent JWT

Endpoint:

POST https://lgwvoomgrwpsgpxwyaec.supabase.co/functions/v1/agent-auth

Request:

curl -X POST "https://lgwvoomgrwpsgpxwyaec.supabase.co/functions/v1/agent-auth" \
-H "Content-Type: application/json" \
-d '{
"api_key": "nxs_ak_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12"
}'

Response:

{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 3600,
"organization_id": "org-uuid"
}

Security guarantees:

  • raw keys are never stored
  • revoked keys are rejected
  • expired keys are rejected
  • auth attempts are logged
  • the endpoint is rate limited to 10 attempts per minute per IP
  • issued agent JWTs expire after 1 hour

Using a bearer token

Include the JWT in the Authorization header of every request:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

For Supabase PostgREST endpoints, also include the apikey header:

apikey: <anon-key>

Token claims

Human JWTs

Human JWTs contain these relevant claims:

ClaimDescription
subUser ID (UUID)
emailUser email
roleSupabase role (authenticated)
app_metadata.organization_id or app_metadata.org_idCurrent organization ID
app_metadata.org_roleOrganization role (owner, admin, member)

Agent JWTs

Agent JWTs contain these relevant claims:

ClaimDescription
subAgent API key ID
roleSupabase role (authenticated)
organization_idCurrent organization ID
org_roleAlways agent
agent_scopesScope array such as ["read"] or ["read","write"]
app_metadata.organization_idCurrent organization ID
app_metadata.org_roleAlways agent
app_metadata.agent_scopesScope array

Row-Level Security

The JWT's organization claims are used by PostgreSQL RLS policies to filter data. Users and agents can only access rows belonging to their organization. Agent write/delete access is additionally gated by scope-aware RLS helpers.

MCP authentication

The hosted MCP endpoint accepts only the agent JWT, not the raw API key:

POST https://lgwvoomgrwpsgpxwyaec.supabase.co/functions/v1/mcp-server
Authorization: Bearer <agent-jwt>

For the full MCP workflow and tool inventory, see AI Agents, API Keys, and MCP.

Webhook authentication

Inbound webhook endpoints (e.g., whatsapp-webhook, shopify-webhook) use different authentication mechanisms:

  • Verify token — a shared secret validated on webhook registration (WhatsApp, Meta).
  • HMAC signature — request body signed with a shared secret (Shopify).
  • Bearer token — a static token in the Authorization header (internal webhooks).

Webhook authentication details are not included in the public OpenAPI spec for security reasons.

Best practices

  1. Never hardcode tokens in client-side code. Use Supabase Auth SDK for token management.
  2. Never use the raw agent API key beyond the agent-auth exchange.
  3. Refresh or re-issue tokens before they expire (expires_in is in seconds).
  4. Never use the service role key in client applications.
  5. Store tokens and API keys securely, ideally in a secret manager.