Documentation
OAuth Settings
This page is the server-side half of auth setup. Your app should use the auth route template and createSSI() with SSI_* environment variables (see the ssi-platform-integration skill for @serialsubscriptions/platform-integration: references/SETUP.md). Here you configure the default OAuth client in your Serial Subscriptions instance so those values work together.
For where these screens live in the product UI, see Platform settings (Auth Settings and Application Settings).
Who does this: a platform_admin on the instance (typically the person who provisioned it).
Where: in the Serial Subscriptions admin UI, open Platform Setup Checklist → OAuth App Integration → Modify (the Auth Settings screen).
What you are aligning
| In Serial Subscriptions (Auth Settings) | In your app (environment / createSSI) |
|---|---|
| Client ID | SSI_CLIENT_ID — must match exactly |
| New client secret (after Save) | SSI_CLIENT_SECRET — must match the secret you set (store only in env/secrets, never in git) |
| Redirect URIs (one line) | SSI_REDIRECT_URI — must match exactly (scheme, host, path, no trailing slash unless you deliberately use one) |
| (implicit: your instance’s OAuth issuer) | SSI_ISSUER_BASE_URL — the HTTPS base URL of this Serial Subscriptions instance (the same site where you open Auth Settings), with no path and no trailing slash |
The library discovers OIDC metadata from that issuer URL. If SSI_ISSUER_BASE_URL points at the wrong host, login and token exchange will fail.
Redirect URI to use with the default template
The auth route template (in the integration skill’s references/SETUP.md, Auth route handler template) serves the callback at:
GET /api/v1/auth/callback
So your Redirect URIs value is your app’s public origin plus that path.
Pattern:
https://<your-app-public-host>/api/v1/auth/callback
Examples:
- App served at
https://app.example.com→https://app.example.com/api/v1/auth/callback - Local Next dev with
NEXTAUTH_URL=http://localhost:3000→http://localhost:3000/api/v1/auth/callback(test only; production should be HTTPS)
Use the same URL in:
- Auth Settings → Redirect URIs (exactly one line, or one line per environment if you maintain separate OAuth clients—usually one client with one production URI is enough).
SSI_REDIRECT_URIin your app’s environment.redirectUripassed tocreateSSI()(oftenprocess.env.SSI_REDIRECT_URI).
Common mistake: a typo, wrong subdomain (www vs app), http vs https, or a trailing slash on only one side. The value must be byte-for-byte identical to what the browser hits on callback.
Step-by-step: recommended defaults with the library and template
Do these in order. Keep Auth Settings and your app’s .env open side by side for the secret step.
1. Client name
Enter a short label you will recognize (product or environment name). This is for administrators only; it does not have to match SSI_CLIENT_ID.
2. Client ID
Choose a unique identifier for this client (letters, numbers, hyphens—whatever your team allows). It must stay stable once apps depend on it.
- Set Client ID on the form to that value.
- Set
SSI_CLIENT_IDin your app to the same string.
Many teams use a readable slug (e.g. my-product-web). The platform may suggest a default from your hostname when you first configure the client; you may keep it or replace it, as long as it matches SSI_CLIENT_ID.
3. New client secret
You need a strong secret known to both the platform and your app.
- Click Generate on the form or paste a secret you created securely.
- Copy it immediately if you generated it.
- Click Save on the form.
- Set
SSI_CLIENT_SECRETin your app to that plaintext secret.
Important: after save, you cannot read the old secret back from the UI. If you lose it, generate a new one, save again, and update SSI_CLIENT_SECRET everywhere your app runs.
4. Grant types
Enable both:
- Authorization code
- Refresh token
The integration relies on the authorization code flow for login and on refresh tokens for automatic renewal in SessionManager (see the integration skill’s SKILL.md, SessionManager section). Do not omit Refresh token unless you have a custom, documented setup.
5. Scope selection
Choose All scopes (recommended).
That matches a typical first integration: your app receives the claims and API access the platform expects for subscription and org-aware features. Tightening scopes is an advanced step after everything works.
6. Redirect URIs
In the Redirect URIs textarea, put one URI per line for each callback you use (for example production only, or production + staging).
For the stock template, each line should be:
https://<your-app-public-host>/api/v1/auth/callback
(No quotes, no spaces at the ends.)
7. Additional OAuth Settings (defaults that work with createSSI)
Expand Additional OAuth Settings and use these starting defaults with the official library and template:
| Setting | Recommended for this integration | Why |
|---|---|---|
| Confidential client | Enabled | createSSI() is configured with clientSecret server-side; that matches a confidential OAuth client. |
| Require PKCE | Disabled (unless your security standard requires PKCE for this stack) | The documented template and typical confidential-server setup work with PKCE off. Turn Require PKCE on only if you also change the app to perform PKCE and test the full flow. |
| Access token expiration (seconds) | Leave the form default (or your org’s standard) | The library refreshes tokens when they are close to expiring; extreme values can cause more refresh traffic or shorter sessions than you expect. |
| Refresh token expiration (seconds) | Leave the form default (or your org’s standard) | Must remain long enough for “stay signed in” behavior; aligns with cookie/session expectations in the integration skill’s SETUP.md (Cookie Configuration). |
| Automatic authorization | Enabled | Skips the approval screen when the platform allows—smoother UX for your own app. |
| Remember approvals | Enabled | Reduces repeated consent prompts for returning users when the platform supports it. |
Save the form. You should return to the Platform Setup Checklist; the OAuth row can show as complete after a successful save.
8. Issuer URL in your app
Set:
SSI_ISSUER_BASE_URL=https://<your-serial-subscriptions-host>
Use the canonical HTTPS URL of the Serial Subscriptions account site (no path, no trailing slash)—the same place you used to open Auth Settings.
Application URLs (related checklist items)
OAuth is only part of the story. On Application Settings, set Login redirect URL and Logout URL to your app’s routes that start login and logout—typically the same app origin as your callback, e.g.:
https://app.example.com/api/v1/auth/loginhttps://app.example.com/api/v1/auth/logout
Those URLs are what end users (and the main menu) use to reach your Next.js handlers; they are not a substitute for Redirect URIs, which must still list the callback path exactly. See Platform settings for Application Settings.
Quick verification checklist
SSI_ISSUER_BASE_URLis the Serial Subscriptions instance origin (HTTPS, no trailing slash).SSI_CLIENT_ID/SSI_CLIENT_SECRETmatch Client ID and the saved secret.SSI_REDIRECT_URImatches Redirect URIs and the live URL of/api/v1/auth/callback.- Grant types include Authorization code and Refresh token.
- Confidential client is on; secret is only in server env, not in client bundles.
After deploy, hit Login, complete the provider flow, and confirm you land back on your app without ?error= on the home redirect. If callback fails once and succeeds on retry, see Callback error handling in the integration skill’s references/SETUP.md.
See also
- Platform settings — checklist, Auth Settings, Application Settings (product UI)
- ssi-platform-integration skill (ships with
@serialsubscriptions/platform-integration):references/SETUP.md,SKILL.md—createSSI(), env vars, auth route template, SessionManager