Status: Draft Version: 0.2.0
The naive approach to Effector security is an allowlist: declare network = true, and the runtime either grants or denies it as a binary decision. This is necessary but not sufficient.
The Effector security model goes further: permissions are types. The [effector.permissions] block is as semantically rich as [effector.interface]. A runtime can perform static analysis on permission declarations before execution — looking for permission creep between versions, over-declared capabilities, or permissions that contradict the declared interface.
Consider: an Effector that declares input: CodeDiff, output: ReviewReport has no legitimate reason to declare filesystem = ["write"]. That mismatch is a security type error, detectable before any code runs.
Permission Type Rules:
input: String, output: Markdown → expect: network=false, filesystem=[]
input: RepositoryRef → expect: env-read=[*TOKEN*]
context: [Docker] → expect: subprocess=true OR network=true
output: Notification → expect: network=true
The effector-audit tool enforces these rules.
Effectors run inside agent runtimes that have access to user data, external APIs, and system resources. The security model defines how Effectors declare their requirements and how runtimes enforce boundaries.
The model follows two principles:
- Declare everything — Effectors must declare every permission they need
- Deny by default — Runtimes grant no permissions unless explicitly declared and approved
[effector.permissions]
network = true # Requires network access
filesystem = ["read"] # "read" | "write" | "read-write"
env-read = ["GITHUB_TOKEN", "HOME"] # Environment variables read
env-write = [] # Environment variables written
subprocess = true # Spawns child processes
secrets = ["github-token"] # Named secrets from secret store| Permission | Values | Default | Description |
|---|---|---|---|
network |
true / false |
false |
Can make HTTP/TCP connections |
filesystem |
[] / ["read"] / ["write"] / ["read-write"] |
[] |
File system access |
env-read |
string array | [] |
Environment variables the Effector reads |
env-write |
string array | [] |
Environment variables the Effector modifies |
subprocess |
true / false |
false |
Can spawn child processes |
secrets |
string array | [] |
Named secrets from the runtime's secret store |
system |
true / false |
false |
Access to system-level operations (rare) |
Filesystem permissions can be scoped to specific paths:
[effector.permissions]
filesystem = ["read"]
filesystem-paths = [
"~/.openclaw/workspace/",
"./output/"
]If filesystem-paths is omitted, the runtime determines the default scope (typically the workspace directory).
Effectors are classified into trust levels based on their source and verification status:
| Level | Source | Verification | Permissions |
|---|---|---|---|
| Bundled | Shipped with the runtime | Signed by runtime team | Full (within declared scope) |
| Verified | Published to an official registry | Passed automated security checks | Declared permissions honored |
| Community | Published by community authors | Basic validation only | Declared permissions + user approval |
| Local | Installed from filesystem | No verification | Declared permissions + user approval |
| Untrusted | Unknown source | None | Sandboxed; all permissions require explicit approval |
A community Effector can be escalated to "verified" if:
- It passes the security toolkit checks (
effector-audit) - A maintainer reviews and signs the package
- It maintains a clean security record over time
Verification can be revoked if:
- A vulnerability is discovered
- The Effector's behavior changes to exceed declared permissions
- The author's registry account is compromised
Before installing an Effector, the runtime SHOULD:
- Display permissions — Show the user what the Effector requires
- Compare trust level — Warn if the Effector's trust level is lower than expected
- Check for conflicts — Flag if permissions conflict with the runtime's security policy
- Verify checksums — Validate the package integrity against the registry's checksum
Installing: github-pr-review v1.2.0 (skill)
Trust level: Community
Permissions requested:
✓ Network access (to connect to GitHub API)
✓ Subprocess execution (to run gh CLI)
✓ Read env: GITHUB_TOKEN
✗ No filesystem write access
✗ No system access
Install and grant permissions? [y/N]
For extension type Effectors (which run code), the runtime SHOULD enforce:
| Constraint | Enforcement |
|---|---|
| Network | Proxy or firewall; allow only declared destinations |
| Filesystem | chroot or permission mask; limit to declared paths |
| Subprocess | Allowlist of permitted binaries |
| Memory | Limit memory allocation per extension |
| CPU | Limit execution time per invocation |
| Secrets | Inject only declared secrets; redact from logs |
Skills (SKILL.md) are instruction-based — they don't execute code directly. But they instruct the agent to use tools, which can be dangerous. Security checks for skills:
- Tool usage audit — Does the skill instruct use of destructive commands (rm, DROP, etc.)?
- Credential handling — Does the skill handle API keys safely (env vars, not hardcoded)?
- Scope creep — Does the skill instruct actions beyond its declared purpose?
- Injection risk — Could the skill's instructions be manipulated by untrusted input?
The effector-audit CLI performs these checks:
npx @effectorhq/audit scan ./SKILL.mdIf you discover a vulnerability in your Effector:
- Immediately publish a patched version
- Add a
[effector.security]advisory to the manifest:
[effector.security]
advisory = "https://github.com/effectorHQ/my-effector/security/advisories/GHSA-xxxx-xxxx-xxxx"
deprecated-versions = ["<1.2.1"]- Notify the registry to flag affected versions
If you discover a vulnerability in an Effector:
- Do not open a public issue (to avoid exploitation)
- Report to the author via GitHub Security Advisory
- If the author is unresponsive, report to the registry administrators
Before publishing an Effector:
- All permissions are declared in
effector.toml - No credentials are hardcoded (use environment variables)
- No destructive commands without explicit user confirmation
- Dependencies are pinned to specific versions (no
*in production) - The Effector passes
effector-auditwith no critical findings - CHANGELOG documents any permission changes between versions
- README clearly states what the Effector accesses and why