Authentication overview
Catentio doesn't have its own login system. We use Huudis — Forjio's shared identity provider — so you can use the same email and password (or Google / Apple account) across Catentio, Plugipay, Storlaunch, Fulkruma, LinkSnap, Pawpado, and any other Forjio product.
If you've signed up for a Forjio product before, you can sign in to Catentio with that same account — subject to the single-user gate explained below.
One identity, many products. Your Huudis account is yours, not Catentio's. We don't store your password — Huudis does. We just trust the bearer tokens Huudis issues us when you sign in.
The single-user gate (v1)
Catentio v1 is single-user. Only one specific Huudis identity — configured at deploy time via the HUUDIS_ALLOWED_USER_ID env var — is allowed to sign in. Every other Huudis-authenticated user hits the OIDC callback, has their sub claim compared against the allowlist, and is sent back with forbidden_user.
This isn't a bug or a placeholder. The architecture decision is locked: ADR-0007 in the catentio repo. The runtime under the control plane runs every agent under one principal's Anthropic OAuth and credentials; multi-tenant Catentio is a separate deployment topology behind the public-SaaS provisioning track.
If you're not the configured user and you'd like to evaluate Catentio, contact us.
How sign-in works (the short version)
Sign-in is a standard OpenID Connect (OIDC) authorization-code flow. The five steps are:
- You click Log in on
catent.io. - The portal redirects you to
huudis.com/api/v1/oidc/authorizewith a request to authenticate. - You enter your email and password (or click Google / Apple) on Huudis.
- Huudis redirects you back to
catent.io/callbackwith a one-timecode. - The portal's callback exchanges the code, verifies your
subagainst the allowlist, sets a secure cookie, and you're in.
You never see steps 2–4 visually; they happen in HTTP redirects.
How sign-in works (the longer version)
Catentio uses OIDC authorization code with PKCE:
- Authorization request —
/api/v1/auth/huudis/startgenerates a randomcode_verifier, derives acode_challenge, stores both in a server-side PKCE cookie, and redirects you to Huudis with the challenge. - User authentication — Huudis prompts you for credentials (or detects an active Huudis session). When you authenticate, Huudis returns a one-time authorization code.
- Redirect with code — Huudis redirects to
catent.io/callback?code=…&state=…. - Token exchange — The callback POSTs the code (and the original
code_verifier) to Huudis's token endpoint and gets access + refresh tokens. - Single-user gate — The portal decodes the access token's claims and rejects anyone whose
subisn'tHUUDIS_ALLOWED_USER_ID. - Session cookie — The portal HMAC-signs a session payload containing the Huudis tokens and sets it as an
httpOnly,Securecookie (catentio_session).
The refresh token rotates on every use, with reuse detection: if Huudis sees the same refresh token presented twice, it treats it as a stolen-token signal and revokes the whole token family. Catentio implements a single-flight refresh cache to prevent this from triggering during normal browser polling.
Who uses which path?
| Audience | Auth path |
|---|---|
| You signing into the portal | OIDC code flow above. Cookie session in the browser. |
| You, calling the API from a script you run yourself | OIDC device flow. Same Huudis identity, different transport. See API authentication. |
| Server-to-server callers (a cron job, an integration) | Static API key. Mint at Dashboard → API keys. |
| The runtime calling the control plane | A signed service token (X-Catentio-CP-Token). Out of scope for these docs — internal. |
| The chat-bubble / live REPL session | Inherits the portal cookie session. |
The portal cookie and an API key are independent. Revoking one doesn't affect the other.
What goes in the session cookie
The Catentio session cookie (catentio_session) is a base64url payload signed with HMAC-SHA256 by the portal backend. It contains:
huudisAccessToken— the active access token, used to call Huudis APIs on your behalf.huudisRefreshToken— used to mint new access tokens when the current one expires.huudisUserId— your Huudissub, used as the durable identifier and matched against the single-user allowlist on every gated request.accessExpAt— epoch millis when the access token expires (triggers proactive refresh).
The cookie is httpOnly (no JavaScript can read it) and Secure (HTTPS-only). It can't be inspected from the browser console.
The chat-bubble session model
Catentio's signature surface is the chat bubble — an embedded gojo REPL bound to your portal session. The bubble is what makes catent.io feel like an operator console rather than a database UI: every dashboard page has the bubble; you can ask it to "go to runs", "invoke cimi with this", "summarise the last seven days of cost" without leaving the page.
The bubble's auth model is deliberately minimal: it sends the same catentio_session cookie the rest of the portal sends. There's no extra token, no Bearer header, no signed handshake from the client side. The server-side /api/v1/chat/* endpoints verify the cookie's HMAC and the single-user gate, then forward to the runtime over the control plane's authenticated service channel.
This means the bubble works wherever your portal cookie is valid — same browser, same domain, same session. It also means signing out of the portal cleanly tears down the bubble.
Single sign-on across products
Because every Forjio product points at the same Huudis instance, you're already signed in to all of them once Huudis has an active session for you. Visit Plugipay after signing into Catentio — you skip the password screen.
You can sign out of one product without signing out of the others: each product owns its own session cookie. To sign out everywhere, click Sign out of all products in the Huudis identity portal.
What can go wrong
forbidden_userat callback. You're a valid Huudis user, but not the one configured in the v1 allowlist. There's no path forward without changingHUUDIS_ALLOWED_USER_IDserver-side.- Email not verified. If you signed up via email and didn't click the verification link, you can't sign in. Re-request from Huudis.
- Forgot password. Catentio can't reset it — Huudis owns passwords. Follow the Forgot password flow.
- Session expired. Cookies live for 7 days of inactivity. After that, you'll be sent back through the OIDC flow on your next page load.
Next
- Sign in — the user-facing flow with screenshots.
- Forgot password — password reset.
- API authentication — Bearer + API-key details.