Establish the live state and find a rollout precondition for G10
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 45s

G10 waits on custody and platform owners and cannot close from here. What was
doable: verify the handoffs actually went out, replace a remembered live state
with an observed one, and find out whether main is safe to deploy. The last
question found a defect in this repository's own recent work.

Handoffs verified independently rather than trusted: all seven messages are in
the hub with receipt ids. This gap was reopened once for claimed-but-unsent
delivery, so the claim deserved the same scrutiny.

Live state read from the cluster read-only: image main-153258b, only the Qonto
secret materialized so the approval clients remain unprovisioned, four registered
clients, no tenantEngine block. That also corrects an earlier claim of mine --
the deployed config sets userOU explicitly, so the KEY-WP-0023 default fix was
never a production issue.

The precondition: KEY-WP-0019 discovers the expected issuer from
authelia.tokenBaseURL, and the deployed Authelia derives its advertised issuer
from the request Host, advertising the in-cluster address to KeyCape and the
browser-facing one to browsers. Verification fails closed, so a mismatch breaks
every human login and looks like a broken login rather than a misconfiguration.
Which value the token carries needs a real login against production to settle and
was not determined here.

Two mitigations: docs/operations.md documents pinning authelia.issuer and
jwksUrl, with the curl that reveals what the provider advertises for a given
Host; and the authentication failure event now carries a specific reason, so
id_token_issuer_mismatch is distinguishable from a signature failure or an
unreachable key set. The browser still learns nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NV9oijZukGyGbRQGGKnK4P

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 713576@bnt-lap001
Assistant-Session: 384c511d-9bce-4cb8-a676-2aef6c0c8df6
This commit is contained in:
tegwick 2026-09-08 11:41:42 +02:00
parent 64942639ad
commit 7dda967c27
6 changed files with 293 additions and 7 deletions

View file

@ -94,6 +94,37 @@ providers either; upstream ID tokens are verified cryptographically instead, so
that assurance does not depend on the network being what we believe it is
(KEY-WP-0019).
## Upstream issuer pinning (read before rolling out KEY-WP-0019)
KeyCape verifies upstream ID tokens against the issuer the provider advertises,
discovered server-side from `authelia.tokenBaseURL`. Some providers — Authelia
among them — derive the advertised issuer from the **request Host**, so the value
KeyCape learns over an in-cluster service address is not the value minted into
tokens issued for the browser-facing host.
Where that is true, pin it explicitly:
```yaml
authelia:
tokenBaseURL: "http://authelia.sso.svc.cluster.local:9091"
issuer: "https://auth.coulomb.social" # exactly the iss claim in ID tokens
jwksUrl: "http://authelia.sso.svc.cluster.local:9091/jwks.json"
```
Verification fails closed, so a mismatch means **every human login fails** — and
it looks like a broken login rather than a configuration error. Check the
issuer before rolling out, not after. The failure is diagnosable: the
authentication failure event carries `error_type=id_token_issuer_mismatch`, as
distinct from `id_token_signature` or `provider_keys_unavailable`.
Confirm the value with the Host the provider will actually see:
```bash
curl -s -H "Host: auth.coulomb.social" \
http://authelia.sso.svc.cluster.local:9091/.well-known/openid-configuration \
| jq -r .issuer
```
## What is not claimed
No resource-efficiency or throughput bounds are asserted here. Nothing in this