મુખ્ય સામગ્રી પર જાઓ
Back to Blog
Engineering

What signed AI agent requests prove, and what they don't

HTTP message signatures give AI agents a verifiable identity. Here is exactly what a valid signature establishes, what it does not, and how to use it.

Toshendra Sharma

By Toshendra SharmaFounder & CEO, AgentCredia · Published November 12, 2026

What signed AI agent requests prove, and what they don't
November 12, 2026
11 min read
#Web Bot Auth#HTTP Message Signatures#Agent Identity#API Security

A valid signature on an AI agent request proves key possession, association with a published identifier such as the operator's domain, integrity of the signed components and freshness within the signed window. It does not prove who instructed the agent, that a person delegated authority, who the operator is in the real world, or that the action is permitted. Treat it as verified client identity, and keep authorization with your own credentials and rules.

That is a real step up from the old approach. For most of the web's history, automated clients have identified themselves with a string. The User-Agent header says "I am this crawler", and HTTP defines it only as information about the user agent originating the request (RFC 9110). The server either believes it or runs extra checks to find out. That has never been a strong foundation, and it is a poor fit for AI agents that act on behalf of real users.

Cryptographic request signing changes this. An agent that signs its requests can give you something a header string never could: evidence you can verify. The IETF Web Bot Auth working group is chartered to standardize methods for cryptographically authenticating automated clients to websites, and that work is shaping how signed agent traffic should look. For how this fits a product team's roadmap, see verified automated requests.

Signatures are easy to misunderstand in the other direction, though. A valid signature is strong evidence about one specific thing. Teams that read it as evidence about everything else end up making authorization decisions on the wrong basis. This post explains exactly what a signature establishes and how to design around it.

How signed agent requests work

HTTP Message Signatures

RFC 9421 defines HTTP Message Signatures: a standard way for a sender to sign selected components of an HTTP message and for a receiver to verify them. Two headers carry the result:

  • Signature-Input lists which components were signed (for example the method, the target URI, the authority and specific headers) together with parameters such as created, expires, keyid, alg and an optional tag.
  • Signature carries the signature value itself.

The receiver rebuilds the same "signature base" from the request it received, fetches the public key for the referenced key identifier, and checks the signature. If anything covered by the signature changed in transit, verification fails.

Web Bot Auth

The IETF Web Bot Auth working group is applying HTTP Message Signatures to automated traffic. Its protocol document, HTTP Message Signatures for automated traffic, describes how an automated client signs outbound requests, requires the signature tag to be web-bot-auth, defines a Signature-Agent header for in-band key discovery, and specifies a key directory based on JWKS served at a well-known URI, typically under the operator's own domain. A server can then validate that a request was signed by a key that the operator publicly associates with its agent.

As of November 2026, these documents are Internet-Drafts and continue to evolve, so implementations should track the current versions rather than treat any single draft as final. The core idea is stable: the operator publishes keys, the agent signs requests, the receiver verifies.

A minimal verification flow

At a high level, a server that validates signed agent requests does the following:

  1. Parse Signature-Input and Signature, and confirm that the covered components include what you need, such as @method, @authority and @path or @target-uri.
  2. Check the created and expires parameters against your clock, with a small tolerance, and reject stale or future-dated signatures.
  3. Resolve the key: fetch the operator's published key directory over HTTPS, find the key referenced by keyid, and cache it with sensible expiry.
  4. Rebuild the signature base exactly as RFC 9421 specifies and verify it with the published public key and declared algorithm.
  5. Record the result with its scope: which key, which identifier, which request, at what time.

Our guide on how to verify signed agent requests covers each of these steps in more detail. Here is a simplified look at the parsing step in Node.js. It is illustrative, not a complete verifier: production code should use a maintained RFC 9421 library rather than hand-rolled parsing.

JS
// Extract the signature parameters for a quick inspection.
function inspectSignatureInput(headerValue) {
  // Example: sig1=("@method" "@authority" "@path");created=1731400000;expires=1731400300;keyid="abc";tag="web-bot-auth"
  const [label, rest] = headerValue.split(/=(.*)/s);
  const components = rest.match(/^\(([^)]*)\)/)?.[1].split(" ").map((c) => c.replace(/"/g, "")) ?? [];
  const params = Object.fromEntries(
    [...rest.matchAll(/;([a-z]+)=("[^"]*"|\d+)/g)].map(([, k, v]) => [k, v.replace(/"/g, "")]),
  );
  return { label, components, params };
}

const now = Math.floor(Date.now() / 1000);
const { components, params } = inspectSignatureInput(req.headers["signature-input"]);
const fresh = Number(params.created) <= now + 5 && (!params.expires || Number(params.expires) > now);
const coversTarget = components.includes("@authority") && (components.includes("@path") || components.includes("@target-uri"));

If fresh or coversTarget is false, the signature cannot support a strong conclusion about this request, even if the cryptography checks out.

