<@U04UQ68083H> Kratos don't send transient payload...
# ory-copilot
a
@chilly-king-10285 Kratos don't send transient payload to my route on a settings password hook, is there a documention about this ?
b
A message from kapa.ai
Based on the knowledge sources, I can see that Ory Kratos supports transient payloads in various self-service flows, including the settings flow. Transient payloads allow you to pass additional data along with self-service flows without storing it permanently. This feature is available in the settings flow, specifically when updating passwords. According to the API reference documentation, when updating settings with the password method, you can include a
transient_payload
field:
Copy code
json {   "csrf_token": "...",   "method": "password",   "password": "new-password",   "transient_payload": { /* your data here */ } }
This transient payload should be passed along to any webhooks configured for the settings flow [Ory Identities API Reference](https://www.ory.sh/docs/kratos/reference/api). For hooks in the settings flow, you need to configure them properly in your configuration file. For example, to configure hooks that run after a password update:
Copy code
yaml selfservice:   flows:     settings:       after:         password:           hooks:             - hook: your_hook_name
If you're not seeing the transient payload in your webhook, make sure: 1. You've properly configured the hook for the settings flow with the password method 2. You're correctly passing the transient payload in your request 3. Your webhook is properly set up to receive and process the payload For more information about configuring hooks in Ory Kratos, you can refer to the [Hook Documentation](https://www.ory.sh/docs/kratos/hooks/configure-hooks).
a
@chilly-king-10285 do you see an error with this config to get transient payload ?
Copy code
settings:
      ui_url: SOMETHING-TO-OVERRIDE
      privileged_session_max_age: 336h
      required_aal: highest_available
      after:
        password:
          hooks:
            - hook: web_hook
              config:
                url: SOMETHING-TO-OVERRIDE
                method: POST
                body: <base64://ZnVuY3Rpb24oY3R4KSB7IGN0eDogY3R4IH0>=
                auth:
                  type: api_key
                  config:
                    name: X-API-Key
                    value: API_KEY_HOOK
                    in: header
        default_browser_return_url: SOMETHING-TO-OVERRIDE
b
A message from kapa.ai
Looking at your configuration, I can see a potential issue that might prevent the transient payload from being properly passed to your webhook. The main problem is with the order of your hooks. According to the troubleshooting documentation for Ory Actions, if you have a
session
hook configured (which is used for "sign in after registration"), it needs to be the last hook to execute because it modifies the HTTP response, preventing other hooks from executing after it. While your configuration doesn't explicitly show a
session
hook, the issue might be similar if there are other hooks configured elsewhere that modify the response. Another potential issue is with your Jsonnet function in the webhook body. The function you're using:
Copy code
function(ctx) { ctx: ctx }
This might not be correctly extracting the transient payload from the context. You might want to ensure your function properly accesses the transient payload data. According to the [Troubleshoot Ory Actions Webhook issues](https://www.ory.sh/docs/troubleshooting/troubleshoot-actions) documentation: > If an Ory Action webhook fails to trigger, verify whether the sign in after registration
session
hook is activated. Because the
session
hook modifies the HTTP response, no other hooks are executed after it. If you want to execute other hooks besides the
session
hook, you need to make sure that it is executed last. To fix this: 1. Make sure your webhook is ordered correctly in relation to any other hooks 2. Consider modifying your Jsonnet function to explicitly access the transient payload 3. You might want to export your full configuration using the Ory CLI to check the complete hook configuration If you're still experiencing issues, you might need to check the webhook events in the Ory Console to see if the webhook is being triggered at all, which could help diagnose the problem further. Would you like me to suggest a more specific Jsonnet function that would better extract the transient payload? [Troubleshoot Ory Actions Webhook issues](https://www.ory.sh/docs/troubleshooting/troubleshoot-actions)
a
@chilly-king-10285 here's complete configuration file, do you see an error in it to get transient_payload from settings password hook ?
Copy code
version: v1.0.0

log:
  level: info
  format: json
  leak_sensitive_values: false
  redaction_text: "***** CENSORED BY Kratos *****"

secrets:
  cookie:
    - 32-LONG-SECRET-NEEDS-AN-OVERRIDE
  cipher:
    - 32-LONG-SECRET-NEEDS-AN-OVERRIDE

ciphers:
  algorithm: xchacha20-poly1305

cookies:
  domain: SOMETHING-TO-OVERRIDE

courier:
  smtp:
    connection_uri: <smtp://SOMETHING-TO-OVERRIDE>

dsn: SOMETHING-TO-OVERRIDE

hashers:
  algorithm: bcrypt
  bcrypt:
    cost: 12

identity:
  default_schema_id: default
  schemas:
    - id: default
      url: file:///etc/config/kratos/identity.schema.json

selfservice:
  default_browser_return_url: SOMETHING-TO-OVERRIDE
  allowed_return_urls:
    - SOMETHING-TO-OVERRIDE
  flows:
    login:
      ui_url: SOMETHING-TO-OVERRIDE
      after:
        password:
          hooks:
            - hook: require_verified_address
    logout:
      after:
        default_browser_return_url: SOMETHING-TO-OVERRIDE
    registration:
      ui_url: SOMETHING-TO-OVERRIDE
      after:
        password:
          hooks:
            - hook: web_hook
              config:
                url: SOMETHING-TO-OVERRIDE
                method: POST
                body: <base64://ZnVuY3Rpb24oY3R4KSB7IGN0eDogY3R4IH0>=
                response:
                  ignore: false
                  parse: true
                auth:
                  type: api_key
                  config:
                    name: X-API-Key
                    value: API_KEY_HOOK
                    in: header
            - hook: show_verification_ui
    verification:
      enabled: true
      ui_url: SOMETHING-TO-OVERRIDE
      use: code
      after:
        hooks:
          - hook: web_hook
            config:
              url: SOMETHING-TO-OVERRIDE
              method: POST
              body: <base64://ZnVuY3Rpb24oY3R4KSB7IGN0eDogY3R4IH0>=
              auth:
                type: api_key
                config:
                  name: X-API-Key
                  value: API_KEY_HOOK
                  in: header
        default_browser_return_url: SOMETHING-TO-OVERRIDE
    recovery:
      enabled: true
      ui_url: SOMETHING-TO-OVERRIDE
      use: code
      notify_unknown_recipients: false
    settings:
      ui_url: SOMETHING-TO-OVERRIDE
      privileged_session_max_age: 336h
      required_aal: highest_available
      after:
        password:
          hooks:
            - hook: web_hook
              config:
                url: SOMETHING-TO-OVERRIDE
                method: POST
                body: <base64://ZnVuY3Rpb24oY3R4KSB7IGN0eDogY3R4IH0>=
                auth:
                  type: api_key
                  config:
                    name: X-API-Key
                    value: API_KEY_HOOK
                    in: header
        default_browser_return_url: SOMETHING-TO-OVERRIDE
  methods:
    password:
      enabled: true
    lookup_secret:
      enabled: true
    code:
      enabled: true
      config:
        lifespan: 20m
    link:
      enabled: true

serve:
  admin:
    base_url: SOMETHING-TO-OVERRIDE
    host: "0.0.0.0"
  public:
    base_url: SOMETHING-TO-OVERRIDE
    cors:
      enabled: true
      allowed_origins:
        - SOMETHING-TO-OVERRIDE
      allowed_headers:
        - Authorization
        - Cookie
        - Content-Type
      exposed_headers:
        - Content-Type
        - Set-Cookie
      allowed_methods:
        - POST
        - GET
        - PUT
        - PATCH
        - DELETE

session:
  lifespan: 336h
b
A message from kapa.ai
Looking at your complete configuration file, I don't see any obvious errors that would prevent the transient payload from being passed to your webhook in the settings password flow. However, there are a few things to note: 1. Your Jsonnet function for the webhook body is very simple:
Copy code
function(ctx) { ctx: ctx }
This will return the entire context object, which should include the transient payload, but it might not be in the format you expect. 2. In your settings flow configuration, you have the webhook configured correctly under the password method:
Copy code
yaml settings:   after:     password:       hooks:         - hook: web_hook           config:             url: SOMETHING-TO-OVERRIDE             method: POST             body: <base64://ZnVuY3Rpb24oY3R4KSB7IGN0eDogY3R4IH0>=             auth:               type: api_key               config:                 name: X-API-Key                 value: API_KEY_HOOK                 in: header
3. One thing I notice is that in your registration flow webhook, you have:
Copy code
yaml response:   ignore: false   parse: true
But this is missing in your settings flow webhook. This might affect how the response is handled, though it shouldn't affect the transient payload being sent. To better access the transient payload specifically, you might want to modify your Jsonnet function to something like:
Copy code
function(ctx) {   transient_payload: ctx.flow.transient_payload }
This would extract just the transient payload from the context and return it. Also, make sure when you're making the settings update request, you're including the transient_payload in your request body as shown in the [Ory Identities API Reference](https://www.ory.sh/docs/kratos/reference/api). For example:
Copy code
json {   "csrf_token": "your-csrf-token",   "method": "password",   "password": "your-new-password",   "transient_payload": {     "your_custom_data": "value"   } }
If you're still not seeing the transient payload in your webhook, you might want to check the Kratos logs for any errors or warnings related to the webhook execution.
a
@chilly-king-10285 do you see an error with this payload to transmit transient payload in settings hook configured above ?
{"method":"password","csrf_token":"s+wat+xci6efGORtWo57QrLf20Szl6gmhFu3g/mLdD2x+QKc7wIAX7/zm8PIdb9wzhHTuWfrRMYO6nBjO0qjeQ==","transient_payload":{"last_name":"Lahousse","first_name":"Mathieu","birthdate":"2025-03-09T23:00:00.000Z","country":"fr","is_invitation_flow":true},"password":"DevDevDev1@","confirmPassword":"DevDevDev1@"}
b
A message from kapa.ai
Looking at your payload, I don't see any errors that would prevent the transient payload from being transmitted to your settings hook. The structure of your payload is correct:
Copy code
json {   "method": "password",   "csrf_token": "s+wat+xci6efGORtWo57QrLf20Szl6gmhFu3g/mLdD2x+QKc7wIAX7/zm8PIdb9wzhHTuWfrRMYO6nBjO0qjeQ==",   "transient_payload": {     "last_name": "Lahousse",     "first_name": "Mathieu",     "birthdate": "2025-03-09T23:00:00.000Z",     "country": "fr",     "is_invitation_flow": true   },   "password": "DevDevDev1@",   "confirmPassword": "DevDevDev1@" }
The
transient_payload
field is properly structured as a JSON object with your custom data. This matches the expected format for the settings flow with password method as documented in the API reference. One thing to note is that I see you have a
confirmPassword
field in your payload. This field is not part of the standard Ory Kratos API for updating settings with the password method. The standard API only requires: -
method
(set to "password") -
csrf_token
(for browser flows) -
password
(the new password) -
transient_payload
(optional) The
confirmPassword
field might be ignored by Kratos, but it shouldn't cause any issues with transmitting the transient payload to your webhook. If you're still not seeing the transient payload in your webhook, I would recommend: 1. Check the Kratos logs for any errors during the webhook execution 2. Verify that your webhook is being triggered at all 3. Try modifying your Jsonnet function to specifically extract and log the transient payload The payload structure itself looks correct for transmitting the transient payload to your settings hook.
a
@chilly-king-10285 i change Jsonnet, here's my new config
Copy code
version: v1.0.0

log:
  level: info
  format: json
  leak_sensitive_values: true
  redaction_text: "***** CENSORED BY Kratos *****"

secrets:
  cookie:
    - 32-LONG-SECRET-NEEDS-AN-OVERRIDE
  cipher:
    - 32-LONG-SECRET-NEEDS-AN-OVERRIDE

ciphers:
  algorithm: xchacha20-poly1305

cookies:
  domain: SOMETHING-TO-OVERRIDE

courier:
  smtp:
    connection_uri: <smtp://SOMETHING-TO-OVERRIDE>

dsn: SOMETHING-TO-OVERRIDE

hashers:
  algorithm: bcrypt
  bcrypt:
    cost: 12

identity:
  default_schema_id: default
  schemas:
    - id: default
      url: file:///etc/config/kratos/identity.schema.json

selfservice:
  default_browser_return_url: SOMETHING-TO-OVERRIDE
  allowed_return_urls:
    - SOMETHING-TO-OVERRIDE
  flows:
    login:
      ui_url: SOMETHING-TO-OVERRIDE
      after:
        password:
          hooks:
            - hook: require_verified_address
    logout:
      after:
        default_browser_return_url: SOMETHING-TO-OVERRIDE
    registration:
      ui_url: SOMETHING-TO-OVERRIDE
      after:
        password:
          hooks:
            - hook: web_hook
              config:
                url: SOMETHING-TO-OVERRIDE
                method: POST
                body: <base64://ZnVuY3Rpb24oY3R4KSB7IGN0eDogY3R4IH0>=
                response:
                  ignore: false
                  parse: true
                auth:
                  type: api_key
                  config:
                    name: X-API-Key
                    value: API_KEY_HOOK
                    in: header
            - hook: show_verification_ui
    verification:
      enabled: true
      ui_url: SOMETHING-TO-OVERRIDE
      use: code
      after:
        hooks:
          - hook: web_hook
            config:
              url: SOMETHING-TO-OVERRIDE
              method: POST
              body: <base64://ZnVuY3Rpb24oY3R4KSB7IGN0eDogY3R4IH0>=
              auth:
                type: api_key
                config:
                  name: X-API-Key
                  value: API_KEY_HOOK
                  in: header
        default_browser_return_url: SOMETHING-TO-OVERRIDE
    recovery:
      enabled: true
      ui_url: SOMETHING-TO-OVERRIDE
      use: code
      notify_unknown_recipients: false
    settings:
      ui_url: SOMETHING-TO-OVERRIDE
      privileged_session_max_age: 336h
      required_aal: highest_available
      after:
        password:
          hooks:
            - hook: web_hook
              config:
                url: SOMETHING-TO-OVERRIDE
                method: POST
                body: <base64://ZnVuY3Rpb24oY3R4KSB7IHRyYW5zaWVudF9wYXlsb2FkOiBjdHguZmxvdy50cmF>uc2llbnRfcGF5bG9hZCB9
                auth:
                  type: api_key
                  config:
                    name: X-API-Key
                    value: API_KEY_HOOK
                    in: header
        default_browser_return_url: SOMETHING-TO-OVERRIDE
  methods:
    password:
      enabled: true
    lookup_secret:
      enabled: true
    code:
      enabled: true
      config:
        lifespan: 20m
    link:
      enabled: true

serve:
  admin:
    base_url: SOMETHING-TO-OVERRIDE
    host: "0.0.0.0"
  public:
    base_url: SOMETHING-TO-OVERRIDE
    cors:
      enabled: true
      allowed_origins:
        - SOMETHING-TO-OVERRIDE
      allowed_headers:
        - Authorization
        - Cookie
        - Content-Type
      exposed_headers:
        - Content-Type
        - Set-Cookie
      allowed_methods:
        - POST
        - GET
        - PUT
        - PATCH
        - DELETE

session:
  lifespan: 336h
And with a request with this payload :
{"method":"password","csrf_token":"tA3yQKTKEJpgma9KBr6WhBRSRsHYFRZFsxWTqdQsB1aByC1xJMo6XmYWr3y6JJi7tiAPUZ5hp1HkKbZJpi/kdQ==","transient_payload":{"last_name":"Lahousse","first_name":"Mathieu","birthdate":"2025-03-02T23:00:00.000Z","country":"fr","is_invitation_flow":true},"password":"DevDevDev1@","confirmPassword":"DevDevDev1@"}
Kratos got an error :
{"error":{"code":500,"status":"Internal Server Error","message":"jsonnetsecure: ERROR: RUNTIME ERROR: Field does not exist: transient_payload\n\<tbase64://ZnVuY3Rpb24oY3R4KSB7IHRyYW5zaWVudF9wYXlsb2FkOiBjdHguZmxvdy50cmF>uc2llbnRfcGF5bG9hZCB9:1:36-62\tobject \u003canonymous\u003e\n\tField \"transient_payload\"\t\n\tDuring manifestation\t\n"}}
Can you see what's wrong ?
b
A message from kapa.ai
I can see the issue with your Jsonnet function in the settings flow webhook configuration. The error message indicates that the field
transient_payload
doesn't exist in the context path you're trying to access. The problem is with your base64-encoded Jsonnet function. Looking at the error message:
Copy code
Field does not exist: transient_payload <tbase64://ZnVuY3Rpb24oY3R4KSB7IHRyYW5zaWVudF9wYXlsb2FkOiBjdHguZmxvdy50cmF>uc2llbnRfcGF5bG9hZCB9:1:36-62
There are two issues: 1. The base64 encoding appears to be corrupted or malformed. Notice the
>
character in the middle of the base64 string, which shouldn't be there. 2. The path
ctx.flow.transient_payload
might not be correct for accessing the transient payload in the settings flow context. Here's how to fix it: 1. First, create a proper base64 encoding of your Jsonnet function. The function should be:
Copy code
function(ctx) { transient_payload: ctx.flow.transient_payload }
2. Encode this properly to base64. You can use an online tool or a command like:
Copy code
echo 'function(ctx) { transient_payload: ctx.flow.transient_payload }' | base64
3. Replace the malformed base64 string in your configuration with the correct one. If you're still having issues, you might want to try a simpler Jsonnet function first to debug:
Copy code
function(ctx) { ctx: ctx }
This will return the entire context, which you can inspect to see the correct path to the transient payload. Based on the [Jsonnet templating documentation](https://www.ory.sh/docs/guides/integrate-with-ory-cloud-through-webhooks#jsonnet-templating), the context structure for flows includes the transient payload, but the exact path might vary depending on the flow type. Once you've identified the correct path, you can update your Jsonnet function accordingly.
a
@chilly-king-10285 Do you think there is an option to enable to have the transient_payload passed to a hook ?
b
A message from kapa.ai
I notice your greeting, but I'll focus on answering your question about transient payloads in Ory. Based on the knowledge sources, the transient_payload feature is already built into Ory Kratos and should be available for various flows including login, registration, recovery, verification, and settings flows. The issue you're experiencing is likely not due to a missing option that needs to be enabled, but rather related to how the webhook is configured or how the context is accessed in your Jsonnet function. Looking at the previous conversation, the main issue was with the malformed base64 encoding in your webhook configuration. The transient_payload should be accessible in the context object, but the exact path might vary depending on the flow. From the GitHub issue comment, we can see that this feature was specifically added to allow passing additional data along with flows:
Copy code
The `UpdateRegistrationFlowBody` type that is used to complete the registration now accepts an optional `transient_payload` field.
And it's described as:
Copy code
The content of this field must be a valid json object. It will be presented to any post registration webhook.
[GitHub Issue #187](https://github.com/ory/network/issues/187) This feature is available in all the flow types as shown in the API references, including settings flows. There's no special option you need to enable - it should work out of the box as long as: 1. Your webhook configuration is correct (with properly encoded base64 Jsonnet) 2. Your Jsonnet function correctly accesses the transient_payload from the context 3. You're including the transient_payload in your request I recommend fixing the base64 encoding issue first, then using a simple Jsonnet function that returns the entire context to identify the correct path to the transient_payload in the settings flow.
A message from kapa.ai
Based on the knowledge sources and our previous conversation, there is no specific option that needs to be enabled to have the transient_payload passed to a webhook hook in Ory Kratos. The transient_payload feature is built into the system by default for various flows including registration, login, recovery, verification, and settings flows. According to the GitHub issue comment: > We added a new feature to better solve the problem of passing additional data along with the registration. The
UpdateRegistrationFlowBody
type that is used to complete the registration now accepts an optional
transient_payload
field. > > The content of this field must be a valid json object. It will be presented to any post registration webhook. [GitHub Issue #187](https://github.com/ory/network/issues/187) This feature is available across all flow types as shown in the API references. The issue you're experiencing is likely related to: 1. The malformed base64 encoding in your webhook configuration that we identified earlier 2. The Jsonnet function not correctly accessing the transient_payload from the context structure To fix this, you should: 1. Properly encode your Jsonnet function to base64 2. Make sure your Jsonnet function correctly accesses the transient_payload (the path might be different than what you're trying to use) 3. Ensure you're including the transient_payload in your request body I recommend first fixing the base64 encoding issue, then using a simple Jsonnet function that returns the entire context (
function(ctx) { ctx: ctx }
) to identify the correct path to the transient_payload in your specific flow.