<@U04UQ68083H> what does state active mean in Krat...
# ory-copilot
q
@chilly-king-10285 what does state active mean in Kratos?
b
A message from kapa.ai
In Ory Kratos, the
state: "active"
property in an identity object indicates that the identity (user account) is active and can be used. This is part of the identity's state property which can have two possible values: - `active`: The identity is active and can be used - `inactive`: The identity is inactive According to the API documentation, this value currently has no effect on the system's behavior, meaning it's primarily an informational field rather than one that controls functionality. When you see this in a session response or identity object, it's telling you that the user account associated with that session or identity is in an active state. For example, in session responses, you'll typically see something like:
Copy code
json {   "identity": {     "id": "c4d24c01-feba-4213-858b-262c8d427f8c",     "state": "active",     "state_changed_at": "2023-02-03T15:41:22.835918Z",     // other identity properties...   },   // other session properties... }
If an account is not active yet, users might see an error message with code 4000010: "Account not active yet. Did you forget to verify your email address?" This suggests that account activation might be related to email verification in some implementations, though the state field itself doesn't directly control this behavior. [Kratos API Reference](https://www.ory.sh/docs/kratos/reference/api) shows this state property in various API responses related to identity management.
q
@chilly-king-10285 can kratos courier give identity information such as the name of the user?
b
A message from kapa.ai
Yes, Ory Kratos courier can include identity information such as the user's name when sending messages. The courier service is responsible for delivering emails and SMS messages to users, and it can include personalized information from the identity in these messages. When configuring HTTP-based email delivery, for example, the courier passes identity information through the
template_data
variable. This allows you to access user details in your message templates:
Copy code
jsonnet function(ctx) {   recipient: ctx.recipient,   template_type: ctx.template_type,   name: if "template_data" in ctx && "identity" in ctx.template_data && "name" in ctx.template_data.identity then ctx.template_data.identity.name else null,   // other fields... }
As shown in this example, you can access the user's name through
ctx.template_data.identity.name
[HTTP based email delivery](https://www.ory.sh/docs/kratos/self-hosted/email-http#configuration). The identity object is available in various message templates, particularly for: - Recovery emails (valid) - Recovery code emails (valid) - Verification emails (valid) - Verification code emails (valid) When creating custom email templates, you can access the identity information directly. For example, in a recovery email template, you could personalize the greeting with the user's first name:
Copy code
Hello {{ upper .Identity.traits.firstName }},  to recover your account, please enter the following code:
This example shows how to access the user's first name from the identity traits [Email templates in self-hosted Ory Kratos](https://www.ory.sh/docs/kratos/self-hosted/mail-courier-templates). The available identity information depends on your identity schema configuration, but typically includes all the traits you've defined in your schema, such as email, name, phone number, etc.
q
@chilly-king-10285 my traits look like this "traits": { "name": { "last": "Boulpaep", "first": "Luka" }, "email": "lukaboulpaep@outlook.com" }, what do I do to get Luka Boulpaep as name attribute in the json http request of the courrier
b
A message from kapa.ai
Based on your identity traits structure, you want to combine the first and last name to get "Luka Boulpaep" as a single name attribute in the JSON HTTP request of the Ory Kratos courier. To achieve this, you need to customize the Jsonnet template used for the HTTP courier request. Here's how you can do it: In your courier configuration, you need to specify a custom Jsonnet template that combines the first and last name fields from the identity traits. You can create a file with the following Jsonnet code:
Copy code
jsonnet function(ctx) {   recipient: ctx.recipient,   template_type: ctx.template_type,   name: if "template_data" in ctx && "identity" in ctx.template_data && "traits" in ctx.template_data.identity && "name" in ctx.template_data.identity.traits          then ctx.template_data.identity.traits.name.first + " " + ctx.template_data.identity.traits.name.last          else null,   to: if "template_data" in ctx && "to" in ctx.template_data then <http://ctx.template_data.to|ctx.template_data.to> else null,   recovery_code: if "template_data" in ctx && "recovery_code" in ctx.template_data then ctx.template_data.recovery_code else null,   recovery_url: if "template_data" in ctx && "recovery_url" in ctx.template_data then ctx.template_data.recovery_url else null,   verification_url: if "template_data" in ctx && "verification_url" in ctx.template_data then ctx.template_data.verification_url else null,   verification_code: if "template_data" in ctx && "verification_code" in ctx.template_data then ctx.template_data.verification_code else null, }
Then, in your configuration file, reference this template:
Copy code
yaml courier:   delivery_strategy: http   http:     request_config:       url: <https://your-api-endpoint.com>       method: POST       body: <file://path/to/your/template.jsonnet>       headers:         Content-Type: application/json
This template specifically combines the first and last name from your identity traits structure to create a single "name" field with the value "Luka Boulpaep" in the HTTP request payload [HTTP based email delivery](https://www.ory.sh/docs/kratos/self-hosted/email-http#configuration). Note that the template checks for the existence of each property in the path to avoid errors if any part of the structure is missing. If you're using email templates directly rather than HTTP delivery, you can also access the combined name in your email templates using:
Copy code
Hello {{ .Identity.traits.name.first }} {{ .Identity.traits.name.last }},
This would render as "Hello Luka Boulpaep," in your email [Email templates in self-hosted Ory Kratos](https://www.ory.sh/docs/kratos/self-hosted/mail-courier-templates).
q
@chilly-king-10285 is this a correct struct to parse the html from it? type EmailTemplate struct { Recipient string
json:"recipient"
TemplateType string
json:"template_type"
Name *string
json:"name,omitempty"
To *string
json:"to,omitempty"
RecoveryCode *string
json:"recovery_code,omitempty"
RecoveryURL *string
json:"recovery_url,omitempty"
VerificationURL *string
json:"verification_url,omitempty"
VerificationCode *string
json:"verification_code,omitempty"
}
b
A message from kapa.ai
Your struct looks mostly correct for parsing the JSON payload from the Ory Kratos courier HTTP delivery, but it's missing a few fields that are available in the default payload. Here's an analysis of your struct and what might need to be added: Your current struct includes: -
Recipient
- The email address of the recipient -
TemplateType
- The type of template being used -
Name
- The name of the user (which you've customized in previous examples) -
To
- The recipient email address (duplicated in template_data) -
RecoveryCode
,
RecoveryURL
- For recovery flows -
VerificationURL
,
VerificationCode
- For verification flows However, based on the default Jsonnet template used by Ory Kratos for HTTP delivery, you should also include:
Copy code
go type EmailTemplate struct {  Recipient        string  `json:"recipient"`  TemplateType     string  `json:"template_type"`  Name             *string `json:"name,omitempty"`  To               *string `json:"to,omitempty"`  RecoveryCode     *string `json:"recovery_code,omitempty"`  RecoveryURL      *string `json:"recovery_url,omitempty"`  VerificationURL  *string `json:"verification_url,omitempty"`  VerificationCode *string `json:"verification_code,omitempty"`  LoginCode        *string `json:"login_code,omitempty"`  RegistrationCode *string `json:"registration_code,omitempty"`  Subject          *string `json:"subject,omitempty"`  Body             *string `json:"body,omitempty"` }
The additional fields are: -
LoginCode
- For one-time code login flows -
RegistrationCode
- For one-time code registration flows -
Subject
- The email subject -
Body
- The email body These fields are included in the default Jsonnet template as shown in the [Use a custom server to send Ory Identity messages to users](https://www.ory.sh/docs/kratos/emails-sms/sending-emails-smtp#send-emails-using-an-http-server) documentation. If you're only handling recovery and verification flows, your current struct might be sufficient, but including all possible fields will make your code more robust for future use cases. Kapa.ai: I've analyzed your Go struct for parsing Ory Kratos courier email templates. It covers most fields but is missing a few that are in the default template. I've provided the complete struct with all fields you should include for full compatibility.
q
this is my jsonnet though: function(ctx) { recipient: ctx.recipient, template_type: ctx.template_type, name: if "template_data" in ctx && "identity" in ctx.template_data && "traits" in ctx.template_data.identity && "name" in ctx.template_data.identity.traits then ctx.template_data.identity.traits.name.first + " " + ctx.template_data.identity.traits.name.last else null, to: if "template_data" in ctx && "to" in ctx.template_data then ctx.template_data.to else null, recovery_code: if "template_data" in ctx && "recovery_code" in ctx.template_data then ctx.template_data.recovery_code else null, recovery_url: if "template_data" in ctx && "recovery_url" in ctx.template_data then ctx.template_data.recovery_url else null, verification_url: if "template_data" in ctx && "verification_url" in ctx.template_data then ctx.template_data.verification_url else null, verification_code: if "template_data" in ctx && "verification_code" in ctx.template_data then ctx.template_data.verification_code else null, }
@chilly-king-10285 this is my jsonnet though: function(ctx) { recipient: ctx.recipient, template_type: ctx.template_type, name: if "template_data" in ctx && "identity" in ctx.template_data && "traits" in ctx.template_data.identity && "name" in ctx.template_data.identity.traits then ctx.template_data.identity.traits.name.first + " " + ctx.template_data.identity.traits.name.last else null, to: if "template_data" in ctx && "to" in ctx.template_data then ctx.template_data.to else null, recovery_code: if "template_data" in ctx && "recovery_code" in ctx.template_data then ctx.template_data.recovery_code else null, recovery_url: if "template_data" in ctx && "recovery_url" in ctx.template_data then ctx.template_data.recovery_url else null, verification_url: if "template_data" in ctx && "verification_url" in ctx.template_data then ctx.template_data.verification_url else null, verification_code: if "template_data" in ctx && "verification_code" in ctx.template_data then ctx.template_data.verification_code else null, }
b
A message from kapa.ai
Your Jsonnet template looks good, but there are a few issues with the formatting that need to be fixed. The HTML entities (
&
) and URL formatting (
<http://template_data.to|template_data.to>
) appear to be incorrectly encoded. Here's the corrected version:
Copy code
jsonnet function(ctx) {   recipient: ctx.recipient,   template_type: ctx.template_type,   name: if "template_data" in ctx && "identity" in ctx.template_data && "traits" in ctx.template_data.identity && "name" in ctx.template_data.identity.traits     then ctx.template_data.identity.traits.name.first + " " + ctx.template_data.identity.traits.name.last     else null,   to: if "template_data" in ctx && "to" in ctx.template_data then <http://ctx.template_data.to|ctx.template_data.to> else null,   recovery_code: if "template_data" in ctx && "recovery_code" in ctx.template_data then ctx.template_data.recovery_code else null,   recovery_url: if "template_data" in ctx && "recovery_url" in ctx.template_data then ctx.template_data.recovery_url else null,   verification_url: if "template_data" in ctx && "verification_url" in ctx.template_data then ctx.template_data.verification_url else null,   verification_code: if "template_data" in ctx && "verification_code" in ctx.template_data then ctx.template_data.verification_code else null, }
This template will correctly extract the user's first and last name from the identity traits and combine them into a single "name" field. However, as mentioned in my previous response, you might want to consider adding the additional fields that are available in the default template: -
login_code
-
registration_code
-
subject
-
body
These fields are included in the default Jsonnet template as shown in the [Use a custom server to send Ory Identity messages to users](https://www.ory.sh/docs/kratos/emails-sms/sending-emails-smtp#send-emails-using-an-http-server) documentation. If you only need to handle the fields you've included, then your template (with the formatting fixes) should work correctly for your use case.
q
@chilly-king-10285 why do I get this? I create a recovery code with type api??? 2025-04-26 143931 time=2025-04-26T123931Z level=info msg=started handling request http_request=map[headersmap[accept encodinggzip content-length:91 user-agent:Go-http-client/1.1] hostkratos4433 method:POST path:/admin/recovery/code query:<nil> remote172.18.0.742882 scheme:http] 2025-04-26 143931 time=2025-04-26T123931Z level=warning msg=A request failed due to a missing or invalid csrf_token value audience=application error=map[debug: detailsmap[docshttps://www.ory.sh/kratos/docs/debug/csrf hint:The anti-CSRF cookie was found but the CSRF token was not included in the HTTP request body (csrf_token) nor in the HTTP Header (X-CSRF-Token). reject_reason:The HTTP Cookie Header was set and a CSRF token was sent but they do not match. We recommend deleting all cookies for this domain and retrying the flow.] message:the request was rejected to protect you from Cross-Site-Request-Forgery reason:Please retry the flow and optionally clear your cookies. The request was rejected to protect you from Cross-Site-Request-Forgery (CSRF) which could cause account takeover, leaking personal information, and other serious security issues.
b
A message from kapa.ai
You're encountering a CSRF (Cross-Site Request Forgery) error when trying to create a recovery code with type "api". This error occurs because Ory Kratos is detecting a mismatch between the CSRF token in your cookies and the one provided in your request. Based on the error message, there are a few key issues: 1. The anti-CSRF cookie was found, but the CSRF token was not included in either: - The HTTP request body as
csrf_token
parameter - The HTTP header as
X-CSRF-Token
2. Or, if you did include a CSRF token, it doesn't match the one in the cookie. ## How to fix this issue: For API-based flows (which you're trying to use), you have a few options: 1. Include the CSRF token in your request body: When submitting the recovery flow, you need to include the
csrf_token
field in your request body. This token can be found in the UI nodes of the flow response as a hidden input field named
csrf_token
[CSRF troubleshooting](https://www.ory.sh/docs/kratos/debug/csrf). 2. Include the CSRF token in the X-CSRF-Token header: Alternatively, you can include the same token in the
X-CSRF-Token
HTTP header. 3. Make sure cookies are properly passed: Ensure that you're passing all cookies from previous requests in your current request. Here's an example of how to properly submit a recovery flow with the CSRF token:
Copy code
curl -X POST \     -H 'Content-Type: application/json' \     -H 'Accept: application/json' \     -b cookies.txt \     -d '{"method":"code","email":"<mailto:example@example.com|example@example.com>","csrf_token":"your-csrf-token"}' \     "<https://your-kratos-domain/self-service/recovery?flow=<your-flow-id>>"
If you're using the admin API, note that even though you're creating a recovery with type "api", the browser-based CSRF protection might still be active if cookies are present in your request [Submit recovery flow](https://www.ory.sh/docs/kratos/bring-your-own-ui/custom-ui-basic-integration#submit-recovery-flow). The maintainer's comment in a similar issue confirms this: "The error in your log clearly indicates that you are not sending the CSRF Token in your request body
csrf_token=…
which is needed to verify the token" [CSRF Error during Login Flow](https://github.com/ory/kratos/discussions/4307). To completely avoid CSRF issues with API flows, you might want to ensure you're not sending any cookies with your request, or use a fresh HTTP client for each request that doesn't store cookies between requests.
q
@chilly-king-10285 This is via postman locally: 025-04-26 144747 time=2025-04-26T124747Z level=info msg=started handling request http_request=map[headersmap[accept*/* accept-encoding:gzip, deflate, br cache-control:no-cache connection:keep-alive content-length:104 content-type:application/json postman-token:5595b45d-87b1-4917-9861-52c72f588000 user-agent:PostmanRuntime/7.43.3] hostlocalhost4434 method:POST path:/admin/recovery/code query:<nil> remote172.18.0.161780 scheme:http] 2025-04-26 144747 time=2025-04-26T124747Z level=info msg=A recovery code has been created. audience=audit identity_id=9e603962-98a1-47e8-8605-9d1e8f073160 recovery_code=Value is sensitive and has been redacted. To see the value set config key "log.leak_sensitive_values = true" or environment variable "LOG_LEAK_SENSITIVE_VALUES=true". service_name=Ory Kratos service_version=v1.3.1 2025-04-26 144747 time=2025-04-26T124747Z level=info msg=completed handling request http_request=map[headersmap[accept*/* accept-encoding:gzip, deflate, br cache-control:no-cache connection:keep-alive content-length:104 content-type:application/json postman-token:5595b45d-87b1-4917-9861-52c72f588000 user-agent:PostmanRuntime/7.43.3] hostlocalhost4434 method:POST path:/admin/recovery/code query:<nil> remote172.18.0.161780 scheme:http] http_response=map[headersmap[cache controlprivate, no-cache, no-store, must-revalidate content-type:application/json; charset=utf-8] size:164 status:201 text_status:Created took:11.417209ms] I will send the logs in the next message for when I call it through my service running in docker-compose
b
A message from kapa.ai
I can see that your Postman request to the
/admin/recovery/code
endpoint was successful. The logs show: 1. The request was received at the admin endpoint 2. A recovery code was successfully created for identity ID
9e603962-98a1-47e8-8605-9d1e8f073160
3. The request completed with a 201 Created status This is working correctly because you're using the admin API endpoint, which doesn't require CSRF protection. The admin API is designed for server-to-server communication and bypasses the CSRF checks that were causing your previous error. When you mentioned in your previous message that you were getting CSRF errors, it was likely because you were either: 1. Using a public-facing endpoint instead of the admin endpoint 2. Or mixing cookie-based authentication with API requests The admin endpoints (like
/admin/recovery/code
that you're using now) don't require CSRF tokens because they're protected by different authentication mechanisms (typically API keys or other admin credentials). I'll wait for your next message with the logs from your service running in docker-compose to help diagnose any issues you might be having there.
q
@chilly-king-10285 logs when I call from my service: 2025-04-26 144617 time=2025-04-26T124617Z level=info msg=started handling request http_request=map[headersmap[accept encodinggzip content-length:91 user-agent:Go-http-client/1.1] hostkratos4433 method:POST path:/admin/recovery/code query:<nil> remote172.18.0.745274 scheme:http] 2025-04-26 144617 time=2025-04-26T124617Z level=warning msg=A request failed due to a missing or invalid csrf_token value audience=application error=map[debug: detailsmap[docshttps://www.ory.sh/kratos/docs/debug/csrf hint:The anti-CSRF cookie was found but the CSRF token was not included in the HTTP request body (csrf_token) nor in the HTTP Header (X-CSRF-Token). reject_reason:The HTTP Cookie Header was set and a CSRF token was sent but they do not match. We recommend deleting all cookies for this domain and retrying the flow.] message:the request was rejected to protect you from Cross-Site-Request-Forgery reason:Please retry the flow and optionally clear your cookies. The request was rejected to protect you from Cross-Site-Request-Forgery (CSRF) which could cause account takeover, leaking personal information, and other serious security issues.
b
A message from kapa.ai
I can see the issue in your logs. When you're calling the
/admin/recovery/code
endpoint from your service, you're encountering a CSRF error, unlike when you call it from Postman. The key difference appears to be related to cookies. The error message states: > The anti-CSRF cookie was found but the CSRF token was not included in the HTTP request body (csrf_token) nor in the HTTP Header (X-CSRF-Token). This suggests that your Go HTTP client is sending cookies with your request, but not including the corresponding CSRF token. Here are a few ways to fix this: 1. Include the CSRF token from the cookie in your request: - Add it to the request body as
csrf_token
- Or add it as an
X-CSRF-Token
header 2. Don't send cookies with your request: - Create a new HTTP client for each request that doesn't store cookies - Or disable cookie jar in your HTTP client Here's how you might modify your Go code to create a client that doesn't use cookies:
Copy code
go client := &http.Client{     Jar: nil, // Explicitly set to nil to disable cookie storage }
According to the Ory maintainer's response to a similar issue: "The token value you send in the body comes from the API response of /self-service/login/flows and is a different value than the one from the cookie" [CSRF Error during Login Flow](https://github.com/ory/kratos/discussions/4307). This suggests that there might be a mismatch between the CSRF token in your cookies and what you're sending (if you're sending one at all). Since the admin API endpoint should work without CSRF protection (as it did in Postman), the most likely issue is that your service is somehow maintaining cookies from previous interactions with Kratos, and those cookies contain CSRF tokens that are triggering the protection mechanism. Try implementing one of the solutions above, particularly disabling cookie storage in your HTTP client, and see if that resolves the issue.
q
@chilly-king-10285 but servers cant store cookies right
b
A message from kapa.ai
Servers don't automatically store cookies like browsers do, but they can receive, forward, and manipulate cookies in HTTP requests and responses. In your case, it appears your Go HTTP client is maintaining cookies between requests. The standard Go HTTP client has a cookie jar that can store cookies from responses and automatically include them in subsequent requests to the same domain. This is likely why you're experiencing different behavior between Postman and your service: 1. Postman (working): Likely not storing/sending cookies with your admin API request 2. Your service (CSRF error): Automatically storing cookies from previous interactions with Kratos and sending them with your admin API request As mentioned in the Ory documentation: > When building a server-side application, make sure to include the
Cookie
header from the client when fetching the self-service flows... Without forwarding the
Cookie
HTTP header you can't fetch the flow due to a security error. [CSRF troubleshooting](https://www.ory.sh/docs/troubleshooting/csrf) For your admin API calls, you should either: 1. Create a fresh HTTP client for each request that doesn't use cookies:
Copy code
go client := &http.Client{     Jar: nil, // Explicitly disable cookie storage }
2. Or clear any existing cookies before making the admin API call This should resolve the CSRF error you're encountering when calling the admin API from your service. Would you like me to provide more specific guidance on how to modify your Go HTTP client implementation?
q
@chilly-king-10285 I asked for a recovery through the admin api. But after saving the password I keep being on the settings page. Is there a way for me to navigate to another page on submit?
b
A message from kapa.ai
I understand you're trying to redirect users to a different page after they complete the recovery flow and save their password, rather than staying on the settings page. This is a known behavior in Ory Kratos. When a recovery flow is successful, Kratos automatically redirects the user to the settings page where they can update their password. After the password is updated, the user remains on the settings page instead of being redirected elsewhere. According to the documentation and GitHub issues, there are a few approaches to handle this: ## Option 1: Configure a redirect URL for the settings flow Since the recovery flow transitions to the settings flow, you can configure a redirect URL for the settings flow:
Copy code
yaml selfservice:   flows:     settings:       after:         default_browser_return_url: <https://your-desired-redirect-url/>
This will redirect users after they complete the settings flow (which includes updating their password after recovery) [Browser redirects and flow completion](https://www.ory.sh/docs/concepts/redirects#redirect-flows). ## Option 2: Use the
return_to
parameter You can include a
return_to
parameter when initializing the recovery flow:
Copy code
sdk.createBrowserRecoveryFlow({   return_to: "<https://your-desired-redirect-url/>" })
However, there's a known issue with this approach. According to a GitHub issue: "When creating a recovery flow with the
return_to
query parameter the url is not respected when the account has two factor authentication" [Recovery flow with Two-Factor does not respect
return_to
](https://github.com/ory/network/issues/222). ## Option 3: Manual redirect in your UI Since the recovery flow redirects to the settings page, you can implement a custom redirect in your settings UI by checking if the user came from a recovery flow and then redirecting them after they submit the password change. ## Important note There's an open issue in the Ory Kratos GitHub repository about this exact problem: "Recovery flow redirect after success not working as expected" [GitHub Issue #2371](https://github.com/ory/kratos/issues/2371). According to this issue, the
default_browser_return_url
configuration for the recovery flow doesn't work as expected because the recovery flow redirects to the settings flow. A user in the issue comments mentioned: "The only way to reliably achieve this behaviour is to cause a manual overriding redirect INSIDE the settings page - By checking the source redirect that brought you to that page, and checking if that value contains the recovery flow identifier." Would you like me to provide more details on any of these approaches?
q
@chilly-king-10285 Can a selfhosted version of Kratos make use of organizations?
b
A message from kapa.ai
Based on the knowledge sources provided, organizations are not available in self-hosted Ory Kratos. This feature is exclusively available in Ory Network. According to the documentation: > Organizations are only available in Ory Network and are not supported in self-hosted Ory Kratos. If you have any questions, or if you would like more information about transitioning to Ory Network, please don't hesitate to [reach out](https://www.ory.sh/contact/). [B2B Single Sign-On & SAML](https://www.ory.sh/docs/kratos/organizations) Similarly, for multi-tenancy functionality: > [Ory Network](https://console.ory.sh) is the only available option to have a multi-tenant Ory Kratos set up. It is not possible to self-host Ory Kratos as a multi-tenant service as its data model does not support this due to data, scalability, and operational complexity. [Multitenancy](https://www.ory.sh/docs/kratos/guides/multi-tenancy-multitenant) Organizations in Ory provide functionality for grouping users within a project, managing B2B enterprise SSO with OIDC or SAML, and handling domain-based registrations. These features are part of Ory Network's commercial offering and are not available in the self-hosted open source version of Kratos. If you need organization functionality, you would need to use Ory Network instead of self-hosting Kratos.
q
@chilly-king-10285 can hydra or kratos run in serverless modes like in AWS Lambda?
b
A message from kapa.ai
The knowledge sources do not explicitly mention support for running Ory Hydra or Ory Kratos in serverless environments such as AWS Lambda. Ory’s architecture is designed around stateless, disposable processes that scale horizontally and run best on container orchestration systems like Kubernetes, CloudFoundry, and OpenShift. The documentation emphasizes that Ory services are typically deployed as long-running processes or containers, relying on a persistent SQL database for state, and do not require additional dependencies beyond the database and the process itself. There is no guidance or example provided for deploying Hydra or Kratos in a serverless function environment like AWS Lambda, which is optimized for short-lived, event-driven workloads rather than persistent HTTP servers [Architecture principles](https://www.ory.sh/docs/ecosystem/software-architecture-philosophy). If you are considering serverless deployment, you may encounter challenges related to connection management, cold starts, and maintaining persistent HTTP endpoints, which are fundamental to how Ory services operate. For best results, Ory recommends using container-based or VM-based deployments.
q
@chilly-king-10285 Does OSS Kratos support webhooks for user events like deletion or creation?
b
A message from kapa.ai
Open Source (OSS) Ory Kratos does not natively support webhooks for user events like identity creation or deletion. Webhooks and the broader "Ory Actions" extensibility mechanism—which allow you to trigger external logic in response to user-related events such as registration, login, account recovery, verification, or settings updates—are features of the Ory Network (the managed, commercial offering) and not available in the self-hosted OSS version of Kratos [Overview of Ory Actions](https://www.ory.sh/docs/kratos/hooks/configure-hooks). While OSS Kratos does allow you to configure hooks for certain self-service flows (like before/after registration, login, settings, etc.), there is no mention in the knowledge sources of webhook support for direct identity lifecycle events such as creation or deletion via the admin API or SCIM. The event streaming and webhook features for these types of events are documented as part of Ory Network’s enterprise capabilities [Live event streams](https://www.ory.sh/docs/actions/live-events/). If you require webhooks for user creation or deletion events, you would need to use Ory Network or implement your own integration layer that listens for these events and triggers webhooks accordingly.
q
@chilly-king-10285 what happens when you initiate a recovery flow when one was already created?
b
A message from kapa.ai
When you attempt to initiate a new recovery flow while one already exists, Ory Kratos expects you to use the existing recovery flow instead of creating a new one. If you try to create a new recovery flow (for example, using the
createNativeRecoveryFlow
endpoint) while a valid session cookie or session token is present, you will receive a
400 Bad Request
error. The documentation states: > On an existing recovery flow, use the
getRecoveryFlow
API endpoint. This means you should retrieve and continue the existing flow using its ID, rather than starting a new one. This approach helps prevent issues such as CSRF attacks and ensures the integrity of the recovery process [Ory API Reference – createNativeRecoveryFlow](https://www.ory.sh/docs/reference/api). If the existing flow has expired, you will need to initiate a new one. Otherwise, always use the current flow until it is completed or expires.
q
What if you do it through the admin api @chilly-king-10285
b
A message from kapa.ai
The knowledge sources do not explicitly state what happens if you initiate a new recovery flow through the admin API when one already exists. The available documentation and examples focus on the self-service (public) API, where you are expected to use the existing flow if one is active, and a new flow is only created if the previous one has expired [Ory API Reference – createNativeRecoveryFlow](https://www.ory.sh/docs/reference/api). For the admin API, the documentation describes how to initiate a recovery flow for a user and receive a recovery link and code, but it does not specify whether multiple concurrent admin-initiated recovery flows are allowed, or if a new request invalidates the previous one [Administrative account recovery](https://www.ory.sh/docs/kratos/manage-identities/account-recovery). Therefore, based on the knowledge sources, it is unclear whether the admin API enforces the same flow reuse/expiration logic as the public API, or if it always creates a new flow and code regardless of existing ones.