<?xml version='1.0' encoding='utf-8'?>
<rfc version="3" ipr="trust200902" category="exp" docName="draft-saez-xcim-03" consensus="false" tocInclude="true" symRefs="true" sortRefs="true">
  <front>
    <title abbrev="XCIM">eXplicit Consent-Identified Mail (XCIM)</title>
    <author initials="D." surname="Saez" fullname="Damian Saez">
      <organization>We Are 14 Inc</organization>
      <address>
        <email>damian@xcim.org</email>
      </address>
    </author>
    <date year="2026" month="October" day="21" />
    <keyword>email</keyword>
    <keyword>explicit consent</keyword>
    <keyword>third-party attestation</keyword>
    <keyword>blockchain</keyword>
    <abstract>
      <t>XCIM specifies evidence that a party controlling an email address
explicitly consented to receive defined types of communication from an identified
sender. A trusted third-party Consent Attester verifies address control, observes
a separate affirmative decision, and signs an attestation binding the recipient,
sender, and agreed types. Blockchain anchoring provides immutable evidence of
the attestation under an admitted finality policy. Authenticated lifecycle events
and fresh status distinguish the historical decision from current consent.</t>
      <t>XCIM concerns the consent relationship independently of individual
email messages. It does not sign, inspect, classify, or authenticate their content.
A receiving email service may use verified current consent as a positive policy
signal after independently establishing the sender identity relevant to its
query. This document defines a portable consent object format and verification
contract, together with requirements for separately admitted blockchain adapters.
It does not select a universal blockchain network or claim operational readiness.</t>
    </abstract>
  </front>
  <middle>
    <section anchor="introduction">
      <name>Introduction</name>
      <t>The question addressed by XCIM is whether the party controlling recipient
address R explicitly authorized identified sender S to send communications of
type T, as attested by accepted third party A, and whether that consent remains
current. The evidence can be created and verified before any email exists.
Verifying it neither consumes the consent nor authorizes a different sender
or communication type.</t>
      <t>A sender in this model is the company or other entity that receives the
consent. A technical application, email service provider, OAuth client, domain,
and signing key can support that entity but are not automatically equivalent
identities. The third party binds the recipient's decision to the identity and
scope actually presented to the recipient.</t>
      <t>Cryptographic signatures authenticate the attester and the recorded
statement. Blockchain evidence preserves its committed history under the
selected consensus and finality assumptions. Neither mechanism independently
observes a human decision or makes a dishonest attester truthful. Explicit
trust in the third party remains part of the protocol.</t>
      <section anchor="scope-correction">
        <name>Scope Correction from Revisions -00 and -01</name>
        <t>Revisions -00 and -01 made a direct-email presentation profile mandatory,
including Message Presentation (MP), Message Signer Authorization (MSA), message
content commitments, DKIM checks, and SMTP replay coordination. That integration
exceeded the intended scope of XCIM. Revision -02 replaced it with a consent
protocol that is independent of individual messages. This is a substantive
scope and wire-format change, not a title-only revision.</t>
        <t>P1 and MAIL01 objects are not accepted as C01 merely by changing their
labels. Historical documents and signed bytes retain their original
interpretations. Their message-processing requirements and tests do not define
conformance to this revision. The consent, identity, cryptographic and
publication concepts that remain relevant are specified explicitly below.</t>
      </section>
      <section anchor="changes-03">
        <name>Changes from Revision -02</name>
        <t>This revision specifies EVP, OAuth-based provider verification and
OIDC as alternative address-control methods. No method is universally required.
It separates their issuance procedures from the common explicit-consent
decision, defines the attester and delegated-origin roles, and requires
method-specific admission policy. The consent relationship, communication
types, lifecycle and blockchain requirements retain their -02 meanings.
No individual email message becomes a core protocol input.</t>
        <t>C01 retains profile string xcim-consent-01 because the existing
oidc-01 fields and their signed meaning are preserved; evp-01 and oauth-01
are explicit new method values. An implementation of -02 that does not
support a method MUST reject it rather than reinterpret it as oidc-01. Local admission
configuration MUST name the method explicitly when upgrading. Historical
WD receipt 0.2 objects are not C01 objects and MUST NOT be relabelled or
converted without a new conforming attestation.</t>
      </section>
    </section>
    <section anchor="scope">
      <name>Scope and Non-Goals</name>
      <t>The core covers address control at the time of consent, the sender identity
and scope shown to the recipient, the descriptions of the accepted communication
types, third-party attestation, immutable blockchain evidence, authenticated
withdrawal, and current-state verification. Promotional and transactional
communications are examples of types for which explicit consent can be given.
A transactional relationship is not itself explicit consent.</t>
      <t>There is no XCIM requirement to sign or hash an email, carry a particular
email header, create one copy per recipient, generate a per-message token, or
contact the attester for every email. Email content, MIME, transport paths,
forwarding, message replay, SMTP acceptance, and mailbox delivery are outside
this core. An implementation MUST NOT require any of them as inputs to core
consent verification.</t>
      <t>A consent result does not certify that a particular message belongs to
the queried type. Classification and use of that result belong to the consuming
application. XCIM does not guarantee message safety, legal compliance, continued
mailbox ownership, or inbox placement.</t>
    </section>
    <section anchor="terminology">
      <name>Requirements Language and Roles</name>
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL"
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>
      <dl>
        <dt>Recipient</dt>
        <dd>The party whose control of an email address is established for the consent decision; this does not require proof of a civil identity.</dd>
        <dt>Sender</dt>
        <dd>The identified company or other entity and bounded scope to which consent is granted.</dd>
        <dt>Consent Attester</dt>
        <dd>The third party that establishes address control, observes explicit consent, and signs attestations and lifecycle observations. This corresponds to the earlier Consent Issuer role.</dd>
        <dt>Publisher</dt>
        <dd>The party making commitments and lifecycle evidence available and anchoring historical records in an admitted blockchain.</dd>
        <dt>Verifier</dt>
        <dd>A party evaluating consent evidence under previously accepted trust and finality policy. It need not operate an email service.</dd>
        <dt>Communication type</dt>
        <dd>A stable, versioned description of the class of communications agreed to, within the sender scope. It is not a classification of an individual email.</dd>
        <dt>C01</dt>
        <dd>The portable consent object and verification profile defined here, with profile string xcim-consent-01.</dd>
      </dl>
    </section>
    <section anchor="architecture">
      <name>Consent Flow and Trust Boundaries</name>
      <figure>
        <artwork type="ascii-art">
 Recipient -- address control + explicit decision --&gt; Attester
 Sender ---- entity/scope enrollment ---------------&gt; Attester
 Attester -- signed consent/lifecycle --------------&gt; Publisher
 Publisher - commitments --------------------------&gt; Blockchain
 Verifier -- recipient/sender/type query -----------&gt; Evidence
 Verifier -- accepted trust + verified chain proof -&gt; Consent result
 Email service (optional) --------------------------&gt; Uses result
</artwork>
      </figure>
      <ol>
        <li>The attester authenticates enrollment of the sender identity and scope.</li>
        <li>The attester establishes control of the recipient address and observes a separate affirmative decision for the frozen sender, notice and type definitions.</li>
        <li>The attester issues the signed consent and publishes an immutable commitment, directly or in the batch defined below, on an admitted blockchain.</li>
        <li>Authenticated withdrawal events remove accepted types without changing the historical grant. Fresh signed status reports the current projection.</li>
        <li>A verifier checks the exact queried relationship, attestation, historical blockchain evidence and current status. Repeated verification does not consume the grant.</li>
      </ol>
      <t>An identity provider and the Consent Attester are different roles even if
one organization performs both. The sender's claim that a recipient consented
is insufficient. Evidence transport and discovery do not establish trust.
A signature by an otherwise unknown attester cannot install that attester
into verifier policy.</t>
    </section>
    <section anchor="common">
      <name>Common Wire Rules and Cryptography</name>
      <t>C01 uses JSON <xref target="RFC8259" />, JCS <xref target="RFC8785" />,
