Ory Kratos: Empty responses from server in verification flow

Hi,

Using the latest Ory Kratos release (v0.3.0-alpha.1), I receive empty responses from the server trying to complete the verification flow. I initiate the flow with a GET /self-service/browser/flows/verification/email. Then, the next call is a call to GET /self-service/browser/flows/requests/verification?request=<request>. Then, as I POST to /self-service/browser/flows/verification/email/complete?request=<request>, the response from the server is empty. However, at this point, an email is sent to the address that needs to be verified. And, finally, following the verification mail in the link, i.e. a GET to /self-service/browser/flows/verification/email/confirm/{code}, also results in an empty response. When I check the logs, there are no traces of errors, even when the log level is set to DEBUG. And if I check the database, the account status is set to complete and the verified flag to true, so the verification seem to work under the hood, but the response from the server is empty.

What could be the problem here? Mails are sent using AWS Simple Email Service.

And after successful verification, what is supposed to happen? Will the user be logged in and given the opportunity to set his password? Self-service registration does not really work for us, so our preferred way of dealing with identities is that an administrator creates the user accounts using the /identities endpoint, then initiates the verification flow so the user receives the email with the verification link, and finally that the user follows the link, is logged in and can set his password. Maybe this is not the way it’s supposed to work? Implementing the self-service registration flow in a server facade seems a bit unpractical, but I guess It’s possible.

Cheers

Lars

Config please!

Here it is (with sensitive info removed). I used the one kratos.yaml I found in the repo, and made some minor changes.

  serve:
    admin:
      host: 0.0.0.0
    public:
      host: 0.0.0.0

  dsn: postgres://postgres:<password>@<host>5432/kratos

  log:
    level: debug
    format: text
    
  security:
    session:
      cookie:
        same_site: Lax

  courier:
    smtp:
      connection_uri: smtps://<smtp>
      from_address: <address>

  urls:
    default_return_to: http://127.0.0.1:4435/auth/login
    mfa_ui: http://127.0.0.1:4435/mfa
    login_ui: http://127.0.0.1:4435/auth/login
    settings_ui: http://127.0.0.1:4435/settings
    verify_ui: http://127.0.0.1:4435/verify
    registration_ui: http://127.0.0.1:4435/auth/registration
    self:
      public: http://127.0.0.1:4433
      admin: http://127.0.0.1:4434
    error_ui: http://127.0.0.1:4435/error
    whitelisted_return_to_urls:
      - http://return-to-1-test.ory.sh/
      - http://return-to-2-test.ory.sh/

  identity:
    traits:
      default_schema_url: file:///etc/config/default_identity_schema.json
      schemas:
        - id: other
          url: http://test.kratos.ory.sh/other-identity.schema.json

  hashers:
    argon2:
      memory: 1048576
      iterations: 2
      parallelism: 4
      salt_length: 16
      key_length: 32

  secrets:
    session:
      # The secret key needs a predefined number of characters: either 16, 24 or 32 
      - <key-1>
      - <key-2>

  selfservice:
    strategies:
      password:
        enabled: true
      oidc:
        enabled: false
        config:
          providers:
            - id: github
              provider: github
              client_id: a
              client_secret: b
              mapper_url: http://test.kratos.ory.sh/default-identity.schema.json
    logout:
      redirect_to: http://127.0.0.1:4435/auth/login

    settings:
      request_lifespan: 99m
      privileged_session_max_age: 1h
      after:
        default_return_to: https://self-service/settings/return_to
        password:
          default_return_to: https://self-service/settings/password/return_to
        profile:
          hooks:
            - hook: verify
    login:
      request_lifespan: 99m
      after:
        default_return_to: https://self-service/login/return_to
        password:
          default_return_to: https://self-service/login/password/return_to
          hooks:
            - hook: revoke_active_sessions
    registration:
      request_lifespan: 98m
      before:
        hooks:
          - hook: redirect
            config:
              default_redirect_url: http://test.kratos.ory.sh:4000/
              allow_user_defined_redirect: false
      after:
        default_return_to: https://self-service/registration/return_to
        password:
          hooks:
            - hook: session
            - hook: verify
            - hook: redirect
              config:
                default_redirect_url: http://test.kratos.ory.sh:4000/
                allow_user_defined_redirect: false
        oidc:
          default_return_to: https://self-service/registration/oidc/return_to
          hooks:
            - hook: verify
            - hook: session
            - hook: redirect
              config:
                default_redirect_url: http://test.kratos.ory.sh:4000/
                allow_user_defined_redirect: false

I think I know what the problem is. There’s a verify part missing under self-service, and most significantly, there’s no return_to attribute. However, that part is missing from the documentation, and was only apparent from going through the source code, so maybe the documentation needs to be updated to include the return_to attribute. I will try setting the return_to attribute and see what happens.

Yeah, adding the return_to fixed the empty response problem. Now I get a redirect to the return_to URL. However, I do not receive a session cookie, so the user can not set his password at this point, and can not login unless he signed up using the self-service registration flow and knows his password. Is it possible to specify a hook with the verification flow so that you get a valid session and can initiate the settings flow?

Did you take a look at the quickstart? It solves the use case you have.

Regarding your config - You’re using the redirect hook after registration - this is probably not what you want to do (we might need to rename it to make this clearer): https://www.ory.sh/kratos/docs/self-service/hooks/index#redirect-3

There are also docs about verification here but as you mentioned the return_to value is missing there. Would be awesome if you could help document that! :slight_smile:

In general it shouldn’t end up with a blank page so that’s definitely a bug. To investigate the cause it would be super helpful if you could get a reproducible set up working!

Thanks for your reply!

I have checked out the Quickstart, but I can’t see how that solves my use-case. First, I’m running Kubernetes in AWS, so I haven’t tried setting up an environment with Docker compose. I prefer setting up the k8s environment the way we intend to use the components. Anyway, the use-case we have is that an administrator would create an identity using the POST /identities endpoint, then initiate the verification flow so the user receives the mail with the verification link. Then, the user would follow the link, and as the 302 redirect happens as part of the final verification, it would be great if session was created and a Set-Cookie with the kratos session was sent, so the user can be redirected to a UI where he can set his password. That’s the use-case. I don’t see how that is implemented in the Quickstart? And I was thinking that the easiest way to accomplish that could be with a hook, for consistency with the other flows.

And yes, I can have a look at the documentation and see if I can create a PR for you.

Cheers

Lars

Ah, this is much clearer - now I understand your use case. I thought you were trying to solve self-service verification, which is implemented in the docs.

Unfortunately, we haven’t done much progress on Admin APIs yet as we’re heavily committed to solving the self-service stuff first. As such it is not possible to import or create users using the Admin API. There’s also an issue for that: https://github.com/ory/kratos/issues/200

We actually want to support your use case as a first-class citizen. So basically the admin creates the account, the user is notified with a temporary password or temporary sign in link, and then activates the account.

We have not decided yet if these Admin APIs are more important than 2FA but we personally tend towards getting out 2FA / MFA first.

What could actually maybe work is, once account recovery lands, that you create an account with the email address as a recovery option - then the user either requests a recovery email him/herself, or you request one in his/her name. The link in the email can be used to set a password!

Account recovery: https://github.com/ory/kratos/pull/428

The account recover could work. You would actually solve 2 use-cases for us by implementing that feature, cause obviously we need account recovery as well. Any idea on when that feature could be implemented (theres seem to be some issues with the PR)? I can build the image myself, so I wouldn’t have to wait for a release.

We don’t give out timelines, but you can follow the progress in the linked PR and other issues. Milestone is 0.4.0

Building and running master is not recommended because of undocumented breaking changes or other stabilization patches

Thanks. It’s a development cluster (nothing in production so far), so I can live with some side-effects. We’ll see how we handle this, but I will track the PR for sure.