feat: expose read-only config snapshot via Shell.config#36
Merged
mkmeral merged 2 commits intoJun 19, 2026
Merged
Conversation
Add a read-only configuration snapshot to a constructed Shell across all three surfaces (Rust core, Python, Node), so embedders can introspect a shell after construction without having held onto the builder/config. This enables using Strands Shell as a sandbox in a larger framework: you can build tool descriptions, surface the curl allowlist, and report the active resource caps from a shell object you were handed. Core (src/shell.rs): - New view types ShellConfig, BindInfo, CredInfo, LimitsInfo (all #[non_exhaustive]); captured at build() time and returned by a new Shell::config() accessor. with_kernel() reports a default snapshot. - Re-exported from the crate root. Python (src/python.rs + python/strands_shell/__init__.py): - Native config carriers plus a frozen public dataclass surface (ShellConfig/ConfigBind/ConfigCred/ConfigLimits) behind a Shell.config property. Node (src/js.rs + index.js + index.d.ts): - napi object types plus a deep-frozen snapshot returned by an async shell.config(); full TypeScript declarations. Security: secret values are never exposed. A credential reports only its URL pattern, kind, and source (a literal was supplied, or the name of the env var it reads from) -- never the token itself. Tests: Rust (tests/config.rs), Python (tests/python/test_config.py), Node (tests/js/test_config.mjs), and TS type coverage (tests/ts/api.types.ts). All exercise the no-secret-leak guarantee. README documents the feature. cargo xtask check passes (fmt, clippy, test, doc + Python/Node bindings).
zastrowm
approved these changes
Jun 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a read-only configuration snapshot to a constructed
Shellacross all three surfaces (Rust core, Python, Node), so an embedder can introspect a shell after construction without having held onto the builder or the config object it was built from.Motivation
Today both bindings build a
Shellfrom a fluent builder / config object and then throw the configuration away. The resulting object only exposesrun,set_env/get_env, and the VFS file ops. If you want to embed Strands Shell as a sandbox in a larger framework, you cannot let users hand you aShelland then build tool descriptions, surface the curl allowlist, or report the active resource caps from it. The Rust core has aShell::limits()accessor, but it is not surfaced to the bindings and only covers resource caps (not binds/urls/creds).This PR fixes that with a single read-only
configaccessor on each surface.What's exposed
The snapshot reports: binds (source/destination/mode/readonly), credentials, the network allowlist, env, umask, timeout, and resource limits.
Security: secrets are never exposed
Strands Shell's whole pitch is that the agent never sees secrets, so the snapshot never carries resolved credential values. Each credential reports its URL pattern, kind, methods/param, and source — either
from_literal = true(a literal token was supplied) orenv_var = "NAME"(the variable it is read from) — but never the token itself. The no-leak guarantee is asserted in every test suite (Rust/Python/Node), including the env-var-backed path.API
Rust
Python (frozen dataclasses)
Node (deep-frozen object)
Changes
src/shell.rs: new#[non_exhaustive]view typesShellConfig,BindInfo,CredInfo,LimitsInfo; snapshot captured atbuild()time; newShell::config()accessor;with_kernel()reports a default snapshot. Re-exported from the crate root (src/lib.rs).src/vfs_config.rs:BindMode/CredKindgainDebug/Copy/Eq+ anas_str()helper.src/python.rs+python/strands_shell/__init__.py: native carriers + a frozen public dataclass surface (ShellConfig/ConfigBind/ConfigCred/ConfigLimits) behind aShell.configproperty.src/js.rs+index.js+index.d.ts: napi object types + a deep-frozen snapshot returned by an asyncshell.config(), with full TS declarations.tests/config.rs,tests/python/test_config.py,tests/js/test_config.mjs, and TS type coverage intests/ts/api.types.ts.Verification
cargo xtask checkpasses end to end —cargo fmt --check, clippy,cargo test --workspace --all-targets,cargo doc(with-D warnings), plus the Python (maturin develop+ pytest) and Node (npm run build+tsc+npm test) binding gates. The one new clippy nit introduced by makingCredKind: Copy(aclone_on_copyinresolve_creds) is fixed in this PR; remaining clippy warnings are pre-existing and unrelated.New tests: 7 Rust, 9 Python, 8 Node, plus TS type checks. Full suites stay green (no regressions).
Notes / open question
The snapshot is read-only (frozen on every surface), matching the issue's "read only is fine." I deliberately withhold raw credential token values for the security reason above — if you'd prefer the literal token values exposed too, that's a one-field change, but I'd lean against it.
cc @mkmeral — addresses the StrandsShell config introspection request. Marked as draft pending your review of the API shape (especially the credential-source-vs-value decision).