This document describes the NATS subjects for listing, linking, and unlinking identities (social providers, email, etc.) to and from user accounts.
- The
user_idis automatically extracted from thesubclaim ofuser.auth_token— it does not need to be provided explicitly - Both Auth0 and Authelia implementations support link and unlink operations. The behaviour differs per implementation — see the sections below.
Retrieves all identities linked to the authenticated user's account.
Subject: lfx.auth-service.user_identity.list
Pattern: Request/Reply
{
"user": {
"auth_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}Success Reply:
{
"success": true,
"data": [
{
"provider": "google-oauth2",
"user_id": "google123",
"isSocial": true,
"profileData": {
"email": "user@gmail.com",
"email_verified": true
}
},
{
"provider": "github",
"user_id": "gh456",
"isSocial": true
}
]
}Error Reply:
{
"success": false,
"error": "auth_token is required"
}nats request lfx.auth-service.user_identity.list '{"user":{"auth_token":"eyJhbG..."}}'Links a verified identity to the user's account. The identity can come from any provider (e.g. Google, LinkedIn, GitHub) or from the email verification flow — in which case the identity_token is the ID token received after successfully verifying an email address.
Subject: lfx.auth-service.user_identity.link
Pattern: Request/Reply
{
"user": {
"auth_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
},
"link_with": {
"identity_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}user.auth_token: A JWT access token with theupdate:current_user_identitiesscope.link_with.identity_token: The ID token representing the identity to be linked. For the email verification flow, this is the token received after completing the OTP verification step.
Success:
{
"success": true,
"message": "identity linked successfully"
}Error:
{
"success": false,
"error": "<error message>"
}nats request lfx.auth-service.user_identity.link '{
"user": {
"auth_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
},
"link_with": {
"identity_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}'Removes a secondary identity (e.g. Google, LinkedIn, GitHub) from the user's account.
Subject: lfx.auth-service.user_identity.unlink
Pattern: Request/Reply
{
"user": {
"auth_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
},
"unlink": {
"provider": "linkedin",
"identity_id": "QhNK44iR6W"
}
}user.auth_token: A JWT access token with theupdate:current_user_identitiesscope.unlink.provider: The identity provider to unlink (e.g.google-oauth2,linkedin,github).unlink.identity_id: The identity's ID as returned by the identity provider. This must be retrieved directly from the identity provider since there is no dedicated subject for listing identities at this time.
Success:
{
"success": true,
"message": "identity unlinked successfully"
}Error:
{
"success": false,
"error": "<error message>"
}nats request lfx.auth-service.user_identity.unlink '{
"user": {
"auth_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
},
"unlink": {
"provider": "linkedin",
"identity_id": "QhNK44iR6W"
}
}'- The Auth Service calls the Auth0 Management API using the user's own token, scoped to
update:current_user_identities. - The
identity_tokenfor social providers is the ID token obtained directly from the provider's OAuth flow. - For email linking, the
identity_tokenis the ID token returned by Auth0 after completing the passwordless OTP flow.
The Authelia implementation stores identities locally in the NATS KV user bucket (no external provider API call is made).
Link — provider detection:
The sub claim of the identity_token determines which flow is used:
| Sub format | Flow | Storage target |
|---|---|---|
email|<email-address> |
Email OTP (generated by auth-service) | alternate_emails |
<provider>|<identity_id> (e.g. google-oauth2|abc123) |
Social identity | identities |
Unlink — provider field:
unlink.provider |
What is removed | unlink.identity_id value |
|---|---|---|
email |
Entry from alternate_emails |
The email address |
Any other (e.g. google-oauth2, linkedin) |
Entry from identities |
The provider-specific user ID |
Both operations use optimistic concurrency on the NATS KV bucket — a conflict error means another process updated the record concurrently and the caller should retry.
The Mock implementation follows the same sub-prefix dispatch and storage targets as Authelia, using an in-memory map instead of NATS KV. No external provider call is made. Social identity tokens passed to user_identity.link are parsed unverified — a crafted JWT with the correct sub claim is sufficient.
When linking an email identity, lfx.auth-service.user_identity.link is used as the final step after completing the OTP verification. For the complete flow see Email Verification Documentation.