goauthentik / authentik

The authentication glue you need.
https://goauthentik.io
Other
13.07k stars 870 forks source link

Recovery emails / links do not respect token_expiry #9671

Open fullykubed opened 4 months ago

fullykubed commented 4 months ago

Describe the bug

No way to change token expiration time window from the default 30 minutes.

This is despite the example flows and API documentation stating that the email stage's token_expiry property should be able to change the token expiry.

To Reproduce

Here is an example stage that demonstrates the issue.

resource "authentik_stage_email" "email" {
  name                     = "example-recovery-email"
  use_global_settings      = true
  activate_user_on_success = true
  token_expiry             = 60
  subject                  = "Reset your ${var.organization_name} account!"
}
  1. Deploy the above and integrate it into a recovery flow.
  2. Try to issue a recovery email or generate a recovery link.
  3. Check the authentik_core_token table. Notice that the expiration time is only 30 minutes in the future.

Expected behavior

The expiration time of tokens should match the configured token_expiry.

Version and Deployment (please complete the following information):

Additional Context:

It seems weird that token_expiry is on the stage rather than the flow, especially since we can generate recovery links without emails. Perhaps this is just an old property that needs to be deleted? If so, it would be ideal to be able to set expiration windows on recovery links via some other mechanism.

fullykubed commented 4 months ago

Additional info: Does not matter whether use_global_settings is true or false.

BeryJu commented 4 months ago

From quickly looking through the code I can see how this would happen if the token expires and is rotated (when the token is rotated we currently default to the default expiry value which is 30 minutes)

fullykubed commented 4 months ago

While I could be confusing terms, I believe the issue we have found is specifically with token creation during the recovery flows.

In other words:

  1. No token / active recovery flow exists for the user
  2. Click create recovery link / send recovery email for the user
  3. Notice that the new token is created in the authentik_core_token table but that it will always have an expiration time 30 minutes in the future regardless of the token_expiry setting.
  4. Validate that after 30 minutes the reset links do not work.
authentik-automation[bot] commented 2 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

fullykubed commented 2 months ago

Still an issue.

nwinkelstraeter commented 2 months ago

I think the problem is that the recovery tokens are created differently from the admin interface/ via the API than they are during flow execution.

The API does not set any expiration time so it will always use the default of 30 minutes. Maybe the API call should check for an email stage in the recovery flow and use the setting from there? At least the recovery_email endpoint gets an email stage passed directly and could use the expiry_token value from that.

https://github.com/goauthentik/authentik/blob/b0507d20635ee6d9f8fa0553f97bdb307561f51a/authentik/core/api/users.py#L450-L456

During flow execution the token is created with the token_expiry setting from the stage. https://github.com/goauthentik/authentik/blob/b0507d20635ee6d9f8fa0553f97bdb307561f51a/authentik/stages/email/stage.py#L83-L89

fullykubed commented 2 months ago

I experienced this via both the links generated from the admin UI and the tokens included in the email link (which I assume are a part of the flow).

Perhaps the flow component has been addressed in a recent release?