Skip to main content
API clients authenticate with the OAuth 2.0 client-credentials grant. Create the client and its credential in Settings → API Clients first (see Create an API client).

Get a token

Exchange the credential for a short-lived (1 hour) bearer token at the token endpoint, https://conduit.example.com/oauth/token (your instance’s exact URL is shown in the client’s Manage credentials dialog). Conduit publishes it, with the rest of its OAuth configuration, in the standard authorization server metadata document at https://conduit.example.com/.well-known/oauth-authorization-server: token_endpoint, the client authentication methods it accepts (token_endpoint_auth_methods_supported — for API clients, client_secret_basic and private_key_jwt; none is for MCP clients), and the algorithms it accepts for a signed assertion (token_endpoint_auth_signing_alg_values_supported: RS256, ES256). OAuth client libraries that support discovery read it given just the instance’s base URL, the document’s issuer.
private_key_jwt is the same grant with a signed client assertion (client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer), which is the stronger option because no shared secret is transmitted. Standard OAuth client libraries implement both and refresh the token for you. Requesting scope down-selects from what the client was granted; omit it to get all granted scopes. The response is a standard OAuth token:
There is no refresh token — re-run the grant when the token expires.

Private-key JWT authentication

private_key_jwt (RFC 7523) is the recommended credential for unattended use. Instead of sending a shared secret, your client signs a short-lived JWT assertion with a private key that never leaves your infrastructure. You register only the matching public key with Conduit, so no reusable secret is ever transmitted to the token endpoint or stored in Conduit’s database — a leaked request log or a database dump can’t be replayed to mint tokens. A client secret, by contrast, is a bearer value: anyone who reads it once can use it until you rotate it. Prefer private_key_jwt for CI and production.

Generate a key pair

Conduit accepts an RSA (≥ 2048-bit) or EC P-256 public key, as a PEM or a JWK. PEM is the simplest — two openssl commands, nothing else to install:
Paste the contents of pub.pem (the -----BEGIN PUBLIC KEY----- block) into Settings → API Clients → Add credential → Public key. Conduit derives a kid for it (the RFC 7638 thumbprint) and shows it next to the credential. Already have a JWK? Paste that instead — the same field takes either form.

Request a token

Standard OAuth libraries build and sign the assertion for you. The raw exchange is the same client-credentials grant, with a signed assertion in place of Basic auth — the assertion’s iss and sub are the client ID (copy it from the API clients table or the client’s Manage credentials dialog), aud is the token endpoint URL (shown in the same dialog), and exp is a few minutes out with a unique jti:
The aud must exactly match your instance — either its base URL or that URL plus /oauth/token (the metadata document’s token_endpoint). This binds the assertion to one instance so it can’t be replayed against another, and a mismatch is the most common setup error: the token endpoint returns invalid_client (deliberately without saying why). Set aud to the token endpoint you’re POSTing to and they always agree.

Revoking access

  • Disable or delete a client, or revoke a single credential, in Settings → API Clients — it takes effect on the next request. Revoking one credential leaves the client’s other credentials working, so it is the clean way to retire a leaked secret mid-rotation.
Instance-wide kill switch: an operator can set CONDUIT_DISABLE_API_CLIENTS=true and restart Conduit to refuse token minting and reject every existing API-client token instance-wide (break-glass for a suspected compromise). Machine actions are attributed to api-client:<name>, and every audit detail includes the immutable client ID plus the credential ID that minted the token. Known-client authentication failures are included in the workspace’s audit:read export, coalesced to one row per client/source-IP/minute; repeats and unknown client IDs remain available through telemetry without amplifying audit-log writes. Each audit entry also carries actor_user_id (the acting user’s id, or the API client’s backing service user), trace_id and span_id. Telemetry identifies people by user.id, never by email, so these are how a SIEM joins an event from your telemetry backend to the audit entry, and its email, behind it. See What telemetry contains.