<@U04UQ68083H> hey, how to check whether user has ...
# ory-copilot
w
@chilly-king-10285 hey, how to check whether user has password or not (since he might be signed up via sso). we using self-hosted version of ory kratos
b
A message from kapa.ai
To check whether a user has a password set (i.e., did not sign up exclusively via SSO/OIDC), you need to inspect the identity's credentials in Ory Kratos. However, the knowledge sources provided do not explicitly document an API endpoint or a direct method to check if a specific identity has the password credential enabled or set. What is documented is that Ory Kratos supports multiple authentication methods (password, OIDC, etc.), and identities can have one or more of these methods enabled. The identity schema can be configured to allow multiple identifiers (e.g., email, username) for password-based login, but there is no explicit mention of a field or API response that directly states whether a password is set for a given user. In practice, you would typically fetch the identity object (using the Admin API) and inspect the
credentials
field to see if the
password
method exists for that identity. If the
password
credential is absent, the user likely registered via SSO/OIDC only. However, this specific approach is not described in the provided documentation, so I cannot confirm the exact field structure or API call from the knowledge sources. Summary: The knowledge sources do not explicitly describe how to check if a user has a password set in self-hosted Ory Kratos. You may need to refer to the Ory Kratos Admin API documentation or experiment with the identity object to determine if the
password
credential is present for a user. If you need further guidance, please consult the official Ory Kratos Admin API documentation or open a support issue with Ory.
w
@chilly-king-10285 I've found a bug with sso account linking flow : it's possible to link different account via settings flow when user have active session. For example: my identity has email like this test@gmail.com, then via settings flow i was able to link account with gmail account like this testTest@gmail.com and this produce an error on our api side when i try do unlink accounts
Copy code
"messages": [
      {
        "id": 4000007,
        "text": "An account with the same identifier (email, phone, username, ...) exists already.",
        "type": "error"
      }
    ]
b
A message from kapa.ai
Based on the knowledge sources, Ory Kratos supports manual account linking through the settings flow, allowing users to link their accounts to social login providers after signing up. However, there are important validation checks: when attempting to link a social account, if the profile (e.g., Google) to be linked is already associated with another identity in the system, an error is expected. The error message you received:
Copy code
{
  "id": 4000007,
  "text": "An account with the same identifier (email, phone, username, ...) exists already.",
  "type": "error"
}
is the documented response for such a conflict, indicating that the email (or other identifier) is already in use by another account and cannot be linked again in this way [An account with the same identifier exists already. (4000007)](https://www.ory.sh/docs/kratos/concepts/ui-messages#an-account-with-the-same-identifier-email-phone-username--exists-already-4000007). The documentation also notes that, during linking/unlinking, there are no expected validation errors except when the profile to be linked is already linked with another identity [Un-/linking from/with Google, Facebook, GitHub, ..., OpenID Connect / OAuth 2.0](https://www.ory.sh/docs/kratos/self-service/flows/user-settings#un-linking-fromwith-google-facebook-github--openid-connect--oauth-20). Your scenario—being able to link a different account with a similar but not identical email (e.g.,
<mailto:test@gmail.com|test@gmail.com>
and
<mailto:testTest@gmail.com|testTest@gmail.com>
)—is not explicitly addressed in the documentation. The sources do not specify whether Ory Kratos enforces strict email matching or normalization (such as Gmail's dot/plus handling) during the linking process. Therefore, if your API or business logic expects stricter matching or normalization, you may need to implement additional validation on your side. Summary: - The error you see is the expected behavior when trying to link an account with an identifier already in use. - The documentation does not specify handling for similar but not identical emails during linking. - If stricter matching is required (e.g., for Gmail aliases), you may need to enforce this in your application logic, as the knowledge sources do not mention built-in support for such normalization. If you believe this is a bug or a missing feature, consider opening an issue with Ory, providing details of your use case and the observed behavior.
w
@chilly-king-10285 hey will this jsonnet works local claims = std.extVar('claims'); local context = std.extVar("__kratos_context"); local hasIdentity = std.objectHas(context, "identity"); local identity = hasIdentity && context.identity; { identity: { traits: if hasIdentity && std.toLower(identity.traits.email) != std.toLower(claims.email) then error "OIDC email does not match current identity email" else { email: claims.email, googleId: claims.sub, providerId: "google-web-dealer", name: { first: claims.given_name, last: if std.objectHas(claims, 'family_name') then claims.family_name else "Unknown", } }, }, metadata_admin: { google_claims: claims, }, metadata_public: { "claims": [{ "type": "role", "value": "dealer" }] }, }
b
A message from kapa.ai
Sorry @wooden-cartoon-49455, I am experiencing especially high traffic right now, please try again. 🧑‍💻
w
@chilly-king-10285 will this jsonnet work ? local claims = std.extVar('claims'); local context = std.extVar("__kratos_context"); local hasIdentity = std.objectHas(context, "identity"); local identity = hasIdentity && context.identity; { identity: { traits: if hasIdentity && std.toLower(identity.traits.email) != std.toLower(claims.email) then error "OIDC email does not match current identity email" else { email: claims.email, googleId: claims.sub, providerId: "google-web-dealer", name: { first: claims.given_name, last: if std.objectHas(claims, 'family_name') then claims.family_name else "Unknown", } }, }, metadata_admin: { google_claims: claims, }, metadata_public: { "claims": [{ "type": "role", "value": "dealer" }] }, }
b
A message from kapa.ai
Based on the knowledge sources, your Jsonnet snippet uses several advanced features: - Accessing external variables:
claims
and
__kratos_context
- Checking if the current context has an identity:
std.objectHas(context, "identity")
- Comparing emails (case-insensitive) and raising an error if they do not match - Setting traits, admin metadata, and public metadata What the documentation says: - You can use
std.extVar('claims')
to access OIDC claims, and the output structure you use for traits and metadata is correct [Data mapping with Jsonnet](https://www.ory.sh/docs/kratos/reference/jsonnet). - The documentation does not mention the use of
__kratos_context
or passing the current identity as an external variable in the data mapping context. There is a suggestion in a GitHub issue that passing the existing identity to the mapper could be useful, but it is not documented as officially supported or available in the current implementation [Can't use metadata fields from multiple social sign-in providers](https://github.com/ory/network/issues/164). - The use of
error
to raise a mapping error is supported [Data mapping with Jsonnet](https://www.ory.sh/docs/kratos/reference/jsonnet). - The rest of your mapping logic (traits, metadata) follows the documented structure. Key uncertainty: - The knowledge sources do not confirm that
__kratos_context
or
context.identity
is available as an external variable in the Jsonnet data mapper. This means the logic relying on
context
and
identity
may not work as expected in Ory Kratos, unless you have specifically configured your deployment to provide this variable. Conclusion: Your Jsonnet code is valid in terms of syntax and structure, and the use of
error
is supported. However, the use of
__kratos_context
and accessing the current identity is not documented as available in the Ory Kratos Jsonnet data mapping context. Therefore, unless you have custom logic to provide this variable, this code may not work as intended. If you need to access the current identity in the data mapper, this is not officially supported according to the current documentation and may require a feature request or custom extension. Summary: - The code is valid Jsonnet and follows documented patterns for claims and error handling. - The use of
__kratos_context
and
context.identity
is not documented as supported in Ory Kratos data mapping, so this part may not work. - If you need this feature, consider opening a feature request with Ory or checking for updates in the documentation [Data mapping with Jsonnet](https://www.ory.sh/docs/kratos/reference/jsonnet) [Can't use metadata fields from multiple social sign-in providers](https://github.com/ory/network/issues/164).
w
@chilly-king-10285 ok, adjust this jsonnet. I need to check whether current user email is the same that we get from oidc handshake
b
A message from kapa.ai
I'm sorry, but the knowledge sources do not provide any information confirming that you can access the current user's identity (such as their email) within the Jsonnet data mapper during the OIDC handshake in Ory Kratos. The only documented external variable available in the Jsonnet data mapper is
claims
, which contains the data returned from the social sign-in provider [Write a Jsonnet data mapper](https://www.ory.sh/docs/kratos/social-signin/data-mapping#write-a-jsonnet-data-mapper). There is no mention in the official documentation that you can access the current session, identity, or any context about the "current user" within the Jsonnet mapping code. Therefore, it is not possible—based on the provided documentation—to compare the current user's email with the email received from the OIDC provider in the Jsonnet data mapper. If you require this functionality, you may need to handle this logic outside of the Jsonnet data mapper, such as in your backend application or by requesting this feature from Ory. Summary: It is not possible to check whether the current user's email matches the OIDC email within the Jsonnet data mapper, according to the available documentation. Only the OIDC claims are available for mapping in Jsonnet.
w
@chilly-king-10285 what body will I receive in settings after oidc hooks. ?
b
A message from kapa.ai
After completing the OIDC linking or unlinking process via the settings flow in Ory Kratos, the response body you receive will include the updated settings flow object. This object contains information about the flow, the UI nodes, and the updated identity, including all traits and linked credentials. A typical response body after a successful settings update (including OIDC hooks) looks like this:
Copy code
json {   "id": "f71743cd-700d-4a30-9275-8edc90de07cc",   "type": "browser",   "expires_at": "2021-04-28T12:39:36.804397011Z",   "issued_at": "2021-04-28T11:39:36.804397011Z",   "request_url": "<https://playground.projects.oryapis.com/self-service/settings/browser>",   "ui": {     "action": "<https://playground.projects.oryapis.com/self-service/settings?flow=f71743cd-700d-4a30-9275-8edc90de07cc>",     "method": "POST",     "nodes": [       // ... UI nodes for available settings methods, including OIDC     ],     "messages": [       {         "id": 1050001,         "text": "Your changes have been saved!",         "type": "info"       }     ]   },   "identity": {     "id": "5b23b651-c186-4398-8717-f15ac72cbc7e",     "schema_id": "default",     "schema_url": "<https://playground.projects.oryapis.com/schemas/default>",     "traits": {       "email": "<mailto:example.user@ory.sh|example.user@ory.sh>"       // ... other traits     },     "verifiable_addresses": [       {         "id": "d2214ea2-8b0e-49c0-a9e0-9998ea4527aa",         "value": "<mailto:example.user@ory.sh|example.user@ory.sh>",         "verified": false,         "via": "email",         "status": "pending",         "verified_at": null       }     ],     "recovery_addresses": [       {         "id": "29ef1378-0f13-4f2e-a9cf-683320771d5b",         "value": "<mailto:example.user@ory.sh|example.user@ory.sh>",         "via": "email"       }     ]     // ... credentials and other identity fields   },   "state": "success" }
The
identity
object will reflect any changes made by the OIDC hook, such as new linked credentials or updated traits. The UI nodes will also include OIDC-related actions (e.g., link/unlink buttons for providers) [Settings flow payloads](https://www.ory.sh/docs/kratos/self-service/flows/user-settings#link-and-unlink-from-google-facebook-github--openid-connect--oauth-20) [Client-side browser clients](https://www.ory.sh/docs/kratos/self-service/flows/user-settings#client-side-browser-clients). If there is an error (for example, trying to link an already-linked account), the response will include an error message in the
ui.messages
array. Note: The exact structure may vary depending on your identity schema and enabled methods, but the pattern above is consistent for settings flows after OIDC hooks.
w
In this example selfservice: flows: settings: after: oidc: hooks: - hook: web_hook config: url: https://your-api/validate-oidc-link method: POST body: file:///config/validate-oidc-link.jsonnet response: ignore: false if the web_hook response will be not 2xx code, the identity will not be patched with oidc ?
@chilly-king-10285 In this example selfservice: flows: settings: after: oidc: hooks: - hook: web_hook config: url: https://your-api/validate-oidc-link method: POST body: file:///config/validate-oidc-link.jsonnet response: ignore: false if the web_hook response will be not 2xx code, the identity will not be patched with oidc ?
b
A message from kapa.ai
Yes, according to the knowledge sources, if your webhook (configured as an
after.oidc
hook in the settings flow) returns a non-2xx HTTP status code, the flow will be interrupted and the identity will not be patched with the OIDC data. This is described in the documentation for flow-interrupting webhooks: > If you want the result of webhook execution to have the potential of interrupting the flow, you can configure the webhook to parse the response: > > - For HTTP response codes
1xx
,
2xx
, and
3xx
, the flow is not interrupted. > - For HTTP response codes
4xx
,
5xx
, the external service interrupts the flow and returns a predefined payload. This means that if your webhook returns a
4xx
or
5xx
code, the linking process will be stopped and the identity will not be updated with the new OIDC link [Flow-interrupting webhooks](https://www.ory.sh/docs/guides/integrate-with-ory-cloud-through-webhooks#flow-interrupting-webhooks).
w
@chilly-king-10285 so body of the hook will look like this ? { "identity": { "id": "1234-5678", "traits": { "email": "existing@gmail.com", ... }, "credentials": { "oidc": { "identifiers": [ "google-external:linkedaccount@gmail.com" ] } } }, "session": { "id": "...", ... }, "flow_id": "9fcf88d5-...", "method": "oidc" } i need to have email that returns from oidc handshake to verify that they identical with that user currently has
b
A message from kapa.ai
The knowledge sources do not provide a full, explicit example of the exact webhook request body for the
after.oidc
settings flow hook in Ory Kratos. However, they do describe the general structure of webhook payloads for self-service flows, which typically include the
identity
,
session
,
flow_id
, and
method
fields [Modify identities](https://www.ory.sh/docs/guides/integrate-with-ory-cloud-through-webhooks#modify-identities). What is not clearly documented is whether the webhook payload will include the raw OIDC claims (such as the email returned from the OIDC handshake) alongside the updated
identity
object. The documentation shows that the
identity
object in the webhook payload will reflect the state after the OIDC linking attempt, meaning the
credentials.oidc.identifiers
array will include the new OIDC identifier if the linking is proceeding. If you need to compare the email from the OIDC handshake with the user's current email, the knowledge sources do not confirm that the OIDC claims (such as the new email) are included separately in the webhook payload. You will see the updated
identity
object, but you may not have access to the OIDC claims directly unless you have mapped them into the identity traits or metadata during the OIDC mapping step. Summary: - The webhook body will include the
identity
,
session
,
flow_id
, and
method
fields. - The
identity
object will show the state after the OIDC linking attempt, including the new OIDC identifier. - The knowledge sources do not confirm that the OIDC claims (such as the email from the handshake) are included separately in the webhook payload. - If you need the OIDC email for verification, you may need to ensure it is mapped into the identity traits or metadata during the OIDC mapping step, as the webhook payload itself may not provide it directly. If you require the raw OIDC claims in the webhook payload, this is not documented as available, and you may need to request this feature or implement a workaround in your mapping logic [Modify identities](https://www.ory.sh/docs/guides/integrate-with-ory-cloud-through-webhooks#modify-identities).
w
@chilly-king-10285 is it possible to receive identity credentials array from pre or post hook on settings flow ?
b
A message from kapa.ai
Based on the knowledge sources, when a webhook is triggered in the settings flow (either as a pre or post hook), the payload sent to the webhook includes the
identity
object. This
identity
object contains all of the identity's fields, including the
credentials
field, which is an object (not an array) that holds all credential types associated with the identity (such as
password
,
oidc
, etc.) [Modify identities](https://www.ory.sh/docs/guides/integrate-with-ory-cloud-through-webhooks#modify-identities). So, yes, it is possible to receive the identity's credentials object in the webhook payload for both pre and post hooks on the settings flow. The credentials are structured as an object keyed by credential type, not as an array. If you need to inspect all credentials, you can access them via
identity.credentials
in the webhook payload. If you need the credentials in array form, you would need to transform the object yourself in your webhook handler, as the default structure is an object. Summary: - The webhook payload includes the
identity.credentials
object for both pre and post hooks in the settings flow. - The credentials are provided as an object, not an array [Modify identities](https://www.ory.sh/docs/guides/integrate-with-ory-cloud-through-webhooks#modify-identities).
w
@chilly-king-10285 I don't have 'credentials' object in webhook payload. Self hosted Kratos version is 1.3.1
b
A message from kapa.ai
I'm sorry, but the knowledge sources do not explicitly state whether the
credentials
object is included in the webhook payload for the settings flow in self-hosted Ory Kratos v1.3.1. The documentation shows examples of webhook payloads that include the
identity
object, but it does not detail the exact structure or confirm the presence of the
credentials
field in these payloads for the settings flow [Modify identities](https://www.ory.sh/docs/guides/integrate-with-ory-cloud-through-webhooks#modify-identities). If you are not seeing the
credentials
object in your webhook payload, this may be due to the current implementation or configuration of Ory Kratos, but the knowledge sources do not provide enough information to confirm or troubleshoot this behavior.
w
@chilly-king-10285 what can i update during jsonnet mapper execution when doing sso login\link for already exising account for now i can say that
metadata_admin
stays empty
b
A message from kapa.ai
When using a Jsonnet data mapper during SSO login or account linking for an already existing account, you can update the following fields in the identity object: - `traits`: These are the user attributes defined by your identity schema (such as email, name, etc.). - `metadata_public`: Public metadata fields, visible to the user but only modifiable via admin APIs. - `metadata_admin`: Admin metadata fields, only visible and modifiable via admin APIs. The Jsonnet mapper allows you to set these fields based on the OIDC claims provided by the social sign-in provider. For example:
Copy code
jsonnet local claims = std.extVar('claims');  {   identity: {     traits: {       email: claims.email,       // ... other traits     },     metadata_public: {       discord_username: claims.discord_username,       // ... other public metadata     },     metadata_admin: {       // ... admin metadata fields     },   } }
However, according to the knowledge sources and recent GitHub issues, when linking a new social account to an existing identity (not during initial registration), the Jsonnet mapper is not applied in the same way. This means that fields like
metadata_admin
may not be updated as expected during the linking process in the settings flow. This is a known limitation, and there are open feature requests to support merging and updating metadata during account linking, but it is not currently supported [Can't use metadata fields from multiple social sign-in providers](https://github.com/ory/network/issues/164) [Data mapping not working when updated from settings](https://github.com/ory/network/issues/170). Summary: - During initial SSO registration, you can update
traits
,
metadata_public
, and
metadata_admin
via the Jsonnet mapper. - During SSO account linking for an existing account (settings flow), updating
metadata_admin
(and other fields via the mapper) is currently not supported, which is why you observe
metadata_admin
staying empty. If you need this functionality, you may want to follow or contribute to the related GitHub issues for updates on this feature.