Skip to main content

Identity Schema - the model that defines the data that makes up user accounts

The Identity Schema is a JSON schema that describes the data model that makes up the identity. In Ory, every identity can have its own model (a unique set of data fields).

Available presets

Ory Cloud provides three basic Identity Schema presets.

Username and password

This preset is useful for applications that don't need the user's email address and don't prioritize a high degree of user anonymity.

danger

This preset disables account verification, account recovery, and account enumeration defenses. Don't use it in security-sensitive environments.

With this preset, every identity has a single trait - the username. The username is the login identifier:

// Identity example
{
id: "6e9d3d30-f93e-4630-901f-c2096953723d",
traits: {
username: "some-username",
},
}

Email and password

With this preset, identities have a single trait, the email. The email is the login identifier and is used for email verification and for account recovery:

// Identity example
{
id: "6e9d3d30-f93e-4630-901f-c2096953723d",
traits: {
email: "foo@bar.com",
},
}

Example with name and newsletter opt-in

This preset has an email field, a first name, last name, and a "newsletter" checkbox.

// Identity example
{
id: "6e9d3d30-f93e-4630-901f-c2096953723d",
traits: {
email: "foo@bar.com",
name: {
first: "Foo",
last: "Bar",
},
newsletter: true,
},
}

Identity Schema vocabulary extensions

Because the system doesn't know that a particular field has a system-relevant meaning, you have to specify that in the schema. For example:

  • This email address should be used for recovering a lost password.
  • This identifier (username or email) should be used for logging in with a password.
  • This is the phone number used for SMS 2FA.

A vocabulary extension can be used within a property:

{
"$id": "http://mydomain.com/schemas/v2/customer.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "A customer (v2)",
"type": "object",
"properties": {
"traits": {
"type": "object",
"properties": {
"email": {
"title": "E-Mail",
"type": "string",
"format": "email",

// This tells Ory Kratos that the field should be used as the "username" for the username+password flow.
// It's an extension to the regular JSON Schema vocabulary.
"ory.sh/kratos": {
"credentials": {
"password": {
"identifier": true
}
}
}
}
}
}
}
}

Identifier for username and password flows

You can configure Ory Identity Service (Ory Kratos) to use specific fields as the identity's identifier. In this example, the password is set as the identifier:

{
"ory.sh/kratos": {
"credentials": {
"password": {
"identifier": true
}
}
}
}

Email

Looking at the traits from above

traits:
# These are just examples
email: office@ory.sh
name:
first: Aeneas
last: Rekkas
favorite_animal: Dog
accepted_tos: true

and using a JSON Schema that uses the email field as the identifier for the password flow:

{
"$id": "http://mydomain.com/schemas/v2/customer.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "A customer (v2)",
"type": "object",
"properties": {
"traits": {
"type": "object",
"properties": {
"email": {
"title": "E-Mail",
"type": "string",
"format": "email",

// This tells Ory Kratos that the field should be used as the "username" for the username and password flow.
"ory.sh/kratos": {
"credentials": {
"password": {
"identifier": true
}
}
}
},
"name": {
"type": "object",
"properties": {
"first": {
"type": "string"
},
"last": {
"type": "string"
}
}
},
"favorite_animal": {
"type": "string"
},
"accepted_tos": {
"type": "string"
}
},
"required": ["email"],
"additionalProperties": false
}
}
}

In this example, Ory understands that traits.email='office@ory.sh' is the identifier for this identity. The system must get office@ory.sh and a password to sign in an user.

Username and Password Credentials contains more information and examples about credentials usage.

Note that the format field of the Identity Schema will perform validation of the given trait. In this example, the email address is validated using the JSONSchema rule set.

Phone number

Let's extend the Identity Schema from the previous chapter with a phone number:

{
"$id": "http://mydomain.com/schemas/v2/customer.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "A customer (v2)",
"type": "object",
"properties": {
"traits": {
"type": "object",
"properties": {
"email": {
"title": "E-Mail",
"type": "string",
"format": "email",

// This tells Ory Kratos that the field should be used as the "username" for the Username and Password Flow.
"ory.sh/kratos": {
"credentials": {
"password": {
"identifier": true
}
}
}
},
"phone": {
"title": "Phone",
"type": "string",
"format": "tel",

// The phone number is marked as an identifier. This allows the user to log in with both email and phone number.
"ory.sh/kratos": {
"credentials": {
"password": {
"identifier": true
}
}
}
},
"name": {
"type": "object",
"properties": {
"first": {
"type": "string"
},
"last": {
"type": "string"
}
}
},
"favorite_animal": {
"type": "string"
},
"accepted_tos": {
"type": "string"
}
},
"required": ["email"],
"additionalProperties": false
}
}
}

By using the "format": "tel" field we enable validation of phone numbers using the Golang port of Google's libphonenumber.

Identity state

The identity can have one of these states:

  • created - via API or self-service registration
  • updated - via API or self-service settings, account recovery, etc.
  • inactive - only via API

An inactive identity can't sign in to the system. When trying to sign in, an inactive identity gets a code 401 error with a message indicating that the account was disabled.