Skip to content

Harden catalog, plugin, sync, config and review paths (SR-4a) - #327

Open
jothimani-rajendran wants to merge 15 commits into
mainfrom
sr-4a-chock-hardening
Open

jothimani-rajendran wants to merge 15 commits into
mainfrom
sr-4a-chock-hardening

Conversation

@jothimani-rajendran

@jothimani-rajendran jothimani-rajendran commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

What

Hardening of paths outside the gate runtime, from the internal security review (plan item SR-4a). One commit per finding (or tightly related pair); each has a test that fails before the change and passes after.

Commit Change
plugin build In-place chock plugin build refuses a symlink at, or above, any path it generates, and writes nothing.
catalog source A source spelled as a URL or user@host:path is always remote; local vs remote is decided from the text, not from what exists in the working directory. The published-commit checks no longer depend on the filesystem.
add: pack lookup The fallback <area>/<id> lookup gets the same containment check as a registry entry; a linked pack directory is refused; the copy does not follow links.
add: credentials user:token@ is dropped from a --from URL before it is recorded in chock.lock, printed, or put in an error.
sync Merged agent configs are written through the no-follow writer used for MCP config; a link anywhere on the path refuses the sync.
YAML policies.disabled keeps only string ids; the guidance nesting limit is measured on parser events.
eval export A manifest id that is not a valid policy id exports nothing.
review With a base ref, only the base defines checks (built-ins plus what the base declares); the head's checks section defines nothing and never runs. A check a PR both adds and requires is not required of that PR; require says it is required from the merge on. docs/reviewer-evidence.md states the contract.

The pack-hash framing change was committed and then reverted in this PR (separate item: the hash is also published outside chock.lock).

Notes for review

  • Review behaviour change. A check must be merged to the base before it can run or be required. Existing tests that defined a check in the head now define it on the base; the test that asserted a head-added check runs now asserts it does not.
  • Merged config permissions. The merged vendor config is now written owner-only (the writer masks to owner bits).
  • Vendored runtime. Nothing under src/chock/gate/, gateway/, guardrails/, cli.py or launch.sh is touched, and the rendered runtime is unchanged. No .chock/ file is written and chock sync was not run.

Definition of done

  • ruff check . and ruff format --check . clean
  • changelog.d/ fragment per change; fragment check passes
  • Full pytest -q and CI: see the checks on this PR

Build checks every generated path under the target and stops on a symlink before writing anything. Covers the in-place default.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
…he disk

A catalog source spelled as a URL or scp-style address is always remote. fetch_catalog, require_on_branch and is_local_source no longer test the filesystem for it, so the published-commit check cannot be switched off by a lookalike directory.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
The area/<id> fallback now requires the resolved pack to stay inside the catalog, a linked pack directory is refused, and copytree no longer follows links.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
… source

record_provenance, the success line and pin errors use the source without credentials.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
…rsion 2

Names and contents are framed by length under a domain tag. A version 1 hash still matches a pack with no NUL byte (where it was unambiguous); chock sync rewrites chock.lock as version 2. Marketplace locks keep the old hash for now. The platform-parity golden is recomputed independently.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
install_merged checks the config path for links and writes it with the fd-pinned writer used for MCP config; a link anywhere on the path refuses the sync. Generic and owned-file installers are not changed here.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
…idance

policies.disabled keeps only string ids; the guidance depth guard counts nesting from parser events instead of characters.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
The id is used as a file name under --out; one that is not a policy id is an error.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
check_registry takes built-ins and the base's declared checks; the head's checks section is ignored when a base ref is given. Existing tests that defined a check in the head now define it on the base; the one that asserted a head-added check runs now asserts it does not.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
…f it from the merge on

required_checks drops names the base does not define; require says which are deferred. A check the base defines and the head requires still applies at once. docs/reviewer-evidence.md states the new contract.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
Import order only.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
…kfile_version 2"

This reverts commit 951d2e2. The pack hash also feeds values published outside chock.lock; changing it needs a cross-repo plan and becomes its own item.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
…er requires nor defines

A check the base requires stays required even when undefined, so a base misconfiguration still fails instead of passing with a notice.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
tests/test_review_require.py passed the 300-line review budget; the checks-from-base tests now live in tests/test_review_checks_from_base.py. No test changed.

Signed-off-by: Jothi Mani Rajendran <250249270+jothimani-rajendran@users.noreply.github.com>
@jothimani-rajendran
jothimani-rajendran marked this pull request as ready for review October 25, 2026 14:14

This branch has not been deployed

No deployments
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