feat(hermes): take the Anthropic credential from Vault
Some checks failed
Tests / Declarative: Post Actions testing.tests.test_repo_structure.test_knowledge_service_mirror_matches_source failed

The Claude subscription OAuth token was created as a manual kubectl Secret in
the interest of demo time, with migration to Vault agreed as follow-up. The
value now lives at kv/atlas/hermes/agent-tokens and is injected as a file.

The hermes role gains that path and binds the hermes-triage service account
the deployment actually runs as; it previously bound only hermes-vault. The
init container prefers the Vault file and falls back to the Secret, so this
can be rolled back by removing the annotations alone, and the Secret should be
deleted once Vault has been serving it for a while.

Vault was reachable all along without the operator credential: Ariadne already
holds a vault-admin Kubernetes auth role, which is how the value was written.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
jenkins 2026-08-06 12:14:47 -03:00
parent ed626a1f7a
commit 83f8d67640
2 changed files with 40 additions and 8 deletions

View File

@ -25,6 +25,22 @@ spec:
ai.bstein.dev/role: testing-triage
ai.bstein.dev/placement: arm64 gateway lane (rpi5 preferred)
ai.bstein.dev/config-rev: "20260804-root-operator-docs"
# The Anthropic credential comes from Vault rather than a manually
# created Secret. The role is declared in
# services/vault/scripts/vault_k8s_auth_configure.sh and bound to
# this pod's service account.
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: hermes
vault.hashicorp.com/agent-inject-secret-anthropic-token: kv/data/atlas/hermes/agent-tokens
vault.hashicorp.com/agent-inject-template-anthropic-token: |
{{- with secret "kv/data/atlas/hermes/agent-tokens" -}}
{{ .Data.data.anthropic_oauth_token }}
{{- end }}
vault.hashicorp.com/agent-pre-populate-only: "true"
vault.hashicorp.com/agent-requests-cpu: 25m
vault.hashicorp.com/agent-requests-mem: 32Mi
vault.hashicorp.com/agent-limits-cpu: 100m
vault.hashicorp.com/agent-limits-mem: 128Mi
spec:
serviceAccountName: hermes-triage
automountServiceAccountToken: true
@ -88,6 +104,13 @@ spec:
name: hermes-api-server-key
key: api-key
optional: true
# Fallback only; Vault is preferred when its file is present.
- name: CLAUDE_CODE_OAUTH_TOKEN_SEED
valueFrom:
secretKeyRef:
name: hermes-anthropic-token
key: token
optional: true
command:
- sh
- -c
@ -115,6 +138,20 @@ spec:
api_key="$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | od -An -tx1 | tr -d ' \n')"
printf '\nAPI_SERVER_KEY=%s\n' "${api_key}" >> /opt/data/.env
fi
# Anthropic credential: Vault first, then the manual Secret. The
# Secret is retained only as a rollback path while the migration
# settles; delete it once Vault has been serving for a while.
anthropic=""
if [ -r /vault/secrets/anthropic-token ]; then
anthropic="$(cat /vault/secrets/anthropic-token)"
elif [ -n "${CLAUDE_CODE_OAUTH_TOKEN_SEED:-}" ]; then
anthropic="${CLAUDE_CODE_OAUTH_TOKEN_SEED}"
fi
if [ -n "${anthropic}" ]; then
grep -v '^CLAUDE_CODE_OAUTH_TOKEN=' /opt/data/.env > /opt/data/.env.tmp || true
printf 'CLAUDE_CODE_OAUTH_TOKEN=%s\n' "${anthropic}" >> /opt/data/.env.tmp
mv /opt/data/.env.tmp /opt/data/.env
fi
chmod 0600 /opt/data/.env
chown -R 10000:10000 /opt/data
securityContext:
@ -218,12 +255,7 @@ spec:
# falls back to openai-codex.
# TODO: migrate to Vault alongside the Gitea token; this manual
# Secret was created in the interest of demo time.
- name: CLAUDE_CODE_OAUTH_TOKEN
valueFrom:
secretKeyRef:
name: hermes-anthropic-token
key: token
optional: true
volumeMounts:
- name: home
mountPath: /opt/data

View File

@ -253,8 +253,8 @@ write_policy_and_role "health" "health" "health-vault-sync" \
"health/*" ""
write_policy_and_role "game-stream" "game-stream" "game-stream-vault" \
"game-stream/*" ""
write_policy_and_role "hermes" "hermes" "hermes-vault" \
"hermes/operator-oidc" ""
write_policy_and_role "hermes" "hermes" "hermes-vault,hermes-triage" \
"hermes/operator-oidc hermes/agent-tokens" ""
write_policy_and_role "veles" "veles" "veles-backend,veles-generator,veles-postgres,veles-vault-sync" \
"veles/* shared/harbor-pull shared/postmark-relay" ""
write_policy_and_role "veles-sim" "veles" "veles-sim" \