A SecretID cannot be renewed the way a token can -- it must be re-issued by a privileged caller -- so renew-app-tokens.sh structurally could not cover it. The original expired on ~2026-07-28 and broke app-get-secret.sh silently until it was noticed on 2026-08-22. This closes the last credential in the stack that had no automated lifecycle. Weekly against a 30d secret_id_ttl gives 4x margin: three consecutive failed rotations can occur before anything actually breaks, and the first failure already mails an alert via OnFailure=openbao-alert@%n.service. Order of operations is the safety property: mint -> verify the new SecretID actually authenticates -> only then overwrite the file -> only then prune old accessors. Any failure leaves the previous working credential in place and exits non-zero. Verified by pointing BAO_ADDR at a dead port: exit 1, file byte-identical, consumer unaffected. A SecretID that fails its verification login is destroyed rather than installed. Accessors are kept one cycle deep (KEEP=2: current + previous) so a consumer that read the file just before rotation can still log in. Verified across three consecutive runs: steady state stays at 2, oldest pruned each cycle. The rotator skips its verification login when secret_id_num_uses would be consumed by it, which is why the policy grants read on the role config. That read exposes TTLs and bound policies but NOT the RoleID, which lives at the separate .../role-id path and stays denied -- verified 403, along with 403 on the demo secret itself and on other AppRoles. Token at /etc/openbao-approle-rotate.token matches the /etc/openbao-*.token glob, so the renew loop picks it up automatically (verified: renewed=10 failed=0) and it cannot lapse the way the backup tokens did. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NFtVLA7VVqXL5G2S18c4Jk
13 lines
417 B
Desktop File
13 lines
417 B
Desktop File
[Unit]
|
|
Description=Rotate the demo-app AppRole SecretID before its 30d TTL expires
|
|
After=network-online.target docker.service
|
|
Wants=network-online.target
|
|
Requires=docker.service
|
|
OnFailure=openbao-alert@%n.service
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
# Runs as root: reads /etc/openbao-approle-rotate.token and writes the
|
|
# SecretID back as lutz:lutz 0600.
|
|
ExecStart=/home/lutz/Projects/OpenBAO/scripts/rotate-approle-secret-id.sh
|