Choose the integration
| Integration | Start here |
|---|---|
| A person using Topolo CLI or MCP | Use the CLI's built-in sign-in. No custom OAuth client is required. |
| An external app signing in a person | Register a developer OAuth client, use provider discovery and perform the reviewed authorization-code flow. |
| An integration accessing a defined application/resource | Use API keys and the current key selection policy. |
An internal first-party service identity is a separate operator capability. Do not copy internal service secrets, restricted setup commands or platform registration credentials into a third-party integration.
Register and inspect the client
Use List developer OAuth clients to discover clients in the current developer organization. Create developer OAuth client defines the required name and developer_id, optional developer_app_id, client type, registered redirect URIs, scopes and grant types. Inspect that exact schema and authorization decision before preparing creation.
topolo whoami --json
topolo actions get app_topolo_auth.developer_oauth_clients.create --detail --json
Choose a public client when the deployed client cannot keep a secret. A confidential client returns a secret once; keep it on its trusted backend and follow the transport's protected credential handling. Do not embed it in browser code or callback URLs. The client owner organization and the consenting user's organization context are separate; do not assume the issued credential acts in the publisher's organization.
Discover provider metadata
Use the production provider's metadata document to obtain the issuer, authorization and token endpoints, userinfo endpoint, signing keys and supported protocol methods:
curl --fail --silent --show-error https://auth.topolo.app/.well-known/openid-configuration
The following HTTP 200 response was captured by running the actual Auth discovery controller locally with its development issuer configuration. It is not a production response and does not prove that a registered client can sign in or that a live signing key is available.
{
"issuer": "https://auth.topolo.dev",
"authorization_endpoint": "https://auth.topolo.dev/api/developer-oauth/authorize",
"token_endpoint": "https://auth.topolo.dev/api/developer-oauth/token",
"userinfo_endpoint": "https://auth.topolo.dev/api/developer-oauth/userinfo",
"jwks_uri": "https://auth.topolo.dev/api/developer-oauth/jwks",
"response_types_supported": [
"code"
],
"grant_types_supported": [
"authorization_code",
"refresh_token",
"urn:ietf:params:oauth:grant-type:device_code"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"scopes_supported": [
"openid",
"profile",
"email",
"offline_access",
"organization:read",
"entitlements:read"
],
"claims_supported": [
"sub",
"email",
"email_verified",
"name",
"org_id",
"org_slug",
"topolo_context_id",
"topolo_app_id"
],
"token_endpoint_auth_methods_supported": [
"none",
"client_secret_post"
],
"code_challenge_methods_supported": [
"S256",
"plain"
]
}
Use one intended provider environment throughout discovery and the flow. Validate the returned issuer and use its published endpoints; do not mix the development example's URLs with production credentials. The discovery response describes provider capabilities, not the scope grants or redirect URLs of your particular client.
Complete authorization and enforce app access
- Send the user to the discovered authorization endpoint with the registered client, exact registered callback, requested allowed scopes and a fresh state value. Use PKCE with
S256; public clients require a code challenge. - The hosted consent flow lets the person approve or deny the request. Preserve denial. Do not infer approval from an existing browser session.
- At the callback, compare state to the initiating session. Exchange the returned one-time code through the discovered token endpoint with the same registered callback and matching PKCE verifier. Confidential clients authenticate at the token endpoint.
- When the approved request includes
openid, validate the returned ID token using the intended issuer and signing keys, including the intended client/audience and expiry. An access token is not an ID token; do not assume the same validation method applies to both. Use the discovered userinfo endpoint for its published identity response. Create or link the app's own local account. - Decide product access from the app's own membership, invitation, plan and resource policy. Identity and consent do not establish those entitlements.
An OAuth authorization code and an SSO sso_code belong to different flows. Do not send one to the other's exchange endpoint, accept bearer credentials in callback URLs, or retry a consumed code as though it were an ordinary resource ID.
Disconnect and recover
List my connected OAuth apps and Disconnect OAuth app manage a person's connection. Disconnect revokes that caller's refresh tokens for the client; it is not a promise that every already-issued access token is immediately invalidated.
Client owners can inspect Rotate developer OAuth client secret and Revoke developer OAuth client. These are reviewed credential mutations, not troubleshooting reads. Follow their current effects, confirmation and verification contract.
An expired code requires a fresh authorization attempt. A denied scope, client or callback requires a corrected authorized registration or request. Do not bypass consent or invent a different endpoint. The linked action references are the current operational contracts; this concept page and local metadata example do not certify a successful live integration.