Version: v0.4

Username or Email and Password

This document summarizes exemplary request payloads for performing "login or sign up with email/username and password" flows using the user login and registration flow with the password strategy.

Browser Clients

Registration

Redirecting the browser to the Self-Service Login and Registration Endpoint initiates the flow. If the password strategy is enabled, the Registration Request Response Payload will include a password method.

ORY Kratos uses the Identity JSON Schema defined in identity.default_schema_url to generate a list of form fields and add it to the Registration Request. Using an Identity JSON Schema like

my/identity.schema.json
{
"$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"properties": {
"traits": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"title": "E-Mail",
"minLength": 3,
"ory.sh/kratos": {
"credentials": {
"password": {
"identifier": true
}
}
}
},
"name": {
"type": "object",
"properties": {
"first": {
"type": "string"
},
"last": {
"type": "string"
}
}
}
},
"required": ["email"],
"additionalProperties": false
}
}
}

will result in the following Registration Request

$ curl http://<kratos-admin>/self-service/browser/flows/requests/registration?request=713df601-d6c8-4331-8195-c29b92db459f
{
id: '713df601-d6c8-4331-8195-c29b92db459f',
expires_at: '2020-01-27T16:31:00.3507956Z',
issued_at: '2020-01-27T16:21:00.3508076Z',
request_url: 'http://127.0.0.1:4455/auth/browser/registration',
methods: {
password: {
method: 'password',
config: {
action: 'http://127.0.0.1:4455/.ory/kratos/public/self-service/browser/flows/registration/strategies/password?request=713df601-d6c8-4331-8195-c29b92db459f',
method: 'POST',
fields: [
{
name: 'csrf_token',
type: 'hidden',
required: true,
value: '0klCuilgIO2k0Ev3J3IEsMOlmxg0RhjiiiWXVKm3Pd7HxZLVkDHWoOSfiT+/BJn69Dg2fmq6MHv8HkEx6MrVlw=='
},
{
name: 'traits.email',
type: 'email',
required: true
},
{
name: 'password',
type: 'password',
required: true
},
{
name: 'traits.name.first',
type: 'text'
},
{
name: 'traits.name.last',
type: 'text'
}
]
}
}
}
}

which in turn is easily to render by filling out a HTML Form template:

<form method="{{ method }}" action="{{ action }}">
<!-- repeat this for every field -->
<input type="{{ field.type }}" name="{{ field.name }} required="{{
field.required }}" value="{{ field.value }}"
<!-- ... -->>
<input type="submit" value="Create account" />
</form>

Once the user clicks "Create Account", the payload will be sent to ORY Kratos' Public API. The data will be validated against the Identity JSON Schema (e.g. checking if a required field is missing, if some condition like minLength is not fulfilled, ...). If the data is invalid or incomplete, the browser will be redirected to the same login endpoint with the same request ID. When fetching that request ID again, error details will be included in the JSON Response, such as:

$ curl http://<kratos-admin>/self-service/browser/flows/requests/registration?request=713df601-d6c8-4331-8195-c29b92db459f
{
id: '713df601-d6c8-4331-8195-c29b92db459f',
expires_at: '2020-01-27T16:31:00.3507956Z',
issued_at: '2020-01-27T16:21:00.3508076Z',
request_url: 'http://127.0.0.1:4433/self-service/browser/flows/registration',
active: 'password', // <- this is now set
methods: {
password: {
method: 'password',
config: {
messages: [
{
/* id, type */
text: 'Please update the Form Fields to proceed.'
}
],
action: 'http://127.0.0.1:4455/.ory/kratos/public/self-service/browser/flows/registration/strategies/password?request=713df601-d6c8-4331-8195-c29b92db459f',
method: 'POST',
fields: [
/* ... */
{
name: 'password',
type: 'text',
value: 't4aegbydfv5234',
messages: [
{
/* id, type */
text: "traits.email: Does not match format 'email'"
}
]
}
/* ... */
]
}
}
}
}

Validation error messages and context will be improved in future releases. This is tracked as kratos#185.

The flow completes otherwise.

Login

Redirecting the browser to the Self-Service Login and Registration Endpoint initiates the flow. If the password strategy is enabled, the Login Request Response Payload will include a password method. In contrast to the Registration sequence, this payload does not change when the Identity JSON Schema changes:

$ curl http://<kratos-admin>/self-service/browser/flows/requests/login?request=0cfb0f7e-3866-453c-9c23-28cc2cb7fead
{
id: '0cfb0f7e-3866-453c-9c23-28cc2cb7fead',
expires_at: '2020-01-27T16:48:53.8826084Z',
issued_at: '2020-01-27T16:38:53.8826392Z',
request_url: 'http://127.0.0.1:4433/self-service/browser/flows/login',
methods: {
password: {
method: 'password',
config: {
action: 'http://127.0.0.1:4455/.ory/kratos/public/self-service/browser/flows/login/strategies/password?request=0cfb0f7e-3866-453c-9c23-28cc2cb7fead',
method: 'POST',
fields: [
{
name: 'csrf_token',
type: 'hidden',
required: true,
value: 'F0LABRxm/os+18VBUcbmz98LkJid1sEj++4X41rcdbcCzhBqpTcIxn6YB4nJsHuF6JY9/sMq6bqN1cGGG6Gd/g=='
},
{
name: 'identifier',
type: 'text',
required: true
},
{
name: 'password',
type: 'password',
required: true
}
]
}
}
}
}