SHA-256 <xref target="RFC6234" />, Ed25519 <xref target="RFC8032" />, and
JWS Flattened JSON Serialization <xref target="RFC7515" />. The fully specified
JOSE algorithm identifier is Ed25519, following <xref target="RFC9864" />.
All objects specified here are closed: unknown members are rejected. An
unsupported profile is not interpreted as an older profile.</t>
      <t>Input MUST be valid UTF-8 without duplicate member names or invalid
Unicode scalar values. JSON number tokens MUST be non-negative integers
without fractional or exponent syntax, from 0 through 9007199254740991.
Boolean values are not integers. Implicit Unicode normalization is forbidden.
JCS ordering and encoding apply exactly; already signed protected headers
and payloads MUST contain their canonical bytes.</t>
      <t>Each envelope contains exactly protected, payload, and signature,
encoded with canonical unpadded base64url <xref target="RFC4648" />.
Decode and re-encode equality, including unused trailing bits, is REQUIRED.
The protected header contains exactly alg, kid, and typ; alg is Ed25519 and
typ is application/xcim-consent+json. The type is provisional and not registered.
No unprotected header, detached payload, b64=false, key URL, embedded key,
or algorithm fallback is accepted. The signature is 64 octets over the ASCII
protected segment, a period, and the ASCII payload segment.</t>
      <t>Every signed payload contains profile equal to xcim-consent-01, its
kind, and issuer. The issuer is identical across all objects combined in an
Evidence Set. Payload commitments use the following function; the signature
envelope is not hashed. Signed kind and profile prevent cross-family reuse.</t>
      <sourcecode type="text">
H(P) = base64url(SHA-256(
  UTF8("XCIM-C01-OBJECT") || 0x00 || JCS(P)))
</sourcecode>
      <t>Hashes and recipient salts decode to 32 octets. Times are non-negative
integer UTC seconds since the Unix epoch; expiry is exclusive. Epochs and
type versions start at one. Issuer, sender, type, policy, log and anchor-profile
identifiers are absolute ASCII HTTPS URIs, at most 512 characters, without
userinfo, query or fragment; they are compared exactly and MUST NOT trigger
automatic discovery. consent_id and event_id are lowercase UUID version 4
URNs as specified in <xref target="RFC9562" />. Random identifiers and salts
MUST be generated with a cryptographically secure random source.</t>
      <t>kid is 1 to 200 printable ASCII characters. Text fields contain 1 to
4096 Unicode scalar values unless a narrower rule is given. Type arrays
contain 1 to 64 entries with unique type_id values, sorted in ASCII order
of type_id. Arrays of type identifiers use the same ordering and uniqueness.
An ordinary JWS envelope is at most 128 KiB; an anchor_batch JWS envelope
is at most 512 KiB, with decoded payload at most 256 KiB. Complete evidence
is at most 2 MiB and JSON depth at most 16. A batch has at most 4096 leaves.
Limits are applied before expensive work; partial verification is not success.</t>
    </section>
    <section anchor="trust">
      <name>Trust Policy, Keys and Sender Epochs</name>
      <t>Before evaluating evidence, the verifier administrator installs policy
binding the exact issuer to an accepted third-party attester, role-authorized
public keys, key identifiers, issuance windows, compromise/revocation state,
sender epoch restrictions, admitted address-control policies, withdrawal
procedures, supported blockchain profiles, clock bounds and policy expiry.
The configuration is authenticated local input, not a member of untrusted
Evidence Sets. No trust-on-first-use or self-declared accreditation is implied.</t>
      <sourcecode type="text">
kind          required signing role
sender        sender_binding
consent       consent_attestation
revocation    consent_revocation
status        consent_status
anchor_batch  anchor_publication
</sourcecode>
      <t>The signature MUST be authorized for its role and issuer at issued_at,
or this_update for status, or created_at for a batch. Current policy determines
whether historical signatures remain acceptable after key retirement or
compromise. Routine key rotation need not erase historical evidence.
The status signing key MUST also be authorized at evaluation time; its
validity end limits the positive-result deadline. Compromise handling can
invalidate previously accepted signatures under authenticated policy.</t>
      <t>Role delegation is not inferred. Rotation and recovery require
authenticated administrator configuration; new keys cannot authorize their
own admission. Losing a policy or rollback-protection store requires
authenticated recovery. A missing store MUST NOT silently become an empty
trusted history.</t>
      <t>The attester MUST stop issuing positive status for a sender epoch
retired because the identified entity or consent scope changed. A verifier
MUST honor known epoch restrictions and MUST NOT return to an older epoch.
Changing a domain or technical key does not transfer a consent relationship
to another company. A new entity, broader scope, or new epoch requires a
new recipient decision and a new consent identifier.</t>
      <t>Each admitted address-control policy MUST identify
exactly one supported method and its immutable validation rules. Admission
of one method MUST NOT admit another implicitly. A changed external revision,
validation rule or delivery-mode authority requires a new policy identifier
and explicit admission. Unknown methods or policies MUST NOT yield a
positive consent result. Merely adding a method to a schema grants no trust.</t>
    </section>
    <section anchor="address">
      <name>Recipient Address Representation</name>
      <t>The selected address_profile is ascii-idna15-1. Remove only outer SP
and HTAB and require exactly one @. The local part is an ASCII dot-atom:
letters, digits and !#$%&amp;'*+-/=?^_`{|}~ separated by single periods.
It contains 1 to 64 octets, with no leading, trailing or consecutive periods.
Its case, periods and plus tags are preserved. No provider-specific alias
equivalence or local-part lowercasing is inferred.</t>
      <t>Map the domain using non-transitional UTS #46 revision 31 with STD3
rules and Unicode 15.1.0 data <xref target="UTS46" />
        <xref target="IDNAMAP151" />,
then apply IDNA2008 validation including hyphen, Bidi and Joiner checks
<xref target="RFC5890" />
        <xref target="RFC5891" />. The result is lowercase
A-labels of 1 to 63 octets, a domain of at most 253 octets, and a complete
address of at most 254 octets. Reject a trailing domain period. Quoted
local parts and SMTPUTF8 addresses are unsupported by this address profile.
Changing tables or equivalence rules requires another profile.</t>
      <t>The canonical address is a private verifier input, not an email body
or header. The attester derives the recipient commitment from its authenticated
observation. A recomputable hash supplied by a sender does not establish
address control.</t>
    </section>
    <section anchor="sender">
      <name>Sender Binding</name>
      <t>The payload has exactly the following members, in addition to the common semantic constraints:</t>
      <sourcecode type="text">
profile, kind, issuer, sender_id, sender_epoch, name, scope,
entity_evidence_commitment, issued_at, expires_at
</sourcecode>
      <t>kind is sender. name and scope identify the company or other entity
and exact brand/service boundaries shown to the recipient. The attester
MUST authenticate the enrolling actor's authority to represent that entity
and retain the observed identity and scope evidence. A display name supplied
by the sender is insufficient. entity_evidence_commitment is a 32-octet
commitment to randomized private evidence under the admitted attester policy;
it is opaque to the verifier and does not claim a universal legal-entity
certification.</t>
      <t>sender_id is an issuer-assigned stable identifier and MUST NOT be
reassigned to another entity. sender_epoch is positive. The binding has finite
validity with issued_at earlier than expires_at. Consent embeds H of this
exact binding. The signed name and scope, rather than an unrelated website
label, are presented during the consent decision. A technical application
identifier can be mapped to this identity by a consuming application but
cannot silently enlarge the consent scope.</t>
    </section>
    <section anchor="consent">
      <name>Consent Attestation</name>
      <t>The payload has exactly the following members, in addition to the common semantic constraints:</t>
      <sourcecode type="text">
profile, kind, issuer, consent_id, sender_id, sender_epoch,
sender_binding_commitment, address_profile, recipient_salt,
recipient_commitment, types, notice, control, decision,
accepted_at, issued_at, expires_at
</sourcecode>
      <t>kind is consent and decision is exactly explicit_consent. Each types
entry contains exactly type_id, version, title and description. The descriptions
are the meanings accepted by the recipient and are covered by the signature.
notice contains exactly language and text; language is 1 to 35 ASCII characters.
control contains exactly method, policy_id, observed_at and evidence_commitment.
method is evp-01, oauth-01 or oidc-01. policy_id identifies an immutable
policy admitted by the verifier for that exact method. The opaque 32-octet evidence commitment binds the randomized
private observation and decision record retained by the attester.</t>
      <t>Require control.observed_at no later than accepted_at, accepted_at no
