# Ory Kratos — identity & self-service auth. Identity schema (email, name) + # password login; recovery & verification run on email codes. Every self-service # flow returns the browser to our own themed routes (§4 renders the fields). DSN + # prod courier/secrets come from the env. The session→JWT tokenizer is wired below; # its JWKS signing key is generated/mounted by the next §3 item. serve: public: base_url: http://127.0.0.1:4433/ cors: enabled: false admin: base_url: http://kratos:4434/ selfservice: default_browser_return_url: http://127.0.0.1:3000/ allowed_return_urls: - http://127.0.0.1:3000 methods: password: enabled: true code: # email one-time code — powers recovery + verification (not login) enabled: true # Social sign-in (Google, Microsoft, or SAML via an OIDC bridge like Ory Polis — # OSS Kratos has no native SAML). OFF by default → a clean clone is password-only. # Activate WITHOUT code changes by supplying env (the whole-array form is the only # env-settable one Kratos offers); providers reference the committed claims mapper, # and §4 derives the buttons from this list: # SELFSERVICE_METHODS_OIDC_ENABLED=true # SELFSERVICE_METHODS_OIDC_CONFIG_PROVIDERS=[{"id":"google","provider":"google", # "client_id":"…","client_secret":"…","scope":["openid","email","profile"], # "mapper_url":"file:///etc/config/kratos/oidc/claims.jsonnet"}] oidc: enabled: false config: providers: [] flows: error: ui_url: http://127.0.0.1:3000/error login: ui_url: http://127.0.0.1:3000/login registration: ui_url: http://127.0.0.1:3000/registration after: password: hooks: - hook: session # log in immediately after sign-up - hook: show_verification_ui settings: ui_url: http://127.0.0.1:3000/settings privileged_session_max_age: 15m required_aal: highest_available recovery: enabled: true use: code ui_url: http://127.0.0.1:3000/recovery verification: enabled: true use: code ui_url: http://127.0.0.1:3000/verification after: default_browser_return_url: http://127.0.0.1:3000/ logout: after: default_browser_return_url: http://127.0.0.1:3000/login # Dev mail catcher (compose.override.yml). Prod overrides via COURIER_SMTP_CONNECTION_URI. courier: smtp: connection_uri: smtp://mailpit:1025/?disable_starttls=true from_address: no-reply@plainpages.local from_name: Plainpages identity: default_schema_id: default schemas: - id: default url: file:///etc/config/kratos/identity.schema.json # "Stay signed in" backbone: a long-lived Kratos session that the app re-mints the # short-lived (~10m) JWT off (§4). Sliding refresh — an active session is extended # back to full lifespan only once it's within earliest_possible_extend of expiry, # so frequent users never lapse without a DB write per request. session: lifespan: 720h # 30 days earliest_possible_extend: 24h cookie: name: plainpages_session persistent: true # survive browser restarts same_site: Lax # Session→JWT tokenizer (§4): whoami(tokenize_as: plainpages) mints a short-lived, # locally-verifiable JWT so the hot path never calls Ory. Claims come from the # committed Jsonnet mapper (sub = identity id, email from traits, roles from the # metadata_admin projection); signed with the JWKS the next §3 item generates/mounts. whoami: tokenizer: templates: plainpages: ttl: 10m subject_source: id claims_mapper_url: file:///etc/config/kratos/tokenizer/plainpages.jsonnet jwks_url: file:///etc/config/kratos/tokenizer/jwks.json # Dev throwaways — production supplies real secrets via env (§3). cipher = 32 chars. secrets: cookie: - PLEASE-CHANGE-ME-dev-kratos-cookie-secret cipher: - 0123456789abcdef0123456789abcdef log: level: info format: text