How the DomainSet Runtime Axis Filters RPC Surfaces, Agent Tools, and Event Subscribers in OpenHuman
The DomainSet runtime axis acts as a registration-time gatekeeper that exposes only RPC controllers, agent tools, and event subscribers belonging to explicitly enabled domain families, creating a minimal attack surface for each process configuration.
OpenHuman's modular architecture relies on orthogonal runtime axes to control feature visibility and security boundaries. The DomainSet runtime axis determines which domain families—such as Agent, Memory, Threads, Config, Security, Skills, and Web3—are active for a given Core instance. When a process starts, the builder populates a DomainSet that is stored in the CoreContext, and every registration point checks this set before exposing functionality to RPC callers, AI models, or the event bus.
Understanding the DomainSet Architecture
The DomainSet is built around the DomainGroup enum, which represents distinct functional families within the system. Each domain group maps to specific controllers, tools, and event subscribers that should only be active when that domain is explicitly enabled.
In src/core/runtime/builder.rs, the CoreBuilder constructs the DomainSet during initialization and injects it into the CoreContext. This context becomes the single source of truth for all subsequent registration checks throughout the application lifecycle.
How DomainSet Filters RPC Controllers
RPC controllers are registered in src/core/all.rs, where each controller schema is tagged with its corresponding DomainGroup. During startup, the core iterates over the controller registry and retains only those entries whose group passes the DomainSet filter.
When a domain is disabled, its associated RPC namespace is never mounted. Calls to methods in that namespace result in an "unknown method" RPC error rather than runtime failures or security exceptions. This registration-time filtering ensures that disabled endpoints have zero network exposure.
How DomainSet Filters Agent Tools
The tool registry in src/openhuman/tools/ops.rs assembles a vector of tool descriptors before exposing them to AI agents. Before adding a tool to the public toolbox, the code verifies that the tool's owning domain is present in the active DomainSet.
If the domain is filtered out, the tool never appears in the model's tool list and cannot be invoked, preventing AI agents from attempting operations in disabled functional areas.
How DomainSet Filters Event Subscribers
Each domain-specific event-bus module—located at paths like src/core/<domain>/bus.rs (for example, src/core/memory/bus.rs)—registers its subscriber with the global event bus only when its domain is enabled.
The subscription routine checks CoreContext::domains().allows(<DomainGroup>) before completing registration. When this check fails, the subscriber is omitted entirely, meaning events from that domain are silently ignored rather than processed or queued.
Practical Implementation Examples
You can construct a minimal runtime using the DomainSet::harness() preset, which includes only essential domain families like Agent, Memory, Threads, Config, and Security:
use openhuman_core::runtime::{DomainSet, ServiceSet};
use openhuman_core::CoreBuilder;
// Build a harness that only runs core domain families
let core = CoreBuilder::new()
.domains(DomainSet::harness())
.services(ServiceSet::none())
.build()
.await?;
To inspect which RPC namespaces are currently active based on your DomainSet configuration:
let schema = core.rpc_schema(); // returns Vec<String> of namespaces
println!("Enabled RPC namespaces: {:?}", schema);
To verify which agent tools are exposed to the model:
let toolbox = core.tool_registry(); // returns list of ToolInfo
println!("Available tools: {}", toolbox.iter()
.map(|t| t.name.clone())
.collect::<Vec<_>>().join(", "));
Summary
- DomainSet acts as a compile-time security boundary that determines functional visibility for each Core instance.
- Registration-time filtering occurs in
src/core/runtime/builder.rsbefore any network surfaces or tool interfaces are exposed. - RPC controllers are filtered in
src/core/all.rsbased on theirDomainGrouptags, preventing disabled namespaces from mounting. - Agent tools are filtered in
src/openhuman/tools/ops.rs, ensuring AI models only see tools from enabled domains. - Event subscribers are conditionally registered in domain-specific
bus.rsmodules, silently ignoring events from disabled domains.
Frequently Asked Questions
What is the DomainSet runtime axis in OpenHuman?
The DomainSet runtime axis is a configuration mechanism in the OpenHuman Core that controls which functional domains (Agent, Memory, Threads, Config, Security, Skills, Web3, etc.) are active for a given process. It is implemented as a bitmask or set structure stored in CoreContext and checked during the registration phase of RPC controllers, agent tools, and event subscribers.
How does DomainSet filtering improve security?
DomainSet filtering improves security by ensuring that disabled functionality has zero runtime exposure. Because the filtering happens at registration time in src/core/runtime/builder.rs, disabled RPC controllers never mount network endpoints, excluded agent tools never appear in the AI's available function list, and omitted event subscribers never process sensitive domain events. This creates a minimal attack surface tailored to each deployment scenario.
Where does the DomainSet check occur for RPC controllers?
The DomainSet check for RPC controllers occurs in src/core/all.rs, where the core iterates over the controller registry during initialization. Each controller schema is tagged with a DomainGroup, and the system retains only those controllers whose domain group is allowed by the active DomainSet stored in the CoreContext.
Can I customize which domains are active in a harness?
Yes, you can customize active domains when building a Core instance. The DomainSet type provides presets like DomainSet::harness() for testing scenarios, or you can construct a custom set using the builder API in src/core/runtime/builder.rs. This allows embedders to create slim builds, such as headless CLI tools, that include only the specific domain families required for a particular use case.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →