Use this page when a module, task, engine, extractor, or MCP integration is blocked by the sandbox.
Start from the exact error. The error usually tells you which layer denied the operation.
Filesystem Denied¶
Error shape:
sandbox_filesystem_denied:<subject>:<path>This means the concrete path is outside the active filesystem roots.
Check:
- Identify the subject in the error.
- Identify the subject kind from the runtime path: module, module task, engine, extractor, or MCP.
- Check the matching declaration location.
- Resolve symlinks and relative paths mentally as absolute paths.
- Confirm the requested path is exactly the declared root or below it.
For modules and module tasks, the declaration belongs in module manifest.json:
{
"access": [
{
"resource_type": "filesystem",
"operation": "read",
"target": "/srv/democrai/reports"
}
]
}For engines and extractors, use the phase that actually runs the code:
{
"runtime": {
"access": [
{
"resource_type": "filesystem",
"operation": "read",
"target": "/srv/democrai/models"
}
]
}
}If the path is user-selected or administrator-selected at runtime, use the external-access flow instead of adding a broad manifest root.
Filesystem FD Denied¶
Error shape:
sandbox_filesystem_fd_denied:<subject>:<key>This means normal runtime code attempted a file-descriptor based path operation through fields such as dir_fd, src_dir_fd, or dst_dir_fd.
Those operations are relaxed only in subprocess/install contexts where package installers and cleanup code need them. Normal module runtime should use ordinary path operations under declared filesystem access entries.
Sensitive Import Denied¶
Error shape:
sandbox_module_denied:<root>This means the subject imported a sensitive native escape hatch without declaring it. Current sensitive roots are:
ctypes_ctypescffi_cffi_backend
Declare the root only when native interop is truly required:
{
"allowed_imports": ["ctypes"]
}If the import is incidental through a dependency, prefer changing the dependency path before allowing native interop broadly.
Subprocess Denied¶
Error shape:
sandbox_subprocess_denied:<entrypoint>This means the current runtime path does not allow child process creation.
Normal module render and actions should not call subprocess directly. Use sdk.tasks.run_subprocess(...) so the runtime enters a task context with subprocess execution enabled and injects the sandbox environment into the child process.
Engines and extractors enable subprocess execution only in install-oriented phases. Runtime phases should not depend on spawning arbitrary child processes unless that runtime path explicitly supports it.
Network Target Missing¶
Error shape:
network_target_missingThis means the network guard received an empty target. Check the URL or host value before the call. Do not treat this as an approval problem; there is no valid target to approve.
External URL Locked¶
Common response:
External URL is locked.This means the target was not allowed by the active sandbox policy, session approval, or permanent approval.
Check:
- Is this target a stable dependency?
- If yes, declare it in the correct manifest or phase.
- If no, call
sdk.access.check_external_access(...)and let the approval flow register a pending request. - If it was previously denied, an administrator must change that decision before the same structured subject/resource/operation/target will be allowed.
For stable module dependencies:
{
"access": [
{
"resource_type": "network",
"operation": "receive",
"target": "https://api.example.com/v1/reports"
}
]
}For stable engine or extractor dependencies:
{
"runtime": {
"access": [
{
"resource_type": "network",
"operation": "receive",
"target": "https://api.example.com/v1/models"
}
]
}
}Approval Does Not Work¶
Approvals are authorized by the access-policy service, not by the module call site.
A user can manage external access only when:
- a runtime user is present
- the user is not scoped to an organization for this decision
- the user has a super role or super access level
If approval raises external_access_admin_required, the current runtime user is not authorized to approve or deny the resource.
Session approval also needs a session key. If there is no session key, approve_for_session(...) is skipped.
OS Network Enforcement Still Blocks¶
If Python-level checks allow a target but Linux egress still fails, inspect the OS-level layer.
Check:
sandbox.os.enabledis enabled only when you intend process-level egress filtering.- The helper is running and reachable through
sandbox.os.helper_socket. - The policy file exists at
sandbox.os.policy_file. - The policy file is owned by the application user and is not group- or world-writable.
- The host resolves to concrete IP addresses.
- The destination port is the one declared or approved.
- The target process is in the cgroup managed by the helper.
With default paths, same-host instances do not share the helper socket or policy file. Their cgroups and iptables chains are also process-specific, using names derived from the process identifier. Policy file collisions and iptables chain replacement between instances should not happen unless deployment config overrides make two instances share the same sandbox.os.policy_file, sandbox.os.helper_socket, or process-specific network enforcement target.
In same-machine multi-instance deployments, verify that custom sandbox.os.policy_file and sandbox.os.helper_socket values are unique per running application process unless the deployment deliberately serializes and owns that sharing.
In multi-node deployments, also check that network.stream.type uses a provider that reaches every node. With the in-memory stream provider, approval refresh events do not cross process boundaries.
Enable OS sandbox debug output when diagnosing helper and allowlist flow:
DEMOCRAI_DEBUG_OS_SANDBOX_FLOW=1For media and external-access checks, this debug flag can also be useful:
DEMOCRAI_DEBUG_MEDIA_FLOW=1Declaration Checklist¶
| Runtime path | Check this first |
|---|---|
| Module render/action/command | module manifest.json |
| Module task | same module manifest.json |
| SDK task subprocess | same module manifest.json and subprocess helper usage |
| Engine runtime | engine manifest runtime section |
| Engine install | engine manifest install section |
| Extractor runtime | extractor manifest runtime section |
| Extractor install | extractor manifest install section |
| MCP | registered MCP endpoint and approval state |
If the resource is expected and stable, declare it narrowly. If it is dynamic, use approval. If neither is true, keep it blocked.