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