Skip to Content
ClicoDOCS

Sign in with Clico

Add Clico sign-in to your application with OAuth 2.1 and OpenID Connect.

Use Clico as an identity provider so people can sign in to your application with their Clico account. This integration uses the OAuth 2.1 authorization-code flow and OpenID Connect (OIDC).

This guide is for application developers integrating Clico sign-in. OAuth client registration is currently managed by Clico operators; dynamic client registration is not available.

Availability: Ask your Clico integration contact to confirm that the OAuth Provider is enabled and to register your application before testing. Do not send a client secret through source control, chat, or a browser bundle.

What this integration provides

After a person signs in and approves the request, your app receives an authorization code and exchanges it for OIDC tokens. Use the ID token to establish the signed-in identity and the UserInfo endpoint to retrieve the claims your client is allowed to request.

OAuth access tokens issued for this sign-in flow do not grant access to Clico's existing API endpoints. Do not send them to api.clico.co REST routes as bearer credentials.

Request client registration

Give your Clico contact:

  • Your application name and a technical contact.
  • Whether the app is a web app or a native app.
  • Every exact callback URI. Production web callbacks must use HTTPS. Native apps can use HTTPS app links or a private-use URI scheme; loopback HTTP is allowed for local development.
  • The OIDC scopes you need: openid, profile, email, and optionally offline_access.
  • Whether the app can keep a client secret securely.

Clico will provide a client_id. A confidential web app can also receive a client_secret; keep it on your server. Public clients, including browser-only and native apps, do not receive a secret and must use PKCE.

Discover the provider

Fetch the metadata at runtime instead of assuming endpoint URLs:

MetadataURL
OAuth authorization-server metadata (RFC 8414)https://auth.clico.co/.well-known/oauth-authorization-server/api/auth
OpenID Connect discoveryhttps://auth.clico.co/api/auth/.well-known/openid-configuration

The expected issuer is https://auth.clico.co/api/auth. The metadata contains the authorization, token, UserInfo, revocation, and JWKS endpoints. Validate the issuer against this exact value.

Authorization-code flow

  1. Generate a cryptographically random state, an OIDC nonce, and a PKCE code_verifier. Calculate code_challenge = BASE64URL(SHA256(code_verifier)) without padding. For a Node.js server, you can generate these values with the built-in crypto module:
import { createHash, randomBytes } from 'node:crypto';

const randomValue = () => randomBytes(32).toString('base64url');
const state = randomValue();
const nonce = randomValue();
const codeVerifier = randomValue();
const codeChallenge = createHash('sha256').update(codeVerifier).digest('base64url');

Store state, nonce, and codeVerifier in the user's short-lived server-side login session. For browser-only and native apps, use a maintained OIDC client library and its system-browser flow. 2. Redirect the person's browser to the authorization_endpoint from the OIDC metadata with:

response_type=code
client_id=YOUR_CLIENT_ID
redirect_uri=YOUR_REGISTERED_CALLBACK_URI
scope=openid profile email
state=YOUR_RANDOM_STATE
nonce=YOUR_RANDOM_NONCE
code_challenge=YOUR_BASE64URL_SHA256_CHALLENGE
code_challenge_method=S256

Include offline_access only if your app needs refresh tokens. Clico requires PKCE with S256, and the redirect_uri must exactly match a URI registered for your client.

  1. Clico handles sign-in and consent on auth.clico.co. After approval, Clico redirects to your registered callback with code, state, and iss. Verify state matches the value stored for this browser session, and verify iss is https://auth.clico.co/api/auth. Handle an access_denied response when the person declines.
  2. Exchange the code from your server. Send the same redirect_uri and the original code_verifier. Confidential clients authenticate with HTTP Basic; public clients send no client secret.

Example for a confidential web client:

curl --request POST "https://auth.clico.co/api/auth/oauth2/token" \
  --user "$CLICO_CLIENT_ID:$CLICO_CLIENT_SECRET" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "code=$CODE" \
  --data-urlencode "redirect_uri=$REDIRECT_URI" \
  --data-urlencode "code_verifier=$CODE_VERIFIER"

For a public client, omit --user and do not send a client_secret. The request must still include the client_id, code, exact redirect_uri, and code_verifier.

curl --request POST "https://auth.clico.co/api/auth/oauth2/token" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "client_id=$CLICO_CLIENT_ID" \
  --data-urlencode "code=$CODE" \
  --data-urlencode "redirect_uri=$REDIRECT_URI" \
  --data-urlencode "code_verifier=$CODE_VERIFIER"

Validate tokens and read the profile

Use a maintained OIDC library to validate the ID token's signature using the provider's jwks_uri, as well as its issuer, audience (client_id), expiration, and nonce. Do not treat decoding a JWT as validation.

Use the access token with the userinfo_endpoint from discovery:

curl "https://auth.clico.co/api/auth/oauth2/userinfo" \
  --header "Authorization: Bearer $ACCESS_TOKEN"

Request only the scopes and claims your app needs. Store tokens server-side when possible. If offline_access was approved, handle refresh-token rotation and securely replace the old refresh token after each successful refresh. Revoke tokens through the revocation_endpoint from provider metadata when disconnecting the Clico account.

Security checklist

  • Use HTTPS in production and register exact redirect URIs.
  • Use a fresh, unpredictable state for every authorization request and validate it on callback.
  • Use PKCE S256 for every client; never embed a confidential client secret in a browser or mobile app.
  • Validate ID tokens with a standard OIDC library, including iss, aud, exp, and nonce.
  • Keep access and refresh tokens out of URLs, logs, analytics, and client-side persistent storage.
  • Treat the OAuth access token as an OIDC/UserInfo credential, not as authorization for Clico REST APIs.