Skip to content

service-setup: per-client accessTokenLifespan passthrough#680

Merged
AlexGodbehere merged 1 commit into
mainfrom
ago/kiosk-token-lifespan
Jul 17, 2026
Merged

service-setup: per-client accessTokenLifespan passthrough#680
AlexGodbehere merged 1 commit into
mainfrom
ago/kiosk-token-lifespan

Conversation

@AlexGodbehere

Copy link
Copy Markdown
Contributor

Follow-on to #668 (the serviceAccountsEnabled passthrough), same shape: one more per-client field for values-declared OIDC clients.

What

ensure_client gains an accessTokenLifespan passthrough (seconds) → the Keycloak client attribute access.token.lifespan, overriding the realm's access-token lifespan (default 300s) for that one client. Unset = realm default, byte-identical behaviour to today.

Why

An unattended kiosk consumer authenticates a display via a JWT that the consuming app re-presents on every request — e.g. Grafana auth.jwt url_login, which is stateless (no session cookie is ever minted; verified by HAR capture on a live wall: hundreds of 200s, then everything 401s the moment the token passes exp + leeway). The wall therefore lives exactly one token lifespan, and with the realm's 300s default it gets bounced to the login screen every few minutes. Such clients need a long-lived token (e.g. 2592000 = 30 days) with the consumer refreshing before expiry; the realm default is untouched for every client where a human signs in.

serviceSetup:
  config:
    openidClients:
      polyptic-kiosk:
        enabled: true
        serviceAccountsEnabled: true
        standardFlowEnabled: false
        accessTokenLifespan: 2592000

Docs added to the values.yaml machine-to-machine client section.

🤖 Generated with Claude Code

A values-declared client can now set accessTokenLifespan (seconds) to
override the realm's 300s access-token lifespan via the client attribute
access.token.lifespan. Needed for unattended kiosk consumers (Grafana
url_login re-presents the JWT on every request, so the wall dies at
exp): give the kiosk client a long lifespan and refresh before expiry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@AlexGodbehere
AlexGodbehere enabled auto-merge July 17, 2026 14:50
@AlexGodbehere
AlexGodbehere disabled auto-merge July 17, 2026 14:51
@AlexGodbehere
AlexGodbehere merged commit 5c4b9ae into main Jul 17, 2026
1 check passed
@AlexGodbehere
AlexGodbehere deleted the ago/kiosk-token-lifespan branch July 17, 2026 14:51
AlexGodbehere added a commit that referenced this pull request Jul 18, 2026
Rewrites the `## v6.0.0` section of `docs/reference/release-notes.md`
against the shipped code and a real v5.1.0 -> v6 upgrade on a seeded
cluster. This document had confidently stated several things that turned
out to be wrong, so the rewrite removes unverified claims and adds the
operator guidance that was missing.

## Corrected

- **Nanosecond timestamp failure mode.** A v5 historian reading a v6
value gets an invalid time and drops the point (verified: `new
Date(1.78e18)` is Invalid Date). It does not store a far-future
timestamp as the old text claimed.
- **Grafana roles.** They are Factory+ permission objects granted via
the ACL editor with the wildcard target, surfaced in the
`fp_permissions` claim - not group membership. Administrator-group
members get Grafana Admin automatically.
- **Account continuity.** Existing accounts are reclaimed with
dashboards and roles intact (proven on the test cluster), replacing the
warning that users might get a fresh Viewer account. The local emergency
admin is called out as the case that was not verified.
- **Let's Encrypt.** Operators must add `openid`/`i3x`/`data-access` to
`acs.letsEncrypt.additionalDnsNames`; the chart certificate does not
include them.

## Added

- An ordered upgrade procedure: the DNS/cert prerequisites, the two
volumes to snapshot (Grafana, and the shared Postgres because the
Directory v13 migration is one-way), watching the `service-setup` Job
because it is not a Helm hook, and verifying playlists by the `Count
validation` log line with `rejected=0` rather than by eye.
- **i3X authenticates but does not authorize** - any principal with a
token, including edge keytabs, can read the whole UNS; how to disable it
and what that costs.
- `accessTokenLifespan` (#680) and the dev-mode JWKS note for `auth.jwt`
kiosks on `secure: false` clusters.
- The folders/dashboards `autoMigrationThreshold` pin and why it is
there.

Reviewed by two adversarial passes (accuracy against the code, and an
operator walking the procedure); their findings are folded in - notably
the emergency-admin mechanism claim was dropped as unverified, the JWKS
wording tied to the observed startup error, and upgrade step 4 changed
from a UI check to the log check the playlist section requires.

Docs only; no code or chart change.
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.

1 participant