# Agent Authorization

A DNS-based standard that lets a domain explicitly opt in to being contacted
by autonomous agents — over email or any other channel — and scope *which*
agents or platforms it accepts, *per channel*.

> Status: Draft standard, version `AGENTS1`. Vendor-neutral and
> provider-agnostic: the record, the tags, and the matching rules name no
> provider and assume no single channel. `primitive.dev` appears only as an
> example provider identifier and `email` only as the first defined channel,
> the same way `example.com` appears as an example domain.
>
> The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, MAY, RECOMMENDED,
> and NOT RECOMMENDED are used per [RFC 2119]/[RFC 8174].

## Quick start

If you just want to let agents on a given platform email your domain, publish
one DNS `TXT` record at `_agents` on your domain (using `primitive.dev` as the
example provider):

```
_agents.example.com.  IN  TXT  "v=AGENTS1; p=accept; channel=email; allow=provider:primitive.dev"
```

No record means no permission, and you can change or remove it at any time. The
rest of this document defines the grammar, the trust model, and the exact
evaluation rules.

## Abstract

Authentication standards answer "is this message really from the domain it
claims?" — SPF, DKIM, and DMARC for email, and analogues elsewhere. None of
them answer "does the recipient *want* contact from an autonomous agent, and
from which ones?"

As autonomous agents become common — and as they reach domains over more
than one channel — recipient domains need a single, public, machine-readable
signal: *"I accept agent contact, here is who I accept it from, and over
which channels."* Agent Authorization is that signal: one DNS `TXT` record
the recipient publishes at `_agents` on its own domain.

It is the mirror image of authorization-to-send standards like SPF. SPF
authorizes servers to send **as** a domain. This record authorizes agents to
make contact **with** a domain. Control of the domain's DNS authenticates the
publisher's *opt-in intent* — only the domain owner can publish the record.
It does **not**, by itself, authenticate the *agent or provider* making
contact; that is the asserting provider's responsibility today, with hooks
reserved (see *Security considerations*) to layer in verifiable proof without
a breaking change.

The standard is split into two layers:

- A **channel-agnostic core** — the record, its grammar, the
  provider/principal trust model, the version-selection and evaluation
  algorithm. None of it is email-specific.
- One or more **channel bindings** — each defines a channel token (e.g.
  `email`) and the two channel-specific details the core leaves open: what the
  **channel principal** is, and how principal values are compared. Email is
  the first binding.

## Terminology

The standard deliberately separates identities that channel authentication
usually conflates:

- **Agent** — an autonomous program that initiates contact (sends mail,
  opens a session, posts a message) without a human composing each exchange.
  For evaluation an agent is described by an **open set of attributes** its
  provider asserts and has verified. `AGENTS1` defines two attributes,
  `provider` and the channel `principal`; future versions MAY define more
  (e.g. a per-agent `id`). Consumers MUST treat the attribute set as open, not
  as a fixed tuple, so new attributes are additive.
- **Provider** (agent platform) — a service that *hosts* agents, identified
  by a **provider identifier**: a domain name it controls, e.g.
  `primitive.dev`. The identifier is **channel-independent**: trusting a
  provider means trusting it to vouch for the agents it hosts, on any channel.
- **Channel** — a transport over which an agent reaches a domain (email today;
  others may be registered later). Each channel has a registered **channel
  token** and a **binding** (see *Channels*).
- **Channel principal** — the per-channel identity an agent presents and the
  channel has verified. **What the principal is, and how it is compared, are
  defined by the channel binding** — it is a domain for some channels, but MAY
  be a public key, a handle, or another identifier for others. The core never
  assumes its shape. For the email binding the principal is the DKIM-aligned
  From domain, and the `domain:` token (below) is its principal-grant form.
- **Publisher** (recipient domain) — the domain that publishes the `_agents`
  record and thereby opts in. The "you" in this document.

