Skip to content

fix: EdDSA to Ed25519 token migration#786

Draft
Stellatsuu wants to merge 7 commits intoDIRACGrid:mainfrom
Stellatsuu:Ed25519-token-migration
Draft

fix: EdDSA to Ed25519 token migration#786
Stellatsuu wants to merge 7 commits intoDIRACGrid:mainfrom
Stellatsuu:Ed25519-token-migration

Conversation

@Stellatsuu
Copy link
Contributor

@Stellatsuu Stellatsuu commented Feb 10, 2026

cc @aldbr
Closes: #718

Changes:

  • changed token creation algorithm to be Ed25519 instead of EdDSA
  • added Ed25519 to the authorized algorithm list. EdDSA is still listed as authorized algorithm so people have time to rotate keys before full migration

TODO:

  • create documentation about keys rotation

@Stellatsuu Stellatsuu changed the title fix: Ed25519 token migration fix: EdDSA to Ed25519 token migration Feb 10, 2026
Copy link
Contributor

@aldbr aldbr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks good, thank you 🙂
I just have a few minor comments around the tests.
Next step: making sure there is a documentation page to rotate the keys (and delete old ones if needed). If it does not exist, then we need to create one based on #499 (comment)

@read-the-docs-community
Copy link

read-the-docs-community bot commented Feb 10, 2026

Documentation build overview

📚 diracx | 🛠️ Build #31400200 | 📁 Comparing 152795e against latest (11433a3)


🔍 Preview build

Show files changed (3 files in total): 📝 3 modified | ➕ 0 added | ➖ 0 deleted
File Status
admin/reference/env-variables/index.html 📝 modified
dev/reference/coding-conventions/index.html 📝 modified
dev/explanations/components/db/index.html 📝 modified

@Stellatsuu
Copy link
Contributor Author

Stellatsuu commented Feb 11, 2026

Small documentation

How to rotate the keys:

  1. Launch demo (+ export Kube config)
  2. Retrieve secrets ids (optional): kubectl get secrets
  3. Retrieve old keys: kubectl get secret diracx-jwks -o yaml
    Output:
data:
  jwks.json: ewogICJrZXlzIjogWwogICAgewogICAgICAiY3J2IjogIkVkMjU1MTkiLAogICAgICAieCI6ICJ0QXY5VmZDUy1ER0I0d3hkUlRScHpoRlBLOU1wbmNUOHZVRHdaMnBJclBVIiwKICAgICAgImQiOiAiVG5vSG0teWJDTGVOY2drbm1ma3lTMkJGSGl2enBEblV2OFl1S2xaMjNNTSIsCiAgICAgICJrZXlfb3BzIjogWwogICAgICAgICJzaWduIiwKICAgICAgICAidmVyaWZ5IgogICAgICBdLAogICAgICAiYWxnIjogIkVkMjU1MTkiLAogICAgICAia2lkIjogIjAxOWM1NjVhMWI1NzczMjE5MGQ2ZGVlYjVjY2MxYzAzIiwKICAgICAgImt0eSI6ICJPS1AiCiAgICB9CiAgXQp9
...
  1. Save olds keys as jwks.json
echo "ewogICJrZXlzIjogWwogICAgewogICAgICAiY3J2IjogIkVkMjU1MTkiLAogICAgICAieCI6ICJ0QXY5VmZDUy1ER0I0d3hkUlRScHpoRlBLOU1wbmNUOHZVRHdaMnBJclBVIiwKICAgICAgImQiOiAiVG5vSG0teWJDTGVOY2drbm1ma3lTMkJGSGl2enBEblV2OFl1S2xaMjNNTSIsCiAgICAgICJrZXlfb3BzIjogWwogICAgICAgICJzaWduIiwKICAgICAgICAidmVyaWZ5IgogICAgICBdLAogICAgICAiYWxnIjogIkVkMjU1MTkiLAogICAgICAia2lkIjogIjAxOWM1NjVhMWI1NzczMjE5MGQ2ZGVlYjVjY2MxYzAzIiwKICAgICAgImt0eSI6ICJPS1AiCiAgICB9CiAgXQp9" | base64 --decode > jwks.json
  1. Rotate the keys: python -m diracx.logic rotate-jwk --jwks-path jwks.json
  2. Delete the old secret: kubectl delete secret diracx-jwks --namespace=$namespace
  3. Upload the new secret (with the new keys):
    kubectl create secret generic diracx-jwks \ --namespace=$namespace \ --from-file=jwks.json \

How to check if rotation worked:

  1. dirac login diracAdmin -> rotate key -> submit job -> check if ok
  2. re-login -> /Users/{username}/.cache/diracx/credentials.json
    -> decode -> check if alg = Ed25519

@Stellatsuu
Copy link
Contributor Author

Stellatsuu commented Feb 11, 2026

joserfc error breaking the demo when trying to login as diracAdmin:

  • HttpResponseError: Operation returned an invalid status 'Internal Server Error'
  • kubectl logs diracx-demo-...

Full Logs:

