Skip to content

docs(rfc): SDK design principles and consumption entrypoints#1590

Open
zanetworker wants to merge 3 commits into
NVIDIA:mainfrom
zanetworker:docs/sdk-file-transfer-rfc
Open

docs(rfc): SDK design principles and consumption entrypoints#1590
zanetworker wants to merge 3 commits into
NVIDIA:mainfrom
zanetworker:docs/sdk-file-transfer-rfc

Conversation

@zanetworker
Copy link
Copy Markdown
Contributor

@zanetworker zanetworker commented May 27, 2026

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:

  • Extend the Python SDK with OIDC auth, provider attach/detach, streaming watch, and file transfer
  • Add streaming UploadFile/DownloadFile gRPC RPCs to the gateway (routed via existing RelayStream infrastructure)
  • Ship an official TypeScript SDK (for OpenClaw and Node.js frameworks)
  • OIDC authentication in both SDKs for cross-namespace K8s deployments

Three sandbox modes covered:

  • Mode 1 (entire agent sandboxed): CLI-driven, no SDK needed
  • Mode 2 (platform-managed): SDK in your worker, brain on the platform (Anthropic, OpenAI Responses API)
  • Mode 3 (framework extension): SDK embedded in the developer's process (OpenAI Agents SDK, OpenClaw)

Five implementation phases with a dependency analysis showing Phase 1 (OIDC + providers) and Phase 2 (file transfer) can run in parallel.

Related Issues

Changes

  • rfc/0006-sdk-and-file-transfer/README.md - Full RFC document
  • rfc/0006-sdk-and-file-transfer/sdk-modes.png - Three sandbox modes architecture diagram
  • rfc/0006-sdk-and-file-transfer/sdk-phase-deps.{mmd,png} - Phase dependency diagram
  • rfc/0006-sdk-and-file-transfer/sdk-file-transfer.png - UploadFile/DownloadFile sequence diagram
  • rfc/0006-sdk-and-file-transfer/sdk-anthropic-worker.png - Anthropic Mode 2 end-to-end sequence

Testing

  • mise run pre-commit passes
  • Markdown lint clean
  • All diagrams render correctly

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • RFC follows the rfc/0000-template structure
  • RFC number (0006) does not conflict with existing or in-flight RFCs

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>
@copy-pr-bot
Copy link
Copy Markdown

copy-pr-bot Bot commented May 27, 2026

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

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
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you clarify what is meant by cross namespace deployments?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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. |
Copy link
Copy Markdown
Collaborator

@derekwaynecarr derekwaynecarr May 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t understand what oidc has to do with k8s, agree the sdk needs to work with a server that is oidc auth

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@zanetworker
Copy link
Copy Markdown
Contributor Author

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:

PR Scope State
#1617 (RFC 0005, @maxdubrinsky) Extract openshell-sdk Rust crate, ship @openshell/sdk TypeScript binding via napi-rs, refactor CLI onto SDK RFC + working prototype
#1621 (@mrunalp) Add OIDC bearer auth to the existing pure-Python SDK Code, ready for review
#1590 (this RFC 0006) Broader SDK roadmap: consumption patterns (Mode 1/2/3), file transfer RPCs, Python SDK surface expansion, platform integration examples (Anthropic, OpenAI, OpenClaw) RFC, no code

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:

  • File transfer RPCs (UploadFile/DownloadFile): gateway proto changes, streaming design, routing via ConnectSupervisor/RelayStream
  • Python SDK surface expansion: provider attach/detach, watch, policy, services (wrapping existing RPCs, not rebuilding transport)
  • Platform consumption patterns: Anthropic Managed Agents (Mode 2), OpenAI Agents SDK (Mode 3), OpenClaw, CI/CD
  • Python-on-shared-core migration path: RFC 0005 defers this as a non-goal; this RFC scopes it as a future phase

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.

Comment on lines +96 to +102
**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:
Copy link
Copy Markdown
Collaborator

@drew drew Jun 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

@zanetworker zanetworker Jun 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

In mode 2 and 3 the same OpenShell SDKs and APIs are getting used, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes If we consolidate on how the SDKs/APIs are getting used (the receiver) its boils down to two modes (so 2,3 the same API/SDKs are getting used). If we want to consider the invoker, and the how from a persona/ownership standpoint. The separation between Mode 2, 3 was intended to express that

platform controls how the SDKs/APIs of OpenShell (the developer just consumes an API abstractions like the responses API/containers API). the developer/Framework having to integrate or call the Openshell themselves.

That idea was that knowing how or where those get invoked is just a mapping of where we would want to go to make a change relating to openshell compatability. For example, contribute to the implementation of those APIs or should the contribution happen at the framework level, or no contribution at all assuming no abstractions in addition to the ones we add with the SDK.

I will reduce to two modes but mention in the text the consumption entrpoint to simplify.


### Three sandbox modes

The SDK serves Mode 2 and Mode 3. Mode 1 stays CLI-driven.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +120 to +122
- **Provider CRUD in the SDK.** Providers are created by the platform
engineer via CLI. SDK consumers attach existing providers, not
create new ones.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to include this? I would expect to have api parity between the CLI and SDK.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Collaborator

@drew drew Jun 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My sense is that it should be possible to lock down provider access, but since many providers are tied to individuals (eg github) we probably should assume these are used across many personas.

Similar philosophy to kube. The entire API surface area is available in the various SDK/CLI interfaces, but access is locked down based on each deployment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense.

Comment thread rfc/0006-sdk-and-file-transfer/README.md Outdated
Comment thread rfc/0006-sdk-and-file-transfer/README.md
Comment thread rfc/0006-sdk-and-file-transfer/README.md Outdated
Comment thread rfc/0006-sdk-and-file-transfer/README.md Outdated
| 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 |
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, will clarify this bit. That said, probably worth-it exploring multi-tenancy in a separate RFC?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 this seems important to start thinking about. I added a roadmap item for it here, #1722.

- "Issue #1044 (SDK roadmap)"
---

# RFC 0006 - SDK Consumption Entrypoints and File Transfer
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator

@drew drew Jun 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. I think maybe this RFC can identify the need/motivation for streaming file transfer but we can defer the design of it separately since it's such a big component that could stand on it's own.

Comment thread rfc/0006-sdk-and-file-transfer/README.md Outdated
- 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>
@zanetworker zanetworker force-pushed the docs/sdk-file-transfer-rfc branch from b57ca6a to fe6e86d Compare June 2, 2026 11:29
@zanetworker zanetworker changed the title docs(rfc): propose SDK consumption entrypoints and file transfer docs(rfc): SDK design principles and consumption entrypoints Jun 2, 2026
@pimlock pimlock added the rfc label Jun 5, 2026
- Consolidate Mode 2 and Mode 3 into "Sandbox as a Tool" pattern,
  aligned with LangChain framing (Agent in Sandbox vs Sandbox as Tool)
- Show consumption entrypoints (platform, framework, direct) as
  variants of the same pattern, not separate modes
- Defer file transfer proto design to NVIDIA#1707; keep motivation and
  need in this RFC
- Update diagram to two-pattern layout
- Remove resolved questions section (decisions already in proposal)
- Add relationship to RFC 0005 (NVIDIA#1617) and link new related PRs

Signed-off-by: Adel Zaalouk <azaalouk@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants