Skip to main content

aph_core/
lib.rs

1// Every public item in a protocol reference implementation is read by
2// implementers, so undocumented surface is a defect.
3#![warn(missing_docs)]
4
5//! APH (Agent per Human) protocol v0.1 core types.
6//!
7//! **Trust model, stated up front.** The human principal signs; the notary
8//! countersigns. An envelope is in one of two modes, and which one decides
9//! what a successful verification actually proves:
10//!
11//! - `PrincipalSigned` — `proof` is a two-element chain whose head was made
12//!   by the human's own key. Verifying it proves *this human authorized
13//!   this*.
14//! - `NotaryAttested` — a single notary proof, and what an ABSENT
15//!   `attestationMode` means. Verifying it proves only *a notary asserts
16//!   this human authorized this*, which is strictly weaker. The human's own
17//!   authorization, if present at all, lives in the `principalSignature` of
18//!   the Delegation Mandate embedded at `policy.delegation_mandate`.
19//!
20//! **Callers must never report the weaker claim as the stronger one.** Use
21//! [`verification::require_mode`] to refuse a downgrade rather than
22//! inspecting the shape by hand, and [`verification::verify_proof_structure`]
23//! to learn which mode an envelope is really in — the declared label is
24//! bound to the proof structure precisely so a notary key alone cannot
25//! forge the stronger claim (spec §7.1.11).
26//!
27//! Standalone implementation of the APH protocol: party roles, mandate
28//! types, notarization flow state machines, the W3C VC 2.0-shaped
29//! `NotarizationEnvelope` on-wire credential, the agent-credential-access
30//! envelope variant, the A2A extension descriptor, SD-JWT-VC profile
31//! pinning, and the JCS / detached-JWS / ECDSA signing helpers used to
32//! sign and verify envelopes.
33//!
34//! The normative protocol specification lives at `../../spec/aph-0.1.md`
35//! in this repository.
36//!
37//! Wire compatibility is this crate's primary invariant: every serde
38//! attribute on the wire types is load-bearing. Envelopes already signed
39//! by existing notaries MUST keep parsing and re-canonicalizing
40//! identically across releases.
41//!
42//! Registered optional extensions (spec §7.5): this implementation accepts
43//! and can emit `credentialSubject.appleAurAcceptance` (§7.5.1),
44//! `linkedMandate.ap2SignedPayloadB64` (§7.5.2), and
45//! `linkedMandate.vaultMutation` (§7.5.3). All are omitted when absent, so
46//! extension-free envelopes round-trip byte-identically. The
47//! `CredentialAccessNotarizationEnvelope` variant remains a spec v0.2
48//! candidate.
49//!
50//! Top-level `credentialStatus` (§6.3.3.1) is a CORE optional field rather
51//! than a registered extension, and it follows the same omit-when-absent
52//! rule for the same reason: an envelope with no status reference is
53//! byte-identical to one written before revocation had a transport, so every
54//! existing signature stays valid. [`credential_status`] holds the type, the
55//! derived-endpoint and same-origin rules, and the §6.3.3.4 trichotomy a
56//! recipient applies at §8.3 step 8a — all of it EXCEPT the status list's
57//! own §6.3.3.3 proof check, which needs a §8.4-resolved notary key this
58//! crate must not hold and is therefore the caller's step (that module's
59//! preamble and `check_envelope_status` state the obligation).
60
61pub mod a2a_extension;
62pub mod aph_config;
63pub mod communication_mandate;
64pub mod credential_access_envelope;
65pub mod credential_status;
66pub mod crypto;
67pub mod delegation_mandate;
68pub mod discovery;
69pub mod envelope;
70pub mod errors;
71pub mod human_not_present_flow;
72pub mod human_present_flow;
73pub mod roles;
74pub mod sd_jwt_profile;
75pub mod vault_mutation;
76pub mod verification;
77
78#[cfg(test)]
79mod prop_tests;
80
81// Re-exports — public surface.
82pub use a2a_extension::{APH_EXTENSION_URI, aph_a2a_extension};
83pub use aph_config::{
84  ALG_EDDSA, ALG_ES256, APH_CONTEXT_V1, APH_CREDENTIAL_TYPE, APH_DI_CRYPTOSUITE, APH_VERSION,
85  DEFAULT_MANDATE_TTL_SECONDS, MAX_BODY_PREVIEW_BYTES, MAX_PREVIEW_LINES, W3C_VC_CONTEXT_V2,
86};
87pub use communication_mandate::CommunicationMandate;
88pub use credential_status::{
89  CredentialStatusEntry, StatusCheck, StatusEntryType, StatusListCredential, StatusListSubject,
90  StatusPurpose, check_credential_status, check_envelope_status, decode_encoded_list,
91  parse_status_list_credential, revocation_bit, status_list_signing_base,
92};
93pub use delegation_mandate::DelegationMandate;
94pub use envelope::{
95  ActClassification, ActLabel, AgentRef, AttestationMode, ChannelDescriptor, ChannelKind,
96  CommunicationDescriptor, ContentClass, CredentialSubject, EnvelopeProof, EnvelopeProofs,
97  HumanPrincipalRef, LinkedMandate, NotarizationEnvelope, NotarizationMetadata, NotaryServiceRef,
98  Audience, AudienceChannelBinding, PolicyDecision, PolicyDescriptor, RecipientClass,
99  VocabularyRef,
100};
101pub use errors::AphError;
102pub use human_not_present_flow::{
103  HumanNotPresentNotarizationFlow, HumanNotPresentNotarizationState,
104};
105pub use human_present_flow::{HumanPresentNotarizationFlow, HumanPresentNotarizationState};
106pub use roles::{AphOperation, AphPartyRole};
107pub use sd_jwt_profile::{
108  APH_SD_JWT_TYP, SD_JWT_BASE_DRAFT_PIN, SD_JWT_VC_DRAFT_PIN, SdJwtVcProfile, current_profile,
109};
110pub use vault_mutation::{VaultMutationKind, VaultMutationMandate};
111
112// Crypto re-exports — JCS canonicalization, detached JWS, and ECDSA
113// mandate signing/verification.
114pub use crate::discovery::{DidUrl, KeyAlgorithm, NotaryPublicKey, https_origin, same_origin};
115pub use crate::crypto::did_key::{DecodedDidKey, decode as decode_did_key, encode_ed25519 as did_key_from_ed25519};
116pub use crate::crypto::eddsa_jcs::{
117  countersign_as_notary, sign_as_principal, sign_envelope, signing_input, verify_envelope,
118  verify_envelope_did_key, verify_proof,
119};
120pub use crate::crypto::jcs::canonicalize_rfc8785;
121pub use crate::crypto::jws_detached::{create_detached_jws, verify_detached_jws};
122pub use crate::crypto::signing::{sign_mandate, verify_mandate};
123pub use crate::crypto::proof_base::{ProofRole, mandate_signing_base, signing_base};
124pub use crate::verification::{
125  require_mode, verify_embedded_mandate_binding, verify_proof_structure,
126  verify_timestamp_order,
127};