File "/diracx_source/diracx/diracx-logic/src/diracx/logic/auth/token.py", line 380, in create_token
   return jwt.encode(
          ^^^^^^^^^^^
 File "/opt/conda/lib/python3.11/site-packages/joserfc/jwt.py", line 80, in encode
   return serialize_compact(_header, payload, key, algorithms, registry)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 File "/opt/conda/lib/python3.11/site-packages/joserfc/jws.py", line 105, in serialize_compact
   alg: JWSAlgModel = registry.get_alg(protected["alg"])
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 File "/opt/conda/lib/python3.11/site-packages/joserfc/_rfc7515/registry.py", line 81, in get_alg
   raise UnsupportedAlgorithmError(f"Algorithm of '{name}' is not supported")
joserfc.errors.UnsupportedAlgorithmError: unsupported_algorithm: Algorithm of 'Ed25519' is not supported

See: https://jose.authlib.org/en/guide/errors/#unsupportedalgorithmerror

Edit: error was due to wrong joserfc version in demo dependencies.

@aldbr
Copy link
Contributor

aldbr commented Feb 13, 2026

I followed your steps on my side to check and I have a few minor comments 🙂

Small documentation

How to rotate the keys:

  1. Launch demo (+ export Kube config)

Note: you launch the demo only when you want to test the key rotation with run_demo locally. In that case, you should use the current version of the rotate_key() (not your version within this PR). It is used by diracx-charts init-keystore to generate the initial key. If you use the new rotate_key(), then you will generate an Ed25519 key instead of an EdDSA key 😉

  1. Retrieve secrets ids (optional): kubectl get secrets
  2. Retrieve old keys: kubectl get secret diracx-jwks -o yaml
    Output:
data:
  jwks.json: ewogICJrZXlzIjogWwogICAgewogICAgICAiY3J2IjogIkVkMjU1MTkiLAogICAgICAieCI6ICJ0QXY5VmZDUy1ER0I0d3hkUlRScHpoRlBLOU1wbmNUOHZVRHdaMnBJclBVIiwKICAgICAgImQiOiAiVG5vSG0teWJDTGVOY2drbm1ma3lTMkJGSGl2enBEblV2OFl1S2xaMjNNTSIsCiAgICAgICJrZXlfb3BzIjogWwogICAgICAgICJzaWduIiwKICAgICAgICAidmVyaWZ5IgogICAgICBdLAogICAgICAiYWxnIjogIkVkMjU1MTkiLAogICAgICAia2lkIjogIjAxOWM1NjVhMWI1NzczMjE5MGQ2ZGVlYjVjY2MxYzAzIiwKICAgICAgImt0eSI6ICJPS1AiCiAgICB9CiAgXQp9
...

So here, if you try to decode the jwks.json content you will notice that the key is already Ed25519.

  1. Save olds keys as jwks.json
echo "ewogICJrZXlzIjogWwogICAgewogICAgICAiY3J2IjogIkVkMjU1MTkiLAogICAgICAieCI6ICJ0QXY5VmZDUy1ER0I0d3hkUlRScHpoRlBLOU1wbmNUOHZVRHdaMnBJclBVIiwKICAgICAgImQiOiAiVG5vSG0teWJDTGVOY2drbm1ma3lTMkJGSGl2enBEblV2OFl1S2xaMjNNTSIsCiAgICAgICJrZXlfb3BzIjogWwogICAgICAgICJzaWduIiwKICAgICAgICAidmVyaWZ5IgogICAgICBdLAogICAgICAiYWxnIjogIkVkMjU1MTkiLAogICAgICAia2lkIjogIjAxOWM1NjVhMWI1NzczMjE5MGQ2ZGVlYjVjY2MxYzAzIiwKICAgICAgImt0eSI6ICJPS1AiCiAgICB9CiAgXQp9" | base64 --decode > jwks.json
  1. Rotate the keys: python -m diracx.logic rotate-jwk --jwks-path jwks.json

Here you should use the updated script.

  1. Delete the old secret: kubectl delete secret diracx-jwks --namespace=$namespace
  2. Upload the new secret (with the new keys):
    kubectl create secret generic diracx-jwks \ --namespace=$namespace \ --from-file=jwks.json \

I think it's cleaner to update the existing secret with:

kubectl create secret generic diracx-jwks \
  --namespace="$namespace" \
  --from-file=jwks.json \
  --dry-run=client -o yaml \
| kubectl apply -f -

You need to restart the diracx-demo pod(s) with:

kubectl rollout restart deployment diracx-demo -n $namespace

How to check if rotation worked:

  1. dirac login diracAdmin -> rotate key -> submit job -> check if ok
  2. re-login -> /Users/{username}/.cache/diracx/credentials.json
    -> decode -> check if alg = Ed25519

In the context of the demo, you also need to check the kid, as you might have started with an Ed25519 key if you started the demo with the new rotate_key function.

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

Successfully merging this pull request may close these issues.

Migration needed: EdDSA algorithm identifier deprecated in favor of Ed25519 (RFC 9864)

2 participants