Skip to main content
Password authentication is the most common authentication method, allowing users to register and sign in with an identifier (such as email or username) and a password.

Overview

The password strategy provides:
  • Registration with password credentials
  • Login with identifier and password
  • Password update and change functionality
  • Built-in password validation and breach detection
  • Support for password migration hooks

Configuration

Enable password authentication

Add the password method to your Kratos configuration:
kratos.yml
selfservice:
  methods:
    password:
      enabled: true

Password validation

Kratos includes a default password validator that:
  • Checks password length (minimum 8 characters recommended)
  • Validates password against haveibeenpwned.com using k-anonymity
  • Ensures password is not too similar to the identifier
  • Prevents common password patterns
The validation is implemented in selfservice/strategy/password/validator.go:59-90 and uses:
  • Troy Hunt’s haveibeenpwned API for breach detection
  • Levenshtein distance to compare password with identifier
  • Longest common substring analysis

Password hashing

Configure the password hashing algorithm:
kratos.yml
hashers:
  algorithm: bcrypt
  bcrypt:
    cost: 12  # Higher cost = more secure but slower
Supported algorithms:
  • bcrypt (recommended)
  • argon2 (more secure, more resource intensive)

Identity schema configuration

Basic password configuration

Define which trait serves as the identifier for password authentication:
identity.schema.json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "traits": {
      "type": "object",
      "properties": {
        "email": {
          "type": "string",
          "format": "email",
          "title": "E-Mail",
          "ory.sh/kratos": {
            "credentials": {
              "password": {
                "identifier": true
              }
            }
          }
        }
      },
      "required": ["email"]
    }
  }
}
The field marked with "identifier": true will be used as the username for login.

Multiple identifiers

You can configure multiple fields as identifiers:
identity.schema.json
{
  "properties": {
    "traits": {
      "properties": {
        "email": {
          "type": "string",
          "format": "email",
          "ory.sh/kratos": {
            "credentials": {
              "password": {
                "identifier": true
              }
            }
          }
        },
        "username": {
          "type": "string",
          "ory.sh/kratos": {
            "credentials": {
              "password": {
                "identifier": true
              }
            }
          }
        }
      }
    }
  }
}
Users can then login with either their email or username.

User flows

Registration flow

1

Initialize registration

Create a new registration flow:
curl -X GET https://your-kratos-instance/self-service/registration/browser
2

Submit registration

Submit the registration form with password credentials:
curl -X POST https://your-kratos-instance/self-service/registration?flow=<flow-id> \
  -H "Content-Type: application/json" \
  -d '{
    "method": "password",
    "password": "your-secure-password",
    "traits": {
      "email": "user@example.com"
    }
  }'
3

Handle response

On success, the user is registered and a session is created.

Login flow

1

Initialize login

Create a new login flow:
curl -X GET https://your-kratos-instance/self-service/login/browser
2

Submit credentials

Submit the login form:
curl -X POST https://your-kratos-instance/self-service/login?flow=<flow-id> \
  -H "Content-Type: application/json" \
  -d '{
    "method": "password",
    "identifier": "user@example.com",
    "password": "your-secure-password"
  }'
3

Session created

On success, a session is created and returned.

Password update

Users can update their password through the settings flow:
curl -X POST https://your-kratos-instance/self-service/settings?flow=<flow-id> \
  -H "Content-Type: application/json" \
  -H "Cookie: ory_kratos_session=<session-token>" \
  -d '{
    "method": "password",
    "password": "new-secure-password"
  }'

Security considerations

Always use HTTPS in production to protect passwords in transit.

Password policy

While Kratos provides default validation, you should:
  1. Enforce minimum password length (8+ characters recommended)
  2. Use the breach detection feature (enabled by default)
  3. Consider implementing rate limiting on login attempts
  4. Enable account recovery flows

Breach detection

Kratos automatically checks passwords against the haveibeenpwned.com database using k-anonymity:
  • Only the first 5 characters of the password hash are sent
  • No plain-text passwords leave your infrastructure
  • Validates against known breached passwords
Implementation details in selfservice/strategy/password/validator.go:93-95.

Password migration

If migrating from another system, you can use password migration hooks:
kratos.yml
selfservice:
  methods:
    password:
      config:
        haveibeenpwned_enabled: true
        max_breaches: 0
        ignore_network_errors: true
The strategy supports checking UsePasswordMigrationHook flag in credentials (see selfservice/strategy/password/strategy.go:91-92).

API reference

Strategy implementation

The password strategy is implemented as:
  • Strategy ID: password (as identity.CredentialsType)
  • Node Group: password group in UI nodes
  • AAL Level: AAL1 (first factor authentication)
See selfservice/strategy/password/strategy.go:78-80 for the strategy structure.

Configuration options

selfservice:
  methods:
    password:
      enabled: true

Next steps

Build docs developers (and LLMs) love