Skip to main content
Dome is the governance layer for agentic software. It gives every agent an identity, enforces what each agent can call, redacts sensitive fields, and records every decision.

Hand this to an AI agent. It runs the setup, then tells you which questions to ask so you can feel allow, redact, and deny yourself.

Open in Cursor
In this tutorial, you will stand up an HR assistant that Dome governs. It can look up employees and org structure, but it cannot read compensation or customer records, and contact details come back masked. You will see those limits enforced from Cursor or Claude in the same chat UI you already use — or, if you prefer not to wire an MCP client, by calling the gateway directly with curl. To do this, you will:
1

Prepare your environment

Create a disposable workspace for this tutorial.
2

Add a tool

Register the demo HR server and attach it to Default.
3

Redact contact fields

Create a JSON Filter and assign it to the response path.
4

Create the agent

Register the assistant and create an API key.
5

Set access rules

Grant gateway access and deploy authorization rules.
6

Connect your client

Point Cursor, Claude, or Codex at the tools ingress — or skip ahead and verify with curl.
7

Verify the results

Test allow, redact, and deny in an AI client or via curl, then inspect audit.

Prerequisites

For this tutorial, you will need:
  • The Dome CLI, installed and signed in.
  • An invitation to Dome. The platform is invitation-only. Contact support@domesystems.ai if you do not have access yet.
  • A role that can provision a sandbox and deploy rules: admin, operator, or equivalent. Refer to Permissions concept.
  • Optional: Cursor, Claude Code, or another MCP client that accepts a remote URL plus a bearer Authorization header. If you only want to exercise the governed tools, curl is enough — skip Connect your client after you have the gateway URL and agent key.

Install the CLI

The Dome CLI is the primary interface for managing agents, deploying rules, and operating the platform. Install it, then confirm the binary is on your PATH.
Homebrew 6 requires you to trust a third-party tap before it loads its formulae. On older Homebrew, brew trust is unnecessary and harmless.
Confirm the binary is on your PATH:

Sign in

Log in with your provisioned account. The CLI opens a browser-based SSO flow and stores a session token locally on success.
If your invitation points at a non-default environment, for example a dedicated development stack, pass the server URL explicitly:
Confirm the session:
You should see Authenticated true with your server and org. List the contexts available to your account. You will provision a sandbox under a tenant in the next section.
This tutorial runs entirely in a sandbox. In a production workspace, attaching backends is typically an operator action and deploying rules a security action.

Prepare your environment

Dome nests resources so teams can share a company account without sharing data.
  • An organization is the company boundary for billing, ownership, and invites.
  • A tenant is a hard isolation wall inside that company. Agents and data in one tenant cannot see another.
  • A workspace is where you actually work: agents, tools, rules, and audit. Refer to Platform scope concept.
A sandbox is a disposable workspace with the same capabilities as production, safe to throw away. Provision one:
The server prefixes the name, creating sandbox-get-started. Sync your local contexts and switch into it:
Confirm you are on the sandbox and note the gateway host. You need it when you configure your client:
Check that the workspace reads sandbox-get-started before continuing. Everything after this point creates or changes resources.

Add a tool

A tool is a backend the gateway calls on an agent’s behalf. The agent never sees its URL or credentials. Register the public demo server as demo-hr and attach it to Default, the Gateway your client will connect to. A tool is unreachable until it belongs to one.
The connection name prefixes every tool it exposes, so the demo server’s ten tools become demo-hr/it/get_incidents, demo-hr/hr/get_employee, and so on. You will use those qualified names when you write rules.

Redact contact fields

The assistant needs employee directory details. It does not need anyone’s email address or phone number. A Guard inspects tool responses before they reach the agent, so you can strip those fields without asking the backend to change. Tool connections take JSON Filters, which match fields by path and act on them. Create redact-contact.json:
redact-contact.json
The **. prefix is recursive descent: it matches the named field at any depth. That covers the top-level email on an employee record and the nested primary_contact.email on a customer record, without enumerating either path. Create the Filter from that config:
You should see Filter created: redact-contact with an ID and v1. Filters are versioned, so a later change deploys a new version and leaves this one in history. Creating a Filter does not apply it. Assign it to the response direction on the connection:
Assignments are per direction. This one inspects what comes back from the tool. A request assignment would inspect the arguments going out.

Create the agent

Register an agent to mint its identity, then issue a credential.
The CLI prints Agent registered: hr-assistant with the agent UUID. The API key is shown once. Save it before moving on:
Store the Token: dome_… value in a password manager or your client config directly. It is a bearer token for a live gateway, so treat it like a production credential.

Set access rules

Access in Dome is two decisions. First, may this agent reach a Gateway at all? Second, once it is there, which tools may it actually call? You will grant the first with a Gateway access grant, then tighten the second with Cedar Rules.

Grant gateway access

You should see confirmation that hr-assistant was granted access to Default. That grant does two things:
  1. Admits the agent at the Default endpoint, so the gateway will accept its requests.
  2. Permits every resource currently in Default, plus any resource added later.
