SIGN IN SIGN UP

fix(deepagents-vfs): enforce S3 prefix as an isolation boundary (#428)

## Summary
- `s3_prefix` only scoped `InitialSync` and the watchers' listing.
`read`, `write`, `edit`, `upload_files`, and `download_files` passed
straight through to `S3Backend` with no check at all, so any caller of
those operations could reach any key in the bucket regardless of the
configured prefix. On a bucket shared across tenants/scopes, `s3_prefix`
isolation was cosmetic, not real.
- `S3Backend` now owns and enforces its own `prefix` inside `_key()` —
the single place every key-level operation funnels through — and raises
`AdapterError(E2009_PATH_OUTSIDE_PREFIX)` for keys outside it (mapped to
the standardized `"permission_denied"` `FileOperationError` literal).
Batch operations (`upload_files`/`download_files`) already caught
`AdapterError` per item, so they get correct partial-success behavior
with no extra code.
- Also changes the default from whole-bucket access to a dedicated
`DEFAULT_PREFIX = "mongodb_vfs/"`. A blank default silently exposes an
entire shared bucket the moment nobody sets `s3_prefix` explicitly — the
new default is safe out of the box, and `s3_prefix=""` opts back into
whole-bucket access for callers that want it.

## Test plan
- [x] Added `TestPrefixScopeEnforcement` in `test_s3_backend.py`:
read/write/edit raise `E2009` for out-of-prefix keys,
`upload_files`/`download_files` report `permission_denied` per-path, the
real default (`DEFAULT_PREFIX`) is enforced when no prefix is passed,
and `prefix=""` is a valid opt-out.
- [x] Updated existing unit/integration/e2e tests that construct
`S3Backend`/`MongoFilesystemBackend` directly: generic CRUD/mechanic
tests opt out with `prefix=""` (they're testing unrelated behavior),
while `test_e2e.py`'s golden-path fixture was updated to use keys under
`DEFAULT_PREFIX` instead, so it still exercises the real default
end-to-end rather than bypassing it.
- [x] `uv run pytest tests/unit_tests tests/integration_tests
tests/e2e_tests/test_e2e.py` — all pass (one pre-existing, unrelated
`test_twine_check` failure on `main`, tracked separately in #427).
- [x] `just lint` / `just typing` — clean.

Signed-off-by: Casey Clements <casey.clements@mongodb.com>
C
Casey Clements committed
d6bd32b746e36fc16f331fbb3b32e10201165741
Parent: 8adab04
Committed by GitHub <noreply@github.com> on 8/19/2026, 12:14:18 AM