Skip to content

config: reject unknown top-level keys in SandboxRuntimeConfigSchema - #517

Open
PranshulSoni wants to merge 1 commit into
anthropics:mainfrom
PranshulSoni:fix/strict-top-level-config-schema
Open

config: reject unknown top-level keys in SandboxRuntimeConfigSchema#517
PranshulSoni wants to merge 1 commit into
anthropics:mainfrom
PranshulSoni:fix/strict-top-level-config-schema

Conversation

@PranshulSoni

Copy link
Copy Markdown

Closes #434

Problem

SandboxRuntimeConfigSchema is the only non-.strict() schema in sandbox-config.ts. A config file with a typo'd key like "denyWriteTypo": ["/Users/me"] loads without any warning, the unknown key is silently stripped, and the command runs — so an operator can believe a filesystem policy is enforced when nothing is.

Solution

Add .strict() to the top-level object, placed before .superRefine() (zod effects don't expose .strict()). This brings the top level in line with the sub-schemas — awsPairs, sigv4, and credentials already reject unknown keys; the credentials one documents the exact reasoning:

Reject unknown keys so a stale credentials.injectHosts (the removed block-level default) fails loudly instead of being silently stripped.

loadConfig already renders every zod issue with its path (config-loader.ts), so a typo now surfaces as a named, actionable error instead of a silent no-op.

Testing

  • 2 new tests in test/config-validation.test.ts: unknown key rejected with the key name present in the issue message, and a valid config with an extra key (allowEverything: true) rejected.
  • Both fail against the unfixed schema and pass with .strict().
  • test/config-validation.test.ts + test/cli-config-loading.test.ts: 122 pass. Full typecheck and lint clean.
  • The repo's full bun test has 144 pre-existing failures in environment-dependent integration tests (missing bwrap/seccomp deps); identical count with and without this change, all outside the config-validation surface.

The top-level schema was the only non-strict one in sandbox-config.ts.
A typo like 'denyWriteTypo' loaded without warning and was silently
stripped, so an operator could believe a policy was enforced when no
restriction existed (issue anthropics#434).

Apply .strict() for parity with the sub-schemas, which already reject
unknown keys for exactly this reason (see the credentials.injectHosts
comment). loadConfig's existing error rendering prints each issue, so
the operator now sees the unrecognized key name.
Copilot AI lite review requested due to automatic review settings September 5, 2026 08:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

Unknown top-level config keys are silently ignored, so a typo'd denyWrite fails open with no warning

2 participants