Watch the lesson video: Securing AI Agents with Cryptographic Receipts
(Lesson video and thumbnail to be added by the Microsoft content team post-merge, matching the lesson 14 / 15 pattern.)
Tatalakayin sa leksyong ito ang:
Pagkatapos ng leksyong ito, malalaman mo kung paano:
Isipin na nag-deploy ka ng AI agent para sa Contoso Travel. Binabasa ng agent ang mga kahilingan ng customer, tumatawag sa flights API para maghanap ng mga opsyon, at nagbubook ng mga upuan para sa customer. Noong nakaraang quarter, nakaproseso ang agent ng 50,000 bookings.
Ngayon, dumating ang auditor. Tinanong nila nang simple: “Ipakita mo sa akin ang ginawa ng iyong agent.”
Ibinigay mo ang mga log files. Tiningnan ito ng auditor at tinanong ang mas mahirap na tanong: “Paano ko malalaman na hindi binago ang mga log na ito?”
Ito ang problema ng audit trail. Karamihan sa mga deployment ngayon ay umaasa sa:
Walang isa man dito ang makakasagot ng tanong ng auditor nang hindi kailangan magtiwala sa isang tao (sino ka man, cloud provider mo, o vendor ng database mo). Para sa internal na gamit, madalas tanggap ang pagtitiwala na ito. Para sa mga regulated workloads (pananalapi, pangangalagang pangkalusugan, anumang sakop ng EU AI Act), hindi ito katanggap-tanggap.
Nilulutas ng cryptographic receipts ito sa pamamagitan ng paggawa ng bawat aksyon ng agent na maaaring i-verify nang independent. Hindi kailangang magtiwala ang auditor sa iyo. Kailangan lang nila ang iyong public key at ang receipt mismo.
Ang receipt ay isang JSON na bagay na nagrerekord ng ginawa ng agent, na nilagdaan gamit ang digital signature.
flowchart LR
A[Ang ahente ay nag-activate ng isang kasangkapan] --> B[Buuhin ang resibo na payload]
B --> C[Isalin ang JSON ayon sa RFC 8785]
C --> D[SHA-256 hash]
D --> E[Ed25519 lagdaan]
E --> F[Resibo na may lagda]
F --> G[Sinusuri ng auditor offline]
G --> H{Valid ba ang lagda?}
H -- oo --> I[Katibayan na hindi nabago]
H -- hindi --> J[Tinatanggihan ang resibo]
Ang isang minimal na receipt ay ganito:
{
"type": "agent.tool_call.v1",
"agent_id": "contoso-travel-bot",
"tool_name": "lookup_flights",
"tool_args_hash": "sha256:a3f9c1...",
"result_hash": "sha256:7b2e1d...",
"policy_id": "contoso-travel-policy-v3",
"timestamp": "2026-04-25T14:30:00Z",
"sequence": 47,
"previous_receipt_hash": "sha256:9d4e6a...",
"signature": {
"alg": "EdDSA",
"sig": "c5af83...",
"public_key": "8f3b2c..."
}
}
Tatlong katangian ang gumagana:
Ang lagda. Nilagdaan ang receipt ng gateway ng agent gamit ang Ed25519 private key. Sinumang may kaukulang public key ay maaaring i-verify ang lagda nang offline. Ang pagbabago ng kahit anong field ay magpapawalang-bisa sa lagda.
Canonical encoding. Bago paglagdaan, isinerializa ang receipt gamit ang JSON Canonicalization Scheme (JCS, RFC 8785). Tinitiyak nito na ang dalawang implementasyon na gumagawa ng parehong lohikal na receipt ay maglalabas ng eksaktong kaparehong bytes. Kung wala ito, iba’t ibang JSON serializers ang magbibigay ng ibang lagda para sa parehong nilalaman.
Hash chaining. Ang field na previous_receipt_hash ay nag-uugnay sa bawat receipt sa naunang receipt. Kapag tinanggal o inayos ang isang receipt, nasisira ang lahat ng kasunod na receipt. Nagiging visible ang panlilinlang sa antas ng chain kahit na malampasan ang indibidwal na mga lagda.
Sama-sama, ang mga katangiang ito ay nagbibigay ng tatlong garantiya:
Hindi mo kailangan ng espesyal na library para gumawa ng receipt. Malawak na available ang mga cryptographic primitive at ang lohika ay ilang dosenang linya lang ng Python.
Ang hands-on exercises sa code_samples/18-signed-receipts.ipynb ay naglalakad sa buong proseso. Ang buod:
import json
import hashlib
import base64
from nacl import signing
from jcs import canonicalize # RFC 8785 na canonical JSON
def b64url_nopad(data: bytes) -> str:
return base64.urlsafe_b64encode(data).decode("ascii").rstrip("=")
def sha256_canonical(obj) -> str:
"""SHA-256 of a Python object's JCS-canonical JSON form."""
return f"sha256:{hashlib.sha256(canonicalize(obj)).hexdigest()}"
# Gumawa o mag-load ng signing key (sa produksyon, itago sa key vault)
signing_key = signing.SigningKey.generate()
verify_key = signing_key.verify_key
# Buuhin ang receipt payload (walang lagda pa)
tool_args = {"origin": "SYD", "destination": "LAX"}
tool_result = [{"flight": "QF11", "price": 1850, "stops": 0}]
payload = {
"type": "agent.tool_call.v1",
"agent_id": "contoso-travel-bot",
"tool_name": "lookup_flights",
"tool_args_hash": sha256_canonical(tool_args),
"result_hash": sha256_canonical(tool_result),
"policy_id": "contoso-travel-policy-v3",
"timestamp": "2026-04-25T14:30:00Z",
"sequence": 0,
"previous_receipt_hash": None,
}
# Canonicalize, hash, lagdaan.
canonical_bytes = canonicalize(payload)
message_hash = hashlib.sha256(canonical_bytes).digest()
signature_bytes = signing_key.sign(message_hash).signature
# Idikit ang isang structured na signature object.
receipt = {
**payload,
"signature": {
"alg": "EdDSA",
"sig": b64url_nopad(signature_bytes),
"public_key": b64url_nopad(bytes(verify_key)),
},
}
Iyan ang buong signing pipeline. Tinuturuan ng exercises sa notebook ang bawat hakbang.
Ang pag-verify ay ang kabaligtarang operasyon:
import base64
import hashlib
from nacl import signing
from nacl.exceptions import BadSignatureError
from jcs import canonicalize
def b64url_decode(s: str) -> bytes:
padding = "=" * ((4 - len(s) % 4) % 4)
return base64.urlsafe_b64decode(s + padding)
def verify_receipt(receipt: dict) -> bool:
# Ang pirma ay isang istrukturadong bagay: {"alg", "sig", "public_key"}.
sig_obj = receipt.get("signature")
if not sig_obj or sig_obj.get("alg") != "EdDSA":
return False
# I-rekonstruksyon ang payload na talaga namang pinirmahan (lahat maliban sa pirma).
payload = {k: v for k, v in receipt.items() if k != "signature"}
canonical_bytes = canonicalize(payload)
message_hash = hashlib.sha256(canonical_bytes).digest()
try:
verify_key = signing.VerifyKey(b64url_decode(sig_obj["public_key"]))
verify_key.verify(message_hash, b64url_decode(sig_obj["sig"]))
return True
except BadSignatureError:
return False
Tumatanggap ang function na ito ng receipt at nagbabalik ng True kung valid ang lagda, False kung hindi. Walang network call, walang dependency sa serbisyo, at walang kailangang pagtitiwala sa sinumang third party.
Para makita ang pagtuklas ng panlilinlang sa aksyon, tinuturo ng notebook ang sumusunod:
tool_args_hash field.Ito ang praktikal na demonstasyon na ang mga receipt ay tamper-evident: anumang pagbabago, gaano man kaliit, ay sumisira sa lagda.
Isang signed receipt ang nagpoprotekta sa isang aksyon. Ang chain ng mga receipt ay nagpoprotekta sa sunod-sunod na mga aksyon.
flowchart LR
R0[Resibo 0<br/>pinagmulan] --> R1[Resibo 1]
R1 --> R2[Resibo 2]
R2 --> R3[Resibo 3]
R1 -. previous_receipt_hash .-> R0
R2 -. previous_receipt_hash .-> R1
R3 -. previous_receipt_hash .-> R2
Itinatala ng bawat receipt ang hash ng naunang receipt. Para tahimik na tanggalin ang receipt 2, kailangang gawin ng attacker ang alinman sa:
previous_receipt_hash field ng receipt 3 (magpapa-invalid sa lagda ng receipt 3), OKung ang private key ay nasa hardware key vault at inilalathala mo ang public key kasama ng bawat receipt, hindi praktikal ang alin mang pag-atake nang hindi natutuklasan.
Pinapakita ng notebook ang:
previous_receipt_hash ng bawat receipt ay tumutugma sa aktwal na hash ng naunang receipt.Ganito mo magagawa ang audit trail na maaaring i-verify ng external auditor nang hindi kailangan magtiwala sa iyo.
Ito ang pinakaimportanteng bahagi ng leksyong ito. Malakas ang kapangyarihan ng mga receipt pero may hangganan ito.
Pinapatunayan ng mga receipt ang tatlong bagay:
Hindi pinatutunayan ng mga receipt:
policy_id ay totoong na-evaluate, o na papayagan nito ang aksyon kung susuriin. Itinatala ng receipt ang inangkin, hindi ang ipinatupad.Mahalaga ang hangganan na ito dahil:
Karaniwang maling palagay ang akalaing kapag “may mga receipt tayo” ay ibig sabihin “nasa ilalim na tayo ng pamamahala.” Hindi. Ang mga receipt ay pundasyon. Ang pamamahala ay ang sistemang itinatayo pagkatapos nito.
Ang Python code sa leksyong ito ay sinadyang minimal upang mabasa mo ang bawat linya at maintindihan nang eksakto kung ano ang nangyayari. Sa produksyon, may dalawang opsyon ka:
Gumawa nang diretso mula sa cryptographic primitives. Ang 50 linya na nakita mo sa itaas ay sapat para sa maraming gamit. Ang PyNaCl (Ed25519) at ang jcs package (canonical JSON) ay mga mahusay at na-audit na libraries.
Gumamit ng production receipt library. May ilang open-source na proyekto na nag-iimplementa ng parehong pattern na may dagdag na features (key rotation, batch verification, JWK Set distribution, integration sa policy engines):
draft-farley-acta-signed-receipts) na kasalukuyang nasa proseso ng pag-standardize.protect-mcp (npm) at @veritasacta/verify (npm) packages ay may Node-based na implementasyon ng receipt signing at offline verification, na dinisenyo para balutin ang anumang MCP server na may tamper-evident audit trail.pip install nobulex) ay nagbibigay ng parehong Ed25519 + JCS signing pattern sa Python na may LangChain at CrewAI integration, kabilang ang inilathalang cross-validation test vectors at compliance mapping na ambag ng OWASP PR #2210.Ang pagpili sa pagitan ng paggawa ng sarili at paggamit ng library ay katulad ng pagpili sa pagitan ng pagsusulat ng sariling JWT library at paggamit ng isang nasubok na library: parehong makatwiran; nakakatipid ng oras at bumabawasan ang audit surface ang library; pinipilit kang maintindihan ang bawat primitive ang paraan na gawa mula sa simula. Itinuturo ng leksyong ito ang paggawa mula sa simula para may pundasyon ka kahit alin ang piliin.
Subukan ang iyong pag-unawa bago lumipat sa practice exercise.
1. Ang isang receipt ay nilagdaan gamit ang private Ed25519 key ng agent. Ang auditor ay may public key lamang. Maaari bang i-verify ng auditor ang receipt nang offline?
2. Binago ng attacker ang policy_id field sa isang receipt upang igiit na mas permissive ang polisiya. Ang lagda ay ginawa sa orihinal na payload. Ano ang nangyayari sa verification?
3. Bakit kasama sa receipt ang tool_args_hash at result_hash sa halip na ang raw arguments at resulta?
4. Ang previous_receipt_hash field ay nag-uugnay sa bawat receipt sa naunang receipt. Kung tahimik na tinanggal ng attacker ang isang receipt sa gitna ng chain, ano ang magiging invalid?
5. Ang isang receipt ay malinis na na-verify. Ipinapakita ba nito na tama, matibay, o sumusunod sa polisiya ang aksyon ng agent?
Buksan ang code_samples/18-signed-receipts.ipynb at kumpletuhin ang apat na seksyon:
Stretch challenge 2: i-SHA-256 hash ang dalawang receipts mo nang magkasama (pagdikitin ang kanilang canonical bytes sa isang deterministic na pagkakasunod) at ipaloob ang nagresultang digest bilang bagong field sa isang pangatlong receipt bago ito pirmahan. Patunayan na ang lahat ng tatlong receipts ay dumadaan pa rin sa round-trip. Nakagawa ka lang ng one-step inclusion proof: sinumang may hawak ng pangatlong receipt ay maaaring patunayan na ang unang dalawang receipts ay umiiral noong pinirmahan ito, nang hindi kinakailangang ibunyag ang kanilang mga nilalaman. Ito ang pattern na ginagamit ng selective-disclosure receipts sa malawakang sukat (Merkle commitments, RFC 6962).
Ang cryptographic receipts ay nagbibigay sa mga AI agent ng audit trail na:
Hindi ito pamalit sa input validation, pagpapatupad ng patakaran, o identity infrastructure. Ito ay pundasyon para sa mga layer na iyon. Kung magde-deploy ka ng mga agent sa regulated workloads, multi-organization workflows, o anumang sitwasyong hindi maaaring asahan na pagkakatiwalaan ng isang future auditor, ang receipts ang paraan upang gawing tapat ang audit trail.
Ang pinakamahalagang takeaway: pinatutunayan ng receipts kung sino ang nagsabi ng ano, kailan. Hindi nito pinatutunayan na ang sinabi ay totoo o tama. Mahigpit na hawakan ang pagkakaibang iyon. Ito ang pagkakaiba sa pagitan ng isang tapat na provenance system at isang mapanlinlang.
Kapag handa ka nang lumipat mula sa araling ito patungo sa pagde-deploy ng receipt-signed agents sa totoong kapaligiran:
https://your-org.example.com/.well-known/agent-keys.json.Sumali sa Microsoft Foundry Discord upang makipagkita sa iba pang mga nag-aaral, dumalo sa office hours, at masagot ang iyong mga tanong tungkol sa AI Agents.
Saklaw ng araling ito ang single-receipt signing at hash-chained sequences. Ang parehong mga primitives ay bumubuo ng ilang mas advanced na pattern na maaari mong matugunan habang lumalalim ang iyong governance posture:
authorization_*) at post-execution (result_*) na kalahati na may independent signatures, kapaki-pakinabang kapag ang decision ng authorization at ang naobserbahang resulta ay galing sa magkaibang actors o sa magkaibang oras. Ito ay idinadagdag sa ibabaw ng receipt format na itinuro sa araling ito.result_hash. Sa totoong mundo, madalas mas mayaman ang payload kaysa sa isang simpleng resulta ng tool call: pre-decision reasoning (model prediction, mga opsyon na kinonsidera, ebidensya at pagiging kumpleto nito, risk posture, accountability chain, resulta ng gate) ay maaaring nasa loob ng payload, na selyado ng isang receipt. Pinananatiling minimal ang format habang pinapayagan ang pag-evolve ng mga payload schema ayon sa domain.signature.alg na field ay maaaring magdala ng ML-DSA-65 (ang NIST post-quantum signature standard) kapag kailangan mong mag-migrate. Magplano para sa transition period kung saan naka-dual-sign ang mga receipt.Building Computer Use Agents (CUA)
(Itatakda ng mga tagapangasiwa ng kurikulum)
Pagtatanggi: Ang dokumentong ito ay isinalin gamit ang serbisyo ng AI translation na Co-op Translator. Bagama’t nagsusumikap kami para sa katumpakan, pakatandaan na ang awtomatikong pagsasalin ay maaaring maglaman ng mga pagkakamali o hindi pagkakatugma. Ang orihinal na dokumento sa orihinal nitong wika ang dapat ituring na pangunahing sanggunian. Para sa mahahalagang impormasyon, inirerekomenda ang propesyonal na pagsasalin ng tao. Hindi kami mananagot sa anumang maling pagkakaintindi o maling interpretasyon na nagmula sa paggamit ng pagsasaling ito.