The provider/principal split is the core of the trust model. A publisher can
trust **a whole platform** ("any agent Primitive hosts is fine") or **a
specific principal** ("only agents presenting `acme.com`, whoever hosts
them"), and these are different decisions — on any channel.

## The record

A publisher opts in by publishing one or more `TXT` records at the `_agents`
label of the domain that will be contacted:

```
_agents.example.com.  IN  TXT  "v=AGENTS1; p=accept; channel=email; allow=provider:primitive.dev"
```

### Lookup procedure

A consumer evaluating contact to `<domain>` over channel `C`:

1. Queries `TXT` at the **exact** name `_agents.<domain>`. `AGENTS1` performs
   no ancestor tree-walk: absence at the exact name means *not opted in* for
   `<domain>`. Subtree inheritance is reserved for a future `sp=` tag, whose
   absence MUST be treated as `sp=strict` (no inheritance). Naming this default
   now means already-published apex records keep a stable meaning when `sp=`
   ships.
2. Consumers MUST support EDNS0 and TCP fallback. A truncated or oversized
   answer MUST be retried over TCP, never silently treated as "no record."
3. NODATA (the name exists but has no `TXT`) is treated identically to NXDOMAIN:
   *not opted in*. An empty or whitespace-only `TXT` string is a malformed
   record and is ignored (net: not opted in). A `CNAME` at `_agents.<domain>`
   is followed normally by the resolver, and the resulting `TXT` set is
   evaluated as if published at `_agents.<domain>`.

### Version selection

The `v` tag carries the format version (`AGENTS1`). Versioning and the
multiple-record rule are defined together so they never fight:

- A consumer MUST ignore any record whose `v` it does not recognize.
- **Version selection runs first.** Among records it recognizes that name
  channel `C`, the consumer determines the highest `v` it understands and
  discards all records naming `C` with a lower `v`. Records that differ only in
  `v` are **NOT** a collision — this is how a publisher runs `AGENTS1` and a
  future `AGENTS2` side by side at one name during a transition. The
  same-version duplicate check (below) then applies **only** to the surviving
  highest-version records; a duplicate at a superseded version never affects
  `C`.
- `v=AGENTS1` is reserved for *breaking grammar* changes only. Backward-
  compatible evolution uses new tags (ignored by older consumers) and the
  critical-tag mechanism (below), not a version bump.

### Multiple records and channels

A domain MAY publish **multiple** `v=AGENTS1` records at `_agents`, each
governing a different channel (or set of channels). Evaluation selects by
channel:

- Records that do not name channel `C` are ignored for `C`, so an unrelated
  channel's record never blocks `C`.
- If **exactly one** `AGENTS1` record names `C`, it governs `C`.
- If **more than one same-version** record names `C`, the configuration is
  ambiguous and fails closed for `C` (**not authorized**). Fail-closed is
  chosen deliberately: under DNS forgery, *denial* is the safe failure,
  whereas a permissive merge would let a forged duplicate broaden access.
  Because this is also a griefing/tamper vector (someone who can inject one
  extra record can deny a channel), consumers SHOULD log/alert on duplicate-
  channel records rather than denying silently, MUST NOT cache the duplicate
  state as a sticky negative, and publishers SHOULD deploy DNSSEC.
- A record naming **multiple** channels (`channel=email chat`) asserts that
  its `allow` set is identical for every channel listed. A publisher needing
  different `allow`/policy per channel MUST use separate records.
- When a record names several channel tokens, a consumer evaluates it for any
  listed token it understands and ignores listed tokens it does not. An
  unrecognized channel token alongside a recognized one (`channel=email foo`,
  `foo` unknown) does **not** invalidate the record for the recognized channel.

### DNS encoding constraints

- A record value longer than 255 octets MUST be split into multiple
  `<character-string>`s within a single RR. Consumers MUST concatenate all
  character-strings of an RR **with no separator** before parsing (the DKIM /
  RFC 1035 rule). This is the single most common TXT implementation error;
  consumers that read only the first string will misparse long records.
- Keep the full `_agents` response small enough to fit a single UDP/EDNS0
  answer where practical. Publishers with large `allow` enumerations SHOULD
  use the reserved `.well-known/agents` companion (see *Future extensions*)
  rather than growing the TXT set unboundedly.
- This standard uses the `TXT` RRTYPE **exclusively**. A dedicated RRTYPE is
  out of scope and SHOULD NOT be introduced; the deprecated SPF RRTYPE
  ([RFC 7208] §3.1) is the cautionary precedent.

## Syntax

The record value is a list of `key=value` tags separated by semicolons,
following the same lexical conventions as SPF and DMARC:

```
record = "v=AGENTS1" *( OWS ";" OWS tag )
tag    = [ "!" ] key "=" value
key    = ALPHA *( ALPHA / DIGIT / "_" )
value  = *( %x09 / %x20-3A / %x3C-7E )  ; any printable ASCII + SP/HTAB, except ";" (%x3B)
OWS    = *( SP / HTAB )           ; ALPHA/DIGIT/SP/HTAB are [RFC 5234] core rules
```

- **Tokenization is two levels.** A record is split into tags at each `;`. A
  tag's `value` runs from the `=` to the next `;` or end of record; leading and
  trailing `OWS` in a value is stripped. There is no escape mechanism in
  `AGENTS1`, so a value MUST NOT contain `;`. For **list-valued** tags
  (`channel`, `allow`), the stripped value is then split into tokens on runs of
  ASCII space, HTAB, and/or comma; interior whitespace in a list value is a
  separator, not data.
- Tag **keys** are case-insensitive, and the `!` critical marker is
  case-irrelevant (`!REQ` ≡ `!req`). Value case rules are per-tag: channel
  tokens and provider identifiers are ASCII case-insensitive; **principal
  values are compared per the channel binding** (which may be case-sensitive,
  e.g. a public key). "Case-insensitive" in this document means ASCII case-
  folding only.
- The `v=AGENTS1` tag MUST come first. A record whose first tag (after `OWS`
  trimming) is not `v=AGENTS1` is malformed and MUST be ignored — consumers do
  not reorder to find `v`.
- **A tag whose key appears more than once makes the record malformed; the
  record MUST be ignored** (fail-closed; avoids first-wins/last-wins
  divergence).
- **Unknown ordinary tags MUST be ignored** (forward compatibility).
- **Critical tags** — a tag key prefixed with `!` is critical. A consumer that
  does not understand a critical tag MUST treat the record as **not
  authorized** rather than ignoring the tag. This reserves the ability to ship
  a *tightening* change (e.g. `!req=`) that older consumers cannot silently
  bypass — the escape hatch a blanket "ignore unknowns" rule otherwise
  forecloses.

### Tags

| Tag | Required | Meaning |
|-----|----------|---------|
| `v` | yes | Format version. MUST be `AGENTS1`. |
| `p` | yes | Policy: `accept` opts in, `reject` is an explicit opt-out. |
| `channel` | yes | One or more registered channel tokens (whitespace- or comma-separated) this record governs, e.g. `email`. |
| `allow` | when `p=accept` | Whitespace- or comma-separated authorization tokens (below). An empty `allow=` under `p=accept` authorizes nothing (deny-all) and is **not** malformed. **Absent** `allow` under `p=accept` makes the record malformed (ignored); use explicit `allow=` for deny-all. `allow` under `p=reject` is ignored, not malformed. |
| `req` (critical-capable; written `!req`) | no (reserved) | Critical strictness requirements (e.g. `dnssec`, `signed`, `verified-provider`). Reserved; defined by a future version. Because it is written critical (`!req`), an older consumer that sees it fails closed rather than honoring a weaker policy. |
| `policy` | no | Absolute `https://` URL to a **human-oriented** acceptance policy. **Advisory and never authoritative** for the accept/reject decision. A malformed value MUST be ignored without invalidating the record. |
| `contact` | no | Abuse / operations contact as a `mailto:` URI. Advisory; malformed value ignored without invalidating the record. |

A record whose `channel` tag is missing, empty (`channel=`), or names no
registered channel the consumer understands is, for that consumer, simply not
applicable to any channel it can evaluate; it MUST be ignored (not malformed,
not treated as governing some default channel).

Any `p` value other than `accept` is treated as `reject` — for both the
authorization decision and caching — so an unknown/typo'd policy fails safe.

### `allow` tokens

Each token in `allow` is a typed grant. The type prefix distinguishes a
**provider** grant from a **principal** grant:

| Token | Grants |
|-------|--------|
| `*` | Any compliant agent on any provider. **NOT RECOMMENDED** — the broadest opt-in and a standing spam target; prefer enumerated grants. Tooling SHOULD warn when a publisher selects it. |
| `provider:<provider-id>` | Any agent hosted by the named provider. Trust the platform. |
| `domain:<principal>` | The **email binding's** principal grant: any agent whose verified channel principal (DKIM-aligned From domain) is the named domain, regardless of provider. Other bindings define their own principal-grant token(s). |
| `agent:<id>` | *Reserved* for a future per-agent identity axis. Will be namespaced (`agent:<id>@<provider>`) and cryptographically attested. Unrecognized in `AGENTS1` and MUST be ignored. |

Rules:

- `provider:` and principal grants (`domain:`) are **orthogonal**; a publisher
  may list any mix.
- `*` is matched literally and is NOT canonicalized. `*` carrying an ignored
  `|`-qualifier (`*|rate=10`) still reduces to the base token `*` and
  authorizes all in `AGENTS1` (qualifiers are advisory here).
- A token with no recognized type prefix (a bare `primitive.dev`) MUST be
  ignored, so future token types degrade safely.
- The vertical bar `|` is **reserved** as a future per-token qualifier
  delimiter (e.g. `domain:acme.com|rate=10`). `AGENTS1` consumers MUST ignore
  everything from the first `|` in a token onward and match only the base
  token. Reserving it now keeps future per-grant scoping additive instead of
  colliding with the `;` tag separator.
- **Canonicalization before comparison** (provider ids and `domain:`-style
  domain principals): strip a single trailing `.`, trim surrounding
  whitespace, ASCII-lowercase, then convert to IDNA2008 A-label (punycode)
  form. **Reject the token** — drop that grant only, do **not** invalidate the
  record — if it is empty or fails IDNA2008 A-label conversion (matching the
  bare-token degradation above). The **same canonicalization is applied to the
  incoming `agent.provider` and to a domain-shaped `agent.principal`** before
  comparison, so both sides are A-labels and comparison is octet-equality.
  Non-domain principals are canonicalized and compared per their binding.

## Channels

A channel is a transport with a registered **channel token** and a **binding**
that supplies the two details the core leaves open: **what the channel
principal is**, and **how principal values are compared**. Everything else —
record, grammar, trust tokens, version selection, evaluation, caching — is
shared across all channels.

Channel tokens and `allow` token-type prefixes live in shared registries (see
*IANA considerations*). Tokens containing a `.` or prefixed `x-` are reserved
for **private use** and MUST NOT be registered, so experimentation cannot
squat the global namespace.

### Email (channel token: `email`)

The first defined binding.

- **Channel principal** = the agent's DKIM-aligned From domain (the
  [RFC 5321] / [RFC 5322] author domain whose DKIM signature passes and
  aligns). A `domain:acme.com` grant authorizes agents that send DKIM-aligned
  mail from `acme.com`.
