<?xml version="1.0" encoding="utf-8"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     version="3"
     category="std"
     consensus="true"
     docName="draft-vilgalys-webbotauth-signed-agent-metadata-00"
     ipr="trust200902"
     submissionType="IETF"
     tocInclude="true"
     sortRefs="true"
     symRefs="true"
     xml:lang="en">
  <front>
    <title abbrev="Signed-Agent-Metadata">The Signed-Agent-Metadata HTTP Header Field for Web Bot Auth</title>
    <seriesInfo name="Internet-Draft" value="draft-vilgalys-webbotauth-signed-agent-metadata-00"/>
    <author initials="R." surname="Vilgalys" fullname="Rim Vilgalys">
      <organization>Google</organization>
      <address>
        <email>interweb@google.com</email>
      </address>
    </author>
    <author initials="P." surname="Gonzalez" fullname="Pablo Gonzalez">
      <organization>Google</organization>
      <address>
        <email>pablogm@google.com</email>
      </address>
    </author>
    <date year="2026" month="November" day="2"/>
    <area>Security</area>
    <workgroup>Web Bot Auth</workgroup>
    <keyword>Web Bot Auth</keyword>
    <keyword>HTTP Message Signatures</keyword>
    <keyword>Signed-Agent-Metadata</keyword>
    <keyword>Bot Authentication</keyword>
    <abstract>
      <t>Web Bot Auth uses HTTP Message Signatures to let automated HTTP clients authenticate their identity to origins via the <tt>Signature-Agent</tt> header field. When a multi-tenant agent platform signs outbound requests with a shared key, all customer workloads on that platform share a single cryptographic identity. Abusive traffic from one tenant or workload can degrade the reputation of the entire platform and cause origins to block legitimate tenants.</t>
      <t>This document defines the <tt>Signed-Agent-Metadata</tt> HTTP header field, an RFC 9651 Dictionary that carries optional, pseudonymous per-request metadata (<tt>product</tt>, <tt>project</tt>, and <tt>session</tt>). By signing <tt>Signed-Agent-Metadata</tt> inside the Web Bot Auth signature, a platform enables verifiers to evaluate traffic, apply rate limits, and isolate reputation at a narrower scope than the signing origin.</t>
    </abstract>
  </front>

  <middle>
    <section anchor="introduction" numbered="true">
      <name>Introduction</name>

      <section anchor="problem-statement" numbered="true">
        <name>Problem Statement: Shared Fate on Multi-Tenant Platforms</name>
        <t>Web Bot Auth (<xref target="I-D.ietf-webbotauth-httpsig-protocol"/>) allows automated HTTP clients to cryptographically sign requests using HTTP Message Signatures (<xref target="RFC9421"/>) and advertise their key discovery URI in the <tt>Signature-Agent</tt> header field.</t>
        <t>This model maps cleanly when a single organization operates a single crawler or bot with robust abuse controls. However, cloud browser providers, hosted AI agent platforms, and enterprise gateways run thousands of independent customer workloads behind shared egress infrastructure. Consider a fictional Acme Corp (<tt>platform.acme.com</tt>), which has pivoted from mail-order industrial products into hosting cloud AI agents. When Acme signs outbound requests with its platform domain key, all traffic from its customers shares one <tt>Signature-Agent</tt> identity:</t>
        <sourcecode type="http-message"><![CDATA[
# NOTE: '\' line wrapping per RFC 8792

Signature-Agent: "https://platform.acme.com/.well-known/\
  http-message-signatures-directory"
]]></sourcecode>
        <t>This creates a shared-fate problem for both platforms and verifiers (origins, CDNs, and security services). Suppose one tenant runs an aggressive scraping workload against <tt>shopping.com</tt>, while hundreds of other tenants run benign research and shopping agents on the same platform. The verifier at <tt>shopping.com</tt> observes malicious traffic authenticated only by <tt>platform.acme.com</tt>. Without sub-identifiers, the verifier must choose between two poor outcomes:</t>
        <ol>
          <li><strong>Penalize the entire platform</strong>: Apply rate limits, challenges, or blocks to all requests from <tt>platform.acme.com</tt>, which disrupts legitimate tenants sharing the platform.</li>
          <li><strong>Permit platform-level abuse</strong>: Allow traffic from <tt>platform.acme.com</tt> to bypass controls, which leaves <tt>shopping.com</tt> exposed to the abusive tenant.</li>
        </ol>
        <t>Platforms and verifiers need a lightweight mechanism to disambiguate sub-identities and convey per-request operational metadata under a shared <tt>Signature-Agent</tt> key without exposing personally identifiable information (PII) on the wire.</t>
      </section>

      <section anchor="relationship" numbered="true">
        <name>Relationship to Web Bot Auth and Signature Agent Cards</name>
        <t>The Web Bot Auth ecosystem separates cryptographic key discovery, static agent description, and dynamic per-request metadata:</t>
        <ul>
          <li><strong>Base Protocol (<xref target="I-D.ietf-webbotauth-httpsig-protocol"/>)</strong>: Defines how an automated client signs HTTP requests and points verifiers to its public keys via <tt>Signature-Agent</tt>.</li>
          <li><strong>Signature Agent Card (<xref target="I-D.meunier-webbotauth-registry"/>)</strong>: Defines a hosted JSON metadata document where an agent operator advertises static, operator-level properties, including <tt>client_name</tt>, <tt>contacts</tt>, and a <tt>web_bot_auth</tt> object (<tt>purpose</tt>, <tt>trigger</tt>, <tt>rate-expectation</tt>, <tt>rfc9309-product-token</tt>, and <tt>rfc9309-compliance</tt>).</li>
          <li><strong>Per-Request Metadata (<tt>Signed-Agent-Metadata</tt>, this document)</strong>: Defines an in-band HTTP header field that carries dynamic, pseudonymous sub-identifiers (<tt>product</tt>, <tt>project</tt>, <tt>session</tt>) covered by the per-request HTTP Message Signature.</li>
        </ul>
        <t><tt>Signed-Agent-Metadata</tt> (SAM) is additive to the Signature Agent Card. Static properties that describe the agent as a whole (such as <tt>purpose</tt> or <tt>trigger</tt>) belong in the hosted Signature Agent Card and are intentionally omitted from <tt>Signed-Agent-Metadata</tt> to avoid redundancy. Similarly, if an operator already publishes a separate <tt>Signature-Agent</tt> URI and Signature Agent Card for each product, the operator does not need to include the <tt>product</tt> member in <tt>Signed-Agent-Metadata</tt>.</t>
      </section>

      <section anchor="related-approaches" numbered="true">
        <name>Related Approaches and Use Cases</name>
        <t>Several existing or proposed mechanisms address adjacent bot authentication problems, each targeting a different operational model:</t>
        <table>
          <thead>
            <tr>
              <th>Mechanism</th>
              <th>Primary Use Case</th>
              <th>Limitation for Multi-Tenant Shared Keys</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Distinct <tt>Signature-Agent</tt> URIs and Keys</td>
              <td>First-party crawlers, single-tenant bots, or distinct product lines where the operator hosts a dedicated JWK Set per identity.</td>
              <td>Provisioning, hosting, and caching separate key directories for thousands of dynamic customer projects or millions of ephemeral sessions creates high operational and key-fetch overhead.</td>
            </tr>
            <tr>
              <td>HTTP Cookies</td>
              <td>Maintaining stateful session continuity within a single browser instance on a single origin after an initial HTTP response.</td>
              <td>Cookies are absent on the first request to an origin, are not persisted by stateless HTTP fetchers, and can be cleared or modified by the client workload. A signed header provides platform-attested continuity from the first request.</td>
            </tr>
            <tr>
              <td>Anonymous Rate-Limiting Tokens (e.g., Privacy Pass <xref target="RFC9576"/>)</td>
              <td>Locally running agents or privacy-sensitive clients proving attestation or rate-limit compliance without linkable identifiers.</td>
              <td>Unlinkable tokens do not allow a verifier to isolate and block a specific abusive tenant mid-attack, nor do they give the platform an identifier to investigate when an origin reports abuse.</td>
            </tr>
          </tbody>
        </table>
        <t><tt>Signed-Agent-Metadata</tt> specifically addresses multi-tenant platforms that sign traffic under a common origin and need low-overhead sub-identity or specific behavior isolation.</t>
      </section>
    </section>

    <section anchor="conventions" numbered="true">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they appear in all capitals, as shown here.</t>
      <t>This document uses the following terms:</t>
      <ul>
        <li><strong>Platform</strong>: An entity that operates agent execution infrastructure and signs outbound HTTP requests with its <tt>Signature-Agent</tt> key on behalf of multiple products, customer projects, customers, or sessions/workflows.</li>
        <li><strong>Tenant</strong>: A customer organization, developer account, or billing workspace that deploys or runs automated workloads on a Platform.</li>
        <li><strong>Verifier</strong>: An HTTP origin server, reverse proxy, Content Delivery Network (CDN), or security provider that validates the HTTP Message Signature and evaluates the <tt>Signed-Agent-Metadata</tt> header field.</li>
        <li><strong>Effective Identity</strong>: The hierarchical tuple formed by the verified <tt>Signature-Agent</tt> URI and the signed <tt>Signed-Agent-Metadata</tt> identifier members present on a request, ordered from broadest to narrowest scope: <tt>(Signature-Agent, product, project, session)</tt>.</li>
      </ul>
    </section>

    <section anchor="header-field" numbered="true">
      <name>The Signed-Agent-Metadata Header Field</name>

      <section anchor="syntax" numbered="true">
        <name>Syntax</name>
        <t>The <tt>Signed-Agent-Metadata</tt> HTTP header field is a Dictionary Structured Field as defined in Section 3.2 of <xref target="RFC9651"/>. Its ABNF syntax follows the <tt>sf-dictionary</tt> production rule:</t>
        <sourcecode type="abnf"><![CDATA[
Signed-Agent-Metadata = sf-dictionary
]]></sourcecode>
        <t>Each dictionary member key is a lowercase token (<tt>key</tt> in <xref target="RFC9651"/>). Each member value defined in this specification <bcp14>MUST</bcp14> be a String (<tt>sf-string</tt> in <xref target="RFC9651"/>). Parameters on dictionary members are not defined by this specification and <bcp14>MUST</bcp14> be ignored by verifiers.</t>
        <t>An example <tt>Signed-Agent-Metadata</tt> header field with all three members present:</t>
        <sourcecode type="http-message"><![CDATA[
Signed-Agent-Metadata: product="Acme-Research", project="prj_89a0f",
  session="sess_88b1"
]]></sourcecode>
      </section>

      <section anchor="dictionary-members" numbered="true">
        <name>Dictionary Members</name>
        <t>Sending the <tt>Signed-Agent-Metadata</tt> header field is <bcp14>OPTIONAL</bcp14>, and all dictionary members within it are <bcp14>OPTIONAL</bcp14>. A platform <bcp14>MAY</bcp14> include any subset of members that fits its architecture and tenancy model to reduce shared-fate penalties across its workloads.</t>
        <table>
          <thead>
            <tr>
              <th>Member Key</th>
              <th>Type</th>
              <th>Description</th>
              <th>Example</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><tt>product</tt></td>
              <td><tt>sf-string</tt></td>
              <td>Identifier or application name of the agent software or service under the signing platform.</td>
              <td><tt>product="Acme-Labs"</tt></td>
            </tr>
            <tr>
              <td><tt>project</tt></td>
              <td><tt>sf-string</tt></td>
              <td>Opaque identifier for the tenant account, workspace, or billing project on the host platform.</td>
              <td><tt>project="prj_9012"</tt></td>
            </tr>
            <tr>
              <td><tt>session</tt></td>
              <td><tt>sf-string</tt></td>
              <td>Ephemeral, opaque identifier for a single bounded task execution, workflow run, or isolated browser context lifecycle.</td>
              <td><tt>session="run_3a2b1c"</tt></td>
            </tr>
          </tbody>
        </table>
        <t>Verifiers <bcp14>MUST</bcp14> ignore unrecognized member keys in the <tt>Signed-Agent-Metadata</tt> dictionary to allow backward-compatible extensions.</t>
      </section>

      <section anchor="scoping" numbered="true">
        <name>Hierarchical Scoping and Chaining</name>
        <t>Identifiers carried in <tt>Signed-Agent-Metadata</tt> are scoped namespaces, not globally unique identifiers. They form a strict hierarchy under the signing <tt>Signature-Agent</tt>:</t>
        <artwork><![CDATA[
Signature-Agent  (Tier 0: Platform / Signing Origin)
  +-- product    (Tier 1: Application / Product)
        +-- project  (Tier 2: Tenant / Workspace)
              +-- session  (Tier 3: Task / Session)
]]></artwork>
        <t>When evaluating <tt>Signed-Agent-Metadata</tt>, verifiers <bcp14>MUST</bcp14> apply the following scoping rules:</t>
        <ol>
          <li><strong>Chained Tuple Evaluation</strong>: A narrower identifier <bcp14>MUST</bcp14> always be evaluated within the namespace of the verified <tt>Signature-Agent</tt> and all broader <tt>Signed-Agent-Metadata</tt> identifier members present in the request. For example, <tt>session="sess_1"</tt> under <tt>project="prj_a"</tt> and <tt>session="sess_1"</tt> under <tt>project="prj_b"</tt> <bcp14>MUST</bcp14> be treated as distinct sessions.</li>
          <li><strong>Omitted Intermediate Tiers</strong>: If a platform omits an intermediate member (for example, sending <tt>product</tt> and <tt>session</tt> without <tt>project</tt>), the scoping chain consists of the present members in their defined hierarchical order: <tt>(Signature-Agent, product, session)</tt>.</li>
        </ol>
      </section>

      <section anchor="generation" numbered="true">
        <name>Identifier Generation, Stability, and Origin Scoping</name>
        <t>To make <tt>Signed-Agent-Metadata</tt> effective for isolating noisy neighbors and avoiding shared-fate penalties, platforms <bcp14>SHOULD</bcp14> follow these generation practices:</t>
        <ol>
          <li><strong>Platform Attestation and Tenant Isolation</strong>: The platform <bcp14>SHOULD</bcp14> populate <tt>Signed-Agent-Metadata</tt> members from authenticated platform state rather than allowing tenant workloads to supply arbitrary unverified values for <tt>project</tt> (or for <tt>product</tt> if shared across tenants). If a platform passes through tenant-supplied <tt>session</tt> identifiers, the platform <bcp14>SHOULD</bcp14> also include an authenticated <tt>project</tt> member (or namespace the <tt>session</tt> identifier per tenant) so that one tenant cannot collide with or spoof identifiers belonging to another tenant.</li>
          <li>
            <t><strong>Identifier Stability</strong>:</t>
            <ul>
              <li><tt>product</tt> and <tt>project</tt> values <bcp14>SHOULD</bcp14> remain stable across requests and across signing key rotations for the lifetime of the product or tenant workspace. Generating a new random <tt>project</tt> value on every HTTP request prevents reputation accrual and reduces the utility of the field.</li>
              <li><tt>session</tt> values <bcp14>SHOULD</bcp14> remain constant across HTTP requests belonging to a single bounded task execution, workflow run, or browser context lifecycle, and <bcp14>SHOULD</bcp14> change when a new task or session starts. If a platform rotates <tt>session</tt> on every request, verifiers cannot link requests within a task and will evaluate traffic at a broader tier.</li>
            </ul>
          </li>
          <li><strong>Origin Scoping for <tt>session</tt></strong>: To prevent unrelated websites from correlating a session across origins, platforms <bcp14>SHOULD</bcp14> derive <tt>session</tt> values per target origin (or per registrable domain). For example, a platform can compute an origin-scoped identifier using a keyed hash over the internal session identifier and the target authority:</li>
        </ol>
        <sourcecode type="pseudocode"><![CDATA[
session_token = base64url(
  HMAC_SHA256(
    platform_secret,
    internal_session_id + ":" + target_origin
  )
)
]]></sourcecode>
        <t>With origin scoping, a verifier at <tt>https://shopping.com</tt> observes a consistent <tt>session</tt> identifier across requests to its own origin, while <tt>https://content.org</tt> and <tt>https://news.net</tt> observe different, uncorrelated values.</t>
      </section>
    </section>

    <section anchor="signing-and-verification" numbered="true">
      <name>Signing and Verification</name>

      <section anchor="signing-requests" numbered="true">
        <name>Signing Requests</name>
        <t>When a platform chooses to send <tt>Signed-Agent-Metadata</tt> on a signed Web Bot Auth request (<xref target="I-D.ietf-webbotauth-httpsig-protocol"/>), it binds the header field to the HTTP request so verifiers can authenticate it:</t>
        <ol>
          <li><strong>Construct the Header</strong>: The platform sets the <tt>Signed-Agent-Metadata</tt> header field with the applicable dictionary members.</li>
          <li><strong>Include in <tt>Signature-Input</tt></strong>: The platform adds <tt>"signed-agent-metadata"</tt> to the list of covered components in the <tt>Signature-Input</tt> header field alongside <tt>"@authority"</tt> and <tt>"signature-agent"</tt>.</li>
          <li><strong>Compute the Signature</strong>: The platform computes the HTTP Message Signature over the signature base as specified in <xref target="RFC9421"/>.</li>
        </ol>
      </section>

      <section anchor="verifier-processing" numbered="true">
        <name>Verifier Processing</name>
        <t>When receiving an HTTP request containing <tt>Signed-Agent-Metadata</tt>, a verifier performs the following steps:</t>
        <ol>
          <li><strong>Verify Signature Coverage</strong>: Check that the <tt>Signature-Input</tt> header field for the Web Bot Auth signature (<tt>tag="web-bot-auth"</tt>) includes <tt>"signed-agent-metadata"</tt> in its covered component list. If <tt>"signed-agent-metadata"</tt> is not covered by the signature, the verifier <bcp14>MUST</bcp14> ignore the <tt>Signed-Agent-Metadata</tt> header field.</li>
          <li><strong>Validate the Signature</strong>: Verify the HTTP Message Signature using the public key discovered via <tt>Signature-Agent</tt>, as specified in <xref target="I-D.ietf-webbotauth-httpsig-protocol"/>. If signature verification fails, the verifier <bcp14>MUST NOT</bcp14> trust the <tt>Signed-Agent-Metadata</tt> header field.</li>
          <li><strong>Parse and Scope</strong>: Parse <tt>Signed-Agent-Metadata</tt> as an <xref target="RFC9651"/> Dictionary. If parsing fails, ignore the header field. Otherwise, extract the recognized string members (<tt>product</tt>, <tt>project</tt>, <tt>session</tt>) and construct the Effective Identity tuple scoped under the verified <tt>Signature-Agent</tt>.</li>
        </ol>
      </section>

      <section anchor="example" numbered="true">
        <name>Complete HTTP Request Example</name>
        <t>The following example shows an HTTP GET request to <tt>www.shopping.com</tt>, signed by Acme's agent platform (<tt>https://platform.acme.com</tt>) on behalf of its <tt>Acme-Research</tt> product, including <tt>product</tt>, <tt>project</tt>, and <tt>session</tt> in <tt>Signed-Agent-Metadata</tt> (lines folded for readability):</t>
        <sourcecode type="http-message"><![CDATA[
# NOTE: '\' line wrapping per RFC 8792

GET /catalog/anvils HTTP/1.1
Host: www.shopping.com
Signature-Agent: "https://platform.acme.com/.well-known/\
  http-message-signatures-directory"
Signed-Agent-Metadata:
  product="Acme-Research", project="prj_104", session="sess_3a2b1c"
Signature-Input:
  sig1=("@authority" "signature-agent" "signed-agent-metadata");\
  created=1772400000;expires=1772400300;\
  keyid="TtgsnS5fiN3jhav0LuKROGskI1rrkxZmeKndLaD8_Fg";\
  tag="web-bot-auth"
Signature:
  sig1=:OwviNIOl6eMJ4Vn006OoVEvgwglY3A6FRfjQgXYKPqBK62/0l2q3bfYiEOf+\
  wwcf3mM0UP7P99ebmYjb/xylCw==:
]]></sourcecode>
      </section>
    </section>

    <section anchor="verifier-considerations" numbered="true">
      <name>Verifier Considerations (Non-Normative)</name>
      <t>This section describes how verifiers (including origin servers such as <tt>shopping.com</tt>, <tt>content.org</tt>, and <tt>news.net</tt>, as well as WAFs, CDNs, and bot management services) can use <tt>Signed-Agent-Metadata</tt> to manage traffic policy and reputation.</t>

      <section anchor="reputation-isolation" numbered="true">
        <name>Reputation Isolation and Fallback</name>
        <t>Verifiers can maintain reputation and rate-limiting state at each level of the Effective Identity tuple:</t>
        <ul>
          <li><strong>Targeted Enforcement</strong>: If a single session (<tt>session="sess_3a2b1c"</tt>) under <tt>project="prj_104"</tt> exhibits abusive behavior on <tt>shopping.com</tt> (such as hoarding rocket-powered roller skates or aggressive price scraping), the verifier can rate-limit, challenge, or block that specific <tt>session</tt>. Other sessions under <tt>prj_104</tt> and other projects on <tt>platform.acme.com</tt> keep their normal standing.</li>
          <li><strong>Hierarchical Rollup</strong>: If a tenant rotates <tt>session</tt> identifiers rapidly to evade per-session limits on <tt>content.org</tt>, the verifier can aggregate anomaly signals at the parent <tt>project</tt> tier (<tt>project="prj_104"</tt>) and restrict the entire project without penalizing the rest of <tt>platform.acme.com</tt>.</li>
          <li><strong>Graceful Fallback</strong>: If a platform signs only <tt>product="Acme-Labs"</tt> and <tt>project="prj_104"</tt>, the verifier evaluates traffic at the project tier. If a request has no signed <tt>Signed-Agent-Metadata</tt> header, the verifier falls back to Tier 0 (evaluating all traffic under the <tt>platform.acme.com</tt> <tt>Signature-Agent</tt> URI).</li>
        </ul>
      </section>

      <section anchor="abuse-reporting" numbered="true">
        <name>Abuse Reporting to Platform Operators</name>
        <t>When a platform publishes contact endpoints in its Signature Agent Card (<tt>contacts</tt> in <xref target="I-D.meunier-webbotauth-registry"/>), a verifier that detects severe abuse can report the incident to the platform by providing:</t>
        <ul>
          <li>The <tt>Signature-Agent</tt> URI and <tt>keyid</tt></li>
          <li>The exact signed <tt>Signed-Agent-Metadata</tt> header value</li>
          <li>The target origin (<tt>@authority</tt>) and request timestamp (<tt>created</tt>)</li>
        </ul>
        <t>Because the platform generated the pseudonymous <tt>project</tt> and <tt>session</tt> identifiers (or derived <tt>session</tt> via HMAC with the target origin), the platform can map the reported tuple back to the responsible internal tenant account and take corrective action.</t>
      </section>
    </section>

    <section anchor="security-considerations" numbered="true">
      <name>Security Considerations</name>

      <section anchor="unsigned-headers" numbered="true">
        <name>Unsigned or Stripped Headers</name>
        <t>An attacker or intermediary could inject a forged <tt>Signed-Agent-Metadata</tt> header onto an unsigned request or append <tt>Signed-Agent-Metadata</tt> to a request whose <tt>Signature-Input</tt> does not cover <tt>"signed-agent-metadata"</tt>. As required in <xref target="verifier-processing"/>, verifiers <bcp14>MUST</bcp14> ignore <tt>Signed-Agent-Metadata</tt> unless <tt>"signed-agent-metadata"</tt> is included in the verified <tt>Signature-Input</tt> component list.</t>
        <t>An intermediary could also strip <tt>Signed-Agent-Metadata</tt> only if <tt>"signed-agent-metadata"</tt> was not included in <tt>Signature-Input</tt>. Once <tt>"signed-agent-metadata"</tt> is listed in <tt>Signature-Input</tt>, removing or modifying the header invalidates the HTTP Message Signature.</t>
      </section>

      <section anchor="cross-tenant-spoofing" numbered="true">
        <name>Cross-Tenant Identifier Spoofing</name>
        <t>If a multi-tenant platform allows customer code to set raw <tt>Signed-Agent-Metadata</tt> headers directly before the platform's signing proxy signs the outbound request, a malicious customer could set <tt>product</tt> or <tt>project</tt> values belonging to another customer. For example, a tenant operating <tt>product="Acme-Crimes"</tt> could claim <tt>product="Acme-Research", project="prj_104"</tt> on requests to <tt>news.net</tt>, either to inherit a trusted customer's reputation or to send abusive traffic that degrades a competitor's standing.</t>
        <t>To protect its own tenants from cross-tenant spoofing, the signing platform <bcp14>SHOULD</bcp14> overwrite, namespace, or validate <tt>Signed-Agent-Metadata</tt> at its signing boundary using authenticated tenant metadata (<xref target="generation"/>).</t>
      </section>

      <section anchor="sybil-attacks" numbered="true">
        <name>Sybil Attacks and Identifier Churn</name>
        <t>A malicious tenant may attempt to reset a poor reputation by cycling through newly created <tt>session</tt> or <tt>project</tt> identifiers on every request. Verifiers <bcp14>SHOULD</bcp14> treat newly observed identifiers as having neutral (unestablished) standing rather than high trust, and <bcp14>SHOULD</bcp14> track the rate of new sub-identifiers created under each parent <tt>project</tt>, <tt>product</tt>, or <tt>Signature-Agent</tt>. High sub-identifier churn under a parent tier is itself a signal to apply policy at the parent tier.</t>
      </section>
    </section>

    <section anchor="privacy-considerations" numbered="true">
      <name>Privacy Considerations</name>

      <section anchor="no-pii" numbered="true">
        <name>Prohibition of Personally Identifiable Information</name>
        <t><tt>Signed-Agent-Metadata</tt> is transmitted in cleartext HTTP headers to origin servers and intermediaries. Platforms <bcp14>MUST NOT</bcp14> place personally identifiable information (PII)—such as email addresses, legal names, usernames, phone numbers, IP addresses, or billing account names—into <tt>project</tt> or <tt>session</tt>. All values for these fields <bcp14>MUST</bcp14> be opaque tokens, UUIDs, or cryptographic hashes.</t>
      </section>

      <section anchor="cross-origin-correlation" numbered="true">
        <name>Cross-Origin Correlation</name>
        <t>As documented in the Privacy Considerations of <xref target="I-D.ietf-webbotauth-httpsig-protocol"/>, persistent identifiers in signed HTTP requests allow visited origins to correlate client activity across websites.</t>
        <t>In <tt>Signed-Agent-Metadata</tt>, <tt>product</tt> and <tt>project</tt> identify commercial software or tenant workspaces, whereas <tt>session</tt> represents an individual task or browsing context. Scoping <tt>session</tt> identifiers to the target origin (<xref target="generation"/>) prevents two collaborating origins from linking a session's activity across sites, while still giving each origin a stable handle for local rate limiting and abuse defense.</t>
      </section>
    </section>

    <section anchor="iana-considerations" numbered="true">
      <name>IANA Considerations</name>

      <section anchor="http-field-registration" numbered="true">
        <name>HTTP Field Name Registration</name>
        <t>IANA is requested to register the following entry in the "Hypertext Transfer Protocol (HTTP) Field Name Registry" defined in <xref target="RFC9110"/>:</t>
        <dl newline="false">
          <dt>Field Name:</dt>
          <dd><tt>Signed-Agent-Metadata</tt></dd>
          <dt>Status:</dt>
          <dd>provisional (or permanent if adopted on Standards Track)</dd>
          <dt>Structured Type:</dt>
          <dd>Dictionary</dd>
          <dt>Reference:</dt>
          <dd>This document (<xref target="header-field"/>)</dd>
        </dl>
      </section>
    </section>

    <section anchor="open-questions" numbered="true">
      <name>Open Questions for the Working Group</name>
      <t>The authors welcome Working Group feedback on the following topics at IETF 127:</t>
      <ol>
        <li><strong>Header Field Naming and Future Metadata</strong>: This draft proposes <tt>Signed-Agent-Metadata</tt> (SAM) to indicate that the header field must be covered by the request signature and can accommodate both sub-identifiers (<tt>product</tt>, <tt>project</tt>, <tt>session</tt>) and future per-request metadata (such as session start timestamps or account tenure). Should the Working Group keep <tt>Signed-Agent-Metadata</tt>, or prefer an alternative such as <tt>Agent-Metadata</tt>, <tt>Signature-Agent-Metadata</tt>, <tt>Signature-Agent-IDs</tt>, <tt>Signature-Agent-Scope</tt>, or <tt>Agent-Context</tt>?</li>
        <li><strong>Intermediate Identifier Between <tt>project</tt> and <tt>session</tt></strong>: Is a fourth identifier needed between <tt>project</tt> (the customer tenant or workspace) and <tt>session</tt> (a single task run) to represent a specific deployed agent, sub-tenant, or credential without introducing a human-level <tt>user</tt> identifier? If so, what term best fits that tier (for example, <tt>resource</tt>, <tt>label</tt>, <tt>workload</tt>, or <tt>parent</tt>)?</li>
        <li><strong>Alignment with the Signature Agent Card Registry</strong>: <xref target="I-D.meunier-webbotauth-registry"/> establishes an IANA registry for <tt>web_bot_auth</tt> metadata parameters. Should the <tt>Signed-Agent-Metadata</tt> dictionary keys be registered in a sub-registry or shared registry, and should a Signature Agent Card be able to declare which <tt>Signed-Agent-Metadata</tt> keys the platform signs?</li>
        <li><strong>Origin Scoping vs. Cross-Origin Security Providers</strong>: Origin-scoped identifiers protect cross-site privacy, whereas security providers operating across multiple origins can reduce cold-start challenges when a pseudonymous identifier is consistent across protected origins. Should the specification define an explicit parameter or convention indicating whether identifiers are origin-scoped or platform-scoped?</li>
      </ol>
    </section>
  </middle>

  <back>
    <references>
      <name>References</name>

      <references>
        <name>Normative References</name>

        <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author initials="S." surname="Bradner" fullname="S. Bradner"/>
            <date year="1997" month="March"/>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>

        <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author initials="B." surname="Leiba" fullname="B. Leiba"/>
            <date year="2017" month="May"/>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>

        <reference anchor="RFC9110" target="https://www.rfc-editor.org/info/rfc9110">
          <front>
            <title>HTTP Semantics</title>
            <author initials="R." surname="Fielding" fullname="R. Fielding" role="editor"/>
            <author initials="M." surname="Nottingham" fullname="M. Nottingham" role="editor"/>
            <author initials="J." surname="Reschke" fullname="J. Reschke" role="editor"/>
            <date year="2022" month="June"/>
          </front>
          <seriesInfo name="STD" value="97"/>
          <seriesInfo name="RFC" value="9110"/>
          <seriesInfo name="DOI" value="10.17487/RFC9110"/>
        </reference>

        <reference anchor="RFC9421" target="https://www.rfc-editor.org/info/rfc9421">
          <front>
            <title>HTTP Message Signatures</title>
            <author initials="A." surname="Backman" fullname="A. Backman" role="editor"/>
            <author initials="J." surname="Richer" fullname="J. Richer" role="editor"/>
            <author initials="M." surname="Sporny" fullname="M. Sporny"/>
            <date year="2024" month="February"/>
          </front>
          <seriesInfo name="RFC" value="9421"/>
          <seriesInfo name="DOI" value="10.17487/RFC9421"/>
        </reference>

        <reference anchor="RFC9651" target="https://www.rfc-editor.org/info/rfc9651">
          <front>
            <title>Structured Field Values for HTTP</title>
            <author initials="M." surname="Nottingham" fullname="M. Nottingham"/>
            <author initials="P." surname="Kamp" fullname="P. Kamp"/>
            <date year="2024" month="September"/>
          </front>
          <seriesInfo name="RFC" value="9651"/>
          <seriesInfo name="DOI" value="10.17487/RFC9651"/>
        </reference>

        <reference anchor="I-D.ietf-webbotauth-httpsig-protocol" target="https://datatracker.ietf.org/doc/html/draft-ietf-webbotauth-httpsig-protocol-01">
          <front>
            <title>HTTP Message Signatures for automated traffic</title>
            <author initials="T." surname="Meunier" fullname="Thibault Meunier"/>
            <author initials="S." surname="Major" fullname="Sandor Major"/>
            <date year="2026" month="October" day="29"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-webbotauth-httpsig-protocol-01"/>
        </reference>
      </references>

      <references>
        <name>Informative References</name>

        <reference anchor="I-D.meunier-webbotauth-registry" target="https://datatracker.ietf.org/doc/html/draft-meunier-webbotauth-registry-04">
          <front>
            <title>Registry and Signature Agent card for Web bot auth</title>
            <author initials="M." surname="Guerreiro" fullname="M. Guerreiro"/>
            <author initials="U." surname="Kirazci" fullname="U. Kirazci"/>
            <author initials="T." surname="Meunier" fullname="Thibault Meunier"/>
            <date year="2026" month="October" day="27"/>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-meunier-webbotauth-registry-04"/>
        </reference>

        <reference anchor="RFC9576" target="https://www.rfc-editor.org/info/rfc9576">
          <front>
            <title>The Privacy Pass Architecture</title>
            <author initials="A." surname="Davidson" fullname="A. Davidson"/>
            <author initials="J." surname="Iyengar" fullname="J. Iyengar"/>
            <author initials="C. A." surname="Wood" fullname="C. A. Wood"/>
            <date year="2024" month="June"/>
          </front>
          <seriesInfo name="RFC" value="9576"/>
          <seriesInfo name="DOI" value="10.17487/RFC9576"/>
        </reference>
      </references>
    </references>
  </back>
</rfc>
