Skip to content

feat(credentials): add provider credential storage drivers - #2437

Merged
mrunalp merged 17 commits into
NVIDIA:mainfrom
sjenning:1931-credential-drivers-implementation
Aug 5, 2026
Merged

feat(credentials): add provider credential storage drivers#2437
mrunalp merged 17 commits into
NVIDIA:mainfrom
sjenning:1931-credential-drivers-implementation

Conversation

@sjenning

Copy link
Copy Markdown
Collaborator

Superseding #1986 while @TaylorMutch is away

Summary

Adds gateway-owned credential storage for Providers v2. New provider credential
writes now persist opaque handles instead of inline secret values, with default
encrypted database storage when no external credential backend is configured and
opt-in Kubernetes Secrets or Vault backends for deployments that want dedicated
secret storage.

Related Issue

Related to #1931

Changes

  • Adds a credential driver protobuf contract for store, resolve, delete, list,
    and capability calls.
  • Adds gateway credential runtime support for a single active external
    credential driver, in-tree drivers, and UDS-connected external drivers.
  • Adds the default encrypted database credential store as
    openshell-driver-db-credstore.
  • Adds standalone UDS-capable openshell-driver-kubernetes-secrets and
    openshell-driver-vault binaries, plus in-tree gateway loading.
  • Updates Providers v2 create/update/delete paths to store new credential values
    through credential storage and persist internal credential_handles.
  • Preserves upgrade compatibility for existing inline/plaintext provider records:
    legacy inline credentials remain readable, config-only updates leave them
    inline, and only newly submitted/rotated credential values move into credential
    storage.
  • Rejects user-supplied provider.credential_handles on provider create/update.
  • Resolves credential handles at runtime for sandbox provider environments,
    provider refresh, and managed inference routes.
  • Updates Helm defaults so no external driver means default encrypted DB
    credential storage, backed by a retained key-encryption-key Secret injected
    into the gateway.
  • Adds Helm/Skaffold values and targeted e2e coverage for Kubernetes Secrets and
    Vault credential storage backends. The local Vault e2e path deploys OpenBao as
    a Vault-compatible fixture.
  • Updates gateway/provider docs, architecture notes, CI labels, and local test
    tasks for credential driver validation.

Default Behavior

Credential drivers are opt-in for external backends. If
[openshell.gateway].credential_drivers is omitted, the gateway uses the default
encrypted database credential store. The submitted secret is encrypted into a
driver-owned credential object outside the provider record, and the provider
record stores only an opaque handle.

The explicit empty list form, credential_drivers = [], is invalid. Operators
should omit the field for default encrypted DB storage or select exactly one
external backend such as kubernetes-secrets or vault.

Existing provider records that already contain inline plaintext credentials are
still resolved for upgrade compatibility, but new provider creates and credential
updates use credential storage handles.

Testing

  • cargo check -p openshell-driver-vault -p openshell-server
  • mise run pre-commit
  • mise run helm:test
  • mise run e2e:kubernetes:credential-drivers
  • mise run e2e:rust
  • mise run e2e:podman - provider/default credential coverage passed before
    the suite failed in sandbox_create_with_no_keep_cleans_up_after_tty_command;
    isolated rerun of OPENSHELL_E2E_PODMAN_TEST=sandbox_lifecycle mise run e2e:podman reproduced the same Podman cleanup failure.

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Architecture docs updated
  • Gateway configuration docs updated

@copy-pr-bot

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@sjenning

Copy link
Copy Markdown
CollaboratorAuthor

Obvious issue left over from the rebase in ‎.github/workflows/branch-e2e.yml. Will fix tomorrow.

@sjenning
sjenningforce-pushed the 1931-credential-drivers-implementation branch 2 times, most recently from 6a10141 to 0d42e4eCompareJuly 23, 2026 14:28
@sjenning

sjenning commented Jul 23, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Obvious issue left over from the rebase in ‎.github/workflows/branch-e2e.yml

Fixed

@sjenning

Copy link
Copy Markdown
CollaboratorAuthor

Hold on this. It is all messed up.

@sjenning
sjenningforce-pushed the 1931-credential-drivers-implementation branch from 0d42e4e to d1e10d1CompareJuly 23, 2026 23:16
@mrunalp

Copy link
Copy Markdown
Collaborator

/ok to test d1e10d1

@mrunalp

Copy link
Copy Markdown
Collaborator

/ok to test 052540f

@sjenning
sjenningforce-pushed the 1931-credential-drivers-implementation branch from 052540f to 1806c9bCompareJuly 28, 2026 19:40
@mrunalp

Copy link
Copy Markdown
Collaborator

/ok to test 1806c9b

@mrunalpmrunalp added the gator:in-review Gator is reviewing or awaiting PR review feedback label Jul 30, 2026

@johntmyersjohntmyers left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gator-agent

PR Review Status

Validation: This is project-valid work for roadmap issue #1931 and implements its gateway-owned credential-storage scope.
Head SHA: 1806c9be07e0307137ac7c0b8cced209018e81fb
Base SHA: b1c7ff684e9b16f88d050c29b0093d07389fbbbb
Merge base SHA: b1c7ff684e9b16f88d050c29b0093d07389fbbbb
Patch ID: 8c7fdb202e6f6004ee9069a12d24c5bb02ffb8c7
Gator payload: 2
Review mode: initial
Previous reviewed SHA: none

Blocking findings:

  • GATOR-1806c9be-01 (Critical): backend object identity is not workspace/provider-unique, allowing a cross-workspace Vault credential collision and disclosure.
  • GATOR-1806c9be-02 (Warning): handle-backed credentials bypass persisted provider expiration.
  • GATOR-1806c9be-03 (Warning): refresh overwrites the committed backend object before validation/CAS and can delete the still-referenced handle on failure.
  • GATOR-1806c9be-05 (Warning): the configured UDS startup timeout does not bound capability negotiation or runtime RPCs.

Carried findings:

  • None.

Non-blocking suggestions:

  • Add openshell-driver-db-credstore to the AGENTS.md architecture inventory and document the new credential-driver Skaffold profiles in the Helm development skill.

Docs: Relevant published provider and gateway-configuration docs are updated.

Next state: gator:in-review

Comment threadcrates/openshell-driver-vault/src/lib.rs Outdated
Comment threadcrates/openshell-server/src/grpc/provider.rs
Comment threadcrates/openshell-server/src/provider_refresh.rs Outdated
Comment threadcrates/openshell-server/src/credentials.rs Outdated
@johntmyersjohntmyers added gator:blocked Gator is blocked by process or repository gates gator:in-review Gator is reviewing or awaiting PR review feedback and removed gator:in-review Gator is reviewing or awaiting PR review feedback gator:blocked Gator is blocked by process or repository gates labels Jul 30, 2026
@sjenning
sjenningforce-pushed the 1931-credential-drivers-implementation branch from 1806c9b to 18e3235CompareJuly 31, 2026 19:39
@sjenning

sjenning commented Jul 31, 2026

Copy link
Copy Markdown
CollaboratorAuthor

@johntmyers thanks for the review! All review feedback should be addressed by the new commits. I also rebased to resolve a conflict.

@johntmyersjohntmyers added gator:blocked Gator is blocked by process or repository gates gator:watch-pipeline Gator is monitoring PR CI/CD status gator:in-review Gator is reviewing or awaiting PR review feedback and removed gator:blocked Gator is blocked by process or repository gates gator:watch-pipeline Gator is monitoring PR CI/CD status gator:in-review Gator is reviewing or awaiting PR review feedback labels Aug 5, 2026
Apply configured timeouts to both startup capability negotiation and runtime
RPCs to prevent indefinite hangs (GATOR-1806c9be-05).
- Add DEFAULT_CREDENTIAL_DRIVER_RPC_TIMEOUT_SECS constant (30s)
- Apply timeout to GetCapabilities during startup connection
- Apply timeout to all runtime RPCs (store, delete, resolve)
- Use tokio::time::timeout to bound the entire GetCapabilities operation
during startup, not just the socket connection
- Return contextual deadline errors on timeout
This prevents a faulty or overloaded driver from hanging gateway operations
indefinitely.
The Kubernetes auth Vault resolve test was constructing a managed path with
test-workspace/test-provider-id but sending default/prov-123 in the request,
causing validation to reject the request (GATOR-18e32351-01).
- Update test to use test-workspace and test-provider-id in the request to
match the logical_path construction
- This ensures the test exercises the intended code path and validates
Kubernetes auth resolution properly
The test now passes and correctly validates identity enforcement.
Stage refresh replacements under genuinely distinct immutable handles using
a unique staging ID to prevent overwriting committed values (GATOR-1806c9be-03).
- Generate a unique staging ID using UUID for each refresh operation
- Use this staging ID when storing credentials instead of the real provider ID
- Pass the same staging ID during cleanup on failure to delete only staged objects
- This ensures deterministic paths (Vault) and object names (K8s) don't collide
with the committed provider's credentials
The fix prevents failed refreshes from silently replacing active credentials
or breaking providers by deleting still-referenced backend objects.
Add local tokio::time::timeout wrappers around credential driver RPCs to
bound non-compliant or stalled UDS peers (GATOR-1806c9be-05).
- Wrap StoreCredential, DeleteCredential, and ResolveCredentials in local timeouts
- Return contextual deadline_exceeded errors when timeouts occur
- Keep existing gRPC timeout metadata for compliant implementations
- GetCapabilities during startup was already wrapped in previous commit
This ensures a faulty local driver cannot hang gateway operations indefinitely,
even if it accepts the connection but never responds to the RPC.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Signed-off-by: Seth Jennings <sjenning@redhat.com>
@sjenning

Copy link
Copy Markdown
CollaboratorAuthor

/ok to test ee5d4d6

1 similar comment
@mrunalp

Copy link
Copy Markdown
Collaborator

/ok to test ee5d4d6

Signed-off-by: Seth Jennings <sjenning@redhat.com>
@sjenning

Copy link
Copy Markdown
CollaboratorAuthor

/ok to test e3c5f70

1 similar comment
@mrunalp

Copy link
Copy Markdown
Collaborator

/ok to test e3c5f70

@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

Review Convergence Checkpoint

Head SHA: e3c5f7004107893a62607066358a78c7ec93c902
Base SHA: 8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032
Merge base SHA: 8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032
Patch ID: a8cfad1a02cfeeab78c4dab5629bb52f0a95e2cf
Gator payload: 3

Three finding-bearing review rounds have completed.

Root-cause findings:

  • All prior root-cause findings remain resolved. The current author-only delta grants actions: read to the credential-driver E2E reusable-workflow call; the bounded Critical-only checkpoint review found no new defect.

Scope growth:

  • None in the current delta.

Reviewer-quality signals:

  • The current reviewer proposed no findings, duplicate invariants, waived or resolved re-raises, unchanged-code findings, or missing-reproducer downgrades. The durable ledger records 17 repeated finding-ID occurrences across historical dispositions; no new occurrence was proposed in this round.

Maintainer action: accept the current scope, split follow-up work, waive a finding, or explicitly authorize another autonomous review round.

Next state: gator:blocked

@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

Monitoring Complete

Monitoring is complete because this PR has merged.

Head SHA: e3c5f7004107893a62607066358a78c7ec93c902
Gator payload: 3

Final status: Gator review completed with no blocking findings remaining, the required test:e2e label was applied, required checks completed, and maintainer approval was present before merge.

I removed the active gator:* label because there is nothing left for gator to monitor on this PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:e2eRequires end-to-end coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@sjenning@mrunalp@johntmyers@TaylorMutch@varshaprasad96