Skip to main content

Sign in with GitHub, GitLab, Google, Facebook, LinkedIn, Microsoft ...

In this document, we will take a look at setting up "Social Sign In" with different providers using Ory Kratos.

Run the Quickstart with Docker Compose:

# This assumes that you have Ory Kratos checked out locally and
# that your current directory ("pwd") is the folder where Ory Kratos
# is.

make quickstart
info

It's very important to add the "session" hook to the after OIDC registration hooks. Otherwise, your users need to use the login flow again to be able to get a session.

path/to/my/kratos/config.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
flows:
registration:
after:
oidc:
hooks:
- hook: session

Discord

To set up "Sign in with Discord" you must create a Discord OAuth2 Application.

Set the "Redirect URI" to:

https://playground.projects.oryapis.com/api/kratos/public/self-service/methods/oidc/callback/discord

The pattern of this URL is:

http(s)://<domain-of-ory-kratos>:<public-port>/self-service/methods/oidc/callback/<provider-id>

The provider ID must point to the provider's ID set in the Ory Kratos configuration file (explained in further detail at OpenID Connect and OAuth2 Credentials).

note

Discord doesn't implement OpenID Connect. Therefore, Ory Kratos makes a request to Discord's User API and adds that data to std.extVar('claims'). However, not all fields are supported. Check the list of supported fields in Kratos' source code.

The identify scope will add following fields:

iss                 # always https://discord.com/api/v6/oauth2/
sub # numeric discord user id
name # username + # + discriminator
nickname # username
preferred_username # username
picture # avatar url
locale # user locale

Additionally, the email scope will add:

email               # user email
email_verified # whether email is verified
contrib/quickstart/kratos/email-password/oidc.discord.jsonnet
local claims = {
email_verified: false
} + std.extVar('claims');

{
identity: {
traits: {
// Allowing unverified email addresses enables account
// enumeration attacks, if the value is used for
// verification or as a password login identifier.
//
// Therefore we only return the email if it (a) exists and (b) is marked verified
// by Discord.
[if "email" in claims && claims.email_verified then "email" else null]: claims.email,
},
},
}

Now, enable the Discord provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: discord # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: discord
client_id: .... # Replace this with the OAuth2 Client ID provided by Discord
client_secret: .... # Replace this with the OAuth2 Client Secret provided by Discord
mapper_url: file:///etc/config/kratos/oidc.discord.jsonnet
scope:
- identify
- email

Discord is now an option to log in via Kratos.

Slack

To set up "Sign in with Slack" you must create a Slack OAuth Application.

Set the "Redirect URI" to:

https://playground.projects.oryapis.com/api/kratos/public/self-service/methods/oidc/callback/slack

The pattern of this URL is:

http(s)://<domain-of-ory-kratos>:<public-port>/self-service/methods/oidc/callback/<provider-id>

The provider ID must point to the provider's ID set in the Ory Kratos configuration file (explained in further detail at OpenID Connect and OAuth2 Credentials).

note

Slack doesn't implement OpenID Connect. Therefore, Ory Kratos makes a request to Slack's Oauth2 API and adds that data to std.extVar('claims'). However, not all fields are supported. Check the list of supported fields in Kratos' source code.

The identity.basic scope will add the following fields:

iss                 # always https://slack.com/oauth/
sub # alphanumeric slack user id
name # username
nickname # username
preferred_username # username
team # team id slack user belongs to

Additionally, the identity.email scope will add:

email               # user email
email_verified # always true

Additionally, the identity.avatar scope will add:

picture             # user avatar (512x512px)
contrib/quickstart/kratos/email-password/oidc.discord.jsonnet
local claims = {
email_verified: true
} + std.extVar('claims');

{
identity: {
traits: {
// Allowing unverified email addresses enables account
// enumeration attacks, if the value is used for
// verification or as a password login identifier.
//
// It's assumed that Slack requires an email to be verified before accessible via OAuth (because they don't provide a email_verified field).
email: claims.email
},
},
}

Now, enable the Slack provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: slack # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: slack
client_id: .... # Replace this with the OAuth2 Client ID provided by Slack
client_secret: .... # Replace this with the OAuth2 Client Secret provided by Slack
mapper_url: file:///etc/config/kratos/oidc.slack.jsonnet
scope:
- identity.basic
- identity.email

Slack is now an option to log in via Kratos.

GitHub

To set up "Sign in with GitHub" you must create either a GitHub OAuth2 Client or GitHub App Client.

Set the "Authorization callback URL" to:

https://playground.projects.oryapis.com/api/kratos/public/self-service/methods/oidc/callback/github

The pattern of this URL is:

http(s)://<domain-of-ory-kratos>:<public-port>//self-service/methods/oidc/callback/<provider-id>

The provider ID must point to the provider's ID set in the Ory Kratos configuration file (explained in further detail at OpenID Connect and OAuth2 Credentials).

note

GitHub doesn't implement OpenID Connect. Therefore, Ory Kratos makes a request to GitHub's User API and adds that data to std.extVar('claims'). Check out what data is available at GitHub's Scope Docs. However, not all GitHub fields are supported. Check the list of supported fields in Kratos' source code.

Only for Github Oauth2 as GitHub App doesn't have scope. See the Differences between GitHub Apps and OAuth2

As explained in OpenID Connect and OAuth2 Credentials, you must also create a Jsonnet code snippet for the provider. Save the code in <kratos-directory>/contrib/quickstart/kratos/email-password/oidc.github.jsonnet. The following JsonNet takes email_primary and maps it to traits.email:

contrib/quickstart/kratos/email-password/oidc.github.jsonnet
local claims = {
email_verified: false
} + std.extVar('claims');

{
identity: {
traits: {
// Allowing unverified email addresses enables account
// enumeration attacks, if the value is used for
// verification or as a password login identifier.
//
// Therefore we only return the email if it (a) exists and (b) is marked verified
// by GitHub.
[if "email" in claims && claims.email_verified then "email" else null]: claims.email,
},
},
}

For GitHub App use github-app and for GitHub OAuth2 use github

Now, enable the GitHub OAuth2 provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: github # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: github
client_id: .... # Replace this with the OAuth2 Client ID provided by GitHub
client_secret: .... # Replace this with the OAuth2 Client Secret provided by GitHub
mapper_url: file:///etc/config/kratos/oidc.github.jsonnet
scope:
- user:email

Or enable the GitHub App provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: github # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: github-app
client_id: .... # Replace this with the OAuth2 Client ID provided by GitHub
client_secret: .... # Replace this with the OAuth2 Client Secret provided by GitHub
mapper_url: file:///etc/config/kratos/oidc.github.jsonnet

Next, open the login endpoint of the SecureApp and you should see the GitHub Login option!

GitLab

To set up "Sign in with GitLab" you must create a GitLab OAuth2 Application.

Set the "Redirect URI" to:

https://playground.projects.oryapis.com/api/kratos/public/self-service/methods/oidc/callback/gitlab

The pattern of this URL is:

http(s)://<domain-of-ory-kratos>:<public-port>/self-service/methods/oidc/callback/<provider-id>
note

While you can use GitLab as an OIDC identity provider, GitLab only returns the sub and sub_legacy claims in the ID token. Therefore, Ory Kratos makes a request to GitLab's /oauth/userinfo API and adds the user info to std.extVar('claims').

contrib/quickstart/kratos/email-password/oidc.gitlab.jsonnet
local claims = {
email_verified: false
} + std.extVar('claims');

{
identity: {
traits: {
// Allowing unverified email addresses enables account
// enumeration attacks, if the value is used for
// verification or as a password login identifier.
//
// Therefore we only return the email if it (a) exists and (b) is marked verified
// by GitLab.
[if "email" in claims && claims.email_verified then "email" else null]: claims.email,
},
},
}

Now, enable the GitLab provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: gitlab # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: gitlab
client_id: .... # Replace this with the OAuth2 Client ID provided by GitLab
client_secret: .... # Replace this with the OAuth2 Client Secret provided by GitLab
mapper_url: file:///etc/config/kratos/oidc.gitlab.jsonnet
scope:
- read_user
- openid
- profile
- email

GitLab is now an option to log in via Kratos.

Auth0

To set up "Sign in with Auth0" you must create an Auth0 Application for your Auth0 Tenant. Note that the endpoint for the application starts with your Tenant's name. for example myAuth0Tenant.auth0.com. This will be the IssuerURL you will use when configuring the OIDC connection.

Set the "Redirect URI" to:

https://playground.projects.oryapis.com/api/kratos/public/self-service/methods/oidc/callback/gitlab

The pattern of this URL is:

http(s)://<domain-of-ory-kratos>:<public-port>/self-service/methods/oidc/callback/<provider-id>
note

While you can use Auth0 as an OIDC identity provider, Auth0 only returns the sub and sub_legacy claims in the ID token. Therefore, Ory Kratos makes a request to Auth0's /userinfo API and adds the user info to std.extVar('claims').

contrib/quickstart/kratos/email-password/oidc.auth0.jsonnet
local claims = {
email_verified: false
} + std.extVar('claims');

{
identity: {
traits: {
// Allowing unverified email addresses enables account
// enumeration attacks, if the value is used for
// verification or as a password login identifier.
//
// Therefore we only return the email if it (a) exists and (b) is marked verified
// by Auth0.
[if "email" in claims && claims.email_verified then "email" else null]: claims.email,
username: claims.nickname,
},
},
}

Now, enable the Auth0 provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml. Note that the issuer_url needs to be the top-level domain for your Auth0 application. This can be found by going to the Auth0 application page and choosing Settings then Advanced Settings then Endpoints. The endpoint is of the form myAuth0Tenant.auth0.com (where myAuth0Tenant is the name of your tenant).

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: auth0 # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: auth0
client_id: .... # Replace this with the OAuth2 Client ID provided by Auth0
client_secret: .... # Replace this with the OAuth2 Client Secret provided by Auth0
mapper_url: file:///etc/config/kratos/oidc.auth0.jsonnet
issuer_url: .... # Replace this with the endpoint of the Auth0 tenant.
scope:
- openid
- profile
- email

Auth0 is now an option to log in via Kratos.

Microsoft

This will enable you to log in using any Azure AD directory - Multi-tenant and personal Microsoft accounts (for example Skype, Xbox) depending on the settings made when creating the application in Azure AD.

Creating an Application in Azure AD

To set up "Sign in with Microsoft" you must first register an application with the Microsoft identity platform.

Select "Web" as the "Redirect URI" type, and set the URI to:

http(s)://<domain-of-ory-kratos>:<public-port>//self-service/methods/oidc/callback/<provider-id>

After the "App Registration" is created, make note of the Application ID and Directory ID on top of the Overview page. To create the client secret, navigate to "Certificates & secrets" and click "+ New client secret". Remember to copy the secret value as it will only be shown once.

Configuring Kratos

Create a Jsonnet claims mapper as described in OpenID Connect and OAuth2 Credentials. Save the code in <kratos-directory>/contrib/quickstart/kratos/email-password/oidc.microsoft.jsonnet.

contrib/quickstart/kratos/email-password/oidc.microsoft.jsonnet
local claims = std.extVar('claims');
{
identity: {
traits: {
// Allowing unverified email addresses enables account
// enumeration attacks, if the value is used for
// verification or as a password login identifier.
//
// If connecting only to your organization (one tenant), claims.email is safe to use if you haven't actively disabled e-mail verification during signup.
//
// The email might be empty if the account isn't linked to an email address.
// For a human readable identifier, consider using the "preferred_username" claim.
[if "email" in claims then "email" else null]: claims.email,
},
},
}

Enable the Microsoft provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: microsoft # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: microsoft
client_id: .... # Replace this with the Application ID from the App Registration
client_secret: .... # Replace this with the generated Secret value from the App Registration
microsoft_tenant: .... # Replace this with the Tenant of your choice (see below)
subject_source: userinfo # or alternatively: me
mapper_url: file:///etc/config/kratos/oidc.microsoft.jsonnet
scope:
- profile
- email

Azure AD is now an option to log in to Ory Kratos.

Choosing Tenant

There are two ways to use the microsoft provider for authentication:

  1. For authenticating users in a single Azure AD Directory (organization), set the tenant value to either the Directory ID from the "App Registration" page, or the organization domain. Examples:8eaef023-2b34-4da1-9baa-8bc8c9d6a490 or example.onmicrosoft.com.
  2. For authenticating any user in the Microsoft identity platform, set the tenant value to either:
  • organizations to allow users with work or school accounts, or
  • consumers to allow users with personal accounts, or
  • common to allow both kind of accounts.
Choosing source of subject identifier

By default, the microsoft provider will rely on identifier taken from the sub field of OIDC ID token. The same identifier is also returned by standard OIDC /userinfo endpoint.

But there are systems out there that use id field returned by https://graph.microsoft.com/v1.0/me endpoint as a subject identifier. To make migrating such systems to Kratos easier the microsoft provider allows using me endpoint's id as an identifier. Set the provider config subject_source field to me to activate this feature.

Twitch

To set up "Sign in with Twitch" you must create a Twitch OAuth2 Application.

Set the "Redirect URI" to:

https://playground.projects.oryapis.com/api/kratos/public/self-service/methods/oidc/callback/twitch

The pattern of this URL is:

http(s)://<domain-of-ory-kratos>:<public-port>/self-service/methods/oidc/callback/<provider-id>

The provider ID must point to the provider's ID set in the Ory Kratos configuration file (explained in further detail at OpenID Connect and OAuth2 Credentials).

As explained in OpenID Connect and OAuth2 Credentials, you must also create a Jsonnet code snippet for the provider. Save the code in <kratos-directory>/contrib/quickstart/kratos/email-password/oidc.twitch.jsonnet.

contrib/quickstart/kratos/email-password/oidc.twitch.jsonnet
local claims = {
email_verified: false
} + std.extVar('claims');

{
identity: {
traits: {
// Allowing unverified email addresses enables account
// enumeration attacks, if the value is used for
// verification or as a password login identifier.
//
// Therefore we only return the email if it (a) exists and (b) is marked verified
// by Twitch.
[if "email" in claims && claims.email_verified then "email" else null]: claims.email,
},
},
}

Now, enable the Twitch provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: twitch # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: generic
client_id: .... # Replace this with the OAuth2 Client ID provided by Twitch
client_secret: .... # Replace this with the OAuth2 Client Secret provided by Twitch
issuer_url: https://id.twitch.tv/oauth2
mapper_url: file:///etc/config/kratos/oidc.twitch.jsonnet
scope:
- openid
- user:read:email # required for email and email_verified claims in the near future
requested_claims: # explicitly request email and email_verified claims because twitch doesn't add them by default
id_token:
email:
essential: true
email_verified:
essential: true

Next, open the login endpoint of the SecureApp and you should see the Twitch Login option!

Facebook

Create Facebook Application

To set up "Sign in with Facebook" you first need a Facebook Developer Account.

Create a Facebook OAuth2 Application.

Add a "Facebook Login" product to this application.

Select "Settings" in the Products menu.

Set the "Valid OAuth Redirect URIs" to:

https://127.0.0.1:4433/self-service/methods/oidc/callback/facebook

The pattern of this URL is:

https://<domain-of-ory-kratos>:<public-port>/self-service/methods/oidc/callback/<provider-id>

Facebook requires HTTPS redirect URIs!

note

While you can use Facebook as an OIDC identity provider, Facebook only returns access_token and not id_token. Therefore, Ory Kratos makes a request to Facebook's graph.facebook.com/me API and adds the user info to std.extVar('claims').

Configuring Kratos

Create a Jsonnet claims mapper as described in OpenID Connect and OAuth2 Credentials. Save the code in <kratos-directory>/contrib/quickstart/kratos/email-password/oidc.facebook.jsonnet.

contrib/quickstart/kratos/email-password/oidc.facebook.jsonnet
local claims = std.extVar('claims');
{
identity: {
traits: {
// Allowing unverified email addresses enables account
// enumeration attacks, if the value is used for
// verification or as a password login identifier.
//
// It's assumed that Facebook requires an email to be verified before accessible via OAuth (because they don't provide an email_verified field).
//
// The email might be empty if the user isn't allowed to an email scope.
[if "email" in claims then "email" else null]: claims.email,
},
},
}

Now, enable the Facebook provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: facebook # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: facebook
client_id: .... # Replace this with the OAuth2 Client ID provided by Facebook app
client_secret: .... # Replace this with the OAuth2 Client Secret provided by Facebook app
mapper_url: file:///etc/config/kratos/oidc.facebook.jsonnet
scope:
- email # required for email and email_verified claims in the near future
# other supported scopes: user_gender, user_birthday

