File: jwt.shtml

package info (click to toggle)
slurm-wlm 22.05.8-4%2Bdeb12u3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 48,492 kB
  • sloc: ansic: 475,246; exp: 69,020; sh: 8,862; javascript: 6,528; python: 6,444; makefile: 4,185; perl: 4,069; pascal: 131
file content (190 lines) | stat: -rw-r--r-- 6,130 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
<!--#include virtual="header.txt"-->

<h1>JSON Web Tokens (JWT) Authentication</h1>

<p>Slurm provides a RFC7519 compliant implementation of
<a href="https://jwt.io/">JSON Web Tokens (JWT)</a>. This authentication can
be used as an <b>AuthAltType</b>, usually alongside <b>auth/munge</b> as the
<b>AuthType</b>. The only supported communication direction is from a client
connecting to <b>slurmctld</b> and <b>slurmdbd</b>. This means that certain
scenarios (specifically interactive jobs using <b>srun</b>) are currently not
supported for clients with auth/jwt enabled (or that have SLURM_JWT in their
environment).</p>

<h2 id="prerequisites">Prerequisites
<a class="slurm_link" href="#prerequisites"></a>
</h2>
<p>JWT requires <a href="download.html#jwt">libjwt</a>.
Both the library and the development headers must be available when Slurm is
compiled.</p>

<h2 id="setup">Setup for Standalone Use
<a class="slurm_link" href="#setup"></a>
</h2>
<ol>
<li><a href="download.html#jwt">
    Configure and build Slurm for JWT support</a></li>
<li>Add JWT key to controller in StateSaveLocation.
Here is an example with the JWT key in /var/spool/slurm/statesave/:
<pre>
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
</pre>
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.
</li>
<li>Add JWT as an alternative authentication in slurm.conf and slurmdbd.conf:
<pre>
AuthAltTypes=auth/jwt
AuthAltParameters=jwt_key=/var/spool/slurm/statesave/jwt_hs256.key
</pre>
</li>
<li>Restart slurmctld</li>
<li>Create tokens for users as desired:
<pre>
scontrol token username=$USER
</pre>
An optional <b>lifespan=$LIFESPAN</b> option can be used to change the token
lifespan from the default 1800 seconds. The root account, or <b>SlurmUser</b>
account can be used to generate tokens for any user. Alternatively, a user
may use the command to generate tokens for themselves by simply calling
<pre>
scontrol token
</pre>
Note that administrators can prevent users from generating tokens by setting
the following parameter in slurm.conf:
<pre>
AuthAltParameters=disable_token_creation
</pre>
This functionality is provided to allow sites to control when and how users are
provided tokens along with controlling the token lifespans.
</li>
<li>Export the <b>SLURM_JWT</b> environment variable before calling any Slurm
command.</li>
</ol>

<h2 id="external_auth">
External Authentication Integration with JWKS and RS256 Tokens
<a class="slurm_link" href="#external_auth"></a>
</h2>
<p>Starting with the 21.08 release, Slurm can support RS256 tokens such as
those generated by
<a href="https://aws.amazon.com/cognito/">Amazon Cognito</a>.</p>

<p>To enable Slurm's RS256 token support, an appropriate JWKS file must be
downloaded and configured as such:
<pre>
AuthAltTypes=auth/jwt
AuthAltParameters=jwks=/var/spool/slurm/statesave/jwks.json
</pre>
</p>

<p>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 <b>jwt_key=</b> option alongside <b>jwks=</b>.
</p>

<h2 id="compatibility">Compatibility
<a class="slurm_link" href="#compatibility"></a>
</h2>
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:
<ol>
<li>Required tokens for Slurm are present:
	<ul>
		<li>iat: Unix timestamp of creation date.</li>
		<li>exp: Unix timestamp of expiration date.</li>
		<li>sun or username: Slurm UserName (
			<a href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_437">
				POSIX.1-2017 User Name
			</a>).
		</li>
	</ul>
</li>
<li>Tokens are signed with HS256 algorithm compliant to RFC7518. RS256 is also
	supported to verify tokens, although Slurm cannot create them
	directly.</li>
<li>Signing key is provided to slurmctld and slurmdbd to allow decryption of
	the tokens. Slurm currently only supports a single signing key.</li>
</ol>

The following scripts require the installation of the JWT Python module.
This script can serve as an example of what you might do to generate
a jwt key for use with Slurm.
<pre>
#!/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))
</pre>

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.
<pre>
#!/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)
</pre>

<p style="text-align:center;">Last modified 14 March 2022</p>

<!--#include virtual="footer.txt"-->