Skip to content

Commit b57ca6a

Browse files
committed
docs(rfc): address review feedback on RFC 0006
- Decouple OIDC motivation from K8s framing per @derekwaynecarr feedback - Reframe as certificate distribution problem, not namespace problem - Add relationship section positioning RFC 0006 relative to RFC 0005 - Add links to RFC 0005 (#1617), Python OIDC PR (#1621), roadmap (#1044)
1 parent 05c3ebc commit b57ca6a

1 file changed

Lines changed: 32 additions & 11 deletions

File tree

rfc/0006-sdk-and-file-transfer/README.md

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ authors:
33
- "@zanetworker"
44
state: draft
55
links:
6+
- "RFC 0005 / PR #1617 (shared SDK core and TS binding, @maxdubrinsky)"
7+
- "PR #1621 (Python SDK OIDC auth, @mrunalp)"
68
- "PR #1404 (per-sandbox auth, merged)"
79
- "PR #1547 (Python SDK fixes, open)"
810
- "PR #1117 (Python wheels, open)"
911
- "PR #1511 (proxy egress RFC, open)"
12+
- "Issue #1044 (SDK roadmap)"
1013
---
1114

1215
# RFC 0006 - SDK Consumption Entrypoints and File Transfer
@@ -18,8 +21,25 @@ consumable as programmable infrastructure for agent platforms and
1821
frameworks. Add streaming UploadFile/DownloadFile gRPC RPCs to the
1922
gateway so SDK consumers can move files in and out of sandboxes
2023
without shelling out to the CLI. Support OIDC authentication in both
21-
SDKs so cross-namespace K8s deployments work without copying mTLS
22-
secrets.
24+
SDKs so any OIDC-enabled gateway is reachable without distributing
25+
client certificates.
26+
27+
### Relationship to RFC 0005
28+
29+
RFC 0005 (PR #1617, @maxdubrinsky) proposes the shared Rust SDK core
30+
and TypeScript binding via napi-rs, with a working prototype. This RFC
31+
is complementary: it covers the broader SDK strategy (consumption
32+
patterns, file transfer RPCs, Python SDK surface expansion, platform
33+
integration examples) that RFC 0005 is the first implementation phase
34+
of. RFC 0005 delivers the "how" for the shared core and TS binding;
35+
this RFC frames the "why" and "what" across both languages.
36+
37+
Areas this RFC covers that RFC 0005 explicitly defers:
38+
39+
- File transfer RPCs (UploadFile/DownloadFile)
40+
- Python SDK surface expansion (provider, watch, policy, services)
41+
- Platform consumption patterns (Anthropic, OpenAI, OpenClaw, CI/CD)
42+
- Python-on-shared-core migration path
2343

2444
## Motivation
2545

@@ -113,7 +133,7 @@ Add wrappers for existing gateway RPCs. No gateway changes needed.
113133

114134
| Method | RPC | Why |
115135
|--------|-----|-----|
116-
| OIDC auth | gRPC metadata interceptor | mTLS-only locks SDK to single namespace. Every K8s production deployment needs cross-namespace auth. |
136+
| OIDC auth | gRPC metadata interceptor | mTLS-only requires distributing client certificates to every SDK consumer. OIDC bearer tokens let any consumer connect to an OIDC-enabled gateway without certificate distribution, regardless of deployment model. |
117137
| `attach_provider()` / `detach_provider()` / `list_providers()` | AttachSandboxProvider, DetachSandboxProvider, ListSandboxProviders | Credential separation is Mode 2's core security property. Without it, SDK consumers must bake credentials into sandbox images or pass them as env vars visible to agent code. |
118138
| `watch()` | WatchSandbox | Polling at scale is untenable. Platforms need real-time status, logs, and error detection. |
119139
| `upload_path()` / `download_path()` | UploadFile, DownloadFile (new RPCs, see below) | Every use case involving local files is blocked without this. |
@@ -237,19 +257,20 @@ Implementation: a gRPC call credentials interceptor that attaches
237257
20 lines per SDK.
238258

239259
```python
240-
# mTLS (today): certs manually copied from another namespace
260+
# mTLS (today): client certificates distributed to every consumer
241261
client = SandboxClient(endpoint=..., tls=TlsConfig(ca_path=..., cert_path=..., key_path=...))
242262

243263
# OIDC (proposed): one token from your existing IdP
244264
client = SandboxClient(endpoint=..., auth=OidcAuth(token=os.environ["OIDC_TOKEN"]))
245265
```
246266

247-
**Why this is required, not nice-to-have:** mTLS secrets live in the
248-
gateway's namespace. Every SDK consumer in a different namespace must
249-
manually copy the Secret and re-copy on every cert rotation. In a
250-
multi-tenant platform, that's N tenant namespaces each needing a
251-
copy. OIDC eliminates this entirely: the SDK sends a JWT, the gateway
252-
validates against the IdP's public keys, no secrets to copy.
267+
**Why this is required, not nice-to-have:** mTLS requires distributing
268+
client certificates to every SDK consumer. Each consumer needs the CA
269+
cert, client cert, and client key, and must re-distribute on every
270+
rotation. In multi-tenant or multi-host deployments, that's N
271+
consumers each needing a copy. OIDC eliminates this: the SDK sends a
272+
JWT, the gateway validates against the IdP's public keys, no
273+
certificates to distribute.
253274

254275
## Implementation plan
255276

@@ -268,7 +289,7 @@ proves everything works. Phase 5 is independent.
268289
- Tests
269290

270291
**Enables:** Remote-mode workloads (git clone inside sandbox, no file
271-
transfer needed). OIDC auth for cross-namespace K8s. Credential
292+
transfer needed). OIDC auth for any gateway deployment. Credential
272293
separation via provider attach.
273294

274295
**Related PRs:** #1404 (auth foundation, merged), #1547 (Python SDK

0 commit comments

Comments
 (0)