nono-ts
v0.3.0
Published
Node.js/TypeScript bindings for nono capability-based sandboxing
Downloads
95
Maintainers
Readme
OS-enforced sandboxing for Node.js applications via Landlock (Linux) and Seatbelt (macOS).
Installation
npm install nono-tsUsage
import { CapabilitySet, AccessMode, apply, isSupported, supportInfo } from 'nono-ts';
// Check platform support
if (!isSupported()) {
console.log('Sandboxing not supported on this platform');
process.exit(1);
}
// Build capabilities
const caps = new CapabilitySet();
caps.allowPath('/tmp', AccessMode.ReadWrite);
caps.allowPath('/usr', AccessMode.Read);
caps.allowFile('/etc/hosts', AccessMode.Read);
caps.blockNetwork();
// Apply sandbox (irreversible)
apply(caps);
// From this point, the process can only access granted resourcesExamples
Runnable examples live in examples/ with both JavaScript and TypeScript variants:
01-support-check: detect platform support02-build-capabilities: build and inspect aCapabilitySet03-query-policy: dry-run policy decisions withQueryContext04-state-roundtrip: serialize/restore withSandboxState05-safe-apply-pattern: guardedapply()flow (NONO_APPLY=1)
npm run examples:list
npm run example:allSee examples/README.md for all commands.
API
CapabilitySet
Build a set of capabilities to grant the sandboxed process.
const caps = new CapabilitySet();
// Directory access
caps.allowPath('/data', AccessMode.Read);
caps.allowPath('/tmp', AccessMode.ReadWrite);
// Single file access
caps.allowFile('/etc/passwd', AccessMode.Read);
// Network
caps.blockNetwork();
// Commands
caps.allowCommand('git');
caps.blockCommand('curl');
// Platform-specific rules (macOS Seatbelt)
caps.platformRule('(allow file-read* (subpath "/opt"))');
// Utilities
caps.deduplicate(); // Remove duplicate capabilities
caps.pathCovered('/tmp/foo'); // Check if path is covered
caps.fsCapabilities(); // List all filesystem capabilities
caps.summary(); // Human-readable summaryAccessMode
enum AccessMode {
Read,
Write,
ReadWrite
}QueryContext
Query whether operations would be permitted without applying the sandbox.
const caps = new CapabilitySet();
caps.allowPath('/tmp', AccessMode.ReadWrite);
caps.blockNetwork();
const query = new QueryContext(caps);
const result = query.queryPath('/tmp/test.txt', AccessMode.Write);
// { status: 'allowed', reason: 'granted_path', grantedPath: '/private/tmp', access: 'read+write' }
const netResult = query.queryNetwork();
// { status: 'denied', reason: 'network_blocked' }SandboxState
Serialize and deserialize sandbox state for process inheritance.
// Serialize
const state = SandboxState.fromCaps(caps);
const json = state.toJson();
// Deserialize
const restored = SandboxState.fromJson(json);
const restoredCaps = restored.toCaps();Functions
// Apply sandbox with capabilities (irreversible)
apply(caps: CapabilitySet): void
// Check if sandboxing is supported
isSupported(): boolean
// Get detailed support information
supportInfo(): SupportInfoResult
// Returns: { isSupported: boolean, platform: string, details: string }Platform Support
| Platform | Backend | Status | |----------|---------|--------| | Linux 5.13+ | Landlock | Supported | | macOS 10.5+ | Seatbelt | Supported | | Windows | - | Not supported |
License
Apache-2.0
