Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JWT library will not accept EC keys - as of today #12792

Open
Mase3206 opened this issue Jan 24, 2025 · 0 comments
Open

JWT library will not accept EC keys - as of today #12792

Mase3206 opened this issue Jan 24, 2025 · 0 comments

Comments

@Mase3206
Copy link

Mase3206 commented Jan 24, 2025

Describe the bug
Existing (and functional as of yesterday) provider configs for Proxmox VE 8 (OIDC), Bookstack (SAML2), and Nextcloud (OIDC), all from the instructions published on the Authentik website when available. My Let's Encrypt cert expired today, so I went in to replace it with a valid one and update all providers. However, now none of my providers will authenticate, as the JWT library is just now complaining about ECDSA.

Mind you, Let's Encrypt has been using elliptic curve for years, and the now expired certs (configured as either the signing key, encryption key, or both) worked without a hitch yesterday.

To Reproduce
Steps to reproduce the behavior:

  1. Retrieve a valid, up to date certificate from Let's Encrypt. These certs all use ECDSA with SHA-384 by default.
  2. Set either the signing key or encryption key to this certificate. In my case, I was updating the certificate from an expired one.
  3. Attempt to authenticate with an OIDC or SAML2 flow.

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots

Image
Image
Image

Logs

Stacktrace from authentik
Traceback (most recent call last):
  File "/ak-root/venv/lib/python3.12/site-packages/asgiref/sync.py", line 518, in thread_handler
    raise exc_info[1]
  File "/ak-root/venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 253, in _get_response_async
    response = await wrapped_callback(
               ^^^^^^^^^^^^^^^^^^^^^^^
  File "/ak-root/venv/lib/python3.12/site-packages/asgiref/sync.py", line 468, in __call__
    ret = await asyncio.shield(exec_coro)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ak-root/venv/lib/python3.12/site-packages/asgiref/current_thread_executor.py", line 40, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ak-root/venv/lib/python3.12/site-packages/asgiref/sync.py", line 522, in thread_handler
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/ak-root/venv/lib/python3.12/site-packages/sentry_sdk/integrations/django/views.py", line 94, in sentry_wrapped_callback
    return callback(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ak-root/venv/lib/python3.12/site-packages/django/views/generic/base.py", line 104, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ak-root/venv/lib/python3.12/site-packages/django/utils/decorators.py", line 48, in _wrapper
    return bound_method(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ak-root/venv/lib/python3.12/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/providers/oauth2/views/token.py", line 560, in dispatch
    response = super().dispatch(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ak-root/venv/lib/python3.12/site-packages/django/views/generic/base.py", line 143, in dispatch
    return handler(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/providers/oauth2/views/token.py", line 589, in post
    return TokenResponse(self.create_code_response())
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/providers/oauth2/views/token.py", line 624, in create_code_response
    access_token.id_token = access_id_token
    ^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/providers/oauth2/models.py", line 473, in id_token
    self.token = value.to_access_token(self.provider)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/providers/oauth2/id_token.py", line 174, in to_access_token
    return provider.encode(final)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/providers/oauth2/models.py", line 347, in encode
    return self.encrypt(encoded)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/providers/oauth2/models.py", line 364, in encrypt
    jwe.add_recipient(key)
  File "/ak-root/venv/lib/python3.12/site-packages/jwcrypto/jwe.py", line 240, in add_recipient
    wrapped = alg.wrap(key, enc.wrap_key_size, self.cek, jh)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ak-root/venv/lib/python3.12/site-packages/jwcrypto/jwa.py", line 368, in wrap
    self._check_key(key)
  File "/ak-root/venv/lib/python3.12/site-packages/jwcrypto/jwa.py", line 364, in _check_key
    raise InvalidJWEKeyType('RSA', key['kty'])
jwcrypto.common.InvalidJWEKeyType: Expected key type RSA, got EC

Version and Deployment (please complete the following information):

  • authentik version: 2024.12.2, but the issue is present on 2024.12.0 as well.
  • Deployment: docker compose

Additional context

  • The Let's Encrypt cert is only used on the LAN. WAN traffic is routed through a Cloudflare tunnel which uses Cloudflare's own cert.
  • I am willing to provide more sensitive materials, like the expired and/or valid certs and the HTTP log, to a maintainer if needed.

I will be using the built-in RSA self-signed cert so I can, you know, use my homelab, but will keep the Let's Encrypt cert in Authentik for later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant