docs(rfc): SDK design principles and consumption entrypoints#1590
docs(rfc): SDK design principles and consumption entrypoints#1590zanetworker wants to merge 2 commits into
Conversation
Add RFC 0006 proposing official Python and TypeScript SDKs for programmatic sandbox consumption by agent platforms and frameworks. The RFC covers: - Three sandbox modes and which the SDK serves (Mode 2 and 3) - Extending the Python SDK with OIDC auth, provider management, streaming watch, and file transfer - Streaming UploadFile/DownloadFile gRPC RPCs for the gateway - A new TypeScript SDK for OpenClaw and Node.js frameworks - Five implementation phases with dependency analysis - Integration examples for Anthropic Managed Agents and OpenAI Agents SDK Includes architecture diagrams for the three modes, file transfer sequence flow, phase dependencies, and Anthropic worker end-to-end. Signed-off-by: Adel Zaalouk <azaalouk@redhat.com>
| frameworks. Add streaming UploadFile/DownloadFile gRPC RPCs to the | ||
| gateway so SDK consumers can move files in and out of sandboxes | ||
| without shelling out to the CLI. Support OIDC authentication in both | ||
| SDKs so cross-namespace K8s deployments work without copying mTLS |
There was a problem hiding this comment.
can you clarify what is meant by cross namespace deployments?
There was a problem hiding this comment.
Good call. "Cross-namespace" is K8s jargon that does not belong here. What I meant: the current Python SDK only supports mTLS, which requires distributing TLS client certificates to every consumer. In a K8s deployment that means copying Secrets across namespaces, but the same friction applies outside K8s — any consumer on a different machine needs those certs.
OIDC removes that distribution problem regardless of deployment model. I will rewrite this section to frame it as "SDK consumers need bearer-token auth so they can connect to any OIDC-enabled gateway without distributing client certificates."
|
|
||
| | Method | RPC | Why | | ||
| |--------|-----|-----| | ||
| | OIDC auth | gRPC metadata interceptor | mTLS-only locks SDK to single namespace. Every K8s production deployment needs cross-namespace auth. | |
There was a problem hiding this comment.
I don’t understand what oidc has to do with k8s, agree the sdk needs to work with a server that is oidc auth
There was a problem hiding this comment.
Agreed — OIDC has nothing to do with K8s specifically. The SDK needs to work with any gateway that has OIDC auth enabled, whether that is on K8s, bare metal, or a managed service. I conflated "the most common deployment where this matters" with "the reason it matters." Will decouple the two in the next revision.
|
Positioning relative to RFC 0005 (#1617) and the Python SDK OIDC PR (#1621) Three SDK efforts are in flight under #1044. Here is how they relate:
RFC 0005 and RFC 0006 are complementary, not competing. RFC 0005 delivers the shared Rust core and TypeScript binding — the "how" for the TS half. This RFC frames the "why" and "what" across both languages: which consumption patterns platforms need, what RPC gaps block adoption (file transfer), and how the SDK surface maps to real platform integrations. Concretely, this RFC covers areas that RFC 0005 explicitly defers or does not address:
The intended reading order: this RFC for the overall SDK strategy and surface area, RFC 0005 for the shared core architecture and TS binding implementation. Will update the RFC text to reference RFC 0005 directly and to decouple OIDC from K8s framing per @derekwaynecarr feedback. |
| **Mode 1: Sandbox the entire agent.** The agent process runs inside | ||
| the sandbox. Interface: CLI. No SDK needed. | ||
|
|
||
| **Mode 2: Platform-managed sandbox.** The platform (Anthropic, OpenAI) | ||
| owns the agent loop. A separate worker on your infrastructure embeds | ||
| the SDK and creates sandboxes. Brain and worker are physically | ||
| separate systems. Mode 2 is a spectrum: |
There was a problem hiding this comment.
I've heard this commonly described as: Agent in a Sandbox (mode 1) and Sandbox as a Tool (mode 2).
Reference: https://www.langchain.com/blog/the-two-patterns-by-which-agents-connect-sandboxes.
OpenShell has always intended to support both. If that analogy is similar to mode 1 and 2, I would suggest framing this RFC around those two terms. This is how I think we should document usage as well. "platform managed sandbox" seems ambiguous to me because "platform" in this case refers more concretely to "brain" and isn't necessarily specific to anthropic or openai, it could just as well be some agentic loop running on my laptop.
There was a problem hiding this comment.
So here is that blind-spot from my perspective.
Today, we have agentic APIs like OpenAI's responses API which exposes "containers" or the containers API, that API is usually another abstractions, there are now open implementations of those APIs. For example see: ogx-ai/ogx#5892
An SDK usually has laxer boundries not APIs that we need to "conform" with or implement rather, code interfaces, where we can plug into via libraries. See API implementation vs. Framework invocation .
It really is "who owns the implementation", in mode 2, its the platform provider/API provider, in mode 3, its the developer, or the framework abstraction. Does that make sense?
That said, I think we can simplify. Basically, we could say, we don't care "who" owns the implementation or what "manages" it, from our end we just need to enable "sandbox as a tool" and it should work with both. The only tradeoff is that we lose visibility into invocations that happen via mode 2 from an integration standpoint.
Wdyt?
|
|
||
| ### Three sandbox modes | ||
|
|
||
| The SDK serves Mode 2 and Mode 3. Mode 1 stays CLI-driven. |
There was a problem hiding this comment.
nit: I think we still want to programmatically launch agents in a sandbox from the SDK. CLI and SDK should generally have API parity outside of things like interactive shell access. For example, I think we also want the policy prover in our SDK.
| - **Provider CRUD in the SDK.** Providers are created by the platform | ||
| engineer via CLI. SDK consumers attach existing providers, not | ||
| create new ones. |
There was a problem hiding this comment.
Any reason not to include this? I would expect to have api parity between the CLI and SDK.
There was a problem hiding this comment.
Yeah, I added that as an open question (number 4):
Provider CRUD in SDK. This RFC scopes the SDK to attach/detach (bind existing providers). Should full provider CRUD (create/update/delete) be in scope for platforms that want fully programmatic provider lifecycle?
This is mostly about personas and concerns decoupling. I.e., do we want developers managing providers, or do we want to keep that gated (e.g., with admin OIDC role) for those permissions, especially in production setups where an instance is shared?
| **Mode 3: Framework sandbox extension.** The developer's process owns | ||
| the agent loop. Harness + SDK live in one process. Logical separation. | ||
| Examples: OpenAI Agents SDK, OpenClaw, LangChain. |
There was a problem hiding this comment.
I'm not understanding how this mode is unique (I think it's just an instantiation of Mode 2, Sandbox as a Tool).
When I read examples like https://developers.openai.com/api/docs/guides/agents/sandboxes#sandbox-providers (which this RFC references as mode 3) I think all we need to support here is Agent as a Tool. This is kind of similar to https://github.com/langchain-ai/openshell-deepagent/blob/main/src/backend.py#L36 where OpenShell's python SDK implements LangChain's BaseSandbox.
Can you elaborate with more concrete examples?
There was a problem hiding this comment.
I added some elaboration here: #1590 (comment)
| Areas this RFC covers that RFC 0005 explicitly defers: | ||
|
|
||
| - File transfer RPCs (UploadFile/DownloadFile) | ||
| - Python SDK surface expansion (provider, watch, policy, services) | ||
| - Platform consumption patterns (Anthropic, OpenAI, OpenClaw, CI/CD) | ||
| - Python-on-shared-core migration path |
There was a problem hiding this comment.
This RFC seems to also detail some of the "how" (see implementation plan). I think we should try and close both RFCs at the same time since they inform each other.
My recommendation is we build a rust core (#1617) so we're not re-implementing common workflows across all languages for features such as OIDC, file transfer, image building, etc. SDKs are thin wrappers over the rust core.
This RFC can serve as
- guidance for how the SDK should be used, eg Agents in a Sandbox and Sandbox as a Tool.
- guidance on what goes into the SDK vs CLI vs gRPC service routes.
| 4. **Provider CRUD in SDK.** This RFC scopes the SDK to attach/detach | ||
| (bind existing providers). Should full provider CRUD | ||
| (create/update/delete) be in scope for platforms that want fully | ||
| programmatic provider lifecycle? |
There was a problem hiding this comment.
yes, i think we want to strive for api parity as a principle.
| **TypeScript SDK maintenance.** A second SDK doubles the maintenance | ||
| surface. Mitigation: both SDKs are thin wrappers around generated | ||
| proto stubs. The Python SDK is ~600 lines. The TypeScript SDK would | ||
| be similar. The proto files are the source of truth; SDK updates are | ||
| mechanical when protos change. |
There was a problem hiding this comment.
Yes, I created this RFC before 1617, will clear that out.
| | Anthropic worker | Create sandboxes, download skills, run tool calls, retrieve artifacts | No OIDC auth, no file transfer RPC | | ||
| | OpenAI Agents SDK adapter | Implement SandboxClient: materialize Manifest, exec, snapshot | No file transfer RPC (session.write() for LocalDir has no clean implementation) | | ||
| | OpenClaw plugin | Create sandboxes, sync workspace, exec commands | No TypeScript SDK (plugins are TS-only), currently shells out to CLI 5+ times per command | | ||
| | Multi-tenant platform | Per-tenant sandboxes with policies and credentials | No OIDC auth, no provider attach/detach in SDK | |
There was a problem hiding this comment.
OIDC auth in OpenShell's current form != multi-tenancy right? For example, if you and I both authenticate against a gateway and create sandboxes, we can see each other's work.
There was a problem hiding this comment.
Agree, will clarify this bit. That said, probably worth-it exploring multi-tenancy in a separate RFC?
| - "Issue #1044 (SDK roadmap)" | ||
| --- | ||
|
|
||
| # RFC 0006 - SDK Consumption Entrypoints and File Transfer |
There was a problem hiding this comment.
nit: sdk design principles and streaming file transfers seem like two distinct things. is there a reason these are linked together? can we decouple the efforts?
There was a problem hiding this comment.
I can decouple the title, file transfer is a strong dependency, happy to create a separate issue for that if it makes sense. I was thinking of that RFC as the spec describing where we want to go, and what dependencies we have to get there, and file-transfer was one.
| | `expose_service()` / service CRUD | ExposeService, GetService, ListServices, DeleteService | Sandbox-hosted HTTP services | | ||
| | `get_logs()` | GetSandboxLogs | One-shot log retrieval for debugging | | ||
|
|
||
| ### 2. Add streaming file transfer RPCs to the gateway |
There was a problem hiding this comment.
I'm supportive of this feature, but I think we'll want to do some more design work around the feature. Streaming file uploads can be hard!
There was a problem hiding this comment.
I agree!
Would you propose a separate RFC for this or a separate tracker issue on the design?
- Move provider CRUD from non-goals to SDK scope (API parity) - Clarify OIDC gives identity, not tenant isolation; per-principal sandbox scoping is separate gateway work - Reference NVIDIA#1617 (shared Rust core) in Risks section - Move TS SDK location and API parity to resolved questions - Add NVIDIA#1617 relationship as open question Signed-off-by: Adel Zaalouk <azaalouk@redhat.com>
b57ca6a to
fe6e86d
Compare
Related: #1044
Summary
RFC 0006 proposing official Python and TypeScript SDKs that make OpenShell consumable as programmable infrastructure for agent platforms and frameworks, plus streaming file transfer RPCs.
Why: Agent platforms (Anthropic Managed Agents, OpenAI Agents SDK, OpenClaw, Cloudflare) all need a secure execution layer. OpenShell has the enforcement (Landlock, seccomp, L4/L7 policy, credential injection, OCSF audit) and the API (54 gRPC RPCs). But only 8 RPCs are wrapped in the Python SDK, there's no TypeScript SDK, no file transfer RPC, and no OIDC auth in the SDK. Every integration must shell out to the CLI binary or build a custom gRPC client.
What this RFC proposes:
Three sandbox modes covered:
Five implementation phases with a dependency analysis showing Phase 1 (OIDC + providers) and Phase 2 (file transfer) can run in parallel.
Related Issues
python/openshell/sandbox.pyChanges
rfc/0006-sdk-and-file-transfer/README.md- Full RFC documentrfc/0006-sdk-and-file-transfer/sdk-modes.png- Three sandbox modes architecture diagramrfc/0006-sdk-and-file-transfer/sdk-phase-deps.{mmd,png}- Phase dependency diagramrfc/0006-sdk-and-file-transfer/sdk-file-transfer.png- UploadFile/DownloadFile sequence diagramrfc/0006-sdk-and-file-transfer/sdk-anthropic-worker.png- Anthropic Mode 2 end-to-end sequenceTesting
mise run pre-commitpassesChecklist
rfc/0000-templatestructure