Skip to main content

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 access
  • rw — 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.tokens in 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 ro mode for directories that skills only need to read
  • Review skill manifests before deployment — permissions are the primary security boundary