When you register an application, you pick one of five types. The type determines what credentials the platform issues, what OAuth flow it expects, and which fields are relevant.
| Type | What it is | Has a client_secret? | Browser-driven? |
|---|---|---|---|
| SPA | Browser-only app (React, Vue, etc.) | No | Yes |
| Server-side | Web app with a backend that holds session state | Yes | Yes (callback to backend) |
| Native | Mobile / desktop app | No | Yes (system browser) |
| M2M (Machine-to-machine) | Backend service calling other backends | Yes | No |
| SAML | Service Provider for SAML 2.0 SSO | n/a (certificate-based) | Yes (POST-binding) |
Your app runs entirely in the browser. React, Vue, Svelte, plain JS. Sign-in is browser-redirect to the IntelliAuth tenant; the user comes back to a callback route in your SPA; the SDK exchanges the code for tokens.
- OAuth flow — authorization code + PKCE.
- Credentials —
client_idonly. No secret (browsers can't keep secrets). - Redirect URIs — required. Where the browser comes back.
- Allowed origins — required for CORS.
- Refresh tokens — by default, kept in memory + an HttpOnly cookie. Can be moved to localStorage if you accept the XSS risk.
If your stack has a backend that holds the OAuth tokens server-side, use Server-side instead, even if your frontend is React.
Server-side
Section titled “Server-side”A web app where a backend (Node, Go, Python, Ruby) holds the OAuth tokens. The browser just gets a session cookie; tokens never reach the browser.
- OAuth flow — authorization code, with or without PKCE (PKCE recommended).
- Credentials —
client_id+client_secret. - Redirect URIs — required. Usually a route on the backend (
https://app.cymmetri.com/auth/callback). - Refresh tokens — stored server-side; the browser never sees them.
This is the safest default for any app with a backend. Use it unless you have a specific reason for SPA.
Native
Section titled “Native”Mobile (iOS / Android) or desktop apps. The user signs in via the system browser (not an in-app webview), then is bounced back to the app via a custom URI scheme or loopback HTTP listener.
- OAuth flow — authorization code + PKCE.
- Credentials —
client_idonly. No secret (an app's binary can be decompiled). - Redirect URIs — required. Custom scheme (
com.cymmetri.banking://callback) or loopback (http://127.0.0.1/callback). - Refresh tokens — stored in the platform's secure storage (iOS Keychain, Android Keystore, OS keyring on desktop).
If your "native" app is actually a Capacitor / Cordova / Electron wrapper around a browser SPA, it's still Native — the OAuth shape is the native pattern.
A backend service calling another backend. No human is signing in.
- OAuth flow — client credentials.
- Credentials —
client_id+client_secret. - Redirect URIs — not applicable.
- Audience — required. The API the M2M tokens will be used against.
- Allowed scopes — required. The list of capabilities this service is permitted to request.
- Refresh tokens — not issued. Get a fresh access token each time the cache expires.
Use M2M for: nightly batch jobs, cron tasks, internal microservices, anything that runs without a user in the loop. Don't use M2M for "the backend of a user-facing web app" — that's Server-side.
A Service Provider for SAML 2.0. Your application accepts SAMLResponse posts from an external IdP (Okta, Entra, etc.) and signs the user in based on the assertion.
- Protocol — SAML 2.0 (not OAuth).
- Credentials — certificate-based. Your tenant issues an SP certificate; the IdP issues a separate certificate; you exchange.
- Settings — entity ID, ACS URL, attribute mapping, JIT provisioning toggle.
- Tokens — IntelliAuth issues its own session + access token after SAML completes; downstream from there it's OAuth-shaped.
If your application is OAuth/OIDC and just happens to be hosted somewhere that also has SAML, pick SPA / Server-side / Native. SAML is for the case where the SAML protocol itself is the protocol.
When in doubt
Section titled “When in doubt”- Browser + no backend → SPA
- Browser + backend → Server-side
- Mobile or desktop app → Native
- Service-to-service, no human → M2M
- "Our IT team's SSO requires SAML" → SAML
You can change every other field on the application later. Type is the lone exception. Picking right the first time pays back across the application's life.