Repository navigation
feat(chart): set allow-listed token clients - #299
Conversation
Add auth.tokenClients (off by default): issuer, jwksUri, audience, claim (default client_id), clients and requireAtJwt, rendered into the service-client settings of tesk-api (#153) by one helper, tesk.tokenClientsEnv, which holds the variable names. The chart fails if the setting is on without an issuer or client IDs, or with mode noauth; the notes warn if it is on with tesk-api 1.2.0 or older. Schema entries, chart tests, the deployment guide (Tokens of services), the values reference and the upgrade notes. Closes #296 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011FSoqMpmDCfbACLj3uy6xV
# Conflicts: # docs/upgrading.md
From the review: add auth.tokenClients.requireClientSubject and document tesk-api's sub check; accept only HTTPS issuers and JWKS URIs; trim the claim and leave a blank one out; warn about pre-releases of tesk-api 1.2.0 and older too; quote numeric client IDs (docs); test a mode left unset and the warning with explicit tags only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011FSoqMpmDCfbACLj3uy6xV
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011FSoqMpmDCfbACLj3uy6xV
Reviewer's GuideAPIDefine the public chart values for configuring allow-listed token clients and their validation requirements.
Uses of the APIAdd the token-client environment entries to the API deployment when the helper emits them.
ImplementationRender token-client settings as tesk-api environment variables, validate required settings, and warn when the configured API version does not support them.
DocumentationExplain the token-client configuration, its security implications, and the version and rollout requirements.
TestsTest disabled and enabled rendering, defaults, validation, schema constraints, and version warnings for token clients.
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #299 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 2 2
Lines 422 422
=========================================
Hits 422 422 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Linked issuesChecked at commit c16d457 #296 feat(chart): set allow-listed token clients · 5 of 6 met · 1 to check by hand
|
There was a problem hiding this comment.
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="charts/tesk/values.yaml" line_range="255" />
<code_context>
+ # deployment; recommended, so that tokens meant for other services are
+ # refused. Empty leaves `aud` unchecked
+ audience: ""
+ # Claim of the token with the client ID (RFC 9068: client_id; some
+ # providers use azp); empty uses tesk-api's default, client_id
+ claim: client_id
</code_context>
<issue_to_address>
**Cross-audience tokens are accepted**
When an operator enables `auth.tokenClients` but leaves its optional audience unset, and a listed client’s valid token for another service is presented to TESK, a listed client’s token for a different service passes the issuer and client checks without an audience restriction, so its holder can submit tasks to this TESK deployment.
Require a non-empty audience whenever token clients are enabled, or make audience validation mandatory with an explicit opt-out for deployments that accept the risk.
Also at `charts/tesk/templates/_helpers.tpl:597`.
</issue_to_address>
### Comment 2
<location path="charts/tesk/templates/common/tesk-deployment.yaml" line_range="175-176" />
<code_context>
+ {{- /* Tokens of allow-listed clients (e.g., of a gateway with the
+ client credentials grant), which tesk-api checks without the user
+ info: only when on, with mode auth (tesk.tokenClientsEnv) */}}
+ {{- with include "tesk.tokenClientsEnv" . }}
+ {{- . | nindent 8 }}
+ {{- end }}
{{- /* Null leaves tesk-api's default (off). tesk-api stops at
</code_context>
<issue_to_address>
**Revoked clients remain accepted during rollout**
When a client ID is removed and requests arrive while Kubernetes is starting the replacement pod, the old pod keeps its previous allow-list while the replacement starts, and requests routed to it still accept the removed client’s tokens. The client therefore remains authorized until the old pod is terminated.
Use a non-overlapping rollout strategy for allow-list changes, or document that revocation takes effect only after the rollout has completed.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 2 findings to address first, and when enabled, tesk-api accepts listed clients’ JWTs without the user-info and group checks, allowing those clients to create tasks and run arbitrary images on the cluster. A mistaken allow-list or token-validation configuration could therefore grant unintended access and trigger work that cannot be undone by reverting the chart; the feature is off by default.
Blocking findings: charts/tesk/values.yaml:255, charts/tesk/templates/common/tesk-deployment.yaml:176
From the Sourcery review: without an audience, tokens that a listed client got for other services would be accepted too. The chart now fails if auth.tokenClients is on without an audience, unless the new auth.tokenClients.allowAnyAudience is true. The deployment guide also says that a removed client is refused only once the rollout has completed, and to disable it at the provider too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011FSoqMpmDCfbACLj3uy6xV
Summary
The chart can now set tesk-api's option for access tokens of allow-listed clients (elixir-cloud-aai/tesk-api#153), e.g., of a TES gateway that calls TESK with tokens of the client credentials grant.
auth.tokenClients(off by default):enabled,issuer,jwksUri(optional; default from discovery),audience(required, unlessallowAnyAudience: trueis set on purpose),claim(defaultclient_id),clients(list of client IDs),requireAtJwtandrequireClientSubject(both null: tesk-api's defaults,true). Issuer and JWKS URI must be HTTPS URLs.tesk.tokenClientsEnv(charts/tesk/templates/_helpers.tpl), which holds all variable names (TESK_API_AUTHORISATION_SERVICE_CLIENTS_*). Client IDs are trimmed, blank ones dropped and joined with commas; empty optional keys leave tesk-api's defaults.allowAnyAudience: true), without client IDs, or with anauth.modeother thanauth. The schema rejects non-URL issuers/JWKS URIs, client IDs with commas or blank, and unknown keys.appVersion), which ignore it.docs/deployment.md"Tokens of services" (example, checks, trust implications, audience recommendation), values reference indocs/configuration.md, upgrade notes ("Unreleased").Closes #296
tesk-api side
The variable names are those of elixir-cloud-aai/tesk-api#154 (for tesk-api#153;
tesk.api.authorisation.service-clients.*:enabled,issuer,jwks-uri,audience,client-claim,client-ids,require-access-token-type,require-client-subject), checked against its branch (AuthorisationProperties.ServiceClientsand the settings table in itsdocs/access-control.md); #154 is merged with these names. Should they change, they change in one place here (tesk.tokenClientsEnv, andTOKEN_CLIENTSin the tests). The setting takes effect only with a tesk-api release that contains #154; until then the notes warn. tesk-api'sclock-skew-secondskeeps its default (60 s) and isn't exposed. The notes' version check (<1.2.1-0) gets the first tesk-api release with the setting once it is known.Verification
MISE_HELM_VERSION=3.22.1 REQUIRE_HELM=1 uv run pytest -q tests/: 792 passed after merging dev (64 new tests: off/unchanged manifests, minimal and full settings, optional keys, values file, withauth.claim, failures, schema, notes).helm lint charts/tesk --strict(default and with the option on): passed.pre-commit run --all-files: passed.mkdocs build --strict: passed.Declined review findings
claimdefaults toclient_idin the chart while tesk-api has the same default (redundant): kept, as the issue specifies the chart defaultclient_id; empty still leaves tesk-api's default.auth.claim.valuesandauth.tokenClients.clients: not extracted; the two are a few lines each andauth.claimlives in the Deployment template, so a refactor of it is outside this issue.tesk-api/access-control.mdwhile the pinned tesk-api docs (v1.2.0) don't cover tokens of services yet: kept, as the page exists and gets the section whendocs-sources.ymlmoves to the tesk-api release with Add missing boilerplate #153.https://issuers and JWKS URIs, stricter than tesk-api (which also allowshttp://on localhost): kept, as a localhost issuer makes no sense inside a pod.requireClientSubject: falsecaveat instead of three (values comment, reference, guide): kept in all three, as the risk should be visible wherever the value is set.clockSkewSecondsnot exposed: tesk-api's default (60 s) fits; can be added on demand.Open questions
None.
🤖 Generated with Claude Code
https://claude.ai/code/session_011FSoqMpmDCfbACLj3uy6xV