The Agent Payment Protocol (AP2) ensures that AI agents cannot make unauthorized purchases by enforcing a cryptographic mandate chain that links user intent to cart construction to final payment execution.Problem: AI agents can hallucinate, make mistakes, or be compromised. Without guardrails, an agent might accidentally spend 10,000insteadof100.Solution: AP2 requires explicit user approval at each step and cryptographically verifies the complete chain before executing any payment.
Sardis validates the mandate chain before executing any payment:
Step 1: Intent Validation
def validate_intent(intent: Intent) -> bool: # 1. Verify user signature if not verify_signature(intent.signature, intent.user_id): raise InvalidSignatureError("Intent signature invalid") # 2. Check intent not expired if intent.approved_at < now() - timedelta(hours=24): raise ExpiredIntentError("Intent expired") # 3. Verify intent not already used if intent_cache.exists(intent.intent_id): raise ReplayAttackError("Intent already used") return True
Checks:
User signature is valid
Intent is not expired (24-hour window)
Intent has not been used before (replay protection)
Step 2: Cart Validation
def validate_cart(cart: Cart, intent: Intent) -> bool: # 1. Verify cart links to intent if cart.intent_id != intent.intent_id: raise IntentMismatchError("Cart does not match intent") # 2. Verify agent signature if not verify_signature(cart.agent_signature, intent.agent_id): raise InvalidSignatureError("Agent signature invalid") # 3. Verify total within intent budget if cart.total > intent.max_amount: raise BudgetExceededError( f"Cart total {cart.total} exceeds intent max {intent.max_amount}" ) # 4. Verify currency matches if cart.currency != intent.currency: raise CurrencyMismatchError("Cart currency does not match intent") return True
Checks:
Cart references the correct intent
Agent signature is valid
Cart total does not exceed intent budget
Currency matches
Step 3: Payment Validation
def validate_payment(payment: Payment, cart: Cart, intent: Intent) -> bool: # 1. Verify payment links to cart and intent if payment.cart_id != cart.cart_id: raise CartMismatchError("Payment does not match cart") if payment.intent_id != intent.intent_id: raise IntentMismatchError("Payment does not match intent") # 2. Verify amount matches cart total if payment.amount != cart.total: raise AmountMismatchError( f"Payment amount {payment.amount} != cart total {cart.total}" ) # 3. Verify mandate chain hash expected_hash = hash(intent, cart, payment) if payment.mandate_chain_hash != expected_hash: raise MandateChainError("Mandate chain hash invalid") # 4. Check spending policy if not policy_engine.check(payment): raise PolicyViolationError("Payment violates spending policy") return True