What a valid signature proves

When verification succeeds and your checks on freshness, covered components and key provenance pass, you have established:

  • Key possession. The request was signed by someone holding the private key that corresponds to the published public key.
  • Association with a published identifier. That key is published under the operator's identifier, typically its domain, so the request is attributable to that operator's agent.
  • Integrity of the covered components. The method, target and any other signed components were not altered after signing.
  • Freshness within the signed window. The signature was created recently, which limits simple replay.

That is valuable. It turns "this client claims to be operator X" into "this request was signed with operator X's published key". You can attribute traffic reliably, apply per-operator policies and keep an auditable record.

What a valid signature does not prove

Who instructed the agent

The signature identifies the agent's operator, not the person or system that gave it a task. An AI assistant fetching your page might be acting for one of your customers, for a stranger, or on its own schedule. Nothing in the signature tells you which.

That a person delegated authority

Delegation, a person authorizing an agent to act for them within limits, is a separate problem. A signed request from an assistant does not mean any particular user approved this particular action, and it does not carry that user's permissions in your system.

The real-world identity behind the operator

A domain-associated key tells you which domain published it. It does not establish the legal entity behind that domain, its reputation, or its intentions. A newly registered domain can publish keys as easily as a well-known one.

That the action is safe or permitted

Most importantly, identity is not authorization. A well-identified agent can still request something it should not be allowed to do, and a correctly signed request can still be harmful. Whether the action is permitted in your application remains your decision, made with your own authentication, authorization and business rules.

Anything outside the covered components

If the signature covers only the method and authority, the path and body could differ from what the signer intended. Always check which components are covered before relying on them.

Three separate questions

A clean way to design around signed requests is to keep three questions apart:

  1. Agent identity: who is calling? Answered by signature verification and similar evidence.
  2. Credentials: which account or integration is this? Answered by your API keys, OAuth tokens or sessions.
  3. Authorization: what may this caller do here? Answered by your access-control rules for that account and route.

A request can be strong on one and absent on another. A signed agent with no account credentials can read public content. An API key without a signature might be a backend job, a person's script or an agent framework. Merging these questions into one "trusted" flag is where most mistakes come from.

Designing policies around signatures

With the boundaries clear, signed requests become a practical tool:

  • Prefer structured access for verified agents. Serve signed agents a structured API or Markdown representation of content instead of making them parse pages built for people.
  • Use signatures for attribution and rate policy. Apply per-operator rate limits and track usage by verified identity instead of by easily changed headers.
  • Keep authorization where it belongs. Account changes, purchases and data exports still require the appropriate credentials and permissions, signed or not.
  • Treat unsigned claims differently. A client that only declares itself an agent should be labeled with a declared basis, and your policy can give it less latitude than a verified one. Some operators also publish IP ranges for their crawlers and agents, for example OpenAI and Anthropic, which gives you a network-level check for unsigned traffic that claims to come from them.
  • Plan for failure modes. Decide what happens when a key directory is unreachable, a signature is expired or the algorithm is unsupported. Record the outcome as unverified, and never upgrade a failed check to a verified result. Requests that end up with no usable evidence belong in Unknown, which our guide on handling unknown traffic treats in depth.

Operational details that matter

  • Clock skew. Allow a small tolerance on created and expires, and keep your servers time-synchronized.
  • Key caching and rotation. Cache published keys, honor reasonable expiry, and refetch when you see an unknown keyid so operators can rotate keys without breaking verification.
  • Replay. Short validity windows limit replay. For sensitive routes, consider tracking recently seen signatures within the window.
  • Proxies and normalization. Load balancers and CDNs can modify headers or paths. Verify at a point where the request still matches what the agent signed, or account for known rewrites.
  • Logging. Store the verification result, the key identifier and the covered components, not the raw signature alone, so later reviews can see what was established.

Where Proof of Actor fits

Proof of Actor treats a validated signature as what it is: verified evidence of agent identity, recorded with the basis "verified" and scoped to the request it came with. It sits alongside declared and inferred signals, and next to the Agent class it never implies authorization. Detect gathers and validates the evidence, Understand shows which agents and operators are using which routes, and Route lets your application apply its own policies, starting in observation mode, with every enforcement decision yours.

If you run an API, MCP server or web application and want verified agent traffic handled properly, see how it applies to APIs and MCP servers, or apply for early access. For a deeper look at how results are formed, see How Proof of Actor works.

Sources

Key Takeaways

  • A valid HTTP message signature proves the request was signed with a key associated with a published identifier, such as an operator's domain.
  • It does not prove who instructed the agent, whether a person delegated authority, or whether the action is safe.
  • Treat agent identity, API credentials and authorization as three separate questions.
  • Validate created and expires parameters, covered components and key provenance, or the signature proves less than you think.
  • Signed requests deserve better treatment than unsigned claims, through policies you define per route.