Documentation

SharkAuth API — Admin Endpoints

All admin endpoints require an admin API key passed as a Bearer token:

Authorization: Bearer sk_live_<random>

The key is written to data/admin.key.firstboot at first boot and is available via GET /api/v1/admin/firstboot/key until the admin account is bootstrapped. All responses use the extended error envelope {error, code, message, docs_url, details}.


Health & System

GET /api/v1/admin/health

Returns server health including DB status, JWT config, SMTP provider, uptime, active signing keys, SSO connection count, and applied migration version.

Response 200:

json
{
  "status": "ok",
  "version": "0.9.0",
  "uptime_seconds": 3600,
  "db": { "driver": "sqlite3", "size_mb": 2.4, "status": "ok" },
  "migrations": { "current": 42, "name": "add_proxy_rules" },
  "jwt": { "mode": "asymmetric", "algorithm": "ES256", "active_keys": 1 },
  "smtp": { "tier": "dev", "configured": true, "sent_today": 3, "daily_limit": 100 },
  "oauth_providers": ["google", "github"],
  "sso_connections": 0
}

GET /healthz — Liveness probe (no auth)

json
{ "status": "ok" }

Returns 503 with { "status": "unhealthy", "error": "database unreachable" } when the DB ping fails.

GET /api/v1/admin/stats

Aggregate dashboard statistics (user count, active sessions, agent count, etc.).

GET /api/v1/admin/stats/trends

Time-series trends for the dashboard stats chart.

GET /api/v1/admin/config / PATCH /api/v1/admin/config

Read or update the runtime configuration stored in the database. Replaces the deprecated YAML config surface (W17).

GET /api/v1/admin/system/mode

Returns the current server mode (dev / production).

POST /api/v1/admin/system/swap-mode

Swaps between dev and production mode. Triggers a drain + re-init cycle.

POST /api/v1/admin/system/reset

Hard-resets all runtime state (sessions, tokens, audit logs). Requires explicit confirmation body. Useful in dev/test.

POST /api/v1/admin/auth/rotate-signing-key

Rotates the JWT signing key. Old key is retired (kept in JWKS for 2× token TTL). Subsequent tokens are signed with the new key.

POST /api/v1/admin/auth/revoke-jti

Revokes a specific JWT by JTI (JWT ID). Useful for immediate admin-forced logout of a single token.

Request:

json
{ "jti": "01HZ2XKA..." }

Bootstrap & First Boot

GET /api/v1/admin/firstboot/key

Returns the admin API key from first boot. Public — returns 404 once the admin account has been bootstrapped. Intended for automated provisioning scripts.

Response 200:

json
{ "key": "sk_live_abc123..." }

POST /api/v1/admin/bootstrap/consume

Consumes the one-time bootstrap token to set up the first admin account. The token in the request body is the credential — no Authorization header needed.

Request:

json
{ "token": "<bootstrap-token>", "email": "admin@example.com", "password": "..." }

GET /api/v1/admin/bootstrap/status

Returns whether the server has been bootstrapped (admin account created).


Users

Base path: /api/v1/users Auth: Admin API key

MethodPathDescription
GET/api/v1/usersList all users (paginated)
GET/api/v1/users/{id}Get a single user
PATCH/api/v1/users/{id}Update user (name, email, metadata)
DELETE/api/v1/users/{id}Delete user + cascade
POST/api/v1/admin/usersCreate user (admin-side)
POST/api/v1/users/{id}/rolesAssign a role
DELETE/api/v1/users/{id}/roles/{rid}Remove a role
GET/api/v1/users/{id}/rolesList user roles
GET/api/v1/users/{id}/permissionsList effective permissions
GET/api/v1/users/{id}/audit-logsUser-scoped audit log
GET/api/v1/users/{id}/sessionsList active sessions
DELETE/api/v1/users/{id}/sessionsRevoke all sessions
GET/api/v1/users/{id}/oauth-accountsList linked social accounts
DELETE/api/v1/users/{id}/oauth-accounts/{oauthId}Unlink social account
GET/api/v1/users/{id}/passkeysList passkey credentials
DELETE/api/v1/users/{id}/mfaForce-disable MFA (support recovery)
POST/api/v1/users/{id}/verify/sendSend email verification
GET/api/v1/users/{id}/agentsList agents belonging to / authorized by user
POST/api/v1/users/{id}/revoke-agentsCascade revoke all agent tokens for user

Example — Get user:

json
{
  "id": "usr_01HZ2XKABCDEF",
  "email": "alice@example.com",
  "email_verified": true,
  "name": "Alice Example",
  "mfa_enabled": false,
  "created_at": "2024-04-01T10:00:00Z"
}

Tier management (proxy paywall gating):

PATCH /api/v1/admin/users/{id}/tier — Set user tier for proxy paywall rules.

json
{ "tier": "pro" }

Agents

Base path: /api/v1/agents Auth: Admin API key

Agents are machine-to-machine OAuth clients registered via the admin API (distinct from DCR which is protocol-level).

MethodPathDescription
POST/api/v1/agentsRegister a new agent
GET/api/v1/agentsList agents
GET/api/v1/agents/{id}Get agent
PATCH/api/v1/agents/{id}Update agent metadata
DELETE/api/v1/agents/{id}Delete agent
GET/api/v1/agents/{id}/tokensList active tokens
POST/api/v1/agents/{id}/tokens/revoke-allRevoke all active tokens
POST/api/v1/agents/{id}/rotate-secretRotate client secret
POST/api/v1/agents/{id}/rotate-dpop-keyRotate DPoP binding key
GET/api/v1/agents/{id}/auditAgent audit log
GET/api/v1/agents/{id}/policiesGet agent policies
POST/api/v1/agents/{id}/policiesSet agent policies

Example — Create agent request:

json
{
  "client_name": "my-billing-agent",
  "grant_types": ["client_credentials", "urn:ietf:params:oauth:grant-type:token-exchange"],
  "scope": "openid billing:read",
  "token_endpoint_auth_method": "client_secret_basic"
}

Response 201 (client_secret shown once):

json
{
  "id": "agt_01HZ2XKABCDEF",
  "client_id": "shark_dcr_abc123",
  "client_secret": "cs_live_...",
  "client_name": "my-billing-agent",
  "grant_types": ["client_credentials"],
  "scope": "openid billing:read",
  "active": true,
  "dpop_bound": false,
  "created_at": "2024-04-01T10:00:00Z"
}

Applications

Base path: /api/v1/admin/apps Auth: Admin API key

Applications represent OAuth clients used by web/mobile frontends.

MethodPathDescription
POST/api/v1/admin/appsCreate application
GET/api/v1/admin/appsList applications
GET/api/v1/admin/apps/{id}Get application
PATCH/api/v1/admin/apps/{id}Update application
DELETE/api/v1/admin/apps/{id}Delete application
POST/api/v1/admin/apps/{id}/rotate-secretRotate client secret
GET/api/v1/admin/apps/{id}/snippetGet integration code snippet

Audit Logs

Base path: /api/v1/audit-logs Auth: Admin API key

MethodPathDescription
GET/api/v1/audit-logsList audit events (filterable by actor, action, date range)
GET/api/v1/audit-logs/{id}Get a single audit event
POST/api/v1/audit-logs/exportExport logs as CSV
POST/api/v1/admin/audit-logs/purgePurge logs older than cutoff

Query parameters for list:

  • actor_type — filter by actor type (user, admin, agent)
  • action — filter by action name (e.g. user.created)
  • from / to — ISO 8601 date range
  • limit / cursor — keyset pagination

Example event:

json
{
  "id": "al_01HZ2XKABCDEF",
  "actor_type": "admin",
  "actor_id": "admin_key",
  "action": "user.deleted",
  "target_type": "user",
  "target_id": "usr_01HZ2XKABCDEF",
  "metadata": {},
  "created_at": "2024-04-01T10:05:00Z"
}

Vault (Token Vault)

Base path: /api/v1/vault Auth: Admin API key (providers), Session cookie (user flows), Bearer token (agent retrieval)

MethodPathAuthDescription
POST/api/v1/vault/providersAdmin keyRegister a new vault provider
GET/api/v1/vault/providersAdmin keyList vault providers
GET/api/v1/vault/providers/{id}Admin keyGet provider
PATCH/api/v1/vault/providers/{id}Admin keyUpdate provider
DELETE/api/v1/vault/providers/{id}Admin keyDelete provider
GET/api/v1/vault/templatesAdmin keyList built-in provider templates
GET/api/v1/vault/connect/{provider}Session cookieStart user OAuth connect flow
GET/api/v1/vault/callback/{provider}Session cookieOAuth callback for connect flow
GET/api/v1/vault/connectionsSession cookieList user's vault connections
DELETE/api/v1/vault/connections/{id}Session cookieDisconnect a vault connection
GET/api/v1/vault/{provider}/tokenBearer (agent)Retrieve stored token for a provider
GET/api/v1/admin/vault/connectionsAdmin keyList all vault connections (cross-user)
DELETE/api/v1/admin/vault/connections/{id}Admin keyAdmin-delete a connection

Client secrets are never returned after creation — rotation goes through the PATCH body field.


Auth Flows (Flow Builder)

Base path: /api/v1/admin/flows Auth: Admin API key

Auth flows are custom trigger-based pipelines that run at signup, login, password-reset, magic-link, and OAuth callback events.

MethodPathDescription
POST/api/v1/admin/flowsCreate a flow
GET/api/v1/admin/flowsList flows
GET/api/v1/admin/flows/{id}Get flow
PATCH/api/v1/admin/flows/{id}Update flow
DELETE/api/v1/admin/flows/{id}Delete flow
POST/api/v1/admin/flows/{id}/testDry-run a flow against test data
GET/api/v1/admin/flows/{id}/runsList historical run results

Supported triggers: signup, login, password_reset, magic_link, oauth_callback

Supported step types: require_email_verification, require_mfa_enrollment, require_mfa_challenge, require_password_strength, redirect, webhook, set_metadata, assign_role, add_to_org, custom_check, delay, conditional

Example — Create flow:

json
{
  "name": "Require MFA on login",
  "trigger": "login",
  "enabled": true,
  "priority": 10,
  "steps": [
    { "type": "require_mfa_enrollment", "config": {} },
    { "type": "require_mfa_challenge", "config": {} }
  ]
}

Webhooks

Base path: /api/v1/webhooks Auth: Admin API key

See 03-webhooks.md for the full webhook documentation including signature verification, event catalogue, and retry behavior.

MethodPathDescription
POST/api/v1/webhooksCreate webhook subscription
GET/api/v1/webhooksList webhooks
GET/api/v1/webhooks/eventsList known event names
GET/api/v1/webhooks/{id}Get webhook
PATCH/api/v1/webhooks/{id}Update webhook
DELETE/api/v1/webhooks/{id}Delete webhook
POST/api/v1/webhooks/{id}/testFire a test event
GET/api/v1/webhooks/{id}/deliveriesDelivery log (paginated)
POST/api/v1/webhooks/{id}/deliveries/{deliveryId}/replayReplay a past delivery

Email Config & Dev Inbox

GET /api/v1/admin/email-config / PATCH /api/v1/admin/email-config

Read or update email redirect URL configuration (post-verification redirect, password-reset links, etc.).

POST /api/v1/admin/test-email

Send a test email using the currently configured provider.

GET /api/v1/admin/email-preview/{template}

Preview a rendered email template.

GET /api/v1/admin/dev/emails

List captured dev-mode emails (only functional when email provider is dev). Useful for local testing without an SMTP server.

GET /api/v1/admin/dev/emails/{id}

Get a specific dev email.

DELETE /api/v1/admin/dev/emails

Delete all captured dev emails.


Email Templates

Base path: /api/v1/admin/email-templates Auth: Admin API key

MethodPathDescription
GET/api/v1/admin/email-templatesList all templates
GET/api/v1/admin/email-templates/{id}Get a template
PATCH/api/v1/admin/email-templates/{id}Update template (subject, HTML body)
POST/api/v1/admin/email-templates/{id}/previewPreview rendered HTML
POST/api/v1/admin/email-templates/{id}/send-testSend a test email with this template
POST/api/v1/admin/email-templates/{id}/resetReset to default

Branding

Base path: /api/v1/admin/branding Auth: Admin API key

MethodPathDescription
GET/api/v1/admin/brandingGet branding config
PATCH/api/v1/admin/brandingUpdate branding (name, colors, fonts)
POST/api/v1/admin/branding/logoUpload logo (multipart)
DELETE/api/v1/admin/branding/logoDelete logo
PATCH/api/v1/admin/branding/design-tokensUpdate design token overrides

Branding assets (logos) are served publicly at /assets/branding/* — content-addressed, immutable-cached.


Sessions (Admin)

Base path: /api/v1/admin/sessions Auth: Admin API key

MethodPathDescription
GET/api/v1/admin/sessionsList all active sessions
DELETE/api/v1/admin/sessionsRevoke all sessions
DELETE/api/v1/admin/sessions/{id}Revoke a single session
POST/api/v1/admin/sessions/purge-expiredPurge expired session rows

Roles & Permissions (Admin RBAC)

Auth: Admin API key

MethodPathDescription
POST/api/v1/rolesCreate role
GET/api/v1/rolesList roles
GET/api/v1/roles/{id}Get role
PUT/api/v1/roles/{id}Update role
DELETE/api/v1/roles/{id}Delete role
POST/api/v1/roles/{id}/permissionsAttach permission to role
DELETE/api/v1/roles/{id}/permissions/{pid}Detach permission from role
POST/api/v1/permissionsCreate permission
GET/api/v1/permissionsList permissions
DELETE/api/v1/permissions/{id}Delete permission
GET/api/v1/permissions/{id}/rolesRoles that have this permission
GET/api/v1/permissions/{id}/usersUsers that have this permission
POST/api/v1/auth/checkCheck if a user has a permission
GET/api/v1/admin/permissions/batch-usageBatch permission usage stats

Organizations (Admin)

Base path: /api/v1/admin/organizations Auth: Admin API key

MethodPathDescription
POST/api/v1/admin/organizationsCreate organization
GET/api/v1/admin/organizationsList organizations
GET/api/v1/admin/organizations/{id}Get organization
PATCH/api/v1/admin/organizations/{id}Update organization
DELETE/api/v1/admin/organizations/{id}Delete organization
GET/api/v1/admin/organizations/{id}/membersList members
DELETE/api/v1/admin/organizations/{id}/members/{uid}Remove member
PATCH/api/v1/admin/organizations/{id}/members/{uid}Update member role
GET/api/v1/admin/organizations/{id}/rolesList org roles
POST/api/v1/admin/organizations/{id}/rolesCreate org role
GET/api/v1/admin/organizations/{id}/invitationsList invitations
POST/api/v1/admin/organizations/{id}/invitationsCreate invitation
DELETE/api/v1/admin/organizations/{id}/invitations/{invitationId}Delete invitation
POST/api/v1/admin/organizations/{id}/invitations/{invitationId}/resendResend invitation

OAuth Consents (Admin)

MethodPathDescription
GET/api/v1/admin/oauth/consentsList all OAuth consents (cross-user)
DELETE/api/v1/admin/oauth/consents/{id}Revoke a consent
POST/api/v1/admin/oauth/revoke-by-patternBulk revoke consents by pattern
POST/api/v1/admin/consentsAdmin-grant a consent (authorize agent on behalf of user)
GET/api/v1/admin/oauth/device-codesList pending device authorization codes
POST/api/v1/admin/oauth/device-codes/{user_code}/approveApprove a device code
POST/api/v1/admin/oauth/device-codes/{user_code}/denyDeny a device code

Proxy (Reverse Proxy Admin)

Base path: /api/v1/admin/proxy Auth: Admin API key

These endpoints return 404 when the proxy is disabled at boot.

MethodPathDescription
GET/api/v1/admin/proxy/statusBreaker stats + upstream health
GET/api/v1/admin/proxy/status/streamSSE stream of status updates
GET/api/v1/admin/proxy/rulesCompiled rule set (YAML-sourced)
POST/api/v1/admin/proxy/simulateSimulate rule matching for a request
GET/api/v1/admin/proxy/rules/dbList DB-backed rule overrides
POST/api/v1/admin/proxy/rules/dbCreate a DB rule override
GET/api/v1/admin/proxy/rules/db/{id}Get rule override
PATCH/api/v1/admin/proxy/rules/db/{id}Update rule override
DELETE/api/v1/admin/proxy/rules/db/{id}Delete rule override
GET/api/v1/admin/proxy/lifecycleProxy lifecycle status
POST/api/v1/admin/proxy/startStart the proxy subsystem
POST/api/v1/admin/proxy/stopStop the proxy subsystem
POST/api/v1/admin/proxy/reloadReload rules without restart

SSO Connections (Admin)

Base path: /api/v1/sso/connections Auth: Admin API key

MethodPathDescription
POST/api/v1/sso/connectionsCreate SSO connection (SAML or OIDC)
GET/api/v1/sso/connectionsList connections
GET/api/v1/sso/connections/{id}Get connection
PUT/api/v1/sso/connections/{id}Update connection
DELETE/api/v1/sso/connections/{id}Delete connection

Public SSO endpoints (no auth):

  • GET /api/v1/sso/saml/{connection_id}/metadata — SAML SP metadata XML
  • POST /api/v1/sso/saml/{connection_id}/acs — SAML ACS (Assertion Consumer Service)
  • GET /api/v1/sso/oidc/{connection_id}/auth — OIDC authorization redirect
  • GET /api/v1/sso/oidc/{connection_id}/callback — OIDC callback

API Keys (Admin)

Base path: /api/v1/api-keys Auth: Admin API key

MethodPathDescription
POST/api/v1/api-keysIssue a new admin API key
GET/api/v1/api-keysList API keys
GET/api/v1/api-keys/{id}Get key details
PATCH/api/v1/api-keys/{id}Update key metadata
DELETE/api/v1/api-keys/{id}Revoke key
POST/api/v1/api-keys/{id}/rotateRotate to a new key value

Admin Logs

MethodPathDescription
GET/api/v1/admin/logs/streamSSE stream of structured admin log output