Enforce Sandbox Filesystem Policy on Shared-Mounted HPC Paths
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 8.7k
- Forks
- 1.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 253
Description
Problem Statement
Summary
Ensure OpenShell filesystem policy is enforced correctly on shared-mounted paths, so a sandboxed workload can run with stricter permissions than the invoking user.
This is important for HPC environments where users often have broad access to shared project paths, but automated or agentic workloads should be constrained to narrower read/write boundaries.
Background
OpenShell already has a filesystem policy model:
filesystem_policy.read_onlyfilesystem_policy.read_write- undeclared paths are inaccessible
landlock.compatibilitycan bebest_effortorhard_requirement- static filesystem controls are locked at sandbox creation
Relevant docs:
- https://docs.nvidia.com/openshell/latest/sandboxes/policies
- https://docs.nvidia.com/openshell/latest/reference/policy-schema
The policy schema docs state that Landlock provides mandatory filesystem access control below what Unix permissions allow, and that hard_requirement should abort sandbox startup if filesystem isolation cannot be applied.
Problem
On shared compute systems, a human user may have broad Unix permissions to project directories, shared scratch, datasets, generated results, or tool areas. However, a sandboxed process launched by that user may need narrower authority.
Examples:
- The user may be able to write a shared project area.
- The sandboxed process should only be able to read that area.
- The process should write only to its assigned job workspace.
- The process should not modify shared tools, reference datasets, golden outputs, or unrelated workspaces.
Standard Unix permissions do not express this distinction because the process may otherwise inherit the user's filesystem authority. OpenShell can provide an additional policy boundary around the workload.
Proposed Design
Requested behavior
When a host/shared path is mounted into the sandbox, OpenShell should enforce the declared policy over that mounted path.
Example:
filesystem_policy:
read_only:
- /hpc/tools
- /hpc/datasets
- /hpc/shared-results
read_write:
- /hpc/workspace
- /tmp
landlock:
compatibility: hard_requirement
process:
run_as_user: sandbox
run_as_group: sandbox
The sandboxed process must not be able to modify /hpc/tools, /hpc/datasets, or /hpc/shared-results, even if the invoking user has write permission to the underlying shared filesystem paths.
User identity and file ownership
This is the model the issue assumes; it should be explicit in the spec so reviewers can argue with it directly.
Default identity
By default, the sandboxed process runs as the invoking user's UID/GID. This is the simplest model on HPC and matches scheduler expectations: the job runs as the submitter, and quotas, accounting, and Unix permissions on Lustre/GPFS/NFS continue to attribute usage to that user.
Under this default:
- Files written to
read_writemounts (e.g.,/hpc/workspace,/tmp) are owned by the invoking user, with the user's primary group, subject to the site's umask. - Files left on shared storage (Lustre / NFS / GPFS) after the sandbox exits are therefore owned by the user, exactly as if the job had run outside OpenShell.
- The additional restriction OpenShell adds is negative: Landlock + policy reduce what the process can write to, below what Unix permissions would otherwise allow. OpenShell does not grant any authority the user does not already have.
Optional alternate identity (run_as_user / run_as_group)
Sites that want a stronger separation between the human user and the agent can opt into running the sandboxed process under a dedicated identity (e.g., sandbox:sandbox, or a per-job system account provisioned by the scheduler).
Under this mode:
- File ownership of outputs is the alternate identity, not the invoking user. This is closer to the "change the container's UID/GID" pattern Josh mentioned.
- Sites must arrange that the alternate identity has appropriate group membership / ACLs to write the declared
read_writemounts and to read the declaredread_onlymounts. - The Supervisor must refuse to start if the requested identity cannot read the required mounts, rather than silently writing files the user cannot later access.
Things the issue must address explicitly:
- Which identity is the default (proposal: invoking user).
- How
run_as_user/run_as_groupinteract with shared-FS POSIX permissions, ACLs, and quotas. - Owner of leftover files after sandbox exit, for both modes.
- Behavior on Lustre/GPFS/NFS where root_squash, ID mapping, or idmapd may rewrite UIDs.
- Whether
umaskis part of the policy (proposal: yes, configurable per sandbox).
Requirements
- Apply read_only and read_write semantics to shared-mounted paths.
- Deny access to mounted paths not declared in policy.
- Support
hard_requirementfor deployments where reduced filesystem isolation is unacceptable. - Fail closed when a required path cannot be protected.
- Log filesystem policy failures and skipped paths clearly.
- Document known limitations with: NFS, Lustre, GPFS, BeeGFS, symlinks, UID/GID mappings, bind mounts, and Landlock behavior.
- Clarify whether execute/no-execute semantics are supported or out of scope.
- Document file-ownership behavior for outputs under both default and
run_as_usermodes (see above).
Acceptance criteria
- A sandboxed process can read from a mounted tool directory but cannot modify it.
- The process can write to its declared workspace mount.
- The process cannot write to a mounted shared project area marked read-only, even if the invoking user can.
- The process cannot access undeclared mounted paths.
hard_requirementprevents sandbox startup if a listed path cannot be enforced.- Tests cover shared-mounted paths, not only container-internal paths.
- Tests assert file-ownership of outputs on a shared FS (e.g., Lustre or NFS test bed) under both default and
run_as_usermodes.
Alternatives Considered
N/A
Agent Investigation
No response
Checklist
- I've reviewed existing issues and the architecture docs
- This is a design proposal, not a "please build this" request
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the architecture documentation and the linked sandbox policy and policy-schema documentation, then trace how filesystem policies and shared-mounted paths are currently handled. Define the identity, mount, Landlock, and failure semantics before implementation. Done requires shared-path tests covering read-only, read-write, undeclared, hard-requirement, and ownership behavior.
Written by the indexing model from the issue text.
Assessment
- Domain
- hpc, operating-systems, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100