feat: add operator-only provider credential retrieval over mTLS
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 25/100
- issue の種類
- 機能追加
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- grpc, rust
- 領域
- api, authentication, security
調査の方向性
Start by reviewing the public protobuf and authentication/provider documentation mentioned in the issue, especially the existing GetSandboxProviderEnvironment RPC and related work #3017 and #3564. The issue proposes a new public gRPC method and operator mTLS identity, but names no implementation files or tests. Done means meeting the acceptance criteria, including real TLS integration tests and safe concurrent credential refresh; this is broad security-sensitive design work.
索引モデルが issue の本文から書いたものです。
説明
User Story
I need to use OpenShell as the credential store for an operator integration, specifically OpenClaw Enterprise. The operator runs outside an OpenShell sandbox and needs to retrieve usable provider credentials as a privileged non-sandbox caller, without receiving sandbox configuration or supervisor-specific metadata.
Problem Statement
OpenShell does not expose a public, operator-only gRPC workflow for retrieving selected usable credentials from a provider.
The existing GetSandboxProviderEnvironment RPC is sandbox-authenticated and returns a sandbox environment snapshot: credentials, non-secret configuration, endpoint bindings, dynamic credential metadata, revisions, and other sandbox-specific state. It is not a credentials-only API for a non-sandbox operator. Provider inspection exposes credential key names rather than secret values.
A separate public RPC is needed with explicit operator authentication, credential selection, and freshness semantics.
Impact / Why This Matters
This gap blocks using OpenShell as the shared source of provider credentials for both sandbox workloads and privileged operator-side workflows. An operator must otherwise retain credentials separately or build a separate retrieval integration; duplicating storage and refresh ownership can introduce stale credentials, additional secret custody, and inconsistent rotation behavior.
Repurposing the sandbox environment call would couple the operator to sandbox lifecycle and expose unrelated state. Broadening ordinary user or administrator access to secret values would also weaken the existing distinction between managing providers and exporting their credentials.
Proposed Design
Operator access
- Add an explicit, default-off operator authentication capability. Authenticate an operator only through a client certificate verified on a direct gateway TLS connection and containing the exact role
OU=operator. - Require TLS and a configured trusted client CA. Support operator authentication alongside OIDC and independently of ordinary mTLS user authentication.
- Give this distinct operator identity gateway-wide access to providers across workspaces without workspace membership, as well as ordinary user and platform-admin capabilities. Do not grant sandbox-only or gateway-peer-only privileges.
- Do not accept ordinary mTLS certificates, OIDC administrators, an OIDC
operatorclaim,openshell:all, forwarded certificate headers, edge-tunnel identity, or local-development identity as operator authorization. Reject mixed operator-certificate/bearer requests in the initial version. - Keep ordinary client certificate generation and gateway registration unchanged; operator authority must be deliberately provisioned.
Credentials-only retrieval
Expose a public GetProviderCredentials gRPC method at /openshell.v1.OpenShell/GetProviderCredentials:
- The operator selects one explicit workspace, one provider by canonical name, and a nonempty, bounded set of runtime credential keys.
- The operator may specify a minimum remaining credential lifetime.
- OpenShell returns exactly those usable runtime values, each with an optional expiration timestamp. The response contains no provider configuration, sandbox bindings, raw storage handles, or refresh metadata.
An empty selection must not mean “return everything.” Reject duplicate or malformed keys, missing workspace/provider selections, and all_workspaces. Keys identify provider runtime values, not backend handles or storage paths. The caller cannot supply arbitrary token endpoints, audience/scope overrides, or credential-driver parameters.
Initially support static runtime credentials and gateway-refresh-managed credentials. For OAuth refresh-managed credentials, return access tokens, never refresh tokens, OAuth client secrets, signing keys, or other gateway-only minting material. Reject supervisor-side, endpoint-specific, and SPIFFE-bound dynamic grants with FAILED_PRECONDITION, without exporting their input secrets.
Return all selected values or fail without a partial credential response. Prevalidate the selection before initiating refreshes. Refresh effects may persist even if another selected credential causes the overall request to fail; response atomicity does not imply rollback of an upstream grant.
Freshness and concurrent use
Reuse credentials that satisfy the requested freshness requirement. Omitted or zero minimum lifetime uses the gateway's normal freshness margin; non-expiring static credentials satisfy the requirement. Reject negative or excessive durations.
When eligible credentials are missing or insufficiently valid, use the configured gateway refresh behavior. Fail rather than return expired or insufficiently valid values, and do not repeatedly mint tokens to chase an impossible lifetime requirement. Respect retry backoff and reauthorization requirements.
Concurrent retrievals, background refresh, and explicit rotation must not consume the same rotating refresh token unsafely, including across gateway replicas. Related outputs from a single refresh must not cause redundant upstream exchanges. Delivery must reflect safely committed refresh state, and cancellation or shutdown must not lose rotated refresh material or blindly repeat an ambiguously completed exchange. Provider deletion, replacement, or reconfiguration during retrieval must not result in delivery from the wrong provider identity.
Security and initial scope
Exporting a credential lets the operator use it outside sandbox endpoint enforcement and the supervisor policy boundary. This is intentional privileged behavior and must be documented. Trusted CA issuance authority and operator private-key custody are platform-administration boundaries.
Audit the operator identity/certificate fingerprint, workspace, provider, requested keys, and refresh/delivery outcome without recording secret values. Never expose credentials through logs, traces, errors, metrics labels, generic interceptor payloads, or mutation replay storage. Retain rate limiting and bound selection size, response size, refresh concurrency, and upstream deadlines.
The initial client surface is the generated/raw gRPC API. A CLI command and curated SDK convenience methods are separate follow-up work.
Suggested UX
Notional gateway configuration for review:
[openshell.gateway.mtls_auth]
operator_enabled = true
After configuring TLS/client-CA trust and separately issuing an operator client certificate, the operator connects directly over mTLS without bearer metadata and calls GetProviderCredentials with a request equivalent to:
{
"workspaceScope": { "workspace": "production" },
"name": "my-graph",
"credentialKeys": ["MS_GRAPH_ACCESS_TOKEN"],
"minimumRemainingLifetime": "300s"
}
Successful response, with an illustrative redacted value:
{
"credentials": {
"MS_GRAPH_ACCESS_TOKEN": {
"value": "<redacted-access-token>",
"expirationTime": "2026-07-01T12:00:00Z"
}
}
}
No sandbox creation or provider attachment is required.
Acceptance Criteria
- A trusted, directly connected mTLS operator can retrieve explicitly selected runtime credentials from a named provider in any explicitly selected workspace without sandbox creation or workspace membership.
- Ordinary mTLS users, OIDC users/admins, sandbox and peer callers, anonymous/local-dev callers, spoofed certificate headers, and edge-tunnel callers cannot retrieve credentials through this API. Disabled operator authentication, invalid/untrusted/expired certificates, and invalid TLS/CA configuration fail closed.
- Operator authentication works alongside OIDC, rejects mixed operator-certificate/bearer requests, and supports ordinary user/admin APIs without acquiring sandbox-only or peer-only authority.
- Responses contain only selected credential values and optional expiration timestamps; gateway-only material and unrelated secrets/configuration are never delivered.
- Static and gateway-refresh-managed credentials satisfy the documented freshness semantics, including token reuse, supported refresh, multi-output refresh, impossible lifetimes, and reauthorization failures.
- Invalid selections, unsupported dynamic grants, missing resources/keys, unusable values, and conflicting changes produce sanitized errors without partial secret responses or secret-valued fallbacks.
- Concurrent retrieval, background refresh, and rotation remain safe across gateway replicas, including refresh-token rotation, persistence failures, cancellation, deletion, replacement, and reconfiguration. Existing sandbox refresh/delivery behavior remains functional.
- Real TLS integration tests prove the operator-only boundary; tests verify that returned and gateway-only secrets do not appear in logs, traces, audit records, interceptors, errors, or replay storage.
- Public API contracts and affected generated/raw clients are updated. Documentation covers configuration, credential selection/freshness, unsupported grants, credential-export implications, and operator certificate issuance, rotation, and revocation behavior, including established TLS connections.
Alternatives Considered
- Reuse or filter
GetSandboxProviderEnvironment: This is sandbox-authenticated and carries a sandbox-specific contract. Filtering a response on the client does not provide a separate non-sandbox authorization boundary or prevent unrelated material from being delivered. - Expose credential-driver
ResolveCredentials: Raw handle resolution is a storage-level operation, not a provider-aware runtime credential contract. It would bypass selection, private-material exclusions, and freshness semantics. - Use existing provider inspection/rotation APIs: Inspection intentionally omits secret values. Rotation can update credentials but does not deliver the resulting values to a non-sandbox operator.
- Implement a middleware or gateway interceptor extension: Supervisor middleware operates in the sandbox traffic path. Interceptors can transform existing RPCs, but transformation alone does not establish a verified operator identity or a safe provider-aware secret-export contract. Keep this sensitive method outside generic interceptor routing initially.
- Maintain a separate operator credential store: This can serve an operator independently, but does not meet the requirement that OpenShell own the credentials and gateway-managed refresh lifecycle for both uses.
Agent Investigation
Checked the upstream public protobuf and the repository's published authentication/provider documentation. The upstream API has GetSandboxProviderEnvironment with auth_mode: "sandbox" and sandbox-specific response fields, but no GetProviderCredentials method. Provider documentation describes key-only inspection and gateway-managed credential refresh. Searches for an existing operator credential retrieval issue or GetProviderCredentials issue did not identify a duplicate.
Related work: #3017 covers auditing credential-disclosure reads, and #3564 covers mandatory TLS client certificates alongside OIDC. Neither defines this credentials-only operator retrieval workflow.
Checklist
- I've reviewed existing issues and the published docs.
- This is a design proposal, not a "please build this" request.
- 主要言語
- Rust
- スター
- 15.4k
- フォーク
- 1.7k
- 平均マージ
- 1日 19時間
- マージ済み PR(30日)
- 347
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
NVIDIA/OpenShell のほかの issue
-
state:triage-needed
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
メンテナーはふだん 1 日以内に返信
-
state:triage-needed
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
メンテナーはふだん 1 日以内に返信
-
docs: document workspace and provider label capabilities対応中かも @johntmyers が 5 日前に担当しました。 オープンarea:docs
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
NVIDIA/OpenShell#4250 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
bug(driver-mxc): test helper fails to compile after gateway-name argument対応中かも @feloy が 7 日前に担当しました。 オープンstate:triage-needed
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信
-
bug: install.sh ignores XDG_CONFIG_HOME for the local gateway config対応中かも @fede-kamel が 10 日前に担当しました。 オープンarea:cli os:linux os:macos state:validated
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
NVIDIA/OpenShell#4042 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
NVIDIA/OpenShell の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
swc-project/swc#12516 ·
メンテナーはふだん 1 日以内に返信
-
mls-rs-crypto-awslc: exact aws-lc-rs =1.16.3 pin blocks rustls security update対応中かも @muscariello が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
-
[work-item] adam-adae-worsening-emergence: conform spec.yaml to the specification style contract (REQ-1280)対応中かも @muse-yamaa-bot が今日担当しました。 オープンwork-item
難易度 1/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 63/100
metasequoiaime/msime#7328 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
eclipse-opensovd/classic-diagnostic-adapter#616 ·
メンテナーはふだん 2 日以内に返信