Security
Luminarys enforces a defense-in-depth security model. Every skill runs in an isolated sandbox, and every interaction with host resources is mediated by the permission manager.
Sandbox model
Skills execute inside an isolated sandbox with no direct access to the host system. The only way for a skill to interact with the outside world is through ABI functions provided by the host. Every ABI call is checked against the skill's declared permissions before execution.
This means:
- A skill cannot read or write files outside its allowed directories
- A skill cannot make network requests to disallowed destinations
- A skill cannot execute arbitrary shell commands
- A skill cannot access another skill's state
- A compromised skill cannot affect other skills or the host
Permissions manifest
Each skill declares its permissions in a YAML manifest. Permissions follow a deny-by-default model — capabilities not explicitly granted are denied.
permissions:
fs:
enabled: true
dirs: ["/data/project:rw", "/config:ro"]
http:
enabled: true
allowlist: ["https://api.example.com/**"]
tcp:
enabled: true
allowlist: ["redis:6379"]
shell:
enabled: true
allowlist: ["git **"]
allowed_dirs: ["/data/project"]
See the Manifest page for the full permissions reference.
File system security
Access control
File system access is restricted to explicitly listed directories with specified access modes:
ro— read-only accessrw— read and write access
Glob patterns provide flexible access control:
dirs:
- "/data:rw" # full access to /data
- "/data/projects/*/src:rw" # write only to src/ in any project
- "/data/shared:ro" # read-only shared directory
Path traversal protection
All file paths are normalized and validated before access:
- Path traversal attempts (
..) are blocked - Symbolic links resolving outside allowed directories are denied
- Paths are resolved to canonical form before permission checks
Network security
HTTP requests
HTTP access is controlled via URL allowlists with wildcard matching:
http:
enabled: true
allowlist:
- "https://api.example.com/**"
- "https://*.internal.company.com/**"
DNS-aware filtering prevents SSRF attacks — destinations not matching any allowlist pattern are denied.
TCP connections
TCP access uses host:port allowlists:
tcp:
enabled: true
allowlist:
- "redis.internal:6379"
- "db.internal:5432"
- "10.0.0.*:*" # any port on 10.0.0.x subnet
Wildcard patterns: * matches a single segment, ** matches everything.
Shell execution security
Shell command execution is the most sensitive permission. When enabled, multiple layers of protection apply:
Command allowlists
Only explicitly listed command patterns are permitted:
shell:
enabled: true
allowlist:
- "git **"
- "go build **"
- "ps **"
Operator blocking
Shell operators that could chain or redirect commands are blocked:
- Command chaining:
&&,||,; - Piping:
| - Redirection:
>,>>
This prevents constructing compound commands that bypass the allowlist.
Working directory restrictions
Shell commands can be restricted to specific directories:
shell:
allowed_dirs:
- "/data/project"
Signed skill packages
Skills are distributed as signed .skill packages. The host verifies every package at load time — unsigned or tampered skills are rejected.
Use lmsk sign to create packages and lmsk info to inspect and verify them.
Inter-skill isolation
Skills can invoke other skills, but only when explicitly permitted by both parties:
invoke_policy:
can_invoke: ["fs-skill"]
can_be_invoked_by: ["*"]
Both the caller's can_invoke and the target's can_be_invoked_by must allow the call. This bidirectional policy prevents unauthorized skill-to-skill communication.
Cluster security
In cluster mode:
- NATS authentication — token-based authentication for all connections
- TLS encryption — optional TLS for NATS, including mutual TLS (mTLS)
- File transfer verification — cross-node file transfers are verified on receipt
- Node identity — each node has a stable identifier for routing and audit
Best practices
- Always set
auth.tokensin production to protect MCP endpoints - Use TLS for NATS connections in production clusters
- Use specific paths in file system permissions — avoid broad
**wildcards - Keep shell allowlists as narrow as possible
- Use
romode for directories that skills only need to read - Review skill manifests before deployment — permissions are the primary security boundary