Skip to content

Applications and clients

An application in IntelliAuth represents one piece of software that authenticates users through the tenant. Each application has a unique client id, declares what kind of grant it can use (authorization code, client credentials, etc.), and is registered with redirect URIs + audiences specific to how it works.

If you've used OAuth before, "application" is what other platforms call a "client" or "OAuth client". IntelliAuth keeps the word "application" because that's what platform operators register through their admin console; "client" appears in the protocol details.

Four types map to the four shapes of OAuth clients:

  • SPA (Single-Page App) — a browser-side app like React, Vue, Svelte. Uses authorization code with PKCE. Doesn't keep a client secret. Common.
  • Native — iOS, Android, desktop apps. Like SPA, uses PKCE, no client secret stored. The redirect URI is a custom scheme (myapp://callback) or a universal/app link.
  • Server-side web — a traditional server-rendered app (Rails, Django, Next.js with server actions). Authorization code with PKCE and a client secret stored on the server. The server is what handles the code exchange.
  • M2M (Machine-to-machine) — no user, no consent. A backend service authenticating to another backend service. Uses the client credentials grant. Has a client id + client secret used to mint tokens.

When you register an application in the tenant admin console, you pick the type first. The remaining configuration (redirect URIs, allowed scopes, token lifetimes) is specific to the type you chose.

The temptation is to share one client id across all of your apps. Resist it. Each separate app should be its own application registration because:

  • Different redirect URIs. Your iOS app's redirect is myapp://callback; your web app's is https://app.banking.cymmetri.com/callback. One application can have multiple redirect URIs, but mixing app types under one application makes the redirect-URI allowlist surface confusing.
  • Different scope budgets. Maybe your iOS app needs read:transactions but not write:settings; your web admin tool needs the opposite. Per-app scope allowlists keep the principle of least privilege enforceable.
  • Different token lifetimes. A long-running native app might benefit from longer refresh tokens; a public-kiosk web app should have shorter ones. Per-app token TTLs lets you tune each surface.
  • Audit clarity. When you read the audit log and see "issued token to client X", you know exactly which surface that was.
  • Revocation surface. If you need to invalidate every session from your mobile app (say, because of a CVE in your app code), you can do it per-application without affecting other surfaces.

The cost of registering a new application is small (it's a CRUD operation in the admin console). The benefits compound.

Your SDK instance is configured with one application's client id:

<IntelliAuthProvider
tenantUrl="https://banking-cymmetri.intelliauth.local"
clientId="app_01HZX..." // ← this is one application
redirectUri={`${window.location.origin}/callback`}
>

If you have multiple frontends, each runs its own SDK instance with its own client id. They might share the same tenant — that's fine; the tenant has many applications — but each one is a separate registration.

A common source of confusion:

  • Application = your software. Long-lived. One per app you maintain.
  • Identity = your user. The human signing in. Created on the fly when they sign up.

Many identities sign into the same application. One application typically has thousands or millions of identities authenticating through it. They're not the same thing; don't conflate them.