Securing Identity Recovery in Ory Kratos: Beyond Basic Email Links
Secure Ory Kratos identity recovery by configuring rate limiting and understanding the flow state machine, preventing enumeration and DoS attacks.
06 Mar 2026, 09:42 UTC

The Problem: Unsecured Identity Recovery is a Direct Attack Vector
When a user needs to reset a password, a simple "send reset link" mechanism is often insufficient. If not properly rate-limited or state-managed, this flow exposes users to email enumeration, token guessing, and denial-of-service (DoS) attacks against your identity service.
Kratos State Machine for Flow Integrity
Ory Kratos manages this via a state machine. Each recovery attempt is tracked using a unique flow_id. The flow progresses through defined states (e.g., ui to success), ensuring actions are sequential and tamper-proof. Security relies on the presence of a csrf_token in requests.
Hardening Recovery with Configuration
Abuse prevention is configured via config.yaml, specifically under identity.recovery. Enabling rate limiting here is crucial for production hardening.
Example: Enabling Rate Limiting
To prevent rapid, automated recovery attempts against a single identity, configure rate limiting:
identity:
recovery:
enabled: true
allow_self_service_recovery_request: true
identity_recovery:
rate_limit_per_identity: 3 # Example: Max 3 requests per identity within a timeframe
Actionable Check: Verify that the Kratos service logs indicate rate-limiting blocks when exceeding the configured threshold, rather than simply rejecting the request silently.
Trade-off: Customization vs. Compliance
While Ory Kratos allows deep customization of email templates using Handlebars syntax (e.g., customizing the subject or body), this flexibility requires the operator to ensure compliance (GDPR/CCPA). Custom templates must not inadvertently leak PII or expose flow state details.
Limitation: Default configurations must be audited. Relying solely on defaults without verifying SMTP setup or rate limits introduces operational risk.
Actionable Next Step
Before deployment, test the full recovery cycle using a local Docker Compose setup. Verify that the email delivery is captured by a local SMTP catcher (like MailHog) and confirm that the rate-limiting logic triggers correctly when exceeding the defined rate_limit_per_identity.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.