Next, open the login endpoint of the SecureApp and you should see the Facebook Login option!

Google

Set up on Google Cloud Platform

  1. Create an OAuth consent screen
  2. Create OAuth 2.0 Client IDs

In the new OAuth 2.0 Client ID, you will need the Client ID and Client secret.

Configuring Kratos

Create a Jsonnet claims mapper as described in OpenID Connect and OAuth2 Credentials. Save the code in <kratos-directory>/contrib/quickstart/kratos/email-password/oidc.google.jsonnet.

contrib/quickstart/kratos/email-password/oidc.google.jsonnet
local claims = {
email_verified: true
} + std.extVar('claims');

{
identity: {
traits: {
[if "email" in claims && claims.email_verified then "email" else null]: claims.email,
// additional claims
// please also see the `Google specific claims` section
first_name: claims.given_name,
last_name: claims.family_name,
[if "hd" in claims && claims.email_verified then "hd" else null]: claims.hd,
},
},
}

Now, enable the Google provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: google # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: google
client_id: .... # Replace this with the OAuth2 Client ID
client_secret: .... # Replace this with the OAuth2 Client secret
mapper_url: file:///etc/config/kratos/oidc.google.jsonnet
scope:
- email
- profile
# other supported scopes can be found in Google OAuth 2.0 dev docs
requested_claims:
id_token:
email:
essential: true
email_verified:
essential: true
given_name:
essential: true
family_name: null
hd: null # If you want the G Suite domain

Google-specific claims

  • hd: The hosted G Suite domain of the user. Provided only if the user belongs to a hosted domain. For a given email account with a custom domain example.com - user1@example.com would produce example.com in the hd claim.

Please look at the Google developer documentation which can be found here .

VK

Create VK Application

Create a VK OAuth2 Application.

Select "Create"

Select "Platform: Website"

Set the "Website address" to:

https://127.0.0.1:4433

Set the "Base domain" to:

127.0.0.1:4433

Select "Connect Website"

Set the "Authorized redirect URI" to:

https://127.0.0.1:4433/self-service/methods/oidc/callback/vk

The pattern of this URL is:

https://<domain-of-ory-kratos>:<public-port>/self-service/methods/oidc/callback/<provider-id>
note

While you can use VK as an OIDC identity provider, VK only returns access_token and not id_token. Therefore, Ory Kratos makes a request to VK's API and adds the user info to std.extVar('claims').

Configuring Kratos

Create a Jsonnet claims mapper as described in OpenID Connect and OAuth2 Credentials. Save the code in <kratos-directory>/contrib/quickstart/kratos/email-password/oidc.vk.jsonnet.

contrib/quickstart/kratos/email-password/oidc.vk.jsonnet
local claims = std.extVar('claims');
{
identity: {
traits: {
// VK don't provide an email_verified field.
//
// The email might be empty if the user isn't allowed to an email scope.
[if "email" in claims then "email" else null]: claims.email,
},
},
}

Now, enable the VK provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: vk # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: vk
client_id: .... # Replace this with the OAuth2 Client ID provided by VK app
client_secret: .... # Replace this with the OAuth2 Client Secret provided by VK app
mapper_url: file:///etc/config/kratos/oidc.vk.jsonnet
scope:
- email # required for email and email_verified claims in the near future

Next, open the login endpoint of the SecureApp and you should see the VK Login option!

Yandex

Create Yandex Application

Create a Yandex OAuth2 Application.

Select "Platforms: Web services"

Set the "Website address" to:

https://127.0.0.1:4433

Select "Connect Website"

Set the "Callback URI" to:

https://127.0.0.1:4433/self-service/methods/oidc/callback/yandex

The pattern of this URL is:

https://<domain-of-ory-kratos>:<public-port>/self-service/methods/oidc/callback/<provider-id>
note

While you can use Yandex as an OIDC identity provider, Yandex only returns access_token and not id_token. Therefore, Ory Kratos makes a request to Yandex's API and adds the user info to std.extVar('claims').

Configuring Kratos

