From 11f689d86d81772ee46dc74877effa41aae21667 Mon Sep 17 00:00:00 2001 From: tegwick Date: Thu, 27 Aug 2026 23:55:08 +0200 Subject: [PATCH] feat(forge): point the credential lane at the built OpenBao objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MASON-WP-0003-T02 delivered the token on 2026-08-27, and three of its details differ from the chart's placeholders: KV v2 puts `data/` in the read path, the field is `FORGE_READ_TOKEN` rather than `token`, and the address matches every existing ClusterSecretStore (`http://openbao.openbao.svc:8200`, mount `platform`, auth mount `kubernetes`). The projected token's audience is now optional and defaults to empty. A token carrying an audience the auth role does not bind is rejected at TokenReview, and the role's audience binding is not readable without a privileged session — the four existing external-secrets roles use the API server audience, so that is the default that can be verified to work. Setting `openbao` here narrows the token to OpenBao alone and is worth doing once the role binds it. Co-Authored-By: Claude Opus 5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 2583210@bnt-lap001 Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006 --- WORK-RECORDS.md | 4 ++-- .../state-hub/templates/deployment.yaml | 6 ++++- .../apps/charts/state-hub/values.yaml | 23 +++++++++++++++---- .../railiance/apps/helm/state-hub-values.yaml | 6 +++++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index 80fef2a..bc330a2 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -317,6 +317,6 @@ | task | STATE-WP-0083-T07 | done | — | workplans/STATE-WP-0083-forge-derived-projection-reset.md | | task | STATE-WP-0083-T08 | done | — | workplans/STATE-WP-0083-forge-derived-projection-reset.md | | task | STATE-WP-0084-T01 | done | — | workplans/STATE-WP-0084-forge-read-for-private-repositories.md | -| task | STATE-WP-0084-T02 | wait | — | workplans/STATE-WP-0084-forge-read-for-private-repositories.md | -| task | STATE-WP-0084-T03 | wait | — | workplans/STATE-WP-0084-forge-read-for-private-repositories.md | +| task | STATE-WP-0084-T02 | progress | — | workplans/STATE-WP-0084-forge-read-for-private-repositories.md | +| task | STATE-WP-0084-T03 | progress | — | workplans/STATE-WP-0084-forge-read-for-private-repositories.md | | task | STATE-WP-0084-T04 | wait | — | workplans/STATE-WP-0084-forge-read-for-private-repositories.md | diff --git a/deploy/railiance/apps/charts/state-hub/templates/deployment.yaml b/deploy/railiance/apps/charts/state-hub/templates/deployment.yaml index d91989b..b6139af 100644 --- a/deploy/railiance/apps/charts/state-hub/templates/deployment.yaml +++ b/deploy/railiance/apps/charts/state-hub/templates/deployment.yaml @@ -52,7 +52,9 @@ spec: sources: - serviceAccountToken: path: token - audience: {{ .Values.forgeRead.openbao.audience | quote }} + {{- with .Values.forgeRead.openbao.audience }} + audience: {{ . | quote }} + {{- end }} expirationSeconds: {{ .Values.forgeRead.openbao.expirationSeconds }} {{- end }} {{- end }} @@ -111,6 +113,8 @@ spec: value: {{ .Values.forgeRead.openbao.addr | quote }} - name: OPENBAO_K8S_ROLE value: {{ .Values.forgeRead.openbao.role | quote }} + - name: OPENBAO_K8S_AUTH_MOUNT + value: {{ .Values.forgeRead.openbao.authMount | quote }} - name: OPENBAO_K8S_TOKEN_PATH value: /var/run/secrets/openbao/token - name: FORGE_READ_SECRET_PATH diff --git a/deploy/railiance/apps/charts/state-hub/values.yaml b/deploy/railiance/apps/charts/state-hub/values.yaml index 0ec45e9..ffa9a81 100644 --- a/deploy/railiance/apps/charts/state-hub/values.yaml +++ b/deploy/railiance/apps/charts/state-hub/values.yaml @@ -51,12 +51,27 @@ secret: forgeRead: enabled: false openbao: - addr: "" + # Matches every existing ClusterSecretStore on this cluster. + addr: http://openbao.openbao.svc:8200 + authMount: kubernetes role: state-hub-forge-derivation - audience: openbao + # KV v2: the read path carries the `data/` infix, mount `platform`. + secretPath: platform/data/workloads/state-hub/forge-derivation + secretKey: FORGE_READ_TOKEN + # Audience for the projected ServiceAccount token. + # + # Empty renders no audience, giving the token the API server's audience — + # what the four existing external-secrets roles use, and what an OpenBao + # Kubernetes auth role with no bound audience will accept. A token with an + # audience the role does not bind is rejected at TokenReview, so this must + # not be set to "openbao" until the role binds that audience. + # + # Worth revisiting: with no audience, a copy of this token is a credential + # for the cluster API. Binding `openbao` on the role and setting it here + # narrows it to OpenBao alone. Either way the token is short-lived and + # kubelet-rotated, which the legacy auto-mounted token is not. + audience: "" expirationSeconds: 3600 - secretPath: "" - secretKey: token resources: requests: diff --git a/deploy/railiance/apps/helm/state-hub-values.yaml b/deploy/railiance/apps/helm/state-hub-values.yaml index f37183d..923cf72 100644 --- a/deploy/railiance/apps/helm/state-hub-values.yaml +++ b/deploy/railiance/apps/helm/state-hub-values.yaml @@ -50,3 +50,9 @@ sweep: hostname: 239.62.205.92.host.secureserver.net hostPath: /home/tegwick sshHostPath: /home/tegwick/.ssh + +# Forge read credential (STATE-WP-0084-T02). Coordinates only — the token lives +# in OpenBao at platform/workloads/state-hub/forge-derivation and reaches the +# pod through Kubernetes auth, never through this file or a Secret. +forgeRead: + enabled: true