Olympus Docs
Get Started

Identity vs OAuth2

Why Olympus runs both Kratos and Hydra

Olympus uses two Ory services per domain, Kratos and Hydra. New operators often ask why; they look like overlapping concerns.

They aren't. They handle different problems.

Kratos, identity

Kratos is the identity database and the self-service flows around it. It owns:

  • Who the users are, identities, traits (the schema-defined trait fields like email, name, role), credentials (password hashes, OIDC links, TOTP secrets, WebAuthn keys).
  • The lifecycle flows, registration, login, password recovery, email verification, settings (change password, change email, enroll TOTP).
  • The sessions, once a user logs in, Kratos issues a session cookie that survives across the user's interactions with your apps.

Kratos has nothing to do with OAuth2.

Hydra, OAuth2

Hydra is an OAuth2 / OIDC server. It owns:

  • OAuth2 clients, registered applications that can request tokens.
  • Authorization grants, implementations of the Authorization Code flow (with PKCE), Client Credentials flow, Refresh tokens, etc.
  • Tokens, access tokens, refresh tokens, ID tokens. Signing keys.
  • The consent flow, when a client requests scopes, Hydra renders or auto-grants a consent decision.

Hydra has nothing to do with passwords. It does not know how to authenticate a user.

How they compose

The handoff is the login challenge. When an app starts an OAuth2 flow:

1. App: redirect user to Hydra /oauth2/auth?client_id=...
2. Hydra: I need to know who this user is. Redirect to Hera (the configured login UI)
         with a login_challenge=abc123.
3. Hera: ask Kratos for the current session.
4a.  If no session: render the Kratos login flow. Let the user log in.
4b.  If session exists: accept the login challenge with Kratos's identity.id.
5. Hera: tell Hydra "this is identity X" by accepting the login challenge.
6. Hydra: now I need consent for the requested scopes. Redirect to Hera with a
          consent_challenge=def456.
7. Hera: render or auto-grant consent.
8. Hera: tell Hydra "consent is granted for scopes [profile, email]".
9. Hydra: issue an authorization code. Redirect to the app's callback.
10. App: exchange code for tokens.

Kratos authenticates the user. Hydra authorizes the app. Hera is the glue UI.

Why not just one server?

The Ory team split them, and Olympus follows, because the two responsibilities have very different shapes:

  • Identity is about long-lived records, schemas, recovery, lifecycle. The hard problems are correctness (no race conditions on credential update), privacy (PII handling, GDPR), and recovery (don't lose access on email change).
  • OAuth2 is about short-lived tokens, cryptography, RFCs, IETF errata. The hard problems are protocol correctness (PKCE, refresh-token rotation, downscoping) and key management (JWKs, rotation).

Conflating them means one codebase tries to be both, and history is littered with auth servers that get one half right and the other wrong.

By splitting, you can also independently scale, version, and operate each.

When you only need one

  • An app that just needs login (no third-party API authorization) can interact with Kratos alone. The Kratos session cookie is enough.
  • A pure machine-to-machine flow (worker → backend API, no human involved) can interact with Hydra alone. The client credentials grant doesn't touch Kratos.

In Olympus the two run in lockstep because the most common case, a customer logging into your app, requires both: Kratos to identify the user, Hydra to authorize your app's session token.

Where next

On this page