Dome Systems

Developer

Register an agent, call tools through a Gateway, and confirm allow and deny in audit.

On Dome, a developer owns the agent as a workload: you register it, mint its credentials, point it at a Gateway, and verify that governed calls succeed or fail for the reasons you expect. Operators usually attach shared backends. Security usually owns the baseline Rules. In this sandbox you finish the loop yourself so you can see the full path.

Hand this to an AI agent. It stands up a sandbox agent, then hands you curl or Python calls that prove allow and deny.

Open in Cursor

In this tutorial, you will register an agent, attach the demo HR tools behind Default, deploy a narrow Cedar allowlist, and prove allow vs deny from curl or Python — then see both decisions in audit.

To do this, you will:

Provision a sandbox

Create a disposable workspace for this role walk.

Register an agent

Mint identity and an API key for the workload.

Attach tools and grant access

Put demo-hr on Default and admit the agent.

Deploy authorization rules

Allow directory tools; deny compensation.

Verify allow and deny

Call the gateway with curl or Python.

Confirm in audit

Read the decisions attributed to your agent.

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 in that sandbox (admin, operator, or equivalent — refer to Permissions concept)

This tutorial runs entirely in a sandbox. In a production workspace, attaching backends is typically an operator action and deploying rules a security action. A developer still needs enough Connect and Govern context to integrate and debug.

Provision a sandbox

A sandbox is a disposable workspace with the same capabilities as production. Provision one for this role track:

dome sandbox provision --scope=workspace --workspace-name role-developer

The server prefixes the name, creating sandbox-role-developer. Sync contexts and switch into it:

dome context sync
dome context use sandbox-role-developer
dome context current

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

Register an agent

An agent is the workload identity every governed call is attributed to. Register one, then mint a credential the gateway will accept as Authorization: Bearer:

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

Save the Token: dome_… value once into a gitignored .env. Tokens are shown once and cannot be recovered — mint another key if you lose it.

Attach tools and grant access

A tool is a backend the gateway calls on the agent's behalf. The agent never sees its URL. Register the public demo HR server and attach it to Default:

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

The connection name prefixes every tool (demo-hr/hr/list_employees, and so on). Admit the agent at Default so the gateway accepts its requests:

dome gateways access grant Default role-dev-agent

That grant admits the agent and permits resources currently in Default. The next step narrows what the agent may actually call.

Deploy authorization rules

Cedar decides every mcp:call. This allowlist keeps directory tools open and blocks compensation (and everything else) with forbid … unless:

role-dev-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"
  ]
};

Deploy it scoped to this agent:

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

Expect Bundle deployed: role-dev-agent. Optionally simulate before a live call:

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

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

Expect ALLOW, then DENY.

Verify allow and deny

Build the tools ingress URL from your sandbox gateway host and Default's id:

dome context current
dome gateways list

Export once:

export DOME_GATEWAY_URL="https://GATEWAY_HOST/gateways/DEFAULT_GATEWAY_ID"
export DOME_TOKEN="dome_..."

Post MCP JSON-RPC tools/call to $DOME_GATEWAY_URL/mcp. Use curl or Python — same payloads, same outcomes.

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": {}
    }
  }'

Expect demo employees in result, including E001.

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": 2,
    "method": "tools/call",
    "params": {
      "name": "demo-hr/finance/get_salary",
      "arguments": { "employee_id": "E001" }
    }
  }'

Expect a JSON-RPC error (authorization deny), not payroll data.

Requires httpx (pip install httpx). Same gateway URL and token as above:

verify_calls.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))

# Allowed — directory
call("demo-hr/hr/list_employees")

# Denied — compensation
call("demo-hr/finance/get_salary", {"employee_id": "E001"})
python verify_calls.py

Expect employees in the first response and an authorization error in the second.

Confirm in audit

Every decision is attributed to the agent. List recent events:

dome audit query --limit 20

Focus on denials:

dome audit query --results denied --limit 10

You should see the allowed list_employees call and the denied get_salary call under role-dev-agent.

Clean up

Delete the sandbox to remove the agent, rules, and grants together:

dome workspaces delete sandbox-role-developer

Next steps

You learned how to register an agent, call tools through a Gateway, and confirm allow and deny in audit. Continue with:

On this page

Was this page helpful?