<?xml version='1.0' encoding='utf-8'?>
<rfc version="3" ipr="trust200902" category="exp" docName="draft-saez-xcim-02" 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="20" />
    <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. This revision replaces 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>
    <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>
    </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.
In this minimum method is oidc-01 and policy_id identifies a policy admitted
by the verifier. 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>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 server-side session freezes sender binding, recipient, notice,
exact type definitions, provider/client, nonce, origin, 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 session and nonce 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>
      </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>
    <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>
    <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
OIDC provider/browser integration, 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>
    </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>
    </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>
