Repository navigation
feat(provider-sync): sync provider credentials from Kubernetes Secrets - #13
Merged
Merged
Conversation
…es Secrets Add openshell-provider-sync, a controller that watches Secrets labelled openshell.nvidia.com/provider-sync=true and sends changed values to the provider they name as a value-only UpdateProvider. Secrets stay owned by whatever manages them (External Secrets Operator, Vault, 1Password), and rotating one no longer needs a redeploy or a sandbox recreate. Each Secret lists the credential keys it backs, so unrelated keys are never read. A Secret with a missing, empty or non-UTF-8 mapped key sends nothing, two live Secrets cannot feed one credential, and the controller never creates, deletes or clears provider credentials. Outcomes are published as Kubernetes Events on the Secret; values never appear in logs or events. Signed-off-by: Matt Jane <matt@monad.com>
…sh an image An agent's Secret backs several providers, so provider-credentials entries now take an optional provider prefix: `[provider:]KEY[=secret-key]`. The provider annotation is only needed for unprefixed entries. Each provider is synced on its own, so a missing or half-written provider no longer holds back the others. A key that is missing or empty counts as absent. A provider with none of its keys set is skipped with a ProviderSyncSkipped event, which lets a Secret list alternative credentials and feed whichever it holds. Some but not all keys set is still refused for that provider. The Monad image workflow builds the controller for amd64 and arm64 and publishes ghcr.io/monad-inc/openshell/provider-sync with the gateway's tags. Signed-off-by: Matt Jane <matt@monad.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
openshell-provider-sync, a controller that keeps provider credentials current with Kubernetes Secrets managed elsewhere (External Secrets Operator syncing from 1Password or Vault). It runs as its own Deployment and talks to the gateway only through the publicUpdateProviderAPI, so a rotated Secret reaches running sandboxes without restarting the gateway or the sandbox. Withstable_placeholder: trueon the credential's profile (NVIDIA#3339, already in monad.14), it also reaches processes that are already running.Related Issue
No fork issue. Upstream, a scoped-down version of NVIDIA#1882 is the long-term path. The agent-fleet side (the chart, plus the Secret labels and annotations) lives on agent-fleet
feat/provider-sync.Changes
openshell-provider-sync. The first commit is the prototype, cherry-picked from upstream main. The second makes it fit agent Secrets:openshell.nvidia.com/provider-credentialstakes[provider:]KEY[=secret-key]entries, all in one workspace fromopenshell.nvidia.com/provider-workspace.ProviderSyncSkippedevent. That lets a Secret list both Claude credential variants. Some keys set but not all is still refused, so a half-written Secret cannot cause a partial rotation.deploy/docker/Dockerfile.provider-sync, distrolesscc-debian13:nonroot,USER 65532:65532, with no writable paths.monad-images.ymlbuilds it for amd64 and arm64 and publishesghcr.io/monad-inc/openshell/provider-syncwith the same tags as the gateway.MONAD.mdimage list.debug-openshell-clusterskill, covering each Event reason and a failure-pattern row.configuration.mdxis unchanged, since no gateway TOML or Helm rendering changes.Testing
cargo test -p openshell-provider-sync: 30 passed. Coverage includes:cargo clippy -p openshell-provider-sync --all-targets -D warnings: clean.mise run pre-commit: passed.Checklist
debug-openshell-clusterskill updatedLimits
🤖 Generated with Claude Code
https://claude.ai/code/session_01DSMF7ZMUu3WSs72KbVBBmJ