later than issued_at, and issued_at earlier than finite expires_at. The sender
binding MUST already be valid at accepted_at, its commitment and sender
identity/epoch MUST match exactly, and its expiry MUST be no earlier than
the consent expiry. The admitted policy specifies a maximum age between
control observation and acceptance; arbitrarily old authentication is not
accepted as current observation.</t>
      <t>recipient_salt is a fresh random 32-octet value. With the canonical
private address, compute the following exact commitment. The signed grant
and its salt are access-controlled evidence; only commitments are published
in the public anchor batch.</t>
      <sourcecode type="text">
recipient_commitment = base64url(SHA-256(
  UTF8("XCIM-C01-RECIPIENT") || 0x00 || JCS([
    issuer, consent_id, sender_id, sender_epoch,
    address_profile, recipient_salt, canonical_recipient
  ])))
</sourcecode>
      <t>Every accepted type is explicit. There is no wildcard, implied
affiliate permission or inference from a transactional relationship.
Changing a description or adding a type requires a new affirmative decision
for that meaning and a new consent identifier. Identical identifiers with
broader descriptions MUST NOT preserve the old consent. The evidence does
not assert that any actual email matches a type description.</t>
      <t>The tuple (issuer, sender_id, sender_epoch, type_id, version) MUST
identify one immutable title and description. A changed definition requires
a higher version or a new type_id, as well as a new consent decision.
A verifier MUST compare a definition with any previously authenticated
definition for that tuple or one supplied by its trusted consuming policy;
different meanings at the same tuple are a conflict, not an expansion
of consent. An unknown definition can be learned only from accepted
attestation evidence, not from an unauthenticated sender label.</t>
      <section anchor="issuance">
        <name>Address Control and Separate Consent Decision</name>
        <t>Address control and communication consent are separate
operations. XCIM supports EVP (evp-01), OAuth-based provider verification
(oauth-01), and OpenID Connect (oidc-01) as alternatives. An attester MAY
implement one or more; a deployment selects a method supported by both
the attester and the verifier's admitted policy. These are alternative
evidence paths, not cumulative prerequisites or a requirement to migrate
to EVP. OAuth-based verification obtains address evidence from an admitted
provider API; OIDC validates an ID Token under its authentication protocol.
OAuth authorization alone is not proof of address control. None of these
operations grants communication consent. Unrelated API authorization and
backend authentication remain outside this choice.</t>
        <section anchor="oidc-control">
          <name>OIDC Address Control (oidc-01)</name>
          <t>OIDC processing uses OpenID Connect Core 1.0 incorporating errata set 2
<xref target="OIDCCore" /> and JWT security guidance <xref target="RFC8725" />.
The attester preselects provider issuer, permitted keys/algorithms, clients,
address-authority policy, consent origin and return URI. Use authorization
code flow with PKCE and session-bound state and nonce. Token claims MUST NOT
choose the trusted provider or cause arbitrary discovery.</t>
          <t>Validate the signature, issuer, audience, authorized party where
applicable, subject, nonce, times and address claims under that policy.
The admitted provider must be authoritative for the observed address;
email_verified alone is insufficient. The observed canonical address MUST
match the frozen recipient. Raw tokens, subjects, credentials and email
addresses MUST NOT be placed in public logs or on chain.</t>
          <t>The authenticated address claims MUST include email_verified
as the Boolean true for the address used. If the address is obtained from
the OIDC UserInfo endpoint, validate that endpoint under the admitted
provider policy and require its subject to match the validated ID Token
subject. A verified claim still requires the provider's address-authority
assessment; it does not establish perpetual ownership of the mailbox.</t>
          <t>Record control.method as oidc-01 only after validating the ID
Token and the address-authority policy. An access token, authorization
code or user-supplied email MUST NOT substitute for that validation.
control.observed_at records successful validation, not the time a login
page was opened. Apply <xref target="RFC9700" /> to the underlying OAuth
flow and use PKCE S256 <xref target="RFC7636" />. A failure MUST NOT be
relabelled as success under oauth-01; changing methods requires a new,
explicitly selected and independently validated flow.</t>
        </section>
        <section anchor="oauth-control">
          <name>OAuth-Based Provider Verification (oauth-01)</name>
          <t>This method uses the authorization-code grant of
<xref target="RFC6749" /> with <xref target="RFC9700" /> and PKCE S256
<xref target="RFC7636" /> to access a provider's authenticated account
address service. OAuth does not define a universal verified-email response.
Consequently, oauth-01 additionally requires an immutable provider profile
admitted under control.policy_id. A provider that offers only an editable
contact field, an unverified address or token-activity information cannot
satisfy this method.</t>
          <t>The provider profile MUST identify the authorization server,
exact HTTPS authorization, token and account-address endpoints, API
revision, registered client and redirect URI, required least-privilege
scopes, response schema, authenticated account identifier, and the exact
semantics and provenance of the provider's address-verification evidence.
It MUST explain why that provider is accepted as authoritative for the
address and how current account control is established. A display name,
username, domain suffix or flag named verified is insufficient without
those semantics. Changes to those rules require new policy admission.</t>
          <t>For this method the attester is the OAuth client, including
any backend component it operates under the same trust boundary. It MUST
start a fresh authorization transaction bound to the recipient's browser
and pending consent session. Freeze the provider profile, client, exact
redirect URI, sender binding, notice and type definitions before redirect.
Generate independent unpredictable state and PKCE verifier values and
validate their transaction binding. Protect against authorization-server
mix-up, code injection, replay and cross-site request forgery. Redeem the
code once at the preconfigured token endpoint with the same redirect URI
and PKCE verifier, and authenticate the client where required.</t>
          <t>The attester MUST obtain the token through that transaction,
not accept an arbitrary bearer token from a sender or browser. Implicit,
password and client-credentials grants do not satisfy this profile.
A refresh token or preexisting application session alone MUST NOT create
a new address observation for consent issuance. Check token response
type, granted scopes and lifetime under the provider profile. Tokens need
not be JWTs: decoding a token or obtaining an active introspection result
is not proof of address control.</t>
          <t>Using that token, the attester MUST request the authenticated
current account's address evidence directly over certificate-validated
HTTPS at the admitted resource endpoint. It MUST NOT use an arbitrary
address-lookup endpoint or an account identifier supplied by the sender.
Reject unexpected redirects, malformed or ambiguous responses, expired
credentials, insufficient scopes and failed account binding. The response
MUST bind a provider-authenticated account identifier to the verified
address, and the profile MUST establish that this is the account that
authorized the transaction. An API accessible with an app-only credential
or returning a client-selected account does not establish that binding.</t>
          <t>The address evidence MUST represent verified control under
the admitted profile, not merely a deliverability check or an address the
account can edit without verification. If several addresses are returned,
the chosen one MUST individually satisfy that profile; selecting a primary
address does not imply verification. Apply <xref target="address" /> only
after validating provider evidence. Preserve the local part and compare
the result with any frozen expected recipient. If none was specified,
freeze the validated address and present it to the recipient before the
separate decision. Account or address mismatch MUST terminate the flow.</t>
          <t>The admitted policy MUST fix finite transaction and
observation-to-decision age bounds, each no greater than 300 seconds for
oauth-01. The transaction MUST be unexpired when the API response is
validated and when the decision is accepted. A new API read MUST NOT
reset the transaction deadline or turn cached historical verification
into a fresh user transaction. control.observed_at is the time the attester
successfully validates the current provider response. The provider profile
MUST specify acceptable age or revalidation rules for the underlying
address evidence; the response retrieval time alone cannot establish it.</t>
          <t>After a separate affirmative decision, record control.method
as oauth-01 and the corresponding admitted policy_id. The randomized
private evidence commitment MUST bind the provider profile and revision,
account/address observation, transaction binding and validation outcome,
sender binding, notice, type definitions and decision. Raw access tokens,
refresh tokens, authorization codes and client secrets MUST NOT appear
in the consent object, public logs or blockchain. Keep credentials only
as needed for the verification transaction, protected from disclosure.
The private evidence record need not retain reusable credentials.</t>
          <t>A later verifier evaluates the attester's admitted method and
policy and the ordinary C01 consent evidence. It does not call the provider
API for each email or receive an access token. OAuth scope approval remains
distinct from approval of communication types. Token expiry or revocation
does not by itself revoke XCIM consent; XCIM withdrawal and fresh status
determine current permission.</t>
        </section>
        <section anchor="evp-control">
          <name>EVP Address Control (evp-01)</name>
          <t>The external protocol for this method is revision -02 of
<xref target="I-D.hardt-email-verification" />. It remains Work in Progress.
The attester MUST validate the presentation according to that revision's
Sections 2.8, 3, 5.3 and 6.5, including the hash input specified in Section
6.4, and apply <xref target="RFC8725" />. A browser trial or future EVP
revision is not automatically interchangeable with this revision.</t>
          <t>The browser obtains an issuer-signed Email Verification Token
(EVT) and presents it with a Key Binding JWT (KB-JWT). The attester uses
the authenticated address observation as one input to its consent session.
The EVP issuer establishes address control; the Consent Attester observes
and attests the separate recipient decision. These roles MUST NOT be
conflated with the sender entity receiving consent.</t>
          <t>For XCIM, the admitted policy MUST fix the external revision,
allowed algorithms, discovery and address-authority rules, validation
software version, delivery mode, exact verification origin, and time
bounds. It MUST NOT select these authorities from an unverified token or
browser-supplied assertion. Discovery MUST use authenticated HTTPS and a
trusted DNS resolution policy, with bounded retrieval, cache lifetime,
redirects and key-set size. Reject destinations outside that policy,
including local or private network addresses unless separately configured.
DNSSEC validation or an authenticated pinned delegation MAY strengthen
domain authority; ordinary DNS resolution does not imply DNSSEC proof.</t>
          <t>Generate a fresh, unpredictable session nonce with at least
128 bits of entropy before requesting address evidence. The attester MUST
bind it to exactly one pending consent context. The expected recipient may
initially be unset, but MUST be frozen from the validated address before
the consent presentation and affirmative decision. A submitted form value
alone MUST NOT select the attested recipient. Once frozen, the address,
sender, types or verification origin MUST NOT be replaced within that
context; a change requires a new nonce and session.</t>
          <t>All external address comparisons MUST use the external protocol's
exact comparison rules before applying the C01 address representation.
When the session already has an expected address, the validated address
MUST match it under those rules before the session can proceed.
Then canonicalize the verified address under <xref target="address" />
and bind it to the consent recipient. The attester MUST NOT lowercase the
local part, remove tags or dots, or substitute a sender's customer-list
entry. An unsupported address is not silently converted. For a private
address, consent applies only to the validated address presented to the
recipient for this decision, not to its underlying mailbox or other aliases.</t>
          <t>The policy MUST set finite maximum ages for both token issue
times and the pending session. For this XCIM method, each maximum MUST
be no greater than 300 seconds; permitted clock uncertainty MUST be no
greater than 60 seconds. With validation time t and uncertainty u, require
each issue time i to satisfy i &lt;= t-u and t+u-i &lt;= its maximum age.
The session MUST remain unexpired at validation and acceptance; an
additional token expiry, when present, MUST also be enforced. The token
age limit MUST NOT be reset by reloading or relaying evidence.
control.observed_at is the attester's successful validation time.
The admitted maximum observation-to-decision age MUST be finite and no
greater than 300 seconds for evp-01.</t>
          <section anchor="evp-delivery">
            <name>Attester Origin and Delegated Origin</name>
            <t>In attester-origin mode, the attester is the EVP relying
party and validates the presentation against its own preconfigured HTTPS
origin and pending-session nonce. It then presents the frozen sender,
notice and type definitions for a separate affirmative decision.</t>
            <t>In delegated-origin mode, a sender or its service operates
the EVP relying-party origin and relays the complete raw presentation to
the attester over an authenticated, confidential backchannel. The attester
MUST preauthorize that exact origin and backend principal for evidence
submission on behalf of the identified sender. This authority neither
permits granting consent nor permits signing XCIM attestations. The
attester MUST validate the raw evidence itself; a backend's verified=true
assertion is insufficient.</t>
            <t>Before collecting evidence, the attester MUST freeze the
delegated origin and nonce in its consent session. An authenticated backend
MAY propose a cryptographically random nonce, but the attester MUST admit
and bind it before evidence collection. At submission it MUST recheck the
delegation, backend principal, session, sender, nonce, expected origin and
expiry. Evidence addressed to the delegated origin MUST NOT be relabelled
as evidence addressed to the attester's origin.</t>
            <t>The browser then reaches the attester's top-level consent
surface through a single-use session continuation bound to the same
browser context. The attester MUST authenticate that continuation and
protect the decision against cross-site request forgery, session fixation
and clickjacking. A leaked session identifier, sender-controlled return
URL or bare redirect MUST NOT enable another browser to approve the
verified recipient's consent. Only the attester observes the final
affirmative action. The handoff API, credentials and browser transport
are deployment choices; this document does not prescribe vendor endpoints.</t>
          </section>
          <section anchor="evp-mapping">
            <name>Attestation Mapping and Failure Handling</name>
            <t>After validating EVP and observing the separate decision,
the attester sets control.method to evp-01, control.policy_id to the
admitted EVP policy, and control.observed_at to the recorded validation
time. The existing private evidence commitment MUST bind the exact
validated presentation, its session and origin, the policy and adapter
version, sender binding, canonical recipient, notice, type definitions
and affirmative decision. Its randomized opening remains private under
attester policy. It is not a public EVT fingerprint or a new bearer token.
No additional member is added to the closed control object.</t>
            <t>The signed consent, publication, withdrawal and fresh-status
procedures are the same for all three address-control methods. A later XCIM
verifier checks the attester's admitted method and policy; it does not
replay the browser's EVP transaction or receive raw identity tokens.
Token expiry after issuance does not revoke consent. Conversely, a valid
token cannot override a withdrawal or renew a grant.</t>
            <t>Missing browser or provider support, an absent token or a
cancelled verification MUST NOT be recorded as successful address control.
Invalid, mismatched or replayed evidence MUST be rejected. An attester MAY
offer OAuth-based provider verification or OIDC as a separately selected
flow with a fresh challenge and its own validation. Such a grant MUST
record oauth-01 or oidc-01 respectively. A switch MUST NOT copy
an earlier decision, bypass validation, or convert an EVP failure into
consent. Unsupported EVP does not by itself establish fraud.</t>
          </section>
        </section>
        <section anchor="explicit-decision">
          <name>Common Explicit Decision</name>
          <t>The server-side session freezes sender binding, recipient, notice,
exact type definitions, selected control method and policy,
method-specific authority and transaction challenge, verification and consent
origins, return URI and expiry.
The attester MUST observe a separate affirmative recipient action in that
same authenticated context. Login, registration, purchase, a preselected
option or a sender-supplied record does not constitute that action.
The implementation retains evidence linking the address observation,
presentation and decision.</t>
          <t>Consume the consent-session decision authority and persist the decision and issued
grant atomically. A denial is terminal for the session. A retry retrieves
the same recorded result and cannot create or broaden another grant.
Refresh or login alone cannot renew consent. Multiple types can be accepted
in one consent session; issuance is independent of email transmissions.</t>
          <t>Successful address-control validation consumes the method's
transaction challenge exactly once and records an identity-verified state bound to
the consent session. That state permits only the subsequent decision in
the same unexpired context. It is not an issued consent grant. Denial,
timeout or loss of continuity terminates the context without granting
permission. The later atomic decision transaction consumes the remaining
consent-session authority.</t>
        </section>
      </section>
    </section>
    <section anchor="lifecycle">
      <name>Withdrawal and Immutable Lifecycle</name>
      <t>The payload has exactly the following members, in addition to the common semantic constraints:</t>
      <sourcecode type="text">
profile, kind, issuer, event_id, consent_id, consent_commitment,
sequence, previous_event_commitment, type_ids, actor, method,
evidence_commitment, requested_at, effective_at, issued_at
</sourcecode>
      <t>kind is revocation. sequence starts at one for each consent and
increases by one. previous_event_commitment is H(consent) for the first event
and H of the previous revocation thereafter. consent_commitment is always
H of the original consent. event_id MUST be unique in that chain.
type_ids is a nonempty sorted unique subset of the original types, excluding
any type already removed. There are at most 64 events because every event
irreversibly removes at least one of at most 64 original types.</t>
      <t>actor is recipient, sender, or attester. These mean respectively an
authenticated recipient withdrawal, an authenticated sender surrender or
restriction, and an authenticated protective action by the attester.
All events are signed by the attester, which retains private evidence of
the actual actor and authority. method matches [A-Za-z0-9._-]{1,64} and
identifies a request procedure admitted in policy. A sender
MUST NOT be allowed to assert that it acted as the recipient.</t>
      <t>The private evidence commitment binds authenticated actor, random
request nonce, consent, affected types and outcome. Require
consent.issued_at &lt;= requested_at &lt;= effective_at &lt;= event.issued_at.
effective_at and event.issued_at MUST NOT decrease across the chain.
The minimum does not schedule future-effective revocations. Request
authentication, nonce consumption, event sequencing and state update MUST
be one durable transaction.</t>
      <t>The first committed valid removal of overlapping types wins.
Retries return the existing result; disjoint removals serialize in the
same event chain. There is no event that grants, extends or reactivates
consent. Regrant requires a new explicit decision and identifier.
Withdrawal is terminal for the affected type in the old grant.</t>
      <t>Publish and anchor revocations as immutable historical events.
An authenticated withdrawal removes the positive signal immediately,
including while its anchor is pending. An attester MUST NOT issue active
status for a removed type after committing its withdrawal. Withholding a
withdrawal anchor cannot restore consent. A deployment specifies its
publication-delay policy and reports breaches; this core does not claim
instantaneous blockchain finality.</t>
    </section>
    <section anchor="status">
      <name>Fresh Current Status</name>
      <t>The payload has exactly the following members, in addition to the common semantic constraints:</t>
      <sourcecode type="text">
profile, kind, issuer, consent_id, consent_commitment, sender_id,
sender_epoch, sequence, event_head, active_type_ids, this_update,
next_update
</sourcecode>
      <t>kind is status. sequence is the number of complete revocation events
supplied, from zero through 64. event_head is H(consent) at zero and H of the
last event otherwise. active_type_ids is the sorted set of original type
identifiers minus the cumulative removed types; it may be empty. Every
identifier, issuer and commitment MUST match the exact grant and lifecycle.
Missing intermediate events or a different projection are invalid.</t>
      <t>this_update is no earlier than consent.issued_at and every supplied
event.issued_at. It is earlier than next_update, with an interval no greater
than 300 seconds. next_update is no later than the consent and sender-binding
expiries. An expired grant need not receive another positive status.
Status is signed by a currently authorized consent_status key.</t>
      <t>Snapshot renewal at the same sequence may change only this_update and
next_update. A different event head, active set or other semantic field at
the same sequence is a conflict. A verifier MUST retain authenticated
terminal removals and sequence/epoch floors. Known later restrictions
override an older still-unexpired active view. Unauthenticated input MUST
NOT advance those records. Conflicting authenticated history requires
quarantine and authenticated recovery.</t>
      <t>Fresh status is the trusted attester's current projection, not an
independent proof that a dishonest attester concealed no withdrawal.
It does not require a new blockchain transaction for each query.
Repeated reads and cache retrieval MUST NOT extend its signed lifetime.
These controls protect lifecycle state, not email replay or SMTP queues.</t>
    </section>
    <section anchor="blockchain">
      <name>Immutable Blockchain Evidence</name>
      <section anchor="batch">
        <name>Anchor Batch</name>
        <t>The payload has exactly the following members, in addition to the common semantic constraints:</t>
        <sourcecode type="text">
profile, kind, issuer, log_id, sequence,
previous_batch_commitment, created_at, leaves
</sourcecode>
        <t>kind is anchor_batch. sequence is a positive safe integer for an
issuer/log. previous_batch_commitment is null only for sequence one;
otherwise it is H of the immediately previous batch. leaves is an ASCII
sorted array of 1 to 4096 unique object-commitment strings. It can aggregate
consent and revocation commitments. The complete list accompanies an
inclusion check; this bounded profile uses no additional Merkle path format.</t>
        <t>For each checked object, H of its payload MUST occur exactly in leaves
and its issued_at MUST be no later than created_at. Verify the batch
signature under the anchor_publication role and compute C = H(batch).
The admitted blockchain adapter MUST establish that this exact C was
anchored in the accepted issuer/log, network and anchor context.
Further objects require another batch, not truncation or a history reset.</t>
        <t>Publishers preserve the batch sequence and predecessor and MUST NOT
publish conflicting batches at one sequence. The deployment binds that
history to its admitted anchoring mechanism. Known conflicts or rollback
withdraw the positive signal. Grant inclusion is historical evidence;
it does not replace the status algorithm. Full consent or recipient
mapping payloads MUST NOT be placed on a public blockchain by this profile.</t>
      </section>
      <section anchor="adapter">
        <name>Blockchain Adapter Contract and Limits</name>
        <t>The payload has exactly the following members, in addition to the common semantic constraints:</t>
        <sourcecode type="text">
profile_id, network_id, genesis_hash, anchor_id, block_hash,
transaction_hash, record_index, batch_commitment, proof
</sourcecode>
        <t>This is an unsigned evidence wrapper, not another signed C01 kind.
profile_id selects a previously admitted adapter. network_id, genesis_hash,
anchor_id, block_hash and transaction_hash are nonempty ASCII strings of at
most 512 characters whose exact encodings are defined by that adapter;
record_index is a non-negative safe integer, batch_commitment a C01 hash,
and proof a bounded JSON object. Schema acceptance does not authenticate
any of these values.</t>
        <t>An admitted adapter MUST specify network and genesis identification,
anchor authority/location and code or transaction semantics, exact committed
bytes, inclusion proofs, consensus/finality verification, history continuity,
halt/conflict handling and recovery. Its trusted configuration is installed
independently of the wrapper. It MUST return an authenticated commitment
and network/anchor context that the caller compares with the expected batch
and policy. An issuer-controlled adapter cannot grant itself trust.</t>
        <t>A transaction URL, issuer-supplied finalized flag, successful HTTPS
response or agreement between untrusted RPC servers is not verified
consensus. A verifier MUST NOT return CONSENT_CURRENT without actual
historical inclusion and finality verification through an admitted adapter.
Unavailable required evidence yields INDETERMINATE; an unsupported profile
is not a fallback to unanchored consent.</t>
        <t>This core specifies the adapter boundary but does not select a
universal blockchain network, consensus bootstrap or chain-specific proof
encoding. Peers need a common admitted adapter to interoperate end to end.
Those deployment dependencies remain explicit. Operating a node is one
possible implementation and is not a universal requirement on every
consuming email service. No live Amoy deployment or finality result is
claimed by this revision.</t>
        <t>The previous AN01 EVM contract work can be reused to publish a C01
batch commitment under a separately specified deployment/profile. Its
application to an earlier AS checkpoint does not make AN01-F01 Evidence
Sets compatible with C01. No historical checkpoint is relabeled.
Blockchain remains part of the protocol; the separation does not create
an unanchored profile with the same positive result.</t>
      </section>
    </section>
    <section anchor="evidence">
      <name>Evidence Set and Acquisition</name>
      <t>The payload has exactly the following members, in addition to the common semantic constraints:</t>
      <sourcecode type="text">
profile, sender, consent, revocations, status, consent_anchor,
revocation_anchors
</sourcecode>
      <t>profile is xcim-consent-01. sender, consent and status are JWS
envelopes of the corresponding kinds; revocations is an ordered array of
revocation JWS envelopes. consent_anchor contains exactly batch (a batch
JWS) and evidence (the anchor wrapper). revocation_anchors is an array of
objects containing exactly event_id, batch and evidence, with unique
event_id values naming supplied revocations. Missing withdrawal anchors
are reported as pending and never imply active consent.</t>
      <t>All signed issuer values MUST match. Every internal sender identifier,
epoch, consent identifier, commitment and lifecycle link MUST match exactly.
Mixing internally inconsistent objects is INVALID_EVIDENCE, even when
their individual signatures verify. A missing required member is a
structural error; an unavailable required proof is not evidence of revocation
or permission.</t>
      <t>Evidence can be exchanged through configured authenticated HTTPS,
authorized local storage or another admitted channel. HTTP transport uses
application/json. This revision does not standardize discovery, endpoint
request syntax or query-credential provisioning. Peers preconfigure these
deployment interfaces; transport alone does not establish consent.</t>
      <t>Evidence access MUST be authorized for the requested recipient/sender
scope. Network retrieval MUST verify certificates and the configured origin,
bound sizes and timeouts, avoid credential leakage, and reject unsolicited
redirects, compression and destination changes. Resolved and connected
addresses must comply with policy to prevent SSRF and DNS rebinding.
Sender-provided URLs cannot install endpoints or trust. A network error,
HTTP 404 or rate limit does not prove absence or withdrawal.</t>
    </section>
    <section anchor="verification">
      <name>Consent Verification and Results</name>
      <t>The verifier takes an authenticated local query containing the canonical
recipient, issuer, sender_id, sender_epoch, type_id, type version, evaluation
time, accepted policy, and evidence. A consuming application establishes
the relationship between its authenticated sender context and this sender
identity. No email message, header, DKIM result, MP or MSA is a core input.</t>
      <ol>
        <li>Check policy, clock and persistent-state availability; apply limits, parsing, profile and closed-object rules.</li>
        <li>Authenticate the issuer, signatures, roles and issuance windows; require identical internal identities and commitments.</li>
        <li>Validate the sender binding, attestation, exact queried address commitment, type/version, explicit decision, admitted address-control method and times.</li>
        <li>Verify the complete terminal revocation chain and status projection; apply known authenticated sender-epoch and withdrawal restrictions.</li>
        <li>Verify consent inclusion in the exact signed batch and historical blockchain inclusion/finality through the admitted adapter.</li>
        <li>Intersect current policy, status-key, binding, consent and status validity with the clock bounds; return the corresponding result.</li>
      </ol>
      <t>For local time t and uncertainty u, u MUST be at most 60 seconds.
For a positive result require this_update &lt;= t-u,
t+u &lt; min(next_update, consent expiry, binding expiry, policy expiry,
status-key validity end), and t+u-this_update &lt;= 300 seconds. Re-evaluate
time before returning or reusing a result. An unbounded clock, stale status,
expired policy or missing trusted recovery state cannot yield a positive
result. No cache grace period extends an authenticated deadline.</t>
      <dl>
        <dt>CONSENT_CURRENT</dt>
        <dd>All mandatory checks succeeded for the exact queried relationship and type. Actual blockchain verification is required.</dd>
        <dt>CONSENT_REVOKED</dt>
        <dd>An authenticated applicable withdrawal is established. Missing finality for that withdrawal cannot restore consent.</dd>
        <dt>CONSENT_EXPIRED</dt>
        <dd>The authenticated grant or sender binding has expired; it cannot establish current consent.</dd>
        <dt>NO_MATCH</dt>
        <dd>Internally consistent evidence does not cover the queried recipient, sender, epoch or type/version.</dd>
        <dt>INVALID_EVIDENCE</dt>
        <dd>Malformed data, invalid signatures, contradictory internal scope, broken lifecycle links or an invalid projection.</dd>
        <dt>UNSUPPORTED_PROFILE</dt>
        <dd>The profile or required algorithm is unsupported; no downgrade is permitted.</dd>
        <dt>INDETERMINATE</dt>
        <dd>Required evidence, finality, current authority or freshness is unavailable, or trusted histories conflict.</dd>
      </dl>
      <t>These are core result labels, not an Authentication-Results method.
No result asserts that an email is safe, authenticated, correctly categorized
or deliverable. A repeated query for the same valid relationship does not
consume consent. Invalid data MUST NOT create persistent restrictions;
authenticated restrictive events MAY be retained before their anchors arrive.
Known withdrawal takes precedence over older active status. Implementations
MUST NOT convert an indeterminate result into positive consent.</t>
    </section>
    <section anchor="mail-integration">
      <name>Optional Consumption by Email Services</name>
      <t>A receiving email service may first use its existing authentication
mechanisms to establish a sender context, map that context to the identified
sender named in the consent, then verify XCIM for its recipient and a requested
communication type. It may use CONSENT_CURRENT as one positive policy input.
This integration is optional and does not change core conformance.</t>
      <t>DKIM <xref target="RFC6376" /> associates a signing domain with signed
message material; DKIM2 <xref target="I-D.ietf-dkim-dkim2-spec" /> develops
message authentication, handling history and replay-related mechanisms.
Neither is the recipient's decision to grant a company communication
permission. They can complement XCIM without becoming dependencies of
consent verification. A shared provider's authenticated domain does not
automatically identify the company that benefits from a consent.</t>
      <t>The integration MUST establish that identity mapping and MUST NOT
borrow another tenant's consent. Determining a particular message's type
is external to XCIM. A sender merely labeling an email transactional does
not prove its category or widen its grant. Positive consent does not require
inbox delivery; missing XCIM does not universally require rejection.
Unsubscribe mechanisms such as <xref target="RFC8058" /> can supply a
withdrawal request through an authenticated integration, but do not create
an original consent decision.</t>
    </section>
    <section anchor="security">
      <name>Security Considerations</name>
      <t>Relevant attackers include a sender fabricating consent, an unauthorized
actor controlling a consent UI, a dishonest accepted attester, a compromised
signing key, a publisher withholding withdrawals, a verifier using stale
state, and a malicious blockchain endpoint. Exact identity, type and
commitment checks prevent substitution only under the admitted trust
assumptions. A cryptographically valid lie remains a lie by the attester.</t>
      <t>A compromised sender or shared service MUST NOT create a grant by
presenting an address hash or another company's binding. Enrollment and
decision evidence require authenticated observations by the third party.
Consent presentation must clearly identify the company, scope and meanings
being accepted. An opaque type token is insufficient for informed selection.</t>
      <t>Address control is observed at consent time. Reassignment, account
takeover and loss of control can undermine later assumptions; finite expiry,
authenticated withdrawal and policy-driven reauthentication limit exposure.
This revision does not claim continuous proof of mailbox ownership.
Freshness bounds limit stale acceptance under an honest publishing attester;
they are not a measured revocation SLA or protection against concealed
withdrawals by that attester.</t>
      <t>History and cache recovery MUST preserve known terminal withdrawals
and epoch restrictions. Durable local storage alone cannot detect rollback
of an entire disk; a deployment requiring that protection needs an
authenticated external recovery floor. An anchor proves committed history
under its finality model, not data availability or correct state computation.
No synthetic chain observation may be promoted to real consensus evidence.</t>
    </section>
    <section anchor="privacy">
      <name>Privacy Considerations</name>
      <t>Public batches and chain records contain commitments, not recipient
addresses, raw identity tokens, credentials or private consent inputs.
The signed grants, salts, sender/type descriptions and address mappings
remain access-controlled evidence. A known salt permits testing candidate
addresses and is not encryption. Randomized private-evidence commitments
also require careful handling of their openings.</t>
      <t>Queries, timestamps and issuer/sender relationships can reveal recipient
interests even without plaintext addresses. Apply access authorization,
data minimization, retention controls and rate limits. Private-data deletion
does not erase an immutable public commitment; it can make later evidence
unavailable. Loss of access must not be misreported as proof of withdrawal
or current consent.</t>
      <section anchor="evp-privacy">
        <name>EVP Evidence and Origin Privacy</name>
        <t>EVP evidence MUST NOT appear in public consent objects, logs,
blockchain records, callback URLs or analytics. Minimize private retention
and protect retained evidence with access controls and encryption. A
delegated-origin flow exposes its presentation to both the relying party
and attester; it MUST NOT be described as hiding the recipient from either.
An attester serving multiple senders can correlate observations even when
the external protocol limits issuer visibility. XCIM does not expand a
private-address grant to another origin, address or sender.</t>
      </section>
    </section>
    <section anchor="iana">
      <name>IANA Considerations</name>
      <t>This revision defines no email header and no Authentication-Results
method. It uses the existing HTTPS URI and UUID URN namespaces, rather than
claiming a registered xcim URN namespace. The JWS typ value
application/xcim-consent+json is a provisional protocol identifier; no
media-type registration is established by this Internet-Draft.
Evidence HTTP transport uses application/json.</t>
      <t>Before an eventual RFC, the media-type registration and any registry
for interoperable address-control or blockchain profiles need concrete
templates, allocation policies and change control. A future change to a
signed typ or identifier requires explicit version selection and migration,
not rewriting prior signed bytes. The result labels here do not imply
IANA assignment.</t>
    </section>
    <section anchor="conformance">
      <name>Conformance, Validation and Remaining Work</name>
      <t>Conformance is evaluated separately for sender enrollment/attestation,
consent issuance, lifecycle/status publication, blockchain adapters, and
consent verification. A core verifier MUST work without an SMTP transaction,
email body, message signature or per-message replay store. A complete
positive result additionally requires a real admitted blockchain adapter;
schema or signature success alone is not sufficient.</t>
      <t>Necessary tests include a valid query without an email, repeated
verification without consuming a grant, independently selected types,
partial and complete withdrawals, expired and stale evidence, altered
signatures, recipient and sender substitution, shared-provider tenant
confusion, wrong type/version, unauthorized actor requests, state rollback,
conflicting history and incorrect blockchain context. Test reports identify
the exact objects, policy, adapter, software and limits used.</t>
      <t>The core object and lifecycle rules are specified in this revision.
Remaining interoperability work is explicit: chain-specific proof encodings
and authenticated finality/bootstrap profiles; discovery and credential
provisioning for evidence services; portable sender-enrollment assurance
policies; and final registration/migration templates. Closure requires exact
formats, trust inputs and adversarial vectors for each selected profile.
These dependencies cannot be bypassed to obtain CONSENT_CURRENT.</t>
      <t>Independent security/privacy review, actual identity-provider flows,
live chain verification, separately operated interoperability and workload
measurements remain evidence tasks. They are not claimed by local fixtures
and do not require adding message-processing obligations to XCIM.</t>
      <section anchor="evp-conformance">
        <name>EVP Profile Validation</name>
        <t>Tests MUST distinguish external-token validation, session/handoff
binding, explicit decision, signed-object verification and current-state
verification. Include valid evidence without consent, wrong or reused
nonce, wrong origin, recipient substitution, stale tokens, substituted
issuer or browser keys, invalid token linkage, unadmitted policy, expired
delegation, cross-browser continuation, fallback mislabelling, denial,
retry, and withdrawal after EVP-based issuance. Passing schema tests
does not validate an EVP transaction.</t>
        <t>Interoperability evidence MUST identify the exact external
revision, browser transport, provider, adapter, policy and delivery mode.
Closure requires a successful browser-to-attester flow and adversarial
cases for that same combination, followed by independent reproduction.
Browser and IETF EVP specifications may differ; such differences require
an explicit compatibility profile and review, not silent acceptance under
evp-01. This revision fixes the IETF revision used for evp-01 but does not
claim that every available browser implements it.</t>
      </section>
      <section anchor="oauth-conformance">
        <name>OAuth Provider Profile Validation</name>
        <t>Before admitting an OAuth provider profile, document its
exact endpoint and response mapping and test a successful code/PKCE/API
transaction plus wrong state, wrong verifier, reused code, provider mix-up,
token substitution, insufficient scopes, inactive credentials, account
substitution, unverified address, stale address evidence and unexpected
redirect cases. Test a successful address check followed by denial or no
consent action, and confirm that neither issues a grant. Test method
switching, policy isolation and withdrawal after issuance separately.
Closure requires repeatable provider/adapter evidence and independent
reproduction; C01 object fixtures do not demonstrate those transactions.</t>
      </section>
    </section>
    <section anchor="implementation">
      <name>Implementation Status</name>
      <t>This section is informative, following <xref target="RFC7942" />.
The project maintains local C01 schemas and a reference verifier with
positive and adversarial fixtures. These exercise consent objects,
signatures, recipient/sender/type relationships, lifecycle, freshness and
batch commitments independently of email messages. Test keys and simulated
anchor adapters are explicitly non-operational.</t>
      <t>A simulated adapter may report successful consent checks for a test
case but MUST NOT produce an operational CONSENT_CURRENT result. No real
EVP, OAuth or OIDC provider/browser integration for this C01 profile,
deployed C01 blockchain profile,
independent interoperability or production security assurance is claimed.
Previous P1/MAIL01 test counts remain historical evidence for those profiles
and are not reused as proof that this corrected scope has been validated.</t>
      <t>The local examples also exercise signed
evp-01 and oauth-01 consent objects and method-specific policy admission.
Their address-control observations are synthetic. They are not an EVP
issuer, browser, OAuth client/API adapter or token validator, and do not establish external-protocol
conformance.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>Normative References</name>
      <reference anchor="RFC2119" target="https://www.rfc-editor.org/rfc/rfc2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author initials="S." surname="Bradner" fullname="Scott Bradner" />
          <date year="1997" month="March" />
        </front>
        <seriesInfo name="BCP" value="14" />
        <seriesInfo name="RFC" value="2119" />
      </reference>
      <reference anchor="RFC8174" target="https://www.rfc-editor.org/rfc/rfc8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author initials="B." surname="Leiba" fullname="Barry Leiba" />
          <date year="2017" month="May" />
        </front>
        <seriesInfo name="BCP" value="14" />
        <seriesInfo name="RFC" value="8174" />
      </reference>
      <reference anchor="RFC7515" target="https://www.rfc-editor.org/rfc/rfc7515">
        <front>
          <title>JSON Web Signature (JWS)</title>
          <author initials="M." surname="Jones" />
          <author initials="J." surname="Bradley" />
          <author initials="N." surname="Sakimura" />
          <date year="2015" month="May" />
        </front>
        <seriesInfo name="RFC" value="7515" />
      </reference>
      <reference anchor="RFC8032" target="https://www.rfc-editor.org/rfc/rfc8032">
        <front>
          <title>Edwards-Curve Digital Signature Algorithm (EdDSA)</title>
          <author initials="S." surname="Josefsson" />
          <author initials="I." surname="Liusvaara" />
          <date year="2017" month="January" />
        </front>
        <seriesInfo name="RFC" value="8032" />
      </reference>
      <reference anchor="RFC8785" target="https://www.rfc-editor.org/rfc/rfc8785">
        <front>
          <title>JSON Canonicalization Scheme (JCS)</title>
          <author initials="A." surname="Rundgren" />
          <author initials="B." surname="Jordan" />
          <author initials="S." surname="Erdtman" />
          <date year="2020" month="June" />
        </front>
        <seriesInfo name="RFC" value="8785" />
      </reference>
      <reference anchor="RFC9864" target="https://www.rfc-editor.org/rfc/rfc9864">
        <front>
          <title>Fully-Specified Algorithms for JSON Object Signing and Encryption (JOSE) and CBOR Object Signing and Encryption (COSE)</title>
          <author initials="M.B." surname="Jones" />
          <author initials="O." surname="Steele" />
          <date year="2025" month="October" />
        </front>
        <seriesInfo name="RFC" value="9864" />
      </reference>
      <reference anchor="RFC8259" target="https://www.rfc-editor.org/info/rfc8259">
        <front>
          <title>The JavaScript Object Notation (JSON) Data Interchange Format</title>
          <author fullname="T. Bray" initials="T." role="editor" surname="Bray" />
          <date month="December" year="2017" />
        </front>
        <seriesInfo name="STD" value="90" />
        <seriesInfo name="RFC" value="8259" />
        <seriesInfo name="DOI" value="10.17487/RFC8259" />
      </reference>
      <reference anchor="RFC4648" target="https://www.rfc-editor.org/info/rfc4648">
        <front>
          <title>The Base16, Base32, and Base64 Data Encodings</title>
          <author fullname="S. Josefsson" initials="S." surname="Josefsson" />
          <date month="October" year="2006" />
        </front>
        <seriesInfo name="RFC" value="4648" />
        <seriesInfo name="DOI" value="10.17487/RFC4648" />
      </reference>
      <reference anchor="RFC6234" target="https://www.rfc-editor.org/info/rfc6234">
        <front>
          <title>US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)</title>
          <author fullname="D. Eastlake 3rd" initials="D." surname="Eastlake 3rd" />
          <author fullname="T. Hansen" initials="T." surname="Hansen" />
          <date month="May" year="2011" />
        </front>
        <seriesInfo name="RFC" value="6234" />
        <seriesInfo name="DOI" value="10.17487/RFC6234" />
      </reference>
      <reference anchor="RFC8725" target="https://www.rfc-editor.org/info/rfc8725">
        <front>
          <title>JSON Web Token Best Current Practices</title>
          <author fullname="Y. Sheffer" initials="Y." surname="Sheffer" />
          <author fullname="D. Hardt" initials="D." surname="Hardt" />
          <author fullname="M. Jones" initials="M." surname="Jones" />
          <date month="February" year="2020" />
        </front>
        <seriesInfo name="BCP" value="225" />
        <seriesInfo name="RFC" value="8725" />
        <seriesInfo name="DOI" value="10.17487/RFC8725" />
      </reference>
      <reference anchor="RFC5890" target="https://www.rfc-editor.org/info/rfc5890">
        <front>
          <title>Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework</title>
          <author fullname="J. Klensin" initials="J." surname="Klensin" />
          <date month="August" year="2010" />
        </front>
        <seriesInfo name="RFC" value="5890" />
        <seriesInfo name="DOI" value="10.17487/RFC5890" />
      </reference>
      <reference anchor="RFC5891" target="https://www.rfc-editor.org/info/rfc5891">
        <front>
          <title>Internationalized Domain Names in Applications (IDNA): Protocol</title>
          <author fullname="J. Klensin" initials="J." surname="Klensin" />
          <date month="August" year="2010" />
        </front>
        <seriesInfo name="RFC" value="5891" />
        <seriesInfo name="DOI" value="10.17487/RFC5891" />
      </reference>
      <reference anchor="OIDCCore" target="https://openid.net/specs/openid-connect-core-1_0-errata2.html">
        <front>
          <title>OpenID Connect Core 1.0 incorporating errata set 2</title>
          <author initials="N." surname="Sakimura" />
          <author initials="J." surname="Bradley" />
          <author initials="M." surname="Jones" />
          <author initials="B." surname="de Medeiros" />
          <author initials="C." surname="Mortimore" />
          <date year="2023" month="December" day="15" />
        </front>
      </reference>
      <reference anchor="UTS46" target="https://www.unicode.org/reports/tr46/tr46-31.html">
        <front>
          <title>Unicode IDNA Compatibility Processing</title>
          <author initials="M." surname="Davis" />
          <author initials="M." surname="Suignard" />
          <date year="2023" month="September" day="5" />
        </front>
        <seriesInfo name="Unicode Technical Standard" value="46, revision 31, Unicode 15.1.0" />
      </reference>
      <reference anchor="IDNAMAP151" target="https://www.unicode.org/Public/idna/15.1.0/IdnaMappingTable.txt">
        <front>
          <title>Unicode IDNA Mapping Table Version 15.1.0</title>
          <author>
            <organization>Unicode Consortium</organization>
          </author>
          <date year="2023" month="August" day="10" />
        </front>
      </reference>
      <reference anchor="RFC9562" target="https://www.rfc-editor.org/rfc/rfc9562">
        <front>
          <title>Universally Unique IDentifiers (UUIDs)</title>
          <author initials="K." surname="Davis" />
          <author initials="B." surname="Peabody" />
          <author initials="P." surname="Leach" />
          <date year="2024" month="May" />
        </front>
        <seriesInfo name="RFC" value="9562" />
      </reference>
      <reference anchor="RFC6749" target="https://www.rfc-editor.org/rfc/rfc6749">
        <front>
          <title>The OAuth 2.0 Authorization Framework</title>
          <author initials="D." surname="Hardt" />
          <date year="2012" month="October" />
        </front>
        <seriesInfo name="RFC" value="6749" />
        <seriesInfo name="DOI" value="10.17487/RFC6749" />
      </reference>
      <reference anchor="RFC7636" target="https://www.rfc-editor.org/rfc/rfc7636">
        <front>
          <title>Proof Key for Code Exchange by OAuth Public Clients</title>
          <author initials="N." surname="Sakimura" />
          <author initials="J." surname="Bradley" />
          <author initials="N." surname="Agarwal" />
          <date year="2015" month="September" />
        </front>
        <seriesInfo name="RFC" value="7636" />
        <seriesInfo name="DOI" value="10.17487/RFC7636" />
      </reference>
      <reference anchor="RFC9700" target="https://www.rfc-editor.org/rfc/rfc9700">
        <front>
          <title>Best Current Practice for OAuth 2.0 Security</title>
          <author initials="T." surname="Lodderstedt" />
          <author initials="J." surname="Bradley" />
          <author initials="A." surname="Labunets" />
          <author initials="D." surname="Fett" />
          <date year="2025" month="January" />
        </front>
        <seriesInfo name="RFC" value="9700" />
        <seriesInfo name="DOI" value="10.17487/RFC9700" />
      </reference>
      <reference anchor="I-D.hardt-email-verification" target="https://datatracker.ietf.org/doc/html/draft-hardt-email-verification-02">
        <front>
          <title>Email Verification Protocol</title>
          <author initials="D." surname="Hardt" />
          <author initials="S." surname="Goto" />
          <date year="2026" month="August" day="25" />
        </front>
        <seriesInfo name="Internet-Draft" value="draft-hardt-email-verification-02" />
        <seriesInfo name="Work in Progress" value="" />
      </reference>
    </references>
    <references>
      <name>Informative References</name>
      <reference anchor="RFC6376" target="https://www.rfc-editor.org/rfc/rfc6376">
        <front>
          <title>DomainKeys Identified Mail (DKIM) Signatures</title>
          <author initials="D." surname="Crocker" role="editor" />
          <author initials="T." surname="Hansen" role="editor" />
          <author initials="M." surname="Kucherawy" role="editor" />
          <date year="2011" month="September" />
        </front>
        <seriesInfo name="RFC" value="6376" />
      </reference>
      <reference anchor="RFC8058" target="https://www.rfc-editor.org/info/rfc8058">
        <front>
          <title>Signaling One-Click Functionality for List Email Headers</title>
          <author fullname="J. Levine" initials="J." surname="Levine" />
          <author fullname="T. Herkula" initials="T." surname="Herkula" />
          <date month="January" year="2017" />
        </front>
        <seriesInfo name="RFC" value="8058" />
        <seriesInfo name="DOI" value="10.17487/RFC8058" />
      </reference>
      <reference anchor="RFC7942" target="https://www.rfc-editor.org/info/rfc7942">
        <front>
          <title>Improving Awareness of Running Code: The Implementation Status Section</title>
          <author fullname="Y. Sheffer" initials="Y." surname="Sheffer" />
          <author fullname="A. Farrel" initials="A." surname="Farrel" />
          <date month="July" year="2016" />
        </front>
        <seriesInfo name="BCP" value="205" />
        <seriesInfo name="RFC" value="7942" />
        <seriesInfo name="DOI" value="10.17487/RFC7942" />
      </reference>
      <reference anchor="I-D.ietf-dkim-dkim2-spec" target="https://datatracker.ietf.org/doc/html/draft-ietf-dkim-dkim2-spec-07">
        <front>
          <title>DomainKeys Identified Mail Signatures v2 (DKIM2)</title>
          <author initials="R." surname="Clayton" />
          <author initials="W." surname="Chuang" />
          <author initials="B." surname="Gondwana" />
          <date year="2026" month="October" day="18" />
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-dkim-dkim2-spec-07" />
        <seriesInfo name="Work in Progress" value="" />
      </reference>
    </references>
  </back>
</rfc>