If the login form is filled out incorrectly, errors are included in the response:

$ curl http://<kratos-admin>/self-service/browser/flows/requests/login?request=0cfb0f7e-3866-453c-9c23-28cc2cb7fead
{
id: '0cfb0f7e-3866-453c-9c23-28cc2cb7fead',
expires_at: '2020-01-27T16:48:53.8826084Z',
issued_at: '2020-01-27T16:38:53.8826392Z',
request_url: 'http://127.0.0.1:4455/auth/browser/login',
active: 'password', // <-- this is now set
methods: {
password: {
method: 'password',
config: {
messages: [
{
/* id, type */
text: 'Please check the data you provided.'
}
],
action: 'http://127.0.0.1:4455/.ory/kratos/public/self-service/browser/flows/login/strategies/password?request=0cfb0f7e-3866-453c-9c23-28cc2cb7fead',
method: 'POST',
fields: [
/* ... */
{
name: 'password',
type: 'password',
required: true,
messages: [
{
/* id, type */
text: 'password: password is required'
}
]
}
]
}
}
}
}

The flow completes otherwise.

API Clients

API-based login and registration using this strategy will be addressed in a future release of ORY Kratos.

Security and Defenses

Password-based authentication flows are subject to frequent abuse through

  • Social Engineering Attacks;
  • Password Guessing Attacks;
  • Phishing Attacks.

Anti-automation

This feature is a work in progress and is tracked as kratos#133.

Actions that cause out-of-band communications, such as sending an activation link via email or an activation code via SMS, can be abused by automated systems. The goal of such an attack is to send out so many emails or SMS, that your reputation worsens (spam filters) or you're faced with massive costs (carrier fees).

CAPTCHA renders these attacks either very difficult or impossible. ORY Kratos has CAPTCHA support built-in. ORY Kratos will prompt the user to complete a CAPTCHA in the following scenarios:

  • The user tries to register more than one account within 72 hours.
  • The user failed provide valid credentials for the third time within 12 hours.
  • The user tries to recover their account for the second time within 72 hours.

For integration guidelines, please check the individual flow's (registration, login, account recovery) integration documentation.

Account Takeover Defenses

The Settings flow implements account takeover defenses as it is not possible to change the password without knowing the existing password. A good example of this flow is the GitHub sudo mode.

Password Validation

Further improvements are work in progress and are tracked on GitHub

To prevent weak passwords ORY Kratos implements different measures. Users often choose passwords similar to their traits. To prevent this ORY Kratos ensures there is a sufficient Levenshtein-Distance (aka "Edit-Distance") between the identifier and the password. It also makes sure that the identifier and password have a small enough longest common substring.

Furthermore the password strategy comes with a build-in check against the "Have I been pwned" breach database. This way ORY Kratos makes sure your users cannot use passwords like "password", "123456" or any other commonly used one. To protect the value of the password the range API is being used.

Account Enumeration Defenses (work in progress)

warning

This feature is a work in progress and is tracked as kratos#133.

It does not yet work as documented!

Account enumeration attacks allow a attacker to find out who is signed up. This compromises the privacy of your users and can hurt reputation depending on the service (e.g. "adult content").

This attack usually makes only sense if an email address or a phone number is collected during registration. For chosen usernames, this attack is much more difficult, as the attacker has to know what usernames the victim is using.

There are three common ways an attacker can figure out if a user is signed up at a service:

  • During login: "No user with this email address was found"
  • During registration: "A user with this email address exists already"
  • During password reset: "No user with this email address was found"

To mitigate this attack, the following strategies need to be deployed:

  • The login form should return the same message regardless of whether the password is wrong or the email/username does not exist: "The provided credentials are invalid."
  • The password reset form should always return a success message and send out an email. If the email address is registered, a normal password reset email is sent. If the email address is not registered, an email is sent to the address indicating that no account is set up with that email address. This is helpful to users that have multiple email addresses and are using the wrong email address for the password reset.
  • The registration form should also always return a success message and send out an email. If the email address is not yet registered, a regular "account activation" email is sent out. If the email address is registered already, a email is sent out telling the user that the account is already set up, and link to the login screen.

If you wish to mitigate account enumeration attacks, it is important to note that you cannot sign in users directly after sign up! Depending on the type of service you provide, you might not care about this specific attack in which case direct login after sign up would be ok.

Enabling Account Enumeration Defenses

Assuming you wish to enable account enumeration defenses, you need to configure ORY Kratos as follows:

  • Collect one or more email addresses during sign up and enable email verification.
  • Do not enable the session post-registration workflow.
selfservice:
flows:
verification:
enabled: true

Disable Account Enumeration Defenses

Enforcing email verification, which requires an email round trip and disrupts the sign up process, is not always feasible. In these cases, you might want to disable account enumeration defenses.

You can disable the defense mechanism on a per-field basis in your Identity JSON Schema:

path/to/my/identity.schema.json
{
"$id": "https://example.com/identity.traits.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"properties": {
"traits": {
"type": "object",
"properties": {
"username": {
"type": "string",
"ory.sh/kratos": {
"credentials": {
"password": {
"identifier": true,
"disable_account_enumeration_defenses": true
}
}
}
}
}
}
}
}

This will tell ORY Kratos to display messages such as "a user with this email address exists already" and "no user with this email address is registered on this site". You can then enable the session post-registration workflow:

selfservice:
flows:
registration:
after:
password:
- hook: session
Last updated on by aeneasr