Create a Jsonnet claims mapper as described in OpenID Connect and OAuth2 Credentials. Save the code in <kratos-directory>/contrib/quickstart/kratos/email-password/oidc.yandex.jsonnet.

contrib/quickstart/kratos/email-password/oidc.yandex.jsonnet
local claims = std.extVar('claims');
{
identity: {
traits: {
// Yandex don't provide an email_verified field.
//
// The email might be empty if the user isn't allowed to an email scope.
[if "email" in claims then "email" else null]: claims.email,
},
},
}

Now, enable the Yandex provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: yandex # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: yandex
client_id: .... # Replace this with the OAuth2 Client ID provided by Yandex app
client_secret: .... # Replace this with the OAuth2 Client Secret provided by Yandex app
mapper_url: file:///etc/config/kratos/oidc.yandex.jsonnet

Next, open the login endpoint of the SecureApp and you should see the Yandex Login option!

Apple

To set up "Sign in with Apple" you must create an app, a service, and a private key.

Set the "Redirect URI" to:

https://playground.projects.oryapis.com/api/kratos/public/self-service/methods/oidc/callback/apple

Due to implementation constraints, the provider ID at the end of this address can't be changed.

The pattern of this URL is:

http(s)://<domain-of-ory-kratos>:<public-port>/self-service/methods/oidc/callback/<provider-id>

The provider ID must point to the provider's ID set in the Ory Kratos configuration file (explained in further detail at OpenID Connect and OAuth2 Credentials).

As explained in OpenID Connect and OAuth2 Credentials, you must also create a Jsonnet code snippet for the provider. Save the code in <kratos-directory>/contrib/quickstart/kratos/email-password/oidc.apple.jsonnet.

contrib/quickstart/kratos/email-password/oidc.apple.jsonnet
local claims = {
email_verified: false
} + std.extVar('claims');

{
identity: {
traits: {
// Allowing unverified email addresses enables account
// enumeration attacks, if the value is used for
// verification or as a password login identifier.
//
// Therefore we only return the email if it (a) exists and (b) is marked verified
// by Apple.
[if "email" in claims && claims.email_verified then "email" else null]: claims.email,
},
},
}

Now, enable the Apple provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: apple # this is `<provider-id>` in the Authorization callback URL. It should be "apple"
provider: apple
client_id: .... # Replace this with the Services ID provided by Apple
apple_team_id: .... # Replace this with the Team ID provided by Apple
apple_private_key_id: .... # Replace this with the private key identifier generated by Apple
apple_private_key: |
-----BEGIN PRIVATE KEY-----
.... # Replace this with the content of the private key downloaded from Apple
-----END PRIVATE KEY-----
mapper_url: file:///etc/config/kratos/oidc.apple.jsonnet
scope:
- email

Next, open the login endpoint of the SecureApp and you should see the Apple Login option!

Spotify

To set up "Sign in with Spotify" you must create an Spotify Application.

Set the "Redirect URI" to:

https://playground.projects.oryapis.com/api/kratos/public/self-service/methods/oidc/callback/spotify

The pattern of this URL is:

http(s)://<domain-of-ory-kratos>:<public-port>/self-service/methods/oidc/callback/<provider-id>
note

While Spotify provides an OIDC discovery URL, Spotify doesn't support the openid claim and only returns an access token. Therefore, Ory Kratos makes a request to Spotify's /me API and adds the user info to std.extVar('claims').

contrib/quickstart/kratos/email-password/oidc.spotify.jsonnet
# claims contains all the data sent by the upstream.
local claims = std.extVar('claims');

{
identity: {
traits: {
email: claims.email
},
},
}

Now, enable the Spotify provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: spotify # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: spotify
client_id: .... # Replace this with the OAuth2 Client ID provided by Spotify
client_secret: .... # Replace this with the OAuth2 Client Secret provided by Spotify
mapper_url: file:///etc/config/kratos/oidc.spotify.jsonnet
scope:
- user-read-email
- user-read-private

Spotify is now an option to log in via Kratos.

NetID

To set up "Sign in with NetID" you must create a NetID Service.

Next you muste create a NetID Client.

Set the "Redirect URI" to:

https://playground.projects.oryapis.com/api/kratos/public/self-service/methods/oidc/callback/netid

