Docs/Authentication/End-user OAuth

End-user OAuth

When a tool requires user-level access (Google Calendar, Slack DMs, Salesforce records), your agent must trigger an OAuth flow before the call will succeed.

The flow at a glance

  1. Agent attempts a call → platform returns 401 unauthorized with auth_required: true and an auth_endpoint.
  2. Agent calls POST /initiateOAuth with appId + userId + clientRedirectUri.
  3. Platform returns authorizationUrl.
  4. Your app redirects the end-user to that URL.
  5. End-user grants permissions on the provider.
  6. Provider redirects to your clientRedirectUri with ?status=success.
  7. Platform exchanges code for tokens server-side, encrypts, stores.
  8. Agent retries the original call. It succeeds.

Initiating the flow

POST/initiateOAuth
Name
Type
Required
Description
appId
string
required
ID of the App requiring authorization
userId
string
required
Your end-user identifier
clientRedirectUri
string
required
Must be pre-registered on AI Client
initiate-oauth.sh
curl -X POST https://us-central1-cortexconnectplatform.cloudfunctions.net/initiateOAuth \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'X-Cortex-Client-Id: YOUR_CLIENT_ID' \ -H 'Content-Type: application/json' \ -d '{ "appId": "your-app-id", "userId": "your-end-user-id", "clientRedirectUri": "https://yourapp.com/oauth/callback" }'

Response:

{ "authorizationUrl": "https://accounts.google.com/o/oauth2/auth?..." }

Callback verification

The platform's callback at /handleOAuthCallback does:

  • CSRF validation via OAuth state (10-minute TTL).
  • PKCE code_verifier check.
  • Token exchange with the provider.
  • Envelope encryption with KMS.
  • Firestore write of the encrypted blob (never plaintext).

Refreshing tokens

You don't. The platform refreshes provider tokens automatically when expired on the proxy hot path. If a refresh fails (revocation, expired grant), the proxy returns 401 with reauth_required: true and the cycle restarts.