drio
Technical Review

Authentication

Authenticate against the drio management API with OAuth 2.0, PKCE, and bearer tokens.

This page is for developers using the drio management API. Public routes such as template listing do not require a token, but protected routes do.

The Auth Model In One View

drio exposes an OAuth 2.0 surface for:

  • discovery
  • authorization
  • token exchange
  • token refresh

You do not need to integrate directly with WorkOS. Treat drio as the OAuth surface your client integrates with.

drio owns:

  • dynamic client registration
  • authorization start
  • the callback bridge
  • token exchange
  • refresh handling

Behind the scenes, drio uses WorkOS for sign-in and then returns tokens from the drio OAuth surface.

When You Need Auth

These routes require a bearer token:

  • /api/v1/me
  • /api/v1/apps
  • /api/v1/apps/{appId}
  • /api/v1/apps/{appId}/config
  • /api/v1/apps/{appId}/commands

Start With Discovery

Most OAuth-aware clients should begin with:

  • GET /.well-known/oauth-authorization-server
  • GET /.well-known/oauth-protected-resource

These discovery documents tell the client:

  • where to authorize
  • where to exchange tokens
  • where to register clients
  • which scopes are supported

Auth Endpoints

drio exposes these auth routes:

  • POST /api/v1/auth/register
  • GET /api/v1/auth/authorize
  • GET /api/v1/auth/callback
  • POST /api/v1/auth/token
  • POST /api/v1/auth/refresh

The callback route is part of the bridge and is not something your client calls directly.

Supported Flow

The current model supports:

  • dynamic client registration
  • authorization code flow
  • PKCE
  • refresh tokens
  • bearer tokens on protected routes

Typical OAuth Flow

1. Discover the auth server

GET /.well-known/oauth-authorization-server

2. Register your client and redirect URIs

curl -X POST https://getdrio.com/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "My App",
    "redirect_uris": ["https://example.com/callback"],
    "grant_types": ["authorization_code", "refresh_token"],
    "response_types": ["code"]
  }'

Save the returned client_id. You will use it during both authorization and token exchange.

3. Redirect the user to authorize

GET /api/v1/auth/authorize?client_id=...&response_type=code&redirect_uri=...&code_challenge=...&code_challenge_method=S256&state=...

drio validates the registered client metadata, redirects the browser to WorkOS for sign-in, receives the upstream callback at /api/v1/auth/callback, and then redirects back to your app with a drio authorization code.

4. Exchange the code for tokens

curl -X POST https://getdrio.com/api/v1/auth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id=CLIENT_ID&code=AUTH_CODE&code_verifier=CODE_VERIFIER&redirect_uri=https://example.com/callback&grant_type=authorization_code"

5. Call protected routes

curl https://getdrio.com/api/v1/apps \
  -H "Authorization: Bearer ACCESS_TOKEN"

6. Refresh when needed

curl -X POST https://getdrio.com/api/v1/auth/refresh \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id=CLIENT_ID&redirect_uri=https://example.com/callback&refresh_token=REFRESH_TOKEN"

What drio Handles For You

This is the important integration boundary:

  • your client talks to drio's OAuth routes
  • drio talks to WorkOS
  • WorkOS never redirects directly back to your client
  • /api/v1/auth/token expects the drio bridge code, not a raw upstream code

That means the values you control are the registered client_id, redirect_uri, PKCE fields, and your bearer-token usage on protected routes.

Scopes

Current supported scopes:

  • openid
  • profile
  • email

Response Shapes

Auth routes return OAuth-style responses, not the drio resource error envelope.

The returned access and refresh tokens are currently WorkOS-backed bearer tokens, even though the flow is brokered through drio.

Success:

{
  "access_token": "ACCESS_TOKEN",
  "refresh_token": "REFRESH_TOKEN",
  "expires_in": 3600,
  "token_type": "Bearer"
}

Failure:

{
  "error": "invalid_request",
  "error_description": "Missing required field: refresh_token"
}

Protected resource routes use the drio API error envelope instead. See Errors.

Continue With