Add guest-only workspace secrets
Add explicit workspace secrets across the CLI, SDK, and MCP, with create-time secret definitions and per-call secret-to-env mapping for exec, shell open, and service start. Persist only safe secret metadata in workspace records, materialize secret files under /run/pyro-secrets, and redact secret values from exec output, shell reads, service logs, and surfaced errors. Fix the remaining real-guest shell gap by shipping bundled guest init alongside the guest agent and patching both into guest-backed workspace rootfs images before boot. The new init mounts devpts so PTY shells work on Firecracker guests, while reset continues to recreate the sandbox and re-materialize secrets from stored task-local secret material. Validation: uv lock; UV_CACHE_DIR=.uv-cache make check; UV_CACHE_DIR=.uv-cache make dist-check; and a real guest-backed Firecracker smoke covering workspace create with secrets, secret-backed exec, shell, service, reset, and delete.
This commit is contained in:
parent
18b8fd2a7d
commit
fc72fcd3a1
32 changed files with 1980 additions and 181 deletions
|
|
@ -22,7 +22,7 @@ Networking: tun=yes ip_forward=yes
|
|||
|
||||
```bash
|
||||
$ uvx --from pyro-mcp pyro env list
|
||||
Catalog version: 2.8.0
|
||||
Catalog version: 2.9.0
|
||||
debian:12 [installed|not installed] Debian 12 environment with Git preinstalled for common agent workflows.
|
||||
debian:12-base [installed|not installed] Minimal Debian 12 environment for shell and core Unix tooling.
|
||||
debian:12-build [installed|not installed] Debian 12 environment with Git and common build tools preinstalled.
|
||||
|
|
@ -72,12 +72,14 @@ deterministic structured result.
|
|||
$ uvx --from pyro-mcp pyro demo
|
||||
$ uvx --from pyro-mcp pyro workspace create debian:12 --seed-path ./repo
|
||||
$ uvx --from pyro-mcp pyro workspace sync push WORKSPACE_ID ./changes
|
||||
$ uvx --from pyro-mcp pyro workspace create debian:12 --secret API_TOKEN=expected --secret-file PIP_TOKEN=./token.txt
|
||||
$ uvx --from pyro-mcp pyro workspace exec WORKSPACE_ID --secret-env API_TOKEN -- sh -lc 'test "$API_TOKEN" = "expected"'
|
||||
$ uvx --from pyro-mcp pyro workspace diff WORKSPACE_ID
|
||||
$ uvx --from pyro-mcp pyro workspace snapshot create WORKSPACE_ID checkpoint
|
||||
$ uvx --from pyro-mcp pyro workspace reset WORKSPACE_ID --snapshot checkpoint
|
||||
$ uvx --from pyro-mcp pyro workspace export WORKSPACE_ID note.txt --output ./note.txt
|
||||
$ uvx --from pyro-mcp pyro workspace shell open WORKSPACE_ID
|
||||
$ uvx --from pyro-mcp pyro workspace service start WORKSPACE_ID app --ready-file .ready -- sh -lc 'touch .ready && while true; do sleep 60; done'
|
||||
$ uvx --from pyro-mcp pyro workspace shell open WORKSPACE_ID --secret-env API_TOKEN
|
||||
$ uvx --from pyro-mcp pyro workspace service start WORKSPACE_ID app --secret-env API_TOKEN --ready-file .ready -- sh -lc 'touch .ready && while true; do sleep 60; done'
|
||||
$ uvx --from pyro-mcp pyro mcp serve
|
||||
```
|
||||
|
||||
|
|
@ -103,6 +105,9 @@ $ uvx --from pyro-mcp pyro workspace exec WORKSPACE_ID -- cat src/note.txt
|
|||
hello from synced workspace
|
||||
[workspace-exec] workspace_id=... sequence=1 cwd=/workspace execution_mode=guest_vsock exit_code=0 duration_ms=...
|
||||
|
||||
$ uvx --from pyro-mcp pyro workspace exec WORKSPACE_ID --secret-env API_TOKEN -- sh -lc 'test "$API_TOKEN" = "expected"'
|
||||
[workspace-exec] workspace_id=... sequence=2 cwd=/workspace execution_mode=guest_vsock exit_code=0 duration_ms=...
|
||||
|
||||
$ uvx --from pyro-mcp pyro workspace diff WORKSPACE_ID
|
||||
[workspace-diff] workspace_id=... total=... added=... modified=... deleted=... type_changed=... text_patched=... non_text=...
|
||||
--- a/src/note.txt
|
||||
|
|
@ -123,7 +128,7 @@ Reset count: 1
|
|||
$ uvx --from pyro-mcp pyro workspace export WORKSPACE_ID src/note.txt --output ./note.txt
|
||||
[workspace-export] workspace_id=... workspace_path=/workspace/src/note.txt output_path=... artifact_type=file entry_count=... bytes_written=... execution_mode=guest_vsock
|
||||
|
||||
$ uvx --from pyro-mcp pyro workspace shell open WORKSPACE_ID
|
||||
$ uvx --from pyro-mcp pyro workspace shell open WORKSPACE_ID --secret-env API_TOKEN
|
||||
[workspace-shell-open] workspace_id=... shell_id=... state=running cwd=/workspace cols=120 rows=30 execution_mode=guest_vsock
|
||||
|
||||
$ uvx --from pyro-mcp pyro workspace shell write WORKSPACE_ID SHELL_ID --input 'pwd'
|
||||
|
|
@ -133,7 +138,7 @@ $ uvx --from pyro-mcp pyro workspace shell read WORKSPACE_ID SHELL_ID
|
|||
/workspace
|
||||
[workspace-shell-read] workspace_id=... shell_id=... state=running cursor=0 next_cursor=... truncated=False execution_mode=guest_vsock
|
||||
|
||||
$ uvx --from pyro-mcp pyro workspace service start WORKSPACE_ID web --ready-file .web-ready -- sh -lc 'touch .web-ready && while true; do sleep 60; done'
|
||||
$ uvx --from pyro-mcp pyro workspace service start WORKSPACE_ID web --secret-env API_TOKEN --ready-file .web-ready -- sh -lc 'touch .web-ready && while true; do sleep 60; done'
|
||||
[workspace-service-start] workspace_id=... service=web state=running cwd=/workspace ready_type=file execution_mode=guest_vsock
|
||||
|
||||
$ uvx --from pyro-mcp pyro workspace service start WORKSPACE_ID worker --ready-file .worker-ready -- sh -lc 'touch .worker-ready && while true; do sleep 60; done'
|
||||
|
|
@ -170,7 +175,7 @@ $ uvx --from pyro-mcp pyro workspace service stop WORKSPACE_ID worker
|
|||
Use `--seed-path` when the workspace should start from a host directory or a local
|
||||
`.tar` / `.tar.gz` / `.tgz` archive instead of an empty `/workspace`. Use
|
||||
`pyro workspace sync push` when you need to import later host-side changes into a started
|
||||
workspace. Sync is non-atomic in `2.8.0`; if it fails partway through, prefer `pyro workspace reset`
|
||||
workspace. Sync is non-atomic in `2.9.0`; if it fails partway through, prefer `pyro workspace reset`
|
||||
to recover from `baseline` or one named snapshot. Use `pyro workspace diff` to compare the current
|
||||
`/workspace` tree to its immutable create-time baseline, `pyro workspace snapshot *` to create
|
||||
named checkpoints, and `pyro workspace export` to copy one changed file or directory back to the
|
||||
|
|
@ -178,7 +183,10 @@ host. Use `pyro workspace exec` for one-shot commands and `pyro workspace shell
|
|||
need a persistent interactive PTY session in that same workspace. Use `pyro workspace service *`
|
||||
when the workspace needs long-running background processes with typed readiness checks. Internal
|
||||
service state and logs stay outside `/workspace`, so service runtime data does not appear in
|
||||
workspace diff or export results.
|
||||
workspace diff or export results. Use `--secret` and `--secret-file` at workspace creation when
|
||||
the sandbox needs private tokens or config. Persisted secret files are materialized at
|
||||
`/run/pyro-secrets/<name>`, and `--secret-env SECRET_NAME[=ENV_VAR]` maps one secret into one
|
||||
exec, shell, or service call without storing that environment mapping on the workspace itself.
|
||||
|
||||
Example output:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue