@@ -23,7 +23,7 @@ The stack seeds these local-only identities:
2323- Human password: ` nemo-user-password-dev `
2424- Human email: ` nemo-user@example.com `
2525- CLI OIDC client: ` nemo-platform-cli `
26- - Workload identity: ` svc-nemo-ci `
26+ - Workload identity: ` svc-nemo `
2727- Workload group: ` nemo-editors `
2828
2929## Start The Stack
@@ -35,35 +35,45 @@ contrib/auth/authentik/run.sh stack
3535```
3636
3737This starts NeMo, Authentik, and the local gateway with the existing default
38- NeMo API image, ` my-registry/nmp-api:local ` . The script does not build images.
38+ NeMo API image, ` my-registry/nmp-api:local ` . The ` stack ` action does not build
39+ images.
3940Leave this process running. Stop it with ` Ctrl-C ` when you are done; the script
4041removes the Compose stack and volumes on exit.
4142
4243To use a different prebuilt image for the example, pass it explicitly:
4344
4445``` bash
45- contrib/auth/authentik/run.sh stack --image registry.example.com/nemo/nmp-api:< tag>
46+ export IMAGE_REGISTRY=registry.example.com/nemo
47+ export BAKE_TAG=< tag>
48+
49+ contrib/auth/authentik/run.sh stack --image " $IMAGE_REGISTRY /nmp-api:$BAKE_TAG "
4650```
4751
48- The auth-idp test suite has one entrypoint:
52+ Use the same ` IMAGE_REGISTRY ` and ` BAKE_TAG ` values in the shell where you
53+ submit the workload job so the job container image matches the running NeMo API
54+ image.
55+
56+ The auth-idp test suite uses the same helper script:
4957
5058``` bash
51- make test-auth-idp
59+ contrib/auth/authentik/run.sh test
5260```
5361
54- To run the tests against the same prebuilt image used by the example, pass the
55- matching registry and tag to that test target:
62+ For iteration or prebuilt images, pass options to the script directly. See
63+ ` contrib/auth/authentik/run.sh --help ` for the full option list.
5664
5765``` bash
58- IMAGE_REGISTRY=registry.example.com/nemo BAKE_TAG=< tag> make test-auth-idp
66+ contrib/auth/authentik/run.sh test --lifecycle reuse
67+ contrib/auth/authentik/run.sh test --image registry.example.com/nemo/nmp-api:< tag>
5968```
6069
61- Wait until the gateway is ready:
70+ Wait until the platform is ready through the gateway :
6271
6372``` bash
64- until curl -sf http://127.0.0.1:18080/apis/auth/discovery > /dev/null; do
73+ until curl -sf http://127.0.0.1:18080/health/ready > /dev/null; do
6574 sleep 2
6675done
76+ echo " NeMo Platform Ready"
6777```
6878
6979The local gateway URL is:
@@ -119,91 +129,80 @@ nemo --context authentik-human workspaces members create \
119129 --workspace " $WORKSPACE " \
120130 --principal nemo-editors \
121131 --roles Viewer \
122- --roles JobLogWriter \
132+ --roles JobRunner \
123133 --wait-role-propagation
124134```
125135
126136Expected result: the human user can manage the workspace, and the workload
127- group can read the workspace and upload job logs .
137+ group can read the workspace from a job.
128138
129139## Run A Workload Job
130140
131141``` bash
132142export JOB_NAME=authentik-workload-demo
133- export WORKLOAD_TOKEN_SECRET=" ${JOB_NAME} -token"
134143```
135144
136- Fetch a local demo token for the seeded workload identity and store it as a
137- workspace secret:
145+ Fetch a local demo token for the seeded workload identity:
138146
139147``` bash
140- export NEMO_WORKLOAD_TOKEN =" $(
148+ export WORKLOAD_ACCESS_TOKEN =" $(
141149 curl -fsS http://127.0.0.1:18080/application/o/token/ \
142150 -d grant_type=password \
143151 -d client_id=nemo-platform \
144152 -d client_secret=nemo-platform-secret-dev \
145- -d username=svc-nemo-ci \
146- -d password=svc-nemo-ci- token-secret-dev \
153+ -d username=svc-nemo \
154+ -d password=svc-nemo-token-secret-dev \
147155 -d scope=" openid email groups" \
148156 | python -c ' import json, sys; print(json.load(sys.stdin)["access_token"])'
149157) "
150-
151- printf ' %s' " $NEMO_WORKLOAD_TOKEN " \
152- | nemo --context authentik-human secrets create " $WORKLOAD_TOKEN_SECRET " \
153- --workspace " $WORKSPACE " \
154- --from-file -
155158```
156159
157- Create the job request:
158-
159- ``` bash
160- python - << 'PY ' >/tmp/authentik-workload-job.json
161- import json
162- import os
163- import sys
164-
165- payload = {
166- "source": "authentik-reference-example",
167- "spec": {"demo": "authentik-workload-auth"},
168- "platform_spec": {
169- "steps": [
170- {
171- "name": "workload-workspace-get",
172- "executor": {
173- "provider": "cpu",
174- "profile": "workload",
175- "container": {
176- "entrypoint": ["nemo-platform"],
177- "command": [
178- "run",
179- "task",
180- "--task",
181- "nmp.hello_world.tasks.workload_workspace_get",
182- ],
183- },
184- },
185- "environment": [
186- {
187- "name": "NEMO_WORKLOAD_TOKEN",
188- "from_secret": {"name": os.environ["WORKLOAD_TOKEN_SECRET"]},
189- }
190- ],
191- "config": {"workspace": os.environ["WORKSPACE"]},
192- }
193- ]
194- },
195- }
196-
197- json.dump(payload, sys.stdout, indent=2)
198- PY
199- ```
160+ Keep this token in a non-reserved shell variable. Do not export it as
161+ ` NEMO_WORKLOAD_TOKEN ` in your shell. The NeMo CLI uses that variable as a
162+ runtime credential override, which would make later CLI commands run as the
163+ workload identity instead of ` authentik-human ` .
200164
201- Submit the job:
165+ Submit a job that runs the built-in hello-world workload auth task :
202166
203167``` bash
204- nemo --context authentik-human jobs create " $JOB_NAME " \
168+ export NMP_API_IMAGE=" ${NMP_API_IMAGE:- ${IMAGE_REGISTRY:- my-registry} / nmp-api: ${BAKE_TAG:- local} } "
169+
170+ cat << EOF | nemo --context authentik-human jobs create "$JOB_NAME " \
205171 --workspace "$WORKSPACE " \
206- --input-file /tmp/authentik-workload-job.json
172+ --input-file -
173+ {
174+ "source": "authentik-reference-example",
175+ "spec": {"demo": "authentik-workload-auth"},
176+ "platform_spec": {
177+ "steps": [
178+ {
179+ "name": "workload-workspace-get",
180+ "executor": {
181+ "provider": "cpu",
182+ "profile": "workload",
183+ "container": {
184+ "image": "${NMP_API_IMAGE} ",
185+ "entrypoint": ["nemo-platform"],
186+ "command": [
187+ "run",
188+ "task",
189+ "--task",
190+ "nmp.hello_world.tasks.workload_workspace_get"
191+ ]
192+ }
193+ },
194+ "environment": [
195+ {
196+ "name": "NEMO_WORKLOAD_TOKEN",
197+ "value": "${WORKLOAD_ACCESS_TOKEN} "
198+ }
199+ ],
200+ "config": {"workspace": "${WORKSPACE} "}
201+ }
202+ ]
203+ }
204+ }
205+ EOF
207206```
208207
209208Watch it complete:
@@ -212,7 +211,11 @@ Watch it complete:
212211nemo --context authentik-human jobs get-status " $JOB_NAME " --workspace " $WORKSPACE "
213212```
214213
215- After the job reaches ` completed ` , read the logs:
214+ Expected result: the job reaches ` completed ` . The workload exits successfully
215+ only after it uses the Authentik workload token to call NeMo through the gateway
216+ and retrieve the workspace.
217+
218+ Read the job logs:
216219
217220``` bash
218221nemo --context authentik-human jobs get-logs " $JOB_NAME " \
@@ -226,9 +229,6 @@ Expected result: the logs include:
226229Successfully retrieved workspace: authentik-demo
227230```
228231
229- That confirms the job workload used the Authentik workload token to call NeMo
230- through the gateway.
231-
232232## Refresh The CLI Session
233233
234234The example requests ` offline_access ` , so the CLI stores a refresh token.
@@ -247,7 +247,6 @@ Remove the demo job and workspace if you created them:
247247
248248``` bash
249249nemo --context authentik-human jobs delete " $JOB_NAME " --workspace " $WORKSPACE "
250- nemo --context authentik-human secrets delete " $WORKLOAD_TOKEN_SECRET " --workspace " $WORKSPACE "
251250nemo --context authentik-human workspaces delete " $WORKSPACE "
252251```
253252
@@ -261,12 +260,19 @@ Then stop the stack with `Ctrl-C` in the terminal running
261260- ` Permission denied ` : verify ` nemo --context authentik-human auth status ` ,
262261 then check
263262 ` nemo --context authentik-human workspaces members list --workspace "$WORKSPACE" ` .
263+ If ` auth status ` reports a ` NEMO_WORKLOAD_TOKEN ` or ` NEMO_WORKLOAD_TOKEN_FILE `
264+ environment override, run ` unset NEMO_WORKLOAD_TOKEN NEMO_WORKLOAD_TOKEN_FILE `
265+ and retry.
264266 If you just created the workspace or member bindings, wait a few seconds and
265267 retry so the authorization cache can refresh.
266268- Job stays ` created ` or ` pending ` : confirm the stack was started with
267269 ` contrib/auth/authentik/run.sh stack ` and Docker is running.
268- - Job completes but logs are missing: confirm ` nemo-editors ` has ` JobLogWriter `
269- on the workspace.
270+ - Job fails while fetching a secret with ` status code 401 ` : confirm the job
271+ request injects ` NEMO_WORKLOAD_TOKEN ` with ` value ` , not ` from_secret ` . The
272+ local gateway accepts Authentik bearer tokens, while the launcher secret-fetch
273+ path uses internal service headers before the workload starts.
274+ - Job fails with ` Permission denied ` : confirm ` nemo-editors ` still has ` Viewer `
275+ and ` JobRunner ` on the workspace before creating the job.
270276
271277## Adapting This Example
272278
0 commit comments