Px/

Authentication

How callers authenticate to Permix — JWT bearer tokens, service API keys, and the admin API key for SaaS operations.

Edit this page on GitHub

Permix supports three authentication modes. Which one you use depends on who is calling and from which part of the API.

JWT bearer tokens#

Most API calls are authenticated with a short-lived JWT issued by your identity provider. Pass the token in the standard Authorization header:

http
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6...

The service validates the token's signature against the JWKS endpoint, then extracts claims to determine the caller's identity, roles, and domain.

Required claims:

ClaimDescription
subSubject — the user or service identity
issIssuer — used to look up the JWKS endpoint
expExpiration time — tokens past expiry are rejected
configured roles_claimRoles array (default: realm_access.roles)
configured domain_claimTenant domain (default: dom)

See JWT for validation details and Identity Providers for claim configuration.

Service API keys#

Service-to-service calls that run outside a user session can use long-lived service API keys. Pass the key in the X-Service-Api-Key header:

http
X-Service-Api-Key: sak_live_xxxxxxxxxxxxxxxx

Service API keys are scoped to a tenant and carry a fixed set of permissions. They are ideal for background workers, CLI tools, and internal microservices that cannot obtain a JWT from an identity provider at runtime.

Create a service API key#

bash
curl -X POST https://api.permix.dev/api/v1/service-api-keys \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "batch-importer",
    "description": "Nightly invoice batch import worker"
  }'

Response 201:

json
{
  "id": "sak_abc123",
  "name": "batch-importer",
  "key": "sak_live_xxxxxxxxxxxxxxxx",
  "created_at": "2026-05-10T08:00:00Z"
}

Store the key immediately

The raw key value is returned only once at creation. Store it in your secrets manager — it cannot be retrieved again.

List and revoke service API keys#

bash
# List
GET /api/v1/service-api-keys

# Revoke
DELETE /api/v1/service-api-keys/{id}

Admin API key#

SaaS admin operations (tenant provisioning, identity provider management) use a separate admin API key configured at deployment time via the ADMIN_API_KEY environment variable. Pass it as either:

http
X-Admin-Api-Key: your-admin-key
# or
Authorization: Bearer your-admin-key

Admin routes are only mounted in MODE=saas. See Tenant Management for available admin endpoints.

Authentication by endpoint group#

Endpoint groupAuth method
GET /healthz/*None — public
POST /api/v1/checkJWT bearer
POST /api/v1/resources/access/checkJWT bearer (forwarded by Java SDK)
GET/POST/PUT/DELETE /api/v1/resources/*JWT bearer or service API key
GET/POST/PUT/DELETE /api/v1/abac/policies/*JWT bearer or service API key
GET/POST/DELETE /api/v1/service-api-keys/*JWT bearer
GET/POST/DELETE /admin/*Admin API key

Self-hosted mode#

In MODE=selfhost, all JWT tokens are validated against a single global JWKS URI configured via environment variables. There is no per-tenant IdP lookup.

env
OIDC_ENABLED=true
AUTH_SERVER_URL=https://keycloak.example.com/realms/myrealm
JWKS_URI=https://keycloak.example.com/realms/myrealm/protocol/openid-connect/certs

See Deployment for the full environment variable reference.