Dome Systems

Security

Author and simulate Cedar, redact sensitive fields, prove denials, and export audit evidence.

On Dome, security owns what each agent may call, what content may leave a backend, and whether the audit trail can prove it. You author and simulate Cedar Rules, apply Guards and Filters, investigate denials, and export evidence. Operators make backends reachable. Developers integrate agents. In this sandbox you stand up just enough substrate to exercise the Govern path end to end.

Hand this to an AI agent. It deploys restrictive Cedar and a contact Filter, then hands you curl or Python calls that prove allow, redact, and deny.

Open in Cursor

In this tutorial, you will deploy a restrictive Cedar allowlist, redact contact fields on the response path, prove allow / redact / deny from curl or Python, and export audit evidence.

To do this, you will:

Provision a sandbox

Create a disposable workspace for this role walk.

Stand up minimal substrate

Register an agent, attach demo-hr, and grant Default.

Redact contact fields

Create a Filter and assign it to tool responses.

Author, simulate, and deploy Rules

Allow directory tools; deny compensation and customers.

Verify allow, redact, and deny

Call the gateway with curl or Python.

Investigate and export evidence

Query denials and export today's audit trail.

Prerequisites

For this tutorial, you will need:

  • The Dome CLI installed and authenticated (dome auth login, then dome auth status)
  • A role that can provision a sandbox and deploy rules (admin, security, or equivalent — refer to Permissions concept)

This tutorial runs entirely in a sandbox. In a production workspace, attaching backends is typically an operator action. Here you attach demo-hr yourself so you can finish the Govern loop.

Provision a sandbox

dome sandbox provision --scope=workspace --workspace-name role-security
dome context sync
dome context use sandbox-role-security
dome context current

Confirm the workspace reads sandbox-role-security before continuing.

Stand up minimal substrate

You need an agent identity and a reachable tool so Rules and Filters have something to govern.

dome agents register --name role-sec-agent --if-not-exists
dome agents create-key role-sec-agent --name service

Save the token to a gitignored .env — do not leave it in chat history.

dome tools add \
  --name demo-hr \
  --url https://demo-mcp.domesystems.ai/mcp \
  --protocol streamable-http \
  --auth-method none \
  --gateway Default

dome gateways access grant Default role-sec-agent

Redact contact fields

A Guard Filter strips sensitive fields from tool responses before the agent sees them. Create redact-contact.json:

redact-contact.json
{
  "json": {
    "components": [
      {
        "fieldActions": [
          {
            "matcher": { "path": "**.email" },
            "action": "FILTER_ACTION_REDACT"
          },
          {
            "matcher": { "path": "**.phone" },
            "action": "FILTER_ACTION_REDACT"
          }
        ]
      }
    ]
  }
}

Create the Filter and assign it to the response direction on demo-hr:

dome guards filters create redact-contact \
  --description "Redact contact fields in tool responses" \
  --config-from redact-contact.json

dome tools guards filters set demo-hr \
  --direction response \
  --filters redact-contact

Author, simulate, and deploy Rules

This allowlist keeps directory tools open. Everything else — including salary and customer records — is denied by forbid … unless:

role-sec-agent.cedar
permit(
  principal is Dome::Agent,
  action == Dome::Action::"mcp:discover",
  resource
);

permit(
  principal is Dome::Agent,
  action == Dome::Action::"mcp:call",
  resource
) when {
  resource in [
    Dome::MCPTool::"demo-hr/hr/list_employees",
    Dome::MCPTool::"demo-hr/hr/get_employee",
    Dome::MCPTool::"demo-hr/hr/org_chart"
  ]
};

forbid(
  principal is Dome::Agent,
  action == Dome::Action::"mcp:call",
  resource
) unless {
  resource in [
    Dome::MCPTool::"demo-hr/hr/list_employees",
    Dome::MCPTool::"demo-hr/hr/get_employee",
    Dome::MCPTool::"demo-hr/hr/org_chart"
  ]
};

Validate and simulate before deploying so you know the allow and deny paths:

dome rules validate role-sec-agent.cedar

dome rules simulate --agent role-sec-agent --action mcp:call \
  --resource demo-hr/hr/list_employees --resource-type mcp_tool

dome rules simulate --agent role-sec-agent --action mcp:call \
  --resource demo-hr/finance/get_salary --resource-type mcp_tool

Expect ALLOW, then DENY. Deploy when those match:

dome rules apply role-sec-agent.cedar --agent role-sec-agent --name role-sec-agent

Verify allow, redact, and deny

dome context current
dome gateways list
export DOME_GATEWAY_URL="https://GATEWAY_HOST/gateways/DEFAULT_GATEWAY_ID"
export DOME_TOKEN="dome_..."

List employees — allowed:

curl -sS -X POST "$DOME_GATEWAY_URL/mcp" \
  -H "Authorization: Bearer $DOME_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "demo-hr/hr/list_employees",
      "arguments": {}
    }
  }'

Get E001 — allowed, email redacted:

curl -sS -X POST "$DOME_GATEWAY_URL/mcp" \
  -H "Authorization: Bearer $DOME_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "demo-hr/hr/get_employee",
      "arguments": { "employee_id": "E001" }
    }
  }'

Expect "email": "[REDACTED]".

Get salary — denied:

curl -sS -X POST "$DOME_GATEWAY_URL/mcp" \
  -H "Authorization: Bearer $DOME_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "demo-hr/finance/get_salary",
      "arguments": { "employee_id": "E001" }
    }
  }'

Requires httpx (pip install httpx):

verify_security.py
import json
import os

import httpx

url = os.environ["DOME_GATEWAY_URL"].rstrip("/") + "/mcp"
token = os.environ["DOME_TOKEN"]

def call(name: str, arguments: dict | None = None) -> None:
    response = httpx.post(
        url,
        headers={
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json",
        },
        json={
            "jsonrpc": "2.0",
            "id": 1,
            "method": "tools/call",
            "params": {"name": name, "arguments": arguments or {}},
        },
        timeout=30.0,
    )
    print(json.dumps(response.json(), indent=2))

call("demo-hr/hr/list_employees")
call("demo-hr/hr/get_employee", {"employee_id": "E001"})
call("demo-hr/finance/get_salary", {"employee_id": "E001"})
python verify_security.py

Expect allow, redacted email, then deny.

Investigate and export evidence

dome audit query --limit 20
dome audit query --results denied --limit 10

Export today's trail as JSON Lines for a compliance package or SIEM:

dome audit export \
  --since "$(date -u +%Y-%m-%dT00:00:00Z)" \
  --format jsonl > security-audit.jsonl

Clean up

dome workspaces delete sandbox-role-security

Next steps

You learned how to author and simulate Cedar, redact sensitive fields, prove denials, and export audit evidence. Continue with:

  • Developer to register agents and verify from the workload side
  • Operator to attach backends and expose Gateways
  • Simulate Rules for deeper pre-deploy checks

On this page

Was this page helpful?