Skip to content

feat(sandbox): index provider env by type and auto-configure Claude Code#311

Open
drew wants to merge 2 commits intomainfrom
feat/provider-env-by-type-claude-autoconfig
Open

feat(sandbox): index provider env by type and auto-configure Claude Code#311
drew wants to merge 2 commits intomainfrom
feat/provider-env-by-type-claude-autoconfig

Conversation

@drew
Copy link
Collaborator

@drew drew commented Mar 15, 2026

Summary

  • Restructure GetSandboxProviderEnvironmentResponse to index credential env vars by provider type (map<string, ProviderEnvironmentEntry>) instead of a flat map<string, string>
  • When the anthropic provider type is present, the sandbox supervisor writes ~/.claude.json with {"hasCompletedOnboarding": true} before spawning the entrypoint
  • This eliminates the manual openshell sandbox upload .claude.json step — --provider anthropic now just works with Claude Code

Motivation

Using Claude Code inside an OpenShell sandbox previously required manually creating and uploading a .claude.json config file. With this change, if a user has ANTHROPIC_API_KEY set and passes --provider anthropic to a sandbox, Claude Code starts without interactive onboarding.

Changes

Proto (proto/openshell.proto)

  • New ProviderEnvironmentEntry message containing map<string, string> environment
  • GetSandboxProviderEnvironmentResponse.environment replaced with map<string, ProviderEnvironmentEntry> providers keyed by provider type
  • Breaking proto change (internal gRPC, not a public API)

Server (crates/openshell-server/src/grpc.rs)

  • resolve_provider_environment now returns ProviderEnvByType — a HashMap<String, HashMap<String, String>> keyed by provider type
  • Multiple providers of the same type merge their credentials under one entry (first value wins on duplicates)
  • Handler converts the indexed structure to the proto response

Sandbox client (crates/openshell-sandbox/src/grpc_client.rs)

  • New ProviderEnvironment struct with by_type: HashMap<String, HashMap<String, String>>
  • flatten() — merges all type entries into a single env map for child process injection
  • has_provider_type(&str) — checks if a specific provider type is present
  • provider_types() — lists all attached provider types

Sandbox supervisor (crates/openshell-sandbox/src/lib.rs)

  • Consumes the indexed response, uses has_provider_type("anthropic") to decide config writing
  • New write_provider_configs() function writes ~/.claude.json to the sandbox user's home directory
  • Resolves home directory from /etc/passwd at runtime (works with standard and BYOC images)
  • Non-fatal: logs a warning and continues if config writing fails

Tests

  • 5 existing resolve_provider_environment tests updated for the new indexed return type
  • 1 new test: resolve_provider_env_same_type_merges — verifies two providers of the same type merge correctly
  • 8 integration test mock servers unaffected (they return default() which is an empty providers map)

Testing

  • mise run pre-commit passes (lint, format, all 698 tests green)
  • E2E: openshell sandbox create --provider anthropic -- claude -p "hello" should work without manual config upload

Restructure GetSandboxProviderEnvironmentResponse to index credential
env vars by provider type instead of a flat map. This lets the sandbox
supervisor know which provider types are attached and act on them.

When the anthropic provider type is present, the supervisor writes
~/.claude.json with hasCompletedOnboarding: true before spawning the
entrypoint, eliminating the need to manually create and upload Claude
Code config files.
@drew drew self-assigned this Mar 15, 2026
@drew drew force-pushed the feat/provider-env-by-type-claude-autoconfig branch from 0a0886e to c09fd4f Compare March 16, 2026 13:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant