Skip to Content

Clients

In Faable Auth, a Client represents an application that authenticates users or requests authorization to access APIs: a Single Page Application (React, Vue, Angular), a native mobile app, a server-side web application, or a backend machine-to-machine service.

Clients are what initiate the OAuth 2.0 and OpenID Connect flows. You manage them from the Faable Dashboard , or create them programmatically with Dynamic Client Registration.

Creating a Client

Registering a client generates two credentials:

  • Client ID — a public, unique identifier. Safe to ship in client-side code (React, Expo); it tells Faable Auth which application is asking.
  • Client Secret — a confidential string that proves the application’s identity. Never expose it in a SPA, a mobile binary, or anything a user can read. It belongs to backends only.

Types of Clients

Your architecture dictates the configuration and the flow:

Client typeWhere the code runsSecret?Flow
Single Page AppThe browser (React, Vue, Angular)❌Authorization Code + PKCE
Native / MobileThe user’s device (iOS, Android, React Native)❌Authorization Code + PKCE
Regular Web AppYour server (Express, Next.js server components)✅Authorization Code
Machine to MachineA backend service or worker, no human involved✅Client Credentials
Device / TV / CLIAn input-constrained device❌Device Code

Faable Auth enforces PKCE with S256 — it advertises no other code challenge method — so public clients are covered whether or not a secret is present.

Client Configuration

Security boundaries

  • Allowed Callback URLs (callbacks) — the whitelist of URLs Faable Auth may redirect to after login (e.g. https://myapp.com/callback). Prevents open-redirect abuse.
  • Allowed Logout URLs (logout_urls) — where users may be sent after RP-Initiated Logout.
  • Allowed Web Origins (web_origins) — origins (scheme://host[:port], no path — e.g. http://localhost:5173) permitted to make cross-origin calls to the token and passwordless endpoints. When the list is empty, any origin is allowed; fill it in to lock browser calls down to your own app. Your account’s auth domain is always allowed implicitly, so you only list your application origins.
  • Connections — which authentication methods (Google, passwordless, database…) this specific client may use. Set on each connection via its Enabled clients list.

Token lifetimes

SettingEffect
refresh_token.token_lifetimeLifetime of issued refresh tokens, in seconds. Default 2592000 (30 days).
Access token lifetimeNot a client setting — it comes from the API the token is issued for (token_lifetime), defaulting to 24 hours.

refresh_token.expiration_mode and refresh_token.infinite_token_lifetime exist on the client object for Auth0 compatibility, but are not enforced today — only token_lifetime governs how long a refresh token lives. Don’t rely on them to build a never-expiring session.

Client authentication at the token endpoint

POST /oauth/token accepts three methods, as published in your tenant’s discovery document:

token_endpoint_auth_methodHow the client authenticatesFor
client_secret_basicHTTP Basic header with client_id:client_secret (the default)Confidential clients
client_secret_postclient_id + client_secret in the form bodyConfidential clients
noneNo secret — the PKCE code_verifier is the proofPublic SPA and native clients

Application metadata

Optional fields, mostly consumed by consent screens and by tooling: client_uri, logo_uri, tos_uri, policy_uri, contacts, application_type (web | native), software_id, software_version.

Front-Channel Logout

A client may register a frontchannel_logout_uri: Faable loads it in a hidden iframe when the user logs out of the OP, so your application can clear its own session. Set frontchannel_logout_session_required to true and Faable includes iss and sid on that call, letting you scope the cleanup to the exact session. See Logout. A client may also register a backchannel_logout_uri: when the session ends, Faable POSTs a signed logout_token there from its own servers — no browser involved — so your application’s server-side session ends too. See Back-channel logout.

Dynamic Client Registration

Clients can be created over HTTP instead of through the dashboard, per OIDC Dynamic Client Registration 1.0 / RFC 7591 . This is what lets a third-party tool onboard itself against your tenant — MCP clients, IDE integrations and OAuth debuggers commonly expect it.

The endpoint is published in your discovery document as registration_endpoint:

curl -X POST 'https://your-domain.auth.faable.link/oidc/register' \ -H 'content-type: application/json' \ -d '{ "client_name": "My Tool", "redirect_uris": ["https://tool.example.com/callback"], "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "token_endpoint_auth_method": "client_secret_basic" }'

Response (201), per RFC 7591 §3.2.1 — this is the only time the secret is returned:

{ "client_id": "…", "client_secret": "…", "client_id_issued_at": 1751641200, "client_secret_expires_at": 0, "redirect_uris": ["https://tool.example.com/callback"], "client_name": "My Tool", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "token_endpoint_auth_method": "client_secret_basic", "application_type": "web" }

Notes on behaviour:

  • redirect_uris is the only required field. Everything else defaults per spec: grant_types to ["authorization_code"], response_types to ["code"], token_endpoint_auth_method to client_secret_basic, application_type to web.
  • Unsupported metadata is rejected, not silently accepted. Requesting a grant type Faable doesn’t implement returns 400. Supported grants are authorization_code, refresh_token, client_credentials, urn:ietf:params:oauth:grant-type:device_code, urn:ietf:params:oauth:grant-type:token-exchange and Auth0’s passwordless OTP grant.
  • client_secret_expires_at is 0 — issued secrets don’t expire.
  • The client is bound to the tenant resolved from the request host, so register against the domain you actually want it to live in.
  • web_origins is accepted as a non-standard extra, with the same rules as in the dashboard.
  • Registration is not itself authenticated. Anyone who can reach your auth domain can create a client in your tenant — a new client grants no access on its own, but if that’s not a trade-off you want, keep an eye on oauth.client.register entries in your logs.

Next Steps

  • Connections — the identity providers you attach to a client.
  • Authorization Code Flow — the mechanics of the standard login flow.
  • APIs — register the resource servers your clients request tokens for.
  • Quickstarts — jump into working code, including FastAPI on the backend side.

Last updated on