Skip to content

feat(config): Revoke Vault token on shutdown#1088

Merged
gtema merged 1 commit into
openstack-experimental:mainfrom
magdang:feat/vault-token-revoke
Jul 24, 2026
Merged

feat(config): Revoke Vault token on shutdown#1088
gtema merged 1 commit into
openstack-experimental:mainfrom
magdang:feat/vault-token-revoke

Conversation

@magdang

@magdang magdang commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Why

Follow-up to #1051 (now merged). Addresses the maintainer's note that the Vault integration is missing something — pointing at HashiCorp's lease, renew, revoke doc.

That doc describes a three-part token lifecycle: lease → renew → revoke. #1051 already leases the auth token (resolvelookup-self, capturing TTL/renewable) and renews it (renew_if_due at half-TTL). The missing third part is revoke: on shutdown the token was simply left to expire on its own TTL, leaving valid credentials outstanding after the process is gone.

When a lease is revoked, it invalidates that secret immediately and prevents any further renewals. When a token is revoked, Vault will revoke all leases that were created using that token.

What

  • VaultRuntime::revoke — calls auth/token/revoke-self via vaultrs Client::revoke(); new VaultConfigError::TokenRevocation.
  • ConfigManager now owns a CancellationToken and the watcher JoinHandle. New ConfigManager::shutdown() cancels the watch loop and awaits it; the loop revokes the Vault token before exiting (covers both the shutdown-cancel and watcher-channel-close exit paths).
  • terminate() (core/src/keystone.rs) — the existing graceful-shutdown hook, awaited before token.cancel() — now calls config_manager.shutdown(), so revocation completes before the process exits (race-free, no reliance on the fire-and-forget task surviving).
  • Reuses the repo's idiomatic CancellationToken + tokio::select! teardown pattern.

Scope notes (deliberately excluded)

  • KV v2 secrets have no leases (per the doc) — no per-secret revoke; rotation is already handled by version-metadata polling from feat(config): Add Vault-backed configuration #1051.
  • Prefix-based revocation (vault lease revoke -prefix) is an operator/CLI action, not something a config loader performs.
  • Dynamic secrets engines (DB/AWS) are a separate feature, out of scope here.

Tests

  • test_vault_token_revoked_on_shutdown — mocks revoke-self, drives ConfigManager::shutdown(), asserts exactly one revoke call.
  • test_shutdown_without_vault_is_noop — non-Vault config: shutdown() returns promptly and doesn't panic.
  • Full config suite green (107 passed); clippy + fmt clean; keystone binary compiles.

🤖 Generated with Claude Code

Complete the Vault token lease lifecycle. The runtime already leases
and renews its token, but never revoked it: on shutdown the token
lingered valid until its TTL expired.

Add VaultRuntime::revoke (auth/token/revoke-self) and drive it from
graceful shutdown. ConfigManager now owns a CancellationToken and the
watcher JoinHandle; ConfigManager::shutdown cancels the watch loop and
awaits it, and the loop revokes the token before exiting. Keystone's
terminate hook calls it, so revocation completes before the process
exits.

Revoking invalidates the token (and any leases created with it)
immediately instead of leaving valid credentials outstanding.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Yousef Hussein <ymh1874@gmail.com>
@magdang
magdang marked this pull request as ready for review July 24, 2026 15:15
@magdang
magdang requested a review from gtema July 24, 2026 15:15
@gtema
gtema added this pull request to the merge queue Jul 24, 2026
Merged via the queue into openstack-experimental:main with commit c7ce2cb Jul 24, 2026
33 checks passed
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.

2 participants