π Downstream Security Policies¶
Importing raw, powerful skills (like
RawDatabaseSkill) directly into an autonomous agent is dangerousβan LLM hallucination could result in dropped tables or modified records.
To safely consume shared skills in client applications, use the SecureSkill wrapper from mirai-agent-core to enforce a Zero-Trust architecture.
π‘οΈ Securing Skills via Declarative Policy¶
In your client application's orchestrator, define explicit policies dictating which tools are safe, which require Human-in-the-Loop (HITL), and which are entirely blocked.
from mirai_core.core.types import SecureSkill, SecurityLevel
from mirai_core.safety.hitl import InMemoryApprovalManager
from mirai_shared_skills.database import RawDatabaseSkill
# 1. Initialize an approval manager
approval_manager = InMemoryApprovalManager()
# 2. Define explicit security policy mapping to tool names
DB_POLICY = {
"db__select_records": SecurityLevel.SAFE,
"db__update_record": SecurityLevel.REQUIRES_HITL,
# Anything not explicitly listed here (like db__drop_table) defaults to BLOCKED.
}
# 3. Wrap the raw skill securely
safe_db_skill = SecureSkill(
underlying_skill=RawDatabaseSkill(),
policy=DB_POLICY,
approval_manager=approval_manager,
default_level=SecurityLevel.BLOCKED
)
π Injecting Secure Skills into Engines¶
When building the worker engine, pass the safe_db_skill instead of the raw version. Crucially, the Engine and the SecureSkill must share the same approval_manager.
from mirai_core.agents.engine import DynamicAgentEngine
from mirai_core.agents.router import SemanticRouter
# Build a database worker engine using the secured skill
db_engine = DynamicAgentEngine(
provider=config,
base_prompt="You are a secure database assistant.",
skills=[safe_db_skill], # The LLM will only see SAFE and REQUIRES_HITL tools
router=SemanticRouter(model=make_llm(config)),
approvals=approval_manager # Link the HITL lifecycle
)
βοΈ How Deterministic HITL Works¶
If a downstream agent attempts to use db__update_record (marked as REQUIRES_HITL), the SecureSkill interceptor pauses execution seamlessly:
- The engine yields a
{"type": "TOOL_CALL_START", "tool_name": "db__update_record"}event via the AG-UI streaming protocol. - The front-end UI reads the
tool_nameand displays an Approve/Deny prompt to the user. - The UI fires
approval_manager.signal_approval("db__update_record", True)back to the server. - The intercepted tool finally executes against the database, and the autonomous agent resumes its context loop.