---
url: 'https://adk.nht.io/the-loop/tools/trust-and-safety.md'
description: >-
  How Tool.trusted flips the executor's render envelope, what it does not do for
  Media results, and where safety/authorisation actually attaches via gates.
---

# Trust and safety

How the `trusted` flag on a [`Tool`](https://adk.nht.io/api/@nhtio/adk/forge/classes/Tool) shapes the executor's render envelope, why it does not propagate to [`Media`](https://adk.nht.io/api/@nhtio/adk/common/classes/Media) results, and where the safety boundary actually lives (the handler, via gates — not the registry).

[Tools](../tools) covers the `Tool` constructor; [Trust tiers](../trust-tiers) covers what each envelope means at render time; [Gates](../gates) covers the suspension primitive every authorisation flow attaches to.

## Trust on the tool, not on the battery

Every tool's output flows through the executor's **untrusted** envelope by default. `trusted: true` on a tool flips that for the rendering of its `string` / `Uint8Array` / artifact results: the executor reads [`Tool.trusted`](https://adk.nht.io/api/@nhtio/adk/forge/classes/Tool#property-trusted) at render time and routes the output through the [trusted envelope](../trust-tiers/envelopes) instead. The flag exists because trust is a property of the *content* the tool produces, not a property of how a particular battery happens to be configured — putting it on the tool means the trust signal travels with the tool wherever it is registered. Q\&A tools that surface operator-authored answers, human-in-the-loop approval gates, configuration tools that return developer-authored constants — those are the canonical cases. Anything returning content from the open web, an external API, or a search index stays untrusted, which is the default for a reason.

What [`Tool.trusted`](https://adk.nht.io/api/@nhtio/adk/forge/classes/Tool#property-trusted) set to `true` *means* at render time is the same thing it would mean if the operator had typed the content into the system prompt themselves: the executor surfaces the result to the model as developer/operator intent, which the model is allowed to read as policy, configuration, or first-party guidance rather than as third-party data that needs to be quoted, summarised, or otherwise held at arm's length. That is exactly the level of authority you do not want to grant to content the tool fetched from anywhere it does not fully control. If a tool's output could ever be authored — even indirectly — by someone outside your trust boundary, the flag stays off.

::: danger `Tool.trusted` does *not* propagate to `Media` results
[`Media`](https://adk.nht.io/api/@nhtio/adk/common/classes/Media) carries its own [`trustTier`](../primitives#media) and the battery reads it directly when rendering a `Media` result. `Tool.trusted` is not consulted, does not override, and does not launder it. A trusted tool that returns a `third-party-public` image renders that image in the untrusted envelope, every time — the same principle that already governs [`Retrievable.trustTier`](../primitives#retrievable) inside a trusted tool's output. Trust is a property of where the *content* came from, not who fetched it. If your tool produces `Media`, the trust decision is made at construction ([`Media.userAttachment`](https://adk.nht.io/api/@nhtio/adk/common/classes/Media#userattachment), [`Media.toolGenerated`](https://adk.nht.io/api/@nhtio/adk/common/classes/Media#toolgenerated), [`Media.retrievedPublic`](https://adk.nht.io/api/@nhtio/adk/common/classes/Media#retrievedpublic), [`Media.retrievedPrivate`](https://adk.nht.io/api/@nhtio/adk/common/classes/Media#retrievedprivate), or the bare constructor) and [`Tool.trusted`](https://adk.nht.io/api/@nhtio/adk/forge/classes/Tool#property-trusted) has nothing further to say.
:::

::: info Trust framing is the executor's job — but you fill in the flag
The ADK records `trusted` and hands it to the executor; the executor decides what to render and how. A battery that ignores `tool.trusted` and renders everything in one envelope is a battery that has voluntarily disabled the only signal the tool gave it. Picking that battery is your call — the ADK will not second-guess it, but it will also not paper over it.
:::

## Safety, authorisation, and human approval

::: danger The ADK cannot make your tools safe
A tool's handler is the last line of defence before a side effect happens. The ADK cannot tell you which actions to allow, which to require approval for, which to deny outright — those are application decisions, not framework decisions. What the ADK gives you is the primitive every one of those defences attaches to: [Gates](../gates).

Gate inside the handler, not in middleware downstream. Middleware can be misordered, replaced, or skipped under a particular configuration; the handler is the one piece of code that always runs at the exact moment the side effect is about to fire. If a tool can do something you would not let a stranger trigger, the handler is where `await` [`TurnContext.waitFor`](https://adk.nht.io/api/@nhtio/adk/types/interfaces/TurnContext#property-waitfor) belongs.
:::

See [Gates](../gates) for the ADK's position on safety, the canonical patterns (RBAC, per-call human approval, second-factor elevation, external-system handoffs), and the worked tool-handler examples that put gates in the right place.