- **Principal comparison** = domain canonicalization above (A-label, ASCII
  case-insensitive).
- The record is consulted on the outbound path, keyed on the recipient's
  domain (the part after `@`). The principal SHOULD be one the channel
  authenticates end-to-end (the receiving side can re-verify DKIM alignment),
  not merely the asserting provider's self-report.

Future channels register a token and define their own principal and comparison.
The core does not change.

## Evaluation (authorizing contact)

A contacting agent is described by provider-asserted, channel-verified
attributes; `AGENTS1` reads two:

- `agent.provider` — the provider identifier the agent runs on.
- `agent.principal` — the agent's verified channel principal, per the binding
  for the channel in use.

To decide whether contact to `<domain>` over channel `C` is authorized:

1. Resolve `TXT` at `_agents.<domain>` per *Lookup procedure*.
2. If resolution is **inconclusive** (SERVFAIL, timeout, truncation that TCP
   retry did not resolve): the result is *unknown*. Treat as **not
   authorized** for this decision, but MUST NOT cache it as a negative (see
   *Caching*); retry later.
3. Discard records whose `v` is unrecognized or malformed (per *Syntax*). From
   the remainder, take the records naming `C`, and select the single governing
   record per *Version selection* and *Multiple records and channels* (zero →
   not authorized; same-version duplicates → not authorized).
4. If any critical tag (`!`-prefixed) in the selected record is not understood
   → **not authorized**. If `p` is not `accept` (including unknown/typo'd
   values) → **not authorized**. If `p=accept` but `allow` is absent → the
   record is malformed → **not authorized** (an explicit empty `allow=` is the
   deny-all form, and authorizes nothing).
5. Contact is **authorized** iff any `allow` token matches (after
   canonicalization):
   - token is `*`, OR
   - token is `provider:X` and `X == agent.provider`, OR
   - token is a principal grant (`domain:Y` for email) and `Y == agent.principal`
     under the binding's comparison.

Fail-closed is the rule throughout: absence, ambiguity, malformed records,
unknown critical tags, and lookup failure all resolve to *not authorized*.
Opting in is an explicit, unambiguous act.

### Pre-flight / dry-run mode

A consumer MAY evaluate without a bound agent identity (a debugger asking "what
would happen?"). With `agent.provider`/`agent.principal` unknown, `*` and
known-value checks that don't depend on the missing attribute may still
resolve, but a `provider:`/`domain:` decision that depends on an unknown
attribute is **indeterminate** and MUST be reported as such (treated as not
authorized), never silently skipped or guessed. If any token resolves to a
definite match (e.g. `*`), report **authorized**; report **indeterminate** only
when no token definitely matches and at least one depends on a missing
attribute.

### Example

```
_agents.example.com. TXT "v=AGENTS1; p=accept; channel=email; allow=provider:primitive.dev domain:acme.com"
_agents.example.com. TXT "v=AGENTS1; p=accept; channel=chat;  allow=*"
```

(`chat` is hypothetical, used only to illustrate multi-channel publishing;
`email` is the one channel `AGENTS1` defines.) Evaluating an **email** contact
(only the first record names `email`):

- Agent on `primitive.dev`, principal `bot.thing.io` → authorized (matches
  `provider:primitive.dev`).
- Agent on another platform, principal `acme.com` → authorized (matches
  `domain:acme.com`).
- Agent on another platform, principal `random.net` → **not** authorized.

## Caching

The record is read on the hot contact path, so implementations SHOULD cache,
keyed on the publisher domain (cache the full `_agents` record set once and
select by channel in memory — not per channel):

- Honor the record's DNS TTL, with a sane floor and a ceiling. For `p=accept`
  the positive-cache ceiling SHOULD be short (≤1h) so revocation takes effect
  quickly; `reject`/absence fail safe and MAY be cached longer.
- Negative results (no record / `reject`) MAY be cached but MUST honor the
  zone SOA negative-TTL as an upper bound ([RFC 2308]) and SHOULD default
  short. If the resolver does not surface the SOA negative-TTL (common with
  high-level/DoH resolvers), fall back to the short default and never cache a
  negative longer than that default.
- **Inconclusive** lookups (SERVFAIL, timeout) MUST NOT be cached as negative;
  retry, so a transient resolver blip never becomes a sticky "this domain
  rejected you."
- On a credible abuse signal for a publisher, a consumer SHOULD re-resolve
  that publisher's record immediately, bypassing cache.

Implementation note: DNS-over-HTTPS hides SERVFAIL behind an HTTP-200 envelope
with `Status: 2` and an empty answer set. Consumers MUST read the response
`Status`, not the answer count, to honor the inconclusive rule above.

## Security considerations

- **DNS control authenticates intent, not the contacting party.** Publishing
  the record proves the *publisher* opted in. It does **not** prove the agent
  or provider is who it claims; in `AGENTS1` those are the asserting provider's
  word (see below). Treat the record as the publisher's consent, layered with
  provider-side and channel-native authentication.
- **Forgery can over-permit without DNSSEC.** An on-path or cache-poisoning
  attacker on an unsigned zone can *fabricate* a more permissive record
  (`allow=*`) and manufacture consent the publisher never gave. So the worst
  case is **not** merely denial — without DNSSEC it includes over-permission.
  DNSSEC is RECOMMENDED; consumers SHOULD prefer authenticated (AD-bit)
  results and MAY require them (future `!req=dnssec`) for `*` grants or any
  grant used to bypass an otherwise-applicable sender restriction.
- **The asserter is the beneficiary.** In the email binding the consumer
  running evaluation is often the sending provider itself, asserting "this is
  DKIM-aligned." The decision SHOULD be anchored to a *receiver-verifiable*
  result (the receiving side re-checks alignment), not a self-report. A future
  signed-assertion mechanism (reserved via `!req=signed` and a proof axis) lets
  a relying party verify the `(provider, principal)` binding without trusting
  the provider's word.
- **Provider-identifier impersonation.** Nothing in `AGENTS1` binds
  `provider:X` to the entity controlling `X`; a bad actor can self-assert any
  provider id. A future version will require proof of control of the provider
  domain (a provider-published record at a reserved label and/or a discoverable
  signing key). Until then, publishers SHOULD understand `provider:` trust is
  only as strong as the ecosystem's provider verification.
- **Class-based, not per-message.** A match authorizes a *category* on a
  channel, not a specific message or session, and does not replace per-contact
  abuse controls (rate limiting, content policy, suppression). The reserved
  per-agent axis (`agent:`) and per-token qualifier delimiter (`|`) are the
  path to finer scoping.
- **`allow=*` is the open relay of agent auth** and makes a domain a soft
  target; it is NOT RECOMMENDED and MAY be deprecated in a future version.
- **The record is a public recon oracle.** `_agents.<domain>` advertises, to
  adversaries too, who accepts agent contact and how loosely. Publishers
  SHOULD avoid `*`, use a role/abuse address for `contact` that can absorb
  load, and prefer narrow grants.
- **Revocation is cache-bounded.** A compromise-then-opt-in attacker's runway
  is the positive-cache TTL; the short `p=accept` ceiling and abuse-triggered
  re-resolve above exist to bound it.

### Reserved for future hardening (no breaking change required)

Unknown ordinary tags are ignored and unknown critical tags fail closed, so the
following can be added to `AGENTS1` records without a version bump:

1. `!req=` strictness (`dnssec` / `signed` / `verified-provider`) — critical,
   so older consumers can't silently honor a weaker policy.
2. A proof/signature axis for verifiable `(provider, principal)` assertions.
3. A provider proof-of-control contract at a reserved provider-side label.
4. Namespaced, attested per-agent identity (`agent:<id>@<provider>`).
5. A machine-readable abuse/revocation feedback hook.

## Conformance

A **compliant** consumer implements the lookup procedure, version selection,
multiple-record and critical-tag rules, canonicalization, and fail-closed
evaluation above. A **compliant** provider asserts only `(provider, principal)`
pairs it has actually verified for the channel in use, honors the publisher's
`contact`, and does not assert a provider id it does not control. "Compliant"
in `allow=*` and elsewhere refers to this profile; it is a behavioral
commitment, not a certification, and provides no security on its own — see
*Security considerations*.

## Future extensions (non-normative)

Reserved for later versions; an `AGENTS1` consumer ignores ordinary ones and
fails closed on critical ones it does not understand:

- `!req=` strictness; signed assertions / proof axis; provider proof-of-control.
- `agent:<id>@<provider>` per-agent identity; `|` per-token qualifiers
  (`rate=`, `for=`).
- `sp=` subdomain policy (default `strict` today) and an org-boundary tree-walk.
- Additional channel bindings beyond `email`.
- A `.well-known/agents` HTTPS companion for large or signed policies. If
  introduced it is **advisory only** unless a future version explicitly makes
  it authoritative via a critical pointer tag; the TXT record remains the
  authoritative accept/reject source for `AGENTS1`.

## IANA considerations (registries)

To keep a vendor-neutral namespace from fragmenting, this standard anticipates
three registries (registration policy: Specification Required / Expert Review):

- **Channel tokens** (e.g. `email`).
- **`allow` token-type prefixes** (e.g. `provider`, `domain`, `agent`).
- **Tag keys** (e.g. `v`, `p`, `channel`, `allow`, `req`, `policy`, `contact`),
  noting which are critical-capable.

Names containing a `.` or prefixed `x-` are reserved for private use in all
three and MUST NOT be registered.

## Provider implementation note (non-normative)

A contacting provider integrates the standard by, on each outbound contact,
resolving `_agents.<recipient-domain>`, selecting the record for the channel in
use, and evaluating it against the agent's asserted-and-verified attributes per
the algorithm above. Practical guidance learned from the email binding:

- Resolve **off** the hot commit/transaction path (as SPF is checked outside
  the message-commit critical section); pass the resolved record set into the
  evaluation as data so the matcher does no network I/O.
- Carry the lookup as a **three-state** result — `found` / `empty` /
  `inconclusive` — not a nullable list, and map DoH `Status` / resolver error
  codes into it so the "don't cache inconclusive as negative" rule is
  implementable.
- An inconclusive lookup is a *retryable* condition, not a denial; it MUST NOT
  be recorded as a permanent rejection of the recipient.

Because the check sits alongside a provider's existing contact authorization,
it is one *additional* path to "allowed", not a replacement for sender-side
requirements (a verified identity, authenticated sending, etc.).

[RFC 2119]: https://www.rfc-editor.org/rfc/rfc2119
[RFC 8174]: https://www.rfc-editor.org/rfc/rfc8174
[RFC 2308]: https://www.rfc-editor.org/rfc/rfc2308
[RFC 5234]: https://www.rfc-editor.org/rfc/rfc5234
[RFC 5321]: https://www.rfc-editor.org/rfc/rfc5321
[RFC 5322]: https://www.rfc-editor.org/rfc/rfc5322
[RFC 7208]: https://www.rfc-editor.org/rfc/rfc7208
