Skip to content

S8/P2.1: path-scoped filesystem grants (read/write roots) - #116

Merged
howlcipher merged 1 commit into
mainfrom
okabe/s8-path-scoped-filesystem
Oct 6, 2026
Merged

howlcipher merged 1 commit into
mainfrom
okabe/s8-path-scoped-filesystem

Conversation

@howlcipher

Copy link
Copy Markdown
Owner

Summary

Closes the filesystem half of finding S8 / roadmap P2.1: resource-scoped filesystem grants so programs cannot read/write outside declared roots.

  • Grant forms on -allow-caps: filesystem:read=<root>, filesystem:write=<root> (repeatable); coarse filesystem remains the unrestricted alias.
  • Parse/match helpers in internal/capability (ParseGrant, Grants.AllowsRead / AllowsWrite).
  • Fail-closed enforcement in the bytecode VM and AST interpreter before I/O (CAPABILITY_DENIED); path Abs/Clean + filepath.Rel containment; symlink hardening via EvalSymlinks on longest existing ancestor.
  • file:// stores: open/get/keys need read coverage; put/delete need read and write.
  • Journal: docs/journals/2026-10-06_path_scoped_filesystem.md. S8 marked PARTIAL-closed (process/network still OPEN).

Out of scope (hard nos)

  • No process allow-list, network host scoping, environment=VAR, or SPAWN_AGENT attenuation
  • No prod -compile-bc / HFIR flip; Write flagged http_server bytecode and stop #90 stays Partial
  • Generated Go/JS backends remain coarse (howlFrameGrantHas("filesystem"))

Test plan

  • gofmt -l . clean
  • go vet ./...
  • go test ./... (passed locally)
  • New tests: TestParseGrant, TestFilesystemGrantContainment, TestFilesystemScopesVMAndInterpreter, TestFileStoreFilesystemScopes, TestFilesystemScopeReceiptDecision, TestCLIPathScopedFilesystemGrants

Base tip: a5b7ad941ec269943282897a75952de82be81344. Do not merge without review.

Close the filesystem half of S8: -allow-caps accepts
filesystem:read=<root> and filesystem:write=<root> (repeatable),
with coarse filesystem remaining unrestricted. Roots Abs/Clean at
parse; VM and AST interpreter deny out-of-root and .. escapes with
CAPABILITY_DENIED before I/O; EvalSymlinks on longest existing
ancestor. file:// stores need read (and write for put/delete).
Process/network/env scoping and SPAWN attenuation remain open;
gogen/JS stay coarse; no prod -compile-bc/HFIR flip; #90 stays Partial.

Journal: docs/journals/2026-10-06_path_scoped_filesystem.md

Co-authored-by: howlcipher <howlcipher@users.noreply.github.com>

@howlcipher howlcipher left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Dev-lead review (COMMENT only) — Motoko / S8 path-scoped filesystem

Head reviewed: 4a8c5f40d84d7207ac355cd609797f174b386898
Base: a5b7ad941ec269943282897a75952de82be81344 (main)
PR state: draft (left draft; no APPROVE / REQUEST_CHANGES / merge / undraft)

Scope vs claim

Diff matches claimed S8 filesystem half:

  • internal/capability/grants.go: ParseGrant accepts repeatable filesystem:read=<root> / filesystem:write=<root> (Abs/Clean at parse); bare filesystem remains unrestricted alias via HasUnrestrictedFilesystem.
  • Fail-closed containment: filepath.Rel + EvalSymlinks / resolveAncestor; denials return false / CAPABILITY_DENIED before I/O.
  • Enforcement in internal/vm/vm.go for VM + interpreter (requireFilesystem on read/write/mkdir) and file:// stores (open/get/keys need read; put/delete need read+write) via storeHandle / OpStoreOpen.
  • Tests present as claimed: TestParseGrant, TestFilesystemGrantContainment, TestFilesystemScopesVMAndInterpreter, TestFileStoreFilesystemScopes, TestFilesystemScopeReceiptDecision, TestCLIPathScopedFilesystemGrants.
  • Journal + docs honesty: S8 PARTIAL-closed (process/network still OPEN); Go/JS backends remain coarse; TOCTOU caveat documented.

Hard nos

  • Intact. No prod -compile-bc / HFIR default flip; journal explicitly keeps #90 Partial.
  • No live LLM / H1 PASS/KILL claims.
  • Expected internal/ grant+VM paths for this slice — not treated as hard-no.

CI

list_check_runs_for_ref / workflow runs for head SHA: none reported yet (empty). Not green from Checks API at review time.

Merge readiness

Conditionally merge-ready on scope/hard-nos. Okabe may undraft and squash-merge when CI green. No code blockers found in this COMMENT pass; do not merge while Checks are absent/red.

Non-blockers / notes

  • Write grants intentionally do not imply read (covered by tests).
  • Generated backends still coarse — correctly called out as remaining work.
  • Symlink TOCTOU called out honestly; not a merge blocker for this slice.
  • Receipt path records scoped deny/allow after path checks (spot-checked).

— Motoko (Dev-lead, COMMENT-only)

@howlcipher
howlcipher marked this pull request as ready for review October 6, 2026 15:06
@howlcipher
howlcipher merged commit 8793d6e into main Oct 6, 2026
1 check passed
@howlcipher
howlcipher deleted the okabe/s8-path-scoped-filesystem branch October 6, 2026 15:09
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