An experimental, microkernel-inspired host environment driven by the security principles of Android SELinux, ARM TrustZone, and strict zero-trust isolation boundaries.
CopCap separates core hardware/host drivers from untrusted third-party code, isolating application logic within a memory-bounded WebAssembly (WASM) sandbox controlled by an Attribute-Based Access Control (ABAC) hypervisor.
Modules represent low-level system drivers executing directly on the host machine within the core runtime process.
- Privilege Level: Ring 0 (Full Host Access).
- Responsibilities: Interfacing with underlying host hardware, low-level OS operations, networking bridges, and complex computations.
- Dependencies: Modules can explicitly depend on other system modules as well as external Python packages installed on the host environment.
Plugins are isolated userland applications running inside MicroPython compiled to WebAssembly.
- Privilege Level: Ring 3 (Untrusted / Memory-Constrained Sandbox).
- Isolation: Every plugin runs inside its own WASM runtime instance with strict RAM limits, controlled execution loops, and intercepted system calls.
webengine is an optional administrative web interface for managing plugins, monitoring logs, and visualizing system state.
- CopCap is fully functional as a headless microkernel daemon without
webengine. Developers can omit it entirely or construct custom web/CLI interfaces over the RPC bridge.
| Component Zone | Trust Level | Privilege & Constraints |
|---|---|---|
plugins/ (Ring 3) |
Low Trust | WASM Sandbox: Code is fully isolated with memory limits, supervised by the ABAC hypervisor. Unsigned third-party plugins can be executed safely here. |
modules/ (Ring 0) |
Full Trust | Host Kernel Space: Code runs directly on the host with full kernel process privileges. Only place code from trusted sources in modules/! |
β οΈ WARNING: Installing unsigned or modified control interfaces/modules can result in complete host compromise, unauthorized file access, and credential theft.
- Trustlets: Only core trustlet-plugins originally included in the official repository can be safely signed.
- Plugin Identifiers: Be cautious when installing new plugins for the first time. Unique plugin IDs are enforced strictly at the OS file-system level via directory naming.
CopCap guarantees Sandbox Isolation (protecting the host system and user sessions from malicious plugin code). However, CopCap is NOT a DRM system designed to protect secret keys embedded inside WASM plugins from the host machine owner.
- DO NOT hardcode commercial API keys, database credentials, or sensitive tokens inside WASM plugins.
- Use a Server-Side Proxy: If your plugin requires access to a paid external API, proxy requests through your own remote backend where authentication keys are securely stored.
Access controls follow a strict precedence rule:
DENY(Highest Priority): If a service, plugin, or module execution is denied anywhere in the policy, all access is immediately blocked, overriding any explicitALLOWrules.ALLOW: Grants access only when no matchingDENYrule is encountered.DEFAULTEffect (Lowest Priority): Fallback rule applied when no explicit rule matches.
CopCap strictly prohibits untrusted WASM plugins from passing raw filesystem paths across the host boundary. Host I/O operations are strictly mediated through an extensible Capability Contract Engine:
- Scoped Storage (
file:<path>): Grants read/write access strictly confined to the plugin's virtual storage enclave (storage/emulated/<plugin_id>/). Paths attempting directory traversal (../), embedded NUL bytes (\x00), or root anchors (/,C:) trigger an immediate hypervisor breach trap. - Static Assets (
static:<path>): Resolves read-only plugin distribution assets (e.g., local configs, UI templates) located inplugins/<plugin_id>/. - Network URIs: Validated network endpoints (
http://,https://,ws://,wss://) pass through untouched viaUrlContract. - Bare Absolute Path Lockdown: Any attempt to pass raw, anchored filesystem paths (such as
/etc/shadowor/bin/sh) without an explicit contract prefix is unconditionally rejected at Ring 1. - Terminal RAW Data Defanging: Any plain data string containing path-like separators (
/,\,:) that does not declare an ABI contract is deterministically transformed using non-decomposing Unicode lookalikes (Division Slashβ, Set Minusβ, Modifier Colonκ). This guarantees that untrusted strings can never be misinterpreted as host filesystem paths down the execution pipeline.
Modules provide host-level capabilities. Developers should always write a Module to expose new hardware or host features rather than modifying copcap_sdk.
backend.py(Required): Contains core driver implementation and system bindings.interface.py(Optional): Exposes clean typed interfaces or high-level abstractions for external consumption.
# modules/my_driver/backend.py
def setup(vault):
"""
Module entry point executed during kernel bootstrap.
Registers services and event listeners.
"""
driver = MyHardwareDriver()
# Register driver service in the global registry
vault.register_service("my_driver", driver)Plugins run within a WASM-compiled MicroPython sandbox. For example i take Fluent:
# CopCap Fluent Example
from copcap_sdk import BasePlugin # base class with context
from modules.l10n import L10n # main driver
# Use locales only for your own project
class MyPlugin(BasePlugin):
def start(self):
l10n_ex = L10n(language="en")
print(L10n.get("greeting_message")) # language will choosed automaticlly by user config in server
print(L10n.get("ban_message", user="@spammer", count=5)) # passing variables to fluent engine
print(l10n_ex.get("greeting_message")) # will return your string ONLY from your own en.ftl file!
# of course you can use def start without class definitionPlugins are defined using a declarative TOML manifest evaluated by the core engine:
name = "WEB Secure Policy Changer"
version = "1.0.0"
author = "Coppfe"
[permissions]
required = [
"modules.trustlet_app.*",
"modules.webengine.*"
]copcap_sdk forms the immutable interface contract between the host kernel, modules, and plugins.
- Immutable Core:
copcap_sdkcannot be safely modified without breaking API contracts and verification signatures. - Extensibility: Extend capabilities by registering new Modules, never by patching SDK internals directly.
Due to WebAssembly execution boundaries and MicroPython's synchronous nature, plugins cannot natively register asynchronous event hooks directly on host loop threads. The EventBus acts as a polling-based host-to-sandbox event bridge:
- Event Loop Polling (
EventBus.listen()): Plugins run a listener loop that retrieves in-flight host events, IPC invocations, and WebEngine actions viaEventService.wait_events. - Host Callback Binding (
EventBus.add_handler): Allows WASM plugins to attach proxy callbacks to host-side driver instances (e.g., Pyrogram message handlers) without giving untrusted code direct access to host listener threads. - Scoped Dispatching: Events arriving from the host are deserialized and dispatched locally inside the sandbox via
copcap_dispatchto matching scoped callbacks (event_bus,copcap_ipc,webengine). - Subsystem Backbone: Serves as the transport layer for both Inter-Plugin Communication (
IPCManager) and administrative UI rendering (WebEngine).
A centralized registry tracking all active system services and drivers:
- Modules publish services via
setup(kernel_context). - Plugins access allowed services lazily over an RPC proxy layer.
Plugins interact with host-side libraries (including complex structures like numpy arrays) transparently via an internal RPC bridge:
- Proxying: Method calls and attribute accesses on host objects are proxied across the WASM-to-Host boundary.
- Lightweight Magic Handles: Instead of serializing large memory spaces into WASM RAM, host objects are held as small, opaque references (handles) on the host, returning lightweight wrapper objects back to the sandbox.
WASM-isolated plugins operate under strict, pre-allocated RAM quotas.
- Unresolvable WASM Crash: If a plugin encounters an unrecoverable memory allocation error or WASM boundary trap that cannot be handled via IPC or plugin logic, please submit an issue or pull request to the repository.
- Manual Garbage Collection (
gc.collect): Do NOT invokegc.collect()inside WASM plugins. MicroPython's internal memory management is aggressive by default; calling explicit collections manually can lead to non-deterministic memory state behavior inside the WASM sandbox runtime.
MicroPython may occasionally behave unexpectedly with implicit dynamic type conversions across the RPC bridge. Always cast variables explicitly (e.g., int(), str(), float()) when passing primitives between WASM and the host kernel.
Use TYPE_CHECKING from copcap_sdk.types! __annotations__ is not supported!
CopCap theoretically supports natively compiled WASM binaries (C/Rust compiled to WASM) alongside MicroPython scripts, though practical validation of custom native targets remains experimental.
- Plugin / Module Developers: Responsible solely for vulnerabilities inside their custom written source code.
- Platform / Upstream: Vulnerabilities originating from underlying WebAssembly runtime engines, MicroPython core implementations, or third-party Python host libraries fall under the scope of those respective upstream maintainers.