The pattern of this URL is:

http(s)://<domain-of-ory-kratos>:<public-port>/self-service/methods/oidc/callback/<provider-id>
note

While you can use NetID as an OIDC identity provider, NetID only returns the sub and sub_legacy claims in the ID token. Therefore, Ory Kratos makes a request to NetID's userinfo API and adds the user info to std.extVar('claims').

contrib/quickstart/kratos/email-password/oidc.netid.jsonnet
local claims = {
email_verified: false
} + std.extVar('claims');

{
identity: {
traits: {
// Allowing unverified email addresses enables account
// enumeration attacks, if the value is used for
// verification or as a password login identifier.
//
// Therefore we only return the email if it (a) exists and (b) is marked verified
// by NetID.
[if "email" in claims && claims.email_verified then "email" else null]: claims.email,
},
},
}

Now, enable the NetID provider in the Ory Kratos config located at <kratos-directory>/contrib/quickstart/kratos/email-password/kratos.yml.

contrib/quickstart/kratos/email-password/kratos.yml
# kratos -c path/to/my/kratos/config.yml serve
selfservice:
methods:
oidc:
enabled: true
config:
providers:
- id: netid # this is `<provider-id>` in the Authorization callback URL. DO NOT CHANGE IT ONCE SET!
provider: netid
client_id: .... # Replace this with the OAuth2 Client ID provided by NetID
client_secret: .... # Replace this with the OAuth2 Client Secret provided by NetID
mapper_url: file:///etc/config/kratos/oidc.netid.jsonnet
requested_claims: # for more information navigate to https://developerzone.netid.dev/sso/#claims-and-scopes
userinfo:
email:
essential: true
email_verified:
essential: true
id_token:
email:
essential: true
email_verified:
essential: true
scope:
- email
- openid

NetID is now an option to log in via Kratos.

LinkedIn

Connecting with other Social Sign In providers will be very similar to the GitHub flow. If you've managed to do it, add to this document by writing it down and making a PR! :)

How to prevent username already taken

Sometimes the username returned by a provider is already taken in your application. To prevent this you can add a random suffix (for example a number) to the OIDC username. You can use the md5 function built in the jsonnet standard library. See the following issue as well: Add random function to the jsonnet library.

If multiple registration methods are configured, users may be redirected to a social login provider to link the accounts after the email verification. To skip this link-up add the session hook after the registration method (for example password):

      after:
password:
hooks:
- hook: session

How Ory Kratos handles OIDC token

The OIDC token isn't being saved in the Ory Kratos database, Ory Kratos exchanges it for a session. For example:

  • Ory Kratos starts the OIDC flow with Google.
  • Google sends back the OIDC id_token (if successfully authenticated).
  • Ory Kratos gets the user information from the id_token (specified in claims, default email, or username).
  • Ory Kratos checks the database if the identity exists: ➡️ if yes, Ory Kratos returns a session token to the user. ➡️ if no, the identity is created and it returns a session token.
  • The id_token from Google is discarded upon completion of the flow.

Log in through social providers if the identifiers match

A user creates an account with the identifier user@example.com. When the same user has an account at for example ACME using the same identifier user@example.com, some providers offer the option to have the user login through ACME, even though the user hasn't created the account using Login with ACME.

Right now there's an explicit extra step to link them as default configuration. There is no way to login through them without linking if for example emails match.

warning

We strongly discourage this practice, consider the following scenario:

  • You have signed up using user@example.com to acme.com.
  • The hacker knows this.
  • The hacker creates a social login account (such as Google) with the email user@example.com and signs in on acme.com.
  • Now the hacker is in your account.

Configuration from environment variable

You can provide the oidc configuration using environment variables by setting the environment variable SELFSERVICE_METHODS_OIDC_CONFIG_PROVIDERS. For example:

SELFSERVICE_METHODS_OIDC_CONFIG_PROVIDERS='[{"id":"google","provider":"google","mapper_url":"<file_location>","client_id":"<client_id>","client_secret":"<client_secret>","scope":["openid","email","profile"],"auth_url":"https://accounts.google.com/o/oauth2/v2/auth","token_url":"https://www.googleapis.com/oauth2/v4/token","issuer_url":"https://accounts.google.com"}]'