Authentication philosophy
Sudomimus treats every protocol boundary as independently exposed: browsers, application servers, native clients, relying parties, and the network between them may each be compromised. A flow should therefore avoid giving any one participant enough material to impersonate every other participant.
These principles apply across Connect, OIDC, and native direct-issue. Some sections use Connect as the concrete example; the protocol-specific mechanics live in the corresponding integration section.
1. Redemption proof is scoped to one session
Section titled “1. Redemption proof is scoped to one session”Most auth systems rely on a long-lived shared secret — OAuth’s client_secret, an API key, a static signing secret in the application’s environment. Leak it once, and every past and future exchange is compromised.
Connect avoids using a long-lived shared secret as sufficient proof to redeem every login. Each round-trip mints a fresh hiddenKey at /establish, uses it exactly once at /redeem, and then permanently consumes it. Leaking one hidden key compromises that redemption, not every login the application has ever handled.
This is proof-of-possession thinking: short, narrowly-scoped secrets beat long-lived shared ones.
What this rejects: trusting a single long-lived
client_secretto authenticate every token exchange forever.
2. Identity is separate from credentials
Section titled “2. Identity is separate from credentials”A Sudomimus account stores who someone is — a stable identity with a name. An authentication method stores how they prove it — a passkey, an email address, a Steam identity, an AccessKey credential. The two live in different records, and one account can hold many methods.
Consequences:
- Account enumeration is harder. The account record carries no email. An attacker probing whether
[email protected]exists has nowhere to query it from. - Switching auth methods doesn’t touch identity. A user adding a passkey to their email-OTP account is just a new authentication record. The account stays the same, and so does anything tied to it.
- There is no password column anywhere. Sudomimus does not store passwords. It cannot leak passwords because it has none to leak. The supported methods are passkeys, email OTP, social sign-in (Google, GitHub, Discord, Battle.net, X), Steam, and AccessKey credentials, with more being added.
What this rejects: treating email as identity, and the legacy of password databases.
3. Identity is opaque, and different for every application
Section titled “3. Identity is opaque, and different for every application”Sudomimus never hands your application its internal account identifier. What you receive is a pairwise identifier — a stable, opaque sub that is unique to your application. The same person signing into two different applications presents two unrelated identifiers, and neither can be reversed into the underlying account.
Consequences:
- No cross-application correlation. Two applications cannot collude to link “their” users into one real person by comparing identifiers.
- The identifier is opaque by contract. It is an exact-match token, not a structured value to parse. Sudomimus can change its internal format without breaking you, precisely because you were never meant to read anything out of it.
- A leaked token leaks one application’s view of a user — not a platform-wide identity.
What this rejects: a single global user id sprayed across every relying party, turning every integration into a tracking vector.
4. Users consent to what each application learns
Section titled “4. Users consent to what each application learns”An access token carries only the identity claims the user has agreed to share with that specific application. Email, first name, and last name are each granted or withheld independently, and a grant can be revoked at any time. Inclusion is re-evaluated live at every issue, so a revocation takes effect on the next token — not “eventually”.
Consequences:
- A claim you’d like may simply not be there. Design for its absence. If your application genuinely needs a claim, declare it required — Sudomimus then gates non-interactive issue until the user consents, rather than silently handing you nothing.
- You store less. Claims you never receive are claims you never have to protect.
What this rejects: the assumption that an application is entitled to a user’s full profile the moment they sign in.
5. Verification is cryptographic, not relational
Section titled “5. Verification is cryptographic, not relational”When your application receives an access token, it is a signed JWT. To trust it, your application verifies the signature against its own token-signing public key, which it fetches once from POST /info (the Connect surface) and caches. You do not call Sudomimus on every request to ask “is this user still logged in?”.
Consequences:
- No latency tax on every authenticated request — verification is local.
- No availability dependency between your service and Sudomimus once the user is signed in.
- Tokens are deliberately short-lived (access tokens default to a few hours, not days). When they expire, one HTTPS call against
/refreshgets a new one — far cheaper than re-authenticating the user.
OIDC ID tokens are a separate case: relying parties verify them against the JWKS at oidc.sudomimus.com/.well-known/jwks.json. See Tokens and verification for the full picture.
What this rejects: the stateful session-on-IdP model that turns every authenticated request into a remote lookup.
6. Access is allow-listed and default-deny
Section titled “6. Access is allow-listed and default-deny”Who may complete an authentication, by which method, and how the result is returned are all governed by explicit allow-lists. An application that has configured nothing authenticates nobody. The safe state is the default: access is something you deliberately open up, never something you have to remember to lock down.
What this rejects: systems that are wide open until an administrator remembers to restrict them.
7. Failure is scoped, not amplified
Section titled “7. Failure is scoped, not amplified”A common anti-pattern is the account lockout: too many wrong attempts and the account is frozen for an hour. It makes brute force harder, but it also gives anyone who knows your email a free denial-of-service vector.
Sudomimus does it differently. Each authentication session carries its own life counter. Wrong attempts decrement that session’s life — not the account’s. When a session runs out of life, that session dies; the user simply starts another one. The account itself is never locked.
What this rejects: punishing the legitimate user for the attacker’s behaviour.
8. Three keys, three vantage points
Section titled “8. Three keys, three vantage points”To forge a successful /redeem against Sudomimus, an attacker must simultaneously hold:
- A secret that lives only on the application server (the hidden key)
- A reference that was only ever sent to one specific browser (the exposure key)
- A proof that Sudomimus only mints after a real challenge succeeds (the confirmation key)
No single point of failure produces all three. A leaked URL does not compromise the server’s secret. A compromised server does not compromise other users’ sessions. A phished user does not compromise the server.
The mechanics are in the three-key model. The principle is general: split a proof three ways across three trust domains.
What this rejects: monolithic session tokens whose theft is full compromise.
9. Trust boundaries are enforced, not documented
Section titled “9. Trust boundaries are enforced, not documented”Sudomimus has exactly five public surfaces — connect-api.sudomimus.com, via.sudomimus.com, device-api.sudomimus.com, native-api.sudomimus.com, oidc.sudomimus.com. Everything an integration can reach, it reaches through one of these; anything else is internal, and internal here means unreachable from outside the platform — enforced at the platform edge, not asserted in a document and left one misconfiguration away from exposure.
The practical consequence: there are a small number of well-defined paths through which an authentication can be completed, and integrations cannot bypass them.
What this rejects: soft conventions like “this is an internal API, please don’t call it.”
What this means for you
Section titled “What this means for you”When you integrate with Sudomimus, you inherit these properties for free:
- You never see a password, so you have nothing to store securely.
- You receive an opaque, per-application identifier — you cannot accidentally become a cross-site tracking vector, because you were never given a global id to leak.
- You only ever hold the identity claims a user agreed to share with you.
- Your application verifies tokens offline; Sudomimus availability doesn’t gate access to your own backend.
- A leak of any single secret in your application is bounded to one session.
- You don’t need to build account lockout logic.
- You don’t need to write account-enumeration defences.
Next, choose an integration path or inspect the concrete Connect flow.