Skip to content

fix(credentials): harden credential storage drivers - #3

Open
varshaprasad96 wants to merge 6 commits into
sjenning:1931-credential-drivers-implementationfrom
varshaprasad96:credential-drivers-fixes
Open

fix(credentials): harden credential storage drivers#3
varshaprasad96 wants to merge 6 commits into
sjenning:1931-credential-drivers-implementationfrom
varshaprasad96:credential-drivers-fixes

Conversation

@varshaprasad96

Copy link
Copy Markdown

Summary

Hardening fixes for the credential storage drivers (NVIDIA#2437), addressing correctness, performance, and operational issues identified during review.

  • Optimistic concurrency: K8s Secrets driver now uses Preconditions (uid + resourceVersion) on delete and resourceVersion on patch to prevent silent overwrites from concurrent modifications
  • Thundering herd prevention: Vault auth token caching changed from RwLock to Mutex with double-check pattern, preventing simultaneous login storms
  • Parallel RPCs: Store and delete operations parallelized with join_all (replacing sequential loops), with partial failure cleanup of successfully-stored handles
  • Delete retry loops: Both K8s Secrets and db-credstore drivers retry on 409/Aborted conflicts up to 3 times
  • Consolidated cleanup: Provider update validation + CAS write wrapped in single async block with one cleanup site (down from 4 manual cleanup call sites)
  • Refresh worker orphan cleanup: apply_minted_credential now cleans up stored handles on CAS failure
  • Retry loop guard bug fix: Removed attempt + 1 < CONFLICT_RETRY_LIMIT guard that made post-loop error unreachable
  • Unprotected validation removal: Removed validation calls outside the async cleanup block that could orphan pre-stored handles
  • GitOps KEK support: Added defaultKeyEncryptionKey Helm value for deterministic key encryption in GitOps workflows
  • RBAC documentation: Added security notes on credential-secrets Role template and gateway-config.mdx
  • Structured orphan warnings: Enhanced warn logs with handle_count, per-handle tuples, and manual deletion advisory

Related Issue

Hardens PR NVIDIA#2437 — addresses 8 of 11 gaps identified during review.

Changes

File Change
openshell-driver-kubernetes-secrets/src/lib.rs Optimistic concurrency (Preconditions on delete, resourceVersion on patch), retry loops
openshell-driver-vault/src/lib.rs Mutex-based cached token with double-check, 0.8x TTL
openshell-driver-db-credstore/src/lib.rs Delete retry loop on Aborted, removed inconsistent .trim()
openshell-server/src/credentials.rs join_all with partial failure cleanup, parallel deletes
openshell-server/src/grpc/provider.rs Consolidated cleanup async block, removed unprotected validation
openshell-server/src/provider_refresh.rs CAS failure cleanup, collapsible-if fix
deploy/helm/ GitOps KEK support, RBAC comments
docs/reference/gateway-config.mdx Security note on namespace isolation

Testing

  • mise run pre-commit passes
  • mise run test passes
  • Self-review with principal-engineer-reviewer agents caught and fixed 3 bugs before commit
  • e2e: gateway deploys and starts correctly on kind cluster; credential driver e2e test blocked by pre-existing sandbox name length issue (58 > 19 chars — unrelated to these changes)

Known remaining gaps (not addressed here)

  • additional_credentials from refresh bypass the driver (AWS STS session tokens silently dropped)
  • allow_reference_namespace parsed but never enforced at runtime

TaylorMutch and others added 6 commits July 23, 2026 18:15
Signed-off-by: Taylor Mutch <taylormutch@gmail.com>
Signed-off-by: Taylor Mutch <taylormutch@gmail.com>
… performance

Address review findings from the credential storage drivers PR:

- Route additional_credentials through the driver on refresh to prevent
  silent data loss for multi-credential providers (e.g. AWS STS)
- Clean up stored credential handles on CAS failure during refresh to
  prevent orphaned secrets in external backends
- Enforce namespace validation in the Kubernetes Secrets driver to
  prevent cross-namespace credential access when allow_reference_namespace
  is not enabled
- Cache Vault Kubernetes auth tokens with 80% TTL to avoid re-authenticating
  on every credential operation
- Parallelize resolve_credentials in all three drivers using try_join_all
  for faster sandbox startup
- Add existingSecret support for the KEK Secret to fix helm template/GitOps
  workflows where lookup returns empty and regenerates the key
- Document RBAC blast radius for the Kubernetes Secrets credential driver
  and recommend a dedicated namespace

Signed-off-by: Varsha Prasad <varshaprasad96@gmail.com>
Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
…rallelize operations

Use resourceVersion optimistic concurrency with retry loop for K8s
Secret ownership checks to prevent TOCTOU races. Switch Vault token
cache from RwLock to Mutex with double-check pattern to prevent
thundering herd on cache miss. Parallelize credential store and delete
operations across independent keys using try_join_all.

Signed-off-by: Varsha Prasad <varshaprasad96@gmail.com>
Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
…ate cleanup

Replace try_join_all with join_all in credential store/delete operations
to handle partial failures — successfully-stored handles are cleaned up
when another key fails. Add retry loop with conflict detection to
db-credstore delete_credential, matching the K8s driver pattern.
Consolidate 4 manual cleanup_pre_stored_provider_credentials call sites
into a single error handler using an async block. Remove inconsistent
.trim() from db-credstore validate_handle_owner.

Signed-off-by: Varsha Prasad <varshaprasad96@gmail.com>
Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
Remove attempt-count guard from 409/Aborted match arms in retry loops
so the post-loop Status::aborted error is reachable after exhausting
retries. Previously, last-attempt conflicts fell through to the
catch-all error arm, producing misleading Status::unavailable errors.

Remove duplicate validation calls that ran after
prepare_provider_credential_update but outside the cleanup-protected
async block, which would leak pre-stored handles on failure.

Signed-off-by: Varsha Prasad <varshaprasad96@gmail.com>
Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
@sjenning
sjenning force-pushed the 1931-credential-drivers-implementation branch from d1e10d1 to 052540f Compare July 27, 2026 18:58
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