That is a useful baseline for a brand-new agent, but it is broader than this HR assistant’s job. The next step narrows it.

Deploy authorization rules

For this assistant, you will deploy three rules:
  1. Keep tool discovery open, so the client still lists every demo tool.
  2. Name the five HR and IT tools this assistant may call.
  3. Add a forbid … unless that blocks everything else.
The last two share the same allowlist. forbid always wins over permit, so tools outside the list stay denied even when the Gateway grant would allow them. Create hr-assistant.cedar:
hr-assistant.cedar
Deploy it as an agent-scoped bundle. Scoping to hr-assistant is what limits principal is Dome::Agent to this one agent:
A successful deploy prints Bundle deployed: hr-assistant with a version and hash. Because only the mcp:call rules carry an allowlist, these rules gate invocation, not discovery. The assistant still lists all ten demo tools in your client. It just cannot call the six outside its job. Keeping discovery open is what lets you watch a denial happen instead of wondering why a tool vanished.

Connect your client

Point your MCP client at the Default gateway’s tools ingress and authenticate as the agent. That path is where MCP discovery and tools/call traffic enter the data plane:
If you would rather not configure an MCP client, keep this URL and the agent token handy and jump to Verify the results — the curl tab hits the same tools ingress. Retrieve the three placeholders:
  • AGENT_API_KEY. The Token: dome_… value printed by dome agents create-key when you created the agent. Tokens are shown once and cannot be recovered. If you did not save it, mint another and use that value:
  • GATEWAY_HOST. Prepend https:// to your current Dome host, for example https://gateway.dev.domesystems.ai.
  • DEFAULT_GATEWAY_ID. The UUID of the Default gateway.
The result should look similar to https://gateway.dev.domesystems.ai/gateways/3f9a2c14-8d7e-4b1a-9c02-5e6f7a8b9c01/mcp. That /mcp path is the tools ingress; model traffic uses a different path under the same /gateways/<id> prefix. Register that endpoint with your client, passing the agent token as a bearer credential. Or skip the tabs below and use the same URL and token with curl in Verify the results.
Use project .cursor/mcp.json or Settings → MCP:
Gitignore this file. It holds a live gateway credential.
Reload MCP. Tools such as demo-hr/hr/list_employees appear once the client connects. If you are verifying with curl instead, you can skip the reload and continue.
These are remediation steps if you get stuck:
  • No tools appear after reloading. Confirm the URL ends in /mcp and includes the /gateways/<id> segment. A bare gateway host serves nothing. Then confirm the agent has both a gateway grant and a deployed bundle:
    Your bundle permits mcp:discover outright, so a DENY here means the bundle did not deploy. An empty access list means the grant did not land.
  • Every call returns an authorization error. The token is incomplete, or it belongs to a different agent. Tokens are shown once and cannot be recovered, so mint a fresh one and replace the credential in your client:
  • The employee record still shows a real email address. The Filter exists but is not assigned, or it is assigned to the wrong direction. Confirm the chain on the response path:
    Assignments are picked up on the next gateway sync, so allow a moment after setting the chain.
  • Tools appear but calls time out. The demo server is public and unauthenticated, so a timeout usually points at egress restrictions on your network. Confirm you can reach https://demo-mcp.domesystems.ai/mcp directly.

Verify the results

Confirm allow, redact, and deny without changing the chat UI. Only the tool path is governed. Use an AI client if you connected one above, or POST MCP JSON-RPC to the same tools ingress with curl. Export the same placeholders once if you are using the curl tab:
Ask the assistant the prompts below.
  1. Who works here? The call is allowed. You receive the demo employee directory, including ids such as E001:
  2. Who is E001, and how do I reach them? The call is allowed, and the Filter masks the contact field on the way back:
    The assistant learns who the person is and loses the ability to contact them directly. The backend still returned the real address. The Filter replaced it before the agent saw it.
  3. What is Alice’s salary? The call is denied. demo-hr/finance/get_salary is not in the allowlist, so the forbid applies. The gateway returns a JSON-RPC error rather than data:
    Your assistant paraphrases this in its own words, so the exact wording in chat varies. The audit trail below is the authoritative record.
  4. Pull up the Acme Corp customer record. Also denied, and you never named this tool in the rule. That is the difference between an allowlist you maintain by hand and a boundary that holds by default.

Inspect the audit trail

Every allow, filter, and deny is attributable to the agent:
You should see mcp.tool_call.attempted, mcp.tool_call.completed, mcp.tool_result.filtered, and access.denied, each carrying the hr-assistant agent ID. To read only the rejections, filter by result:

Test rule changes without a client

Simulation runs the same evaluator as the gateway with no side effects, so you can check a rule before shipping it without a client reload or a real call:
Expect ALLOW. Swap the resource for demo-hr/finance/get_salary or demo-hr/sales/get_customer and expect DENY for both. This is the loop to use when you tighten the rule later.

Next steps

You learned how to register an agent, attach a tool through a Gateway, deploy Rules and a Guard, and verify allow, redact, and deny. Keep the sandbox-get-started workspace for the rest of this track. Continue with: