Pozrite si video lekcie: Zabezpečenie AI agentov pomocou kryptografických potvrdení
(Video lekcie a miniatúra budú pridané tímom Microsoftu po zlúčení, v súlade so vzorom lekcie 14 / 15.)
Táto lekcia pokrýva:
Po dokončení tejto lekcie budete vedieť:
Predstavte si, že ste nasadili AI agenta pre Contoso Travel. Agent číta požiadavky zákazníkov, volá API letov na vyhľadanie možností a rezervuje miesta v mene zákazníka. Za posledný štvrťrok spracoval agent 50 000 rezervácií.
Dnes prichádza audítor. Položí jednoduchú otázku: „Ukážte mi, čo váš agent urobil.“
Odovzdáte im svoje protokolové súbory. Audítor ich prezerá a pýta si náročnejšiu otázku: „Ako viem, že tieto protokoly neboli upravené?“
Toto je problém audítorskej stopy. Väčšina dnešných nasadení agentov spolieha na:
Žiadny z týchto zdrojov nedokáže odpovedať na otázku audítora bez toho, aby si musel audítor niekomu dôverovať (vám, vášmu cloud poskytovateľovi, vášmu dodávateľovi databázy). Pre interné použitie je táto dôvera často prijateľná. Pre regulované záťaže (financie, zdravotníctvo, čokoľvek podliehajúce zákonu o AI EÚ) nie je.
Kryptografické potvrdenia to riešia tým, že každú akciu agenta robia nezávisle overiteľnou. Audítor nemusí dôverovať vám. Potrebuje iba váš verejný kľúč a samotné potvrdenie.
Potvrdenie je JSON objekt, ktorý zaznamenáva, čo agent urobil, podpísaný digitálnym podpisom.
flowchart LR
A[Agent vyvolá nástroj] --> B[Vytvoriť dáta dokladu]
B --> C[Kanonalizovať JSON RFC 8785]
C --> D[SHA-256 hash]
D --> E[Podpísať Ed25519]
E --> F[Doklad s podpisom]
F --> G[Audítor overuje offline]
G --> H{Platný podpis?}
H -- áno --> I[Dôkaz odolný proti manipulácii]
H -- nie --> J[Doklad zamietnutý]
Minimálne potvrdenie vyzerá takto:
{
"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..."
}
}
Tri vlastnosti robia prácu:
Podpis. Potvrdenie je podpísané bránou agenta pomocou súkromného Ed25519 kľúča. Ktokoľvek s príslušným verejným kľúčom môže offline overiť podpis. Akákoľvek manipulácia s ľubovoľným poľom podpis zneplatní.
Kanonické kódovanie. Pred podpisom sa potvrdenie serializuje pomocou JSON Canonicalization Scheme (JCS, RFC 8785). Toto zaručuje, že dve implementácie produkujúce logicky rovnaké potvrdenie vytvoria identický bajtový výstup. Bez kanonizácie by rôzne JSON sérializátory vytvárali rozdielne podpisy na ten istý obsah.
Hashové reťazenie. Pole previous_receipt_hash spája každé potvrdenie s tým predchádzajúcim. Odstránenie alebo preusporiadanie potvrdenia poruší každý nasledujúci záznam. Manipulácia je viditeľná na úrovni reťazca aj v prípade prejdenia jednotlivých podpisov.
Tieto vlastnosti spolu poskytujú tri záruky:
Na vytvorenie potvrdenia nepotrebujete špeciálnu knižnicu. Kryptografické primitíva sú široko dostupné a logika zaberie len niekoľko desiatok riadkov Pythonu.
Praktické cvičenia v code_samples/18-signed-receipts.ipynb prejdú celý proces podrobne. Skrátená verzia:
import json
import hashlib
import base64
from nacl import signing
from jcs import canonicalize # RFC 8785 kanonický 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()}"
# Generovať alebo načítať podpisový kľúč (v produkcii uložiť v kľúčovej skrinke)
signing_key = signing.SigningKey.generate()
verify_key = signing_key.verify_key
# Vytvoriť obsah účtenky (zatiaľ bez podpisu)
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,
}
# Kanonizovať, hašovať, podpísať.
canonical_bytes = canonicalize(payload)
message_hash = hashlib.sha256(canonical_bytes).digest()
signature_bytes = signing_key.sign(message_hash).signature
# Pripojiť štruktúrovaný objekt podpisu.
receipt = {
**payload,
"signature": {
"alg": "EdDSA",
"sig": b64url_nopad(signature_bytes),
"public_key": b64url_nopad(bytes(verify_key)),
},
}
To je celý proces podpisovania. Cvičenia v notebooku prechádzajú každý krok.
Overenie je opačný proces:
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:
# Podpis je štruktúrovaný objekt: {"alg", "sig", "public_key"}.
sig_obj = receipt.get("signature")
if not sig_obj or sig_obj.get("alg") != "EdDSA":
return False
# Zrekonštruujte obsah, ktorý bol skutočne podpísaný (všetko okrem podpisu).
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
Táto funkcia prijíma potvrdenie a vráti True, ak je podpis platný, inak False. Žiadne sieťové volanie, žiadna závislosť na službe, žiadna dôvera v tretiu stranu nie je potrebná.
Na demonštráciu zisťovania manipulácie notebook prejde:
tool_args_hash.Toto praktické ukazuje, že potvrdenia sú zjavné na manipuláciu: akákoľvek úprava, akokoľvek malá, poruší podpis.
Jedno podpísané potvrdenie chráni jednu akciu. Reťaz potvrdení chráni sekvenciu akcií.
flowchart LR
R0[Príjemka 0<br/>genéza] --> R1[Príjemka 1]
R1 --> R2[Príjemka 2]
R2 --> R3[Príjemka 3]
R1 -. previous_receipt_hash .-> R0
R2 -. previous_receipt_hash .-> R1
R3 -. previous_receipt_hash .-> R2
Každé potvrdenie zaznamenáva hash predchádzajúceho potvrdenia. Ak chce útočník ticho odstrániť potvrdenie 2, musel by:
previous_receipt_hash v potvrdení 3 (čo zruší podpis potvrdenia 3), ALEBOAk je súkromný kľúč uložený v hardvérovej peňaženke a verejný kľúč publikujete s každým potvrdením, ani jeden útok nie je bez odhalenia možný.
Notebook prejde:
previous_receipt_hash každého potvrdenia zodpovedá skutočnému hashu predchádzajúceho.Takto vytvoríte audítorskú stopu, ktorú môže externý audítor overiť bez dôvery vo vás.
Toto je najdôležitejšia časť lekcie. Potvrdenia sú silné, ale ich moc je obmedzená.
Potvrdenia dokazujú tri veci:
Potvrdenia NEdokazujú:
policy_id bola naozaj vyhodnotená, alebo že by povolila danú akciu, ak by bola skontrolovaná. Potvrdenie zaznamenáva, čo sa tvrdilo, nie čo sa vynucovalo.Táto hranica je dôležitá z dvoch dôvodov:
Bežnou chybou je predpokladať, že „máme potvrdenia“ znamená „sme riadení.“ Nie je to tak. Potvrdenia sú základ. Riadenie je systém, ktorý na nich staviate.
Python kód v tejto lekcii je zameraný na minimalistickosť, aby ste mohli čítať každý riadok a presne chápať, čo sa deje. V produkcii máte dve možnosti:
Budovať priamo na kryptografických primitívoch. Tých 50 riadkov, ktoré ste videli, stačí pre mnohé použitia. PyNaCl (Ed25519) a balík jcs (kanonický JSON) sú dobre udržiavané a auditované knižnice.
Použiť produkčnú knižnicu na potvrdenia. Niekoľko open-source projektov implementuje rovnaký vzor s doplnkovými funkciami (rotácia kľúčov, hromadné overovanie, distribúcia JWK súboru, integrácia s motorom politík):
draft-farley-acta-signed-receipts), ktorý je momentálne v procese štandardizácie.protect-mcp (npm) a @veritasacta/verify (npm) poskytujú implementáciu podpisu a offline overenia potvrdení v Node, určenú na zabalenie akéhokoľvek MCP servera so zjavnou auditnou stopou.Rozhodnutie medzi vlastnou implementáciou a knižnicou je podobné ako medzi písaním vlastnej JWT knižnice a použitím testovanej: obe možnosti sú rozumné; knižnica ušetrí čas a zníži auditné riziko; cesta odznova vás núti pochopiť každý primitiv. Táto lekcia učí cestu od znova, aby ste mali základ pre oba prístupy.
Otestujte si porozumenie pred začatím praktického cvičenia.
1. Potvrdenie je podpísané súkromným Ed25519 kľúčom agenta. Audítor má iba verejný kľúč. Môže audítor potvrdenie overiť offline?
2. Útočník upraví pole policy_id potvrdenia, aby tvrdil, že bolo riadené voľnejšou politikou. Podpis bol vypočítaný nad pôvodnou záťažou. Čo sa stane počas overenia?
3. Prečo potvrdenie obsahuje hash argumentov nástroja (tool_args_hash) a výsledkov (result_hash) namiesto surových argumentov a výsledku?
4. Pole previous_receipt_hash spája každé potvrdenie s jeho predchodcom. Čo sa stane, ak útočník ticho vymaže jedno potvrdenie uprostred reťazca?
5. Potvrdenie sa overí ako platné. Dokazuje to, že akcia agenta bola správna, zmysluplná alebo v súlade s pravidlami?
Otvorte code_samples/18-signed-receipts.ipynb a dokončite všetky štyri sekcie:
Doplnková výzva 1: rozšírte schému potvrdenia o ďalšie vlastné pole (napríklad ID požiadavky na sledovanie), aktualizujte kanonickú logiku podpisovania tak, aby ho zahrňovala, a potvrďte, že potvrdenie stále prechádza spätným overením. Potom upravte pole po podpise a potvrďte, že overenie zlyhá. Toto vás núti pochopiť, ako každý bajt kanonického kódovania prispieva k podpisu. Výzva na precvičenie 2: Zahashujte SHA-256 spolu dva svoje potvrdenia (spojte ich kanonické bajty v deterministickom poradí) a vložte výsledný digest ako nové pole do tretieho potvrdenia pred jeho podpísaním. Overte, že všetky tri potvrdenia je možné stále obojsmerne zakódovať a dekódovať. Práve ste vytvorili jednoprvkový dôkaz o zaradení: ktokoľvek, kto vlastní tretie potvrdenie, môže dokázať, že prvé dve existovali v čase, keď bolo toto potvrdenie podpísané, bez nutnosti odhaľovať ich obsah. Toto je vzor, ktorý v rozsahu používajú potvrdenia s výberovým zverejnením (Merkle záväzky, RFC 6962).
Kryptografické potvrdenia dávajú AI agentom audítovateľnú stopu, ktorá je:
Nie sú náhradou za validáciu vstupov, dodržiavanie pravidiel alebo identitnú infraštruktúru. Sú základom pre tieto vrstvy. Keď nasadzujete agentov na regulované úlohy, v rámci viacerých organizácií alebo v prostredí, kde nemôžete predpokladať, že vám budúci audítor dôveruje, potvrdenia sú spôsob, ako zabezpečiť poctivú audítovateľnú stopu.
Najdôležitejšie poučenie: potvrdenia preukazujú, kto čo povedal a kedy. Neprekazujú, že to čo bolo povedané, je pravda alebo správne. Držte tento rozdiel pevne. Je to rozdiel medzi poctivým systémom pôvodu a zavádzajúcim.
Keď ste pripravení prejsť od tejto lekcie k nasadeniu agentov s podpisovanými potvrdeniami v reálnom prostredí:
https://your-org.example.com/.well-known/agent-keys.json.Pridajte sa na Microsoft Foundry Discord, kde sa stretnete s ďalšími študentmi, môžete navštíviť konzultačné hodiny a získať odpovede na otázky o AI agentoch.
Táto lekcia pokrýva podpisovanie jedného potvrdenia a hash reťazcové sekvencie. Rovnaké primitivá sa skladajú do niekoľkých pokročilejších vzorov, na ktoré môžete natrafiť, keď sa váš riadiaci prístup vyvíja:
authorization_*) a po výkonnú (result_*) s nezávislými podpismi, užitočné keď rozhodnutie o povolení a pozorovaný výsledok vytvárajú rôzni aktéri alebo v rôznom čase. Tento vzor je doplnkový k formátu potvrdení vyučovanému v tejto lekcii.result_hash. Reálne dáta sú často bohatšie než jeden výsledok nástroja: pred rozhodnutím dôvody (predpoveď modelu, zvážené možnosti, dôkazy a ich úplnosť, postoj k riziku, reťaz zodpovednosti, výsledok brány) môžu byť všetky v prehrávacej položke uzavreté jedným potvrdením. Umožňuje to udržať formát potvrdenia minimalistický, zatiaľ čo schémy obsahu sa vyvíjajú podľa oblastí.signature.alg môže niesť hodnotu ML-DSA-65 (štandard NIST pre postkvantový podpis) keď bude potrebné prejsť. Plánujte prechodné obdobie so súčasným dvojitým podpisovaním.Budovanie agentov pre používanie počítača (CUA)
(Bude určená koordinátormi kurikula)
Vyhlásenie o zodpovednosti: Tento dokument bol preložený pomocou AI prekladateľskej služby Co-op Translator. Hoci sa snažíme o presnosť, vezmite prosím na vedomie, že automatické preklady môžu obsahovať chyby alebo nepresnosti. Pôvodný dokument v jeho natívnom jazyku by mal byť považovaný za autoritatívny zdroj. Pre kritické informácie sa odporúča profesionálny ľudský preklad. Nie sme zodpovední za žiadne nedorozumenia alebo nesprávne interpretácie vyplývajúce z použitia tohto prekladu.