JSON Web Tokens (JWT) Authentication
Slurm provides a RFC7519 compliant implementation of JSON Web Tokens (JWT). This authentication can be used as an AuthAltType, usually alongside auth/munge as the AuthType. The only supported communication direction is from a client connecting to slurmctld and slurmdbd. This means that certain scenarios (specifically interactive jobs using srun) are currently not supported for clients with auth/jwt enabled (or that have SLURM_JWT in their environment).
Prerequisites
JWT requires libjwt. Both the library and the development headers must be available when Slurm is compiled.
Setup for Standalone Use
- Configure and build Slurm for JWT support
- Add JWT key to controller in StateSaveLocation.
Here is an example with the JWT key in /var/spool/slurm/statesave/:
dd if=/dev/random of=/var/spool/slurm/statesave/jwt_hs256.key bs=32 count=1 chown slurm:slurm /var/spool/slurm/statesave/jwt_hs256.key chmod 0600 /var/spool/slurm/statesave/jwt_hs256.key chown slurm:slurm /var/spool/slurm/statesave chmod 0755 /var/spool/slurm/statesave
The key does not have to be in the StateSaveLocation, but that is a convenient location if you have multiple controllers since it is shared between them. The key should not be placed in a directory where non-admin users might be able to access it. The key file should be owned by SlurmUser or root, with recommended permissions of 0400. The file must not be accessible by 'other'. - Add JWT as an alternative authentication in slurm.conf and slurmdbd.conf:
AuthAltTypes=auth/jwt AuthAltParameters=jwt_key=/var/spool/slurm/statesave/jwt_hs256.key
- Restart slurmctld
- Create tokens for users as desired:
scontrol token username=$USER
An optional lifespan=$LIFESPAN option can be used to change the token lifespan from the default 1800 seconds. The root account, or SlurmUser account can be used to generate tokens for any user. Alternatively, a user may use the command to generate tokens for themselves by simply callingscontrol token
Note that administrators can prevent users from generating tokens by setting the following parameter in slurm.conf:AuthAltParameters=disable_token_creation
This functionality is provided to allow sites to control when and how users are provided tokens along with controlling the token lifespans. - Export the SLURM_JWT environment variable before calling any Slurm command.
- Export the SLURM_JWT=daemon environment variable before starting the slurmrestd daemon to activate AuthAltTypes=auth/jwt as the primary authentication mechanism.
External Authentication Integration with JWKS and RS256 Tokens
Starting with the 21.08 release, Slurm can support RS256 tokens such as those generated by Amazon Cognito, Azure AD, or Keycloak.
To enable Slurm's RS256 token support, an appropriate JWKS file must be downloaded and configured as such:
AuthAltTypes=auth/jwt AuthAltParameters=jwks=/var/spool/slurm/statesave/jwks.json
The jwks file should be owned by SlurmUser or root, must be readable by SlurmUser, with recommended permissions of 0400. The file must not be writable by 'other'.
Note that, by default, the built-in ability to generate HS256 tokens will be disabled when JWKS support is enabled. It can be re-enabled by explicitly configuring the jwt_key= option alongside jwks=.
Note: Slurm ignores the x5c and x5t fields and does not attempt to verify the certificate chain if presented in the JWKS file. JWTs are only verified against RSA 256 bit keys provided via e and n fields.
Compatibility
Slurm uses libjwt to view and verify RFC7519 JWT tokens. Compliant tokens generated by another solution can be used as long as the following requirements are met:- Required tokens for Slurm are present:
- iat: Unix timestamp of creation date.
- exp: Unix timestamp of expiration date.
- sun or username: Slurm UserName ( POSIX.1-2017 User Name ).
- Tokens are signed with HS256 algorithm compliant to RFC7518. RS256 is also supported to verify tokens, although Slurm cannot create them directly.
- Signing key is provided to slurmctld and slurmdbd to allow decryption of the tokens. Slurm currently only supports a single signing key.
#!/usr/bin/env python3 import sys import os import pprint import json import time from datetime import datetime, timedelta, timezone from jwt import JWT from jwt.jwa import HS256 from jwt.jwk import jwk_from_dict from jwt.utils import b64decode,b64encode if len(sys.argv) != 3: sys.exit("gen_jwt.py [user name] [expiration time (seconds)]"); with open("/var/spool/slurm/statesave/jwt.key", "rb") as f: priv_key = f.read() signing_key = jwk_from_dict({ 'kty': 'oct', 'k': b64encode(priv_key) }) message = { "exp": int(time.time() + int(sys.argv[2])), "iat": int(time.time()), "sun": sys.argv[1] } a = JWT() compact_jws = a.encode(message, signing_key, alg='HS256') print("SLURM_JWT={}".format(compact_jws))Similarly, the following script can be used as an example of how you might verify that a jwt key is valid for use with Slurm.
#!/usr/bin/env python3 import sys import os import pprint import json import time from datetime import datetime, timedelta, timezone from jwt import JWT from jwt.jwa import HS256 from jwt.jwk import jwk_from_dict from jwt.utils import b64decode,b64encode if len(sys.argv) != 2: sys.exit("verify_jwt.py [JWT Token]"); with open("/var/spool/slurm/statesave/jwt.key", "rb") as f: priv_key = f.read() signing_key = jwk_from_dict({ 'kty': 'oct', 'k': b64encode(priv_key) }) a = JWT() b = a.decode(sys.argv[1], signing_key, algorithms=["HS256"]) print(b)
Last modified 11 January 2024