Skip to main content
Driftstack DRIFTSTACK

OAuth 2.0 integration

Driftstack uses OAuth 2.0 with PKCE-S256 for third-party app access. This page documents the authorization code flow your app uses to act on a Driftstack customer's behalf.

Getting a client_id

Self-service OAuth client registration is not yet open (follow-up). Until it is, email [email protected] with:

We turn around new client registrations within one business day. You get back a client_id (prefixed oac_) and a client_secret (prefixed oas_). The secret is shown to you ONCE — we only store the hash on our side, so we cannot recover it for you. Treat it like a Stripe secret key.

Available scopes

ScopeWhat it grants
read:sessionsRead session metadata + history.
write:sessionsStart + stop sessions on the account.
read:profilesRead browser-profile metadata.
write:profilesCreate + update browser profiles.
admin:profilesDelete + manage shared profiles.
read:webhooksList webhook endpoints + delivery history.
write:webhooksCreate webhook endpoints + send test events.
admin:webhooksRotate webhook secrets + delete endpoints.
read:api-keysList the account’s API keys (metadata only).
admin:api-keysMint + revoke API keys.
read:billingRead invoices, usage, and crypto-order history.
admin:billingInitiate checkout sessions + manage subscriptions.
read:auditRead the account audit log.

Scopes follow the verb:resource pattern. Always request the narrowest scope set your app actually needs — broad scopes get pushed back during the human review step.

Authorization flow

1. Mint a PKCE verifier

Generate a high-entropy random string (RFC 7636 §4.1, 43–128 characters from [A-Za-z0-9-._~]). Compute the code_challenge as the URL-safe base64 of SHA-256(verifier). Keep the verifier in your app until step 3 — never send it to anyone except Driftstack at the token endpoint.

2. Redirect the customer to /v1/oauth/authorize

GET /v1/oauth/authorize
  ?client_id=oac_…
  &redirect_uri=https://yourapp.com/oauth/callback
  &state=<csrf-token>
  &code_challenge=<sha256(verifier) base64url>
  &code_challenge_method=S256
  &scope=read:sessions write:sessions

The customer signs into Driftstack if they aren't already, then sees a consent screen for your app + the requested scopes. On approval they're redirected back to your redirect_uri with ?code=…&state=…. Verify state matches what you sent (CSRF guard).

3. Exchange the code for an access token

POST /v1/oauth/token
Content-Type: application/json

{
  "code": "...",
  "code_verifier": "<your pkce verifier>",
  "client_id": "oac_…",
  "client_secret": "oas_…",
  "redirect_uri": "https://yourapp.com/oauth/callback"
}

The response carries the token:

{
  "access_token": "oat_…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": ["read:sessions", "write:sessions"]
}

Tokens live for one hour. There are no refresh tokens — when the token expires, run the full authorize → exchange dance again. This is intentional: it makes consent re-confirmation a regular event rather than a forever-grant.

4. Use the token

Bearer-token authentication against the Driftstack API:

Authorization: Bearer oat_…

The token can only call API surfaces whose required scope is a subset of the token's scope. A token with read:sessions can call GET /v1/sessions but not POST /v1/sessions.

Introspection (RFC 7662)

Check whether a token is still active + what scopes it carries:

POST /v1/oauth/introspect
Content-Type: application/json

{ "token": "oat_…" }

→ { "active": true, "client_id": "oac_…", "account_id": "acc_…",
    "scope": ["read:sessions"], "exp": 1736600000 }

A revoked or expired token returns {"active": false}. Use introspection sparingly — the access-token request itself already carries the scope information.

Revocation (RFC 7009)

Invalidate a token before its 1-hour expiry — useful when the customer signs out of your app:

POST /v1/oauth/revoke
Content-Type: application/json

{ "token": "oat_…", "token_type_hint": "access_token" }

→ 200 OK

The endpoint always returns 200 — even for tokens that don't exist — per RFC 7009 to prevent token-enumeration probes. token_type_hint is optional and informational.

Security expectations

Rate limits

Token-issued requests count against the customer's account rate limits, not your app's. If you're going to mint many tokens for many customers, be aware that high per-customer QPS will hit the tier limits.

Sandbox

We don't yet operate a separate sandbox environment. Test against your own dev account on the production API; use the read:*-only scopes if you don't want your dev account's session usage to count against billing.

Support

Questions, bug reports, or scope requests: [email protected]. We aim to respond within one business day.