> For an index of all Botscent documentation, see https://botscent.nibnalin.me/llms.txt.

# The trust model

Which verdict you can use to decide access, and what a verified signature proves.

The *trust model* says which verdict you can use to decide access. Only the request's own verdict, checked with `isVerified`, is fit for that.

```ts title="app/api/checkout/route.ts"
import { inspect, isVerified } from 'botscent/server'

export async function POST(request: Request) {
  const own = await inspect(request)
  const verified = isVerified(own, 'chatgpt')
  // => true only for a signature verified against ChatGPT's bundled keys
  return Response.json({ verified })
}
```

## Which verdict to use for what

| Verdict                                            | Where Botscent computes it                                                     | Use it for                             |
| -------------------------------------------------- | ------------------------------------------------------------------------------ | -------------------------------------- |
| The request's own verdict, with `isVerified` true  | On your server, from a verified signature or the platform's verified-bot field | Access                                 |
| The request's own verdict, with `isVerified` false | On your server, from declarations and product shapes that anyone can produce   | Measurement and adapting what you show |
| The page verdict                                   | In the visitor's browser                                                       | Measurement and adapting what you show |
| A page report                                      | In the visitor's browser, sent by the page's own scripts                       | Measurement and adapting what you show |
| A verdict from `combine`                           | Partly in the visitor's browser                                                | Measurement and adapting what you show |

The page verdict, a page report and a joined verdict all come from the visitor's browser. Scripts on the page can change them. So none of them is fit to decide access.

## What `isVerified` checks

[`isVerified`](/docs/server-api#isverified) has two forms:

* `isVerified(verdict)` is true when `reasons` holds `signer.web-bot-auth.verified` or `signer.edge-verified-bot`, without the `page.` prefix. Only `inspect` gives those reasons.
* `isVerified(verdict, name)` is true when `reasons` holds `signer.web-bot-auth.verified`, `agent_name` is `name`, and no reason has the `page.` prefix.

In Python, the function is `botscent.is_verified`, with the same two forms.

The platform's verified-bot field never passes the check with a name. The field says that some agent was verified, not which agent. So `isVerified(verdict) && verdict.agent_name === 'chatgpt'` can join the platform's check of one agent with a name that the agent only declared.

> **Warning:** Do not use `agent_name` or a reason string to allow access. Anyone can send the headers that produce them. Use `isVerified(verdict, 'chatgpt')` for one agent.

## What a verified signature proves

A verified signature proves that the agent operator's infrastructure signed the request. It does not prove who the person is, or which model runs the session.

Each signature has a time window, from 5 s before its `created` time to its `expires` time. Someone who captures a signed request can replay the signature to the same host within that window.

## Keys are fixed in each release

The server half makes no request to fetch keys. Each release bundles the signers' keys as the maintainers fetched them for that release. The release notes give the date of that fetch.

So a signer's key changes reach you only when you upgrade:

* A key that a signer adds after the release gives `signer.web-bot-auth.declared` until you upgrade.
* A key that a signer removes, because it rotated or leaked, stays verified until you upgrade. Nothing in a deployed copy can revoke it.

If you allow access with `isVerified`, keep the package current. The age of your release limits how old your keys can be. A scheduled job in the repository opens a pull request when a signer's published keys change.

## What no verdict tells you

* No verdict proves that a person is present. `human` means only that Botscent saw no agent evidence.
* No verdict describes the person behind an agent.
* No verdict says who performed a particular action.
* Botscent does not authorize anything. Your code decides what a verified agent can do.

## Related

* [The verdict](/docs/verdict): what `type`, `agent_name` and `reasons` mean.
* [From the page to the server](/docs/page-to-server): how a page report reaches your server and stays apart.
* [Versions and stability](/docs/versions): which releases change verdicts, and why to pin a version.
