Skip to content

πŸ”’ 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:

  1. The engine yields a {"type": "TOOL_CALL_START", "tool_name": "db__update_record"} event via the AG-UI streaming protocol.
  2. The front-end UI reads the tool_name and displays an Approve/Deny prompt to the user.
  3. The UI fires approval_manager.signal_approval("db__update_record", True) back to the server.
  4. The intercepted tool finally executes against the database, and the autonomous agent resumes its context loop.