---
title: "Edge, model and tool security"
url: /trust/security
---

# Edge, model and tool security

> Security past the Keys: the edge in front of every product, untrusted text on an agent's model path, and act classes and signed tool lists that agents trust.

Security past the [Keys](/reference/platform.md#key) covers three places: the edge every call crosses, the model path an agent reads, and the tools a buyer's agent trusts.

**A call, from the edge to its tool.** A request from anywhere.

1. Edge: rules and bots. Or challenged: or refused.
2. Policy (passes): IPs, mutual TLS. Or 403: off the list.
3. Schema (admitted): every field.
4. Model path (an agent reads): marked, redacted.
5. Tool (the gate decides): its act class. Or held: irreversible.

Text an agent reads never decides a move; the gate does.

## Three places, one gate
Every family below feeds [the one decision](/identity.md#decision) or runs before it; none of them is a second place a rule can live.

| Family | What it does |
| --- | --- |
| The edge | Rules against known attacks, floods absorbed before they reach a region, and limits on bursts per address and per Key |
| Bots | `operate.edge.bots`: allow, challenge or refuse unsigned automated traffic; a signed agent passes on [its rung](/identity/sign-in.md#agents) |
| Customer network policy | An IP list and mutual TLS each Customer's admin sets as Verbs, when `operate.edge` lets it; a call from outside answers 403 |
| Schema at the gate | Every body checked against its Verb's schema and size before anything runs; unknown fields are refused, never ignored |
| Security Events | A burst refused, a failed sign-in streak, a Key used from a new country, a list changed: each an Event a [Watch](/reference/platform.md#watch) or a sink receives |
| Untrusted text | Text from a [Source](/patterns/dataset-api.md#how-a-field-is-filled), an inbound message or a member reaches an agent marked as data; it can ask, never decide, since every tool call still passes the gate |
| Redaction | Fields by data class, redacted or refused before a model sees them, as [data governance](/trust/governance.md) sets |
| Provider terms | The model router uses only providers that keep nothing and process in the [Namespace](/reference/platform.md#namespace)'s region, and a call no such provider serves is refused |
| Output checks | Each generative and agentic Verb's output checked against its `returns` and its `check` before it is kept or sent |
| Act classes | Each Verb is `read`, `write`, `money`, `sends` or `irreversible`, from its moves or from `acts`, and a mandate can name the classes it covers |
| Signed tool lists | The tools a product serves, with their act classes, signed and pinned to the [Definition](/reference/platform.md#definition)'s [Digest](/reference/platform.md#digest); a buyer's agent re-approves when the list changes |
| Reports | `/security` on your Domain, rendered from the file, with a Verb that takes a vulnerability report and answers it |

| Act class | MCP annotations | What the decision adds |
| --- | --- | --- |
| `read` | `readOnlyHint` | Nothing past the Role and the plan |
| `write` | `idempotentHint` where a retry is safe | The record's state and rules |
| `money` | `openWorldHint` | A mandate that covers the price and currency |
| `sends` | `openWorldHint` | Consent on the channel, and the sending identity |
| `irreversible` | `destructiveHint` | A present person or an approval, never an agent alone |

### Example
Filing with the state is irreversible, bots are challenged, and each Customer may set its own IP list and mutual TLS.

```ts title="definition.ts"
import { define, agentic } from 'apis.dev'

/** Annual reports for each client, filed with the state once the client signs. */
export default define({
  name: 'filings', domain: 'filings.apis.dev',
  Filing: {
    company: 'string', year: 'number',
    status: {
      order: [],
      sign: { in: 'ordered', floor: 'signature' },
      file: { in: 'signed', run: agentic('File the signed report with the state') },
      accept: 'filed', reject: 'filed',
    },
  },
  acts: { 'Filing.file': 'irreversible' },          // a filing cannot be taken back
  operate: { edge: { bots: 'challenge', ips: true, mtls: true } },
  offer: {
    'Filing.order': { price: 25, when: 'accepted', accept: 'customer',
                      acceptWithin: '7d', remedy: 'redo', grade: 'measured' },
  },
})
```

A buyer's agent reads the signed tool list before it calls, and pins the digest.

```json title="filings.apis.dev/.well-known/agents.json · tools"
{
  "tools": {
    "definition": "sha256:9d41c07e",
    "signature": "ed25519:W2nQ8rT5vX1bK7mY3pL9sD4fH6jC0aZ",
    "items": [
      { "name": "orderFiling", "act": "money" },
      { "name": "signFiling", "act": "write", "person": true },
      { "name": "fileFiling", "act": "irreversible" },
      { "name": "getFiling", "act": "read" }
    ]
  }
}
```

## Rules, lists and keys, state by state
Every move is a Verb on the product's [Interfaces](/every-product.md) or the [Operator plane](/trust/planes.md), and each writes its Event.

| Thing | States | What moves it |
| --- | --- | --- |
| A client at the edge | `allowed`, `challenged`, `blocked`, then `released` | Its traffic against the rules and the bot setting; a block lapses or your operator releases it |
| A Customer's IP list | `draft`, `enforced`, `removed` | The Customer's admin; enforcing it never locks out the admin who set it |
| A mutual TLS certificate | `active`, `expiring`, `rotated`, `revoked` | The Customer's admin; the product warns 30 days before it expires |
| A security Event | `raised`, `acknowledged`, `resolved` | The edge or the gate raises it; the Customer's admin or your operator answers it |
| A signed tool list | `published`, then `changed` and `published` again | Each deploy that adds, removes or reclasses a tool; each buyer's pin holds until its agent re-approves |
| A vulnerability report | `received`, `triaged`, `fixed`, `disclosed` | The reporter, your team, and the deploy that fixes it |

## What Customers, reviewers and agents meet
- **A Customer's admin.** Its own IP list and mutual TLS, security Events in its audit log, and a 403 that says which rule refused.
- **A security reviewer.** The edge rules, how text reaches an agent, which models see which classes, and every tool's act class.
- **A buyer's agent.** A signed tool list it pins, act classes its mandate can name, and a re-approval when the list changes.
- **An agent inside the product.** Text it reads cannot widen what it may do, because each tool call meets the gate.

---

Every call crosses the edge, every text an agent reads is data, and every tool carries its act class, so the gate decides alone.