Skip to content

feat: Further syft-restrict improvements and red-team hardening#9461

Merged
koenvanderveen merged 19 commits into
devfrom
pjwerneck/fix-restrict-loose-ends
Jul 23, 2026
Merged

feat: Further syft-restrict improvements and red-team hardening#9461
koenvanderveen merged 19 commits into
devfrom
pjwerneck/fix-restrict-loose-ends

Conversation

@pjwerneck

Copy link
Copy Markdown
Collaborator

Summary

Finishes the loose ends from #9436 and closes the verifier gaps found across three independent red-team passes (kimi-k3, Grok 4.5, Opus 4.8).

Changes

Security

  • Import resolution bug: import jax.numpy (no as) bound the root jax to the full path jax.numpy, so jax.numpy.save mis-resolved to jax.numpy.numpy.save and slipped the disallow_functions floor while runtime hit the real function. Now binds the package root correctly. (astutil.py)
  • Star imports (from x import *) banned anywhere — they can silently shadow a trusted name and are unreviewable. (verifier.py)
  • Safe-local verdict now cleared on tuple-unpack and for-loop rebinds (b = self.safe; b, _ = evil, b; b(x) no longer trusts the stale verdict). (verifier.py)
  • Boundary-straddling statements (a call opened on a public line, args in the private region) are now verified as private (default-deny) instead of skipped. (astutil.py, verifier.py)
  • Block markers must be on their own line — code sharing a -start/-end marker line was escaping verification; now a MarkerError. (markers.py)

API / UX:

  • run() is markers-only (no obfuscate=/hide=); explicit line ranges moved to internal _run(). (runner.py)
  • Two optional strictness flags: allow_local_assignments, allow_base_class_attributes (both default to current behavior). (policy.py, verifier.py)
  • post_init restored to the allowed hooks.

Docs / examples:

  • README example switched to default-deny (explicit allow_functions); widened the recommended disallow_functions floor; clarified public-region/import handling in verify.md/blacklist.md.
  • Examples renamed: gemma_inference.py is now the canonical markers version; the explicit-ranges variant is gemma_inference_ranges.py (+ matching generate*.py).

Testing

  • New test_policy_flags.py plus regressions in test_bypasses, test_markers, test_disallowed, test_whitelist, test_run.

Asana task

https://app.asana.com/1/1185126988600652/project/1216249688888494/task/1216630823225716?focus=true

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR further hardens syft-restrict’s verifier/marker workflow against bypasses found in red-team passes, tightening import/call resolution and region enforcement while updating the public API, docs, examples, and tests to match the “markers-first” UX.

Changes:

  • Close multiple verifier gaps (multi-segment import binding, boundary-straddling statements treated as private, star-imports banned, safer local-alias handling and new strictness flags).
  • Make run() markers-only and introduce internal _run() for explicit-range callers; strengthen marker parsing (block markers must be on their own line).
  • Expand/refresh tests, docs, and examples to reflect default-deny posture and updated behaviors.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/syft-restrict/src/syft_restrict/astutil.py Fix import-binding semantics and add overlap detection for boundary-straddling nodes.
packages/syft-restrict/src/syft_restrict/verifier.py Add boundary-straddle enforcement, star-import ban, safe-local tracking changes, and new policy-flag wiring.
packages/syft-restrict/src/syft_restrict/policy.py Add optional strictness flags and allow __post_init__ as an allowed hook.
packages/syft-restrict/src/syft_restrict/runner.py Make run() markers-only; add internal _run() for explicit numeric ranges; plumb policy flags.
packages/syft-restrict/src/syft_restrict/markers.py Tighten marker scanning: block markers must be on a line by themselves; clearer MarkerError messaging.
packages/syft-restrict/tests/verify/helpers.py Update make_policy() helper to expose the two new strictness flags.
packages/syft-restrict/tests/verify/test_policy_flags.py New tests pinning behavior when strictness flags are flipped off.
packages/syft-restrict/tests/verify/test_bypasses.py Add regressions for tuple-unpack/for-loop rebind clearing, boundary straddles, and multi-segment import floors.
packages/syft-restrict/tests/verify/test_disallowed.py Add star-import rejection tests; adjust disallowed dunder list consistent with allowed __post_init__.
packages/syft-restrict/tests/verify/test_whitelist.py Add tests for comprehension scoping and fully-private multiline calls; expand allowed dunder hook test.
packages/syft-restrict/tests/test_run.py Update tests to call _run() for explicit-range cases; enforce markers-only behavior for run().
packages/syft-restrict/tests/test_markers.py Add tests ensuring code-sharing block markers raise MarkerError.
packages/syft-restrict/tests/obfuscate/test_obfuscate.py Switch fixture runs to _run() for explicit-range flows.
packages/syft-restrict/README.md Update guidance to default-deny allowlists, markers-only run(), and document optional strictness flags.
packages/syft-restrict/docs/verify.md Update marker semantics (markers required) and clarify public-import vs private-use enforcement; star-import policy.
packages/syft-restrict/docs/blacklist.md Update hook allowlist to include __post_init__.
packages/syft-restrict/examples/generate.py Update example to rely on marker-resolved private region (no hand-counted ranges).
packages/syft-restrict/examples/generate_ranges.py Add explicit-range regeneration example via internal _run().
packages/syft-restrict/examples/generate_marked.py Remove obsolete generator (markers are now the primary run() UX).
packages/syft-restrict/examples/gemma_inference.py Add syft-restrict markers to designate private/hidden regions in the canonical example.
packages/syft-restrict/examples/gemma_inference.obfuscated.py Regenerated obfuscated output reflecting marker-based private ranges.
packages/syft-restrict/examples/gemma_inference.certificate.json Update certificate for new marker-resolved ranges/policy id.
packages/syft-restrict/examples/gemma_inference_ranges.py Remove markers (ranges example is now driven by _run() + hand-counted ranges).
packages/syft-restrict/examples/gemma_inference_ranges.obfuscated.py Regenerated ranges-based obfuscated output.
packages/syft-restrict/examples/gemma_inference_ranges.certificate.json Add certificate for the explicit-ranges example path.
packages/syft-restrict/examples/gemma_inference_marked.certificate.json Remove obsolete certificate for removed marked-example variant.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/syft-restrict/src/syft_restrict/verifier.py Outdated
Comment thread packages/syft-restrict/src/syft_restrict/verifier.py
Comment thread packages/syft-restrict/src/syft_restrict/runner.py
- Ensure run and _run read the source only once.
- Enhance `_Checker` to clear safe locals for `for` loops overlapping private ranges; add test for public loop headers over private bodies.
- Ensure references to ast.TryStar and ast.Match don't crash on Python < 3.11
@pjwerneck
pjwerneck marked this pull request as ready for review July 21, 2026 12:50

@koenvanderveen koenvanderveen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed: security-focused verifier hardening. Fixes are sound and well-tested (import-binding bypass, boundary straddle, star imports, safe-local clearing, dunder-in-call, own-line markers, policy_id includes new flags). Approving.

@koenvanderveen
koenvanderveen merged commit 0b46d50 into dev Jul 23, 2026
20 checks passed
@koenvanderveen
koenvanderveen deleted the pjwerneck/fix-restrict-loose-ends branch July 23, 2026 11:59
@koenvanderveen

Copy link
Copy Markdown
Collaborator

awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants