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
The Ory Network 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.
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 Identities 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 Identities (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 Identities 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 Identities 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 registrationupdated
- 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.