feat: add operator-only provider credential retrieval over mTLS
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 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 小时
- 30 天内合并 PR
- 347
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 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 于 11 天前认领。 未关闭area:cli os:linux os:macos state:validated
难度 2/5 1-3 小时 新手友好度 88/100
NVIDIA/OpenShell#4042 · 2 条评论 ·
维护者通常 1 天内回复
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 69/100
router-for-me/EasyCLIProxyAPI#406 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 67/100
-
难度 2/5 1-3 小时 新手友好度 83/100
维护者通常 1 天内回复
-
ai-priority/P2 bug db/oracle user-priority/P1
难度 2/5 1-3 小时 新手友好度 67/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 63/100