Pozrite si video lekcie: Zabezpečenie AI agentov pomocou kryptografických potvrdení
(Video lekcie a náhľadový obrázok pridá tím Microsoft obsahu po zlúčení, podľa vzoru lekcie 14 / 15.)
Táto lekcia pokryje:
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, aby našiel možnosti, a rezervuje letenky v ich mene. Minulý štvrťrok agent spracoval 50 000 rezervácií.
Dnes prichádza audítor. Položí jednoduchú otázku: „Ukážte mi, čo váš agent urobil.“
Podáte mu vaše logy. Audítor sa pozrie a položí ťažšiu otázku: „Ako viem, že tieto logy neboli upravené?“
Toto je problém auditnej stopy. Väčšina dnešných nasadení agentov spolieha na:
Žiadny z nich však nedokáže odpovedať audítorovi bez nutnosti dôvery v niekoho (vás, vášho cloudového poskytovateľa, vášho dodávateľa databázy). Pre interné použitie je táto dôvera často akceptovateľná. Pre regulované pracovné zaťaženia (financie, zdravotníctvo, všetko podliehajúce zákonu EÚ o AI) nie.
Kryptografické potvrdenia toto riešia tým, že každú akciu agenta sprístupňujú na nezávislé overenie. Audítor nemusí dôverovať vám. Potrebuje len 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áva nástroj] --> B[Vytvoriť zaťažovací údaj príjmu]
B --> C[Kanonizovať JSON RFC 8785]
C --> E[Ed25519 podpísať kanonické bajty]
E --> F[Príjem s podpisom]
F --> G[Auditor overuje offline]
G --> H{Podpis platný?}
H -- yes --> I[Dôkaz nezmenenosti]
H -- no --> J[Príjem odmietnutý]
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 svoju prácu:
Podpis. Potvrdenie je podpísané bránou agenta pomocou súkromného kľúča Ed25519. Každý s príslušným verejným kľúčom môže podpis offline overiť. Zásah do akéhokoľvek poľa podpis zneplatní.
Kanonické kódovanie. Pred podpisom sa potvrdenie serializuje podľa JSON Canonicalization Scheme (JCS, RFC 8785). Tým sa zabezpečí, že dve implementácie, ktoré vytvoria rovnaké logické potvrdenie, vytvoria aj bitovo identický výstup. Bez kanonizácie by rôzne JSON serializéry produkovali odlišné podpisy rovnakého obsahu.
Hashové reťazenie. Pole previous_receipt_hash spája každé potvrdenie s predchádzajúcim. Odstránenie alebo zmena poradia potvrdí každý nasledujúci doklad. Zásah je viditeľný na úrovni reťazca, aj keď sú obídené jednotlivé podpisy.
Spoločne tieto vlastnosti poskytujú tri záruky:
Na vytvorenie potvrdenia nepotrebujete žiadnu špeciálnu knižnicu. Kryptografické primitíva sú široko dostupné a logika je pár desiatok riadkov Python kódu.
Praktické cvičenia v code_samples/18-signed-receipts.ipynb prejdú celý proces. Zhrnutie:
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()}"
# Vygenerujte alebo načítajte podpisovací kľúč (vo výrobe uložte v trezore kľúčov)
signing_key = signing.SigningKey.generate()
verify_key = signing_key.verify_key
# Vytvorte 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,
}
# Kanonizujte a priamo podpíšte bajty JCS. PureEdDSA interné hašovanie.
canonical_bytes = canonicalize(payload)
signature_bytes = signing_key.sign(canonical_bytes).signature
# Pripojte štruktúrovaný objekt podpisu.
receipt = {
**payload,
"signature": {
"alg": "EdDSA",
"sig": b64url_nopad(signature_bytes),
"public_key": b64url_nopad(bytes(verify_key)),
},
}
Toto je celý podpisovací pipeline. Cvičenia v notebooku prejdú každý krok.
Overenie je inverzná operácia:
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
# Rekonštruujte náklad, 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)
try:
verify_key = signing.VerifyKey(b64url_decode(sig_obj["public_key"]))
verify_key.verify(canonical_bytes, b64url_decode(sig_obj["sig"]))
return True
except BadSignatureError:
return False
Táto funkcia prijíma potvrdenie a vracia True, ak je podpis platný, inak False. Žiadne sieťové volanie, žiadna závislosť na službe, žiadna potreba dôvery v tretie strany.
Ak chcete vidieť detekciu zásahu v akcii, notebook prejde:
tool_args_hash.Toto je praktický dôkaz toho, že potvrdenia sú odolné voči neoprávneným zásahom: akákoľvek úprava, akokoľvek malá, zruší podpis.
Jedno podpísané potvrdenie chráni jednu akciu. Reťaz potvrdení chráni sekvenciu.
flowchart LR
R0[Príjem 0<br/>genéza] --> R1[Príjem 1]
R1 --> R2[Príjem 2]
R2 --> R3[Príjem 3]
R1 -. previous_receipt_hash .-> R0
R2 -. previous_receipt_hash .-> R1
R3 -. previous_receipt_hash .-> R2
Každé potvrdenie zapisuje hash predchádzajúceho potvrdenia. Na tiché odstránenie potvrdenia 2 by útočník musel buď:
previous_receipt_hash potvrdenia 3 (čo zruší podpis potvrdenia 3), ALEBOAk je súkromný kľúč uložený v hardvérovej bezpečnostnej skrinke a verejný kľúč publikujete s každým potvrdením, žiadny z týchto útokov nie je možný bez odhalenia.
Notebook prejde:
previous_receipt_hash každého potvrdenia zodpovedá skutočnému hashu predchádzajúceho dokladu.Takto vytvoríte auditnú stopu, ktorú môže vonkajší audítor overiť bez dôvery vo vás.
Toto je najdôležitejšia časť tejto lekcie. Potvrdenia sú silné, ale ich sila je obmedzená.
Potvrdenia dokazujú tri veci:
Potvrdenia nedokazujú:
policy_id bola skutočne vyhodnotená, alebo že by akciu povolila, ak by bola skontrolovaná. Potvrdenie zaznamenáva, čo sa tvrdilo, nie čo bolo vykonané.Táto hranica je dôležitá z dvoch dôvodov:
Bežnou chybou je predpoklad, že „máme potvrdenia“ znamená „sme riadení.“ Nie je to tak. Potvrdenia sú základ. Riadenie je systém, ktorý na tom staviate.
Bod 3 vyššie si zaslúži vlastnú časť: potvrdenie akcie hovorí „tento kľúč podpísal tento obsah,“ nikdy nie „človek to autorizoval.“ Pre vysoko rizikové akcie (refundácie, vymazania, prevody peňazí) rámce riadenia čoraz častejšie vyžadujú práve toto chýbajúce tvrdenie, a je ho možné vytvoriť s rovnakými primitívami, ktoré ste už v tejto lekcii použili.
Nasledujúci notebook code_samples/human-authorization-receipts.ipynb pridáva druhý typ potvrdenia, human.approval.v1, v rovnakom formáte ako potvrdenia z lekcie (typovaný payload podpísaný Ed25519 nad jeho kanonickými JCS bajtmi, s objektom signature mimo podpísaných bajtov). Menovaný schvaľovateľ podpisuje plnú kanonickú akciu a jej digest pred vykonaním; akcia agenta má ten istý digest akcie a parent_approval_ref, receipt_hash schválenia, rovnaká konvencia ako previous_receipt_hash v reťazci, ktorý ste postavili vyššie. Jediná funkcia verify_chain prejde obe artefakty pod samostatnými registrovými kľúčmi (kľúče schvaľovačov vs kľúče agentov), takže kódová cesta je spoločná, ale autority nie.
Tá vlastnosť, vyjadrená opatrne: človek autorizoval túto presnú akciu a agent vykonal práve tú autorizovanú akciu. Notebook obsahuje príklady odmietnutí, ktoré túto vlastnosť robia reálnou, nie iba tvrdenou:
Každé zlyhanie zamietne s odlišným dôvodom, takže audítor pri čítaní odmietnutia vie, či autorita vypršala alebo sa vykonaná akcia zmenila. Pravidlo vyučované v notebooku: podpísané schválenie samo o sebe nie je autorita. Autorita existuje iba vtedy, ak sa obe potvrdenia stále viažu na rovnakú kanonickú akciu v čase vykonania. Potvrdenie ľudského schválenia je vzdelávací nástroj definovaný touto lekciou, nie typ potvrdenia definovaný draft-farley-acta-signed-receipts.
Python kód v tejto lekcii je úmyselne minimalistický, aby ste mohli čítať každý riadok a presne pochopiť, čo sa deje. V produkcii máte dve možnosti:
Postaviť priamo na kryptografických primitívach. 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ť knižnicu na produkčné potvrdenia. Niekoľko open-source projektov implementuje ten istý vzor s ďalšími funkciami (rotácia kľúčov, dávkové overovanie, distribúcia JWK Set, integrácia s politickými nástrojmi):
draft-farley-acta-signed-receipts, revízia 02). Vzdelávacie plakové potvrdenie v tejto lekcii sa líši od draftu s obalom {payload, signature} a nie je prezentované ako konformná implementácia. Draft zverejňuje súbor pre spoločnú testovaciu sadu (agent-governance-testvectors) pre implementácie cieliace na jeho formát.protect-mcp (npm) a @veritasacta/verify (npm) poskytujú Node-based implementáciu podpisovania potvrdení a offline overovanie, určené na zabezpečenie ľubovoľného servera MCP auditnou stopou odolnou voči úpravám, vrátane toku s požiadavkou na spolupodpis, kde pozastavená akcia vystaví schvaľovacie potvrdenie viazané na digest akcie (podpora WebAuthn v desktop toku), rovnako ako schvaľovacie potvrdenie v notebooku ľudskej autorizácie vyššie.pip install nobulex) poskytuje rovnaký vzor podpisovania Ed25519 + JCS v Pythone s integráciami LangChain a CrewAI, vrátane zverejnených testovacích vektorov pre krížové overovanie a mapovania zhody prispievanej cez OWASP PR #2210.Rozhodnutie medzi vlastnou implementáciou a knižnicou je podobné rozhodnutiu medzi písaním vlastnej JWT knižnice alebo použitím testovanej: obe sú rozumné; knižnica šetrí čas a znižuje auditnú plochu; prístup od nuly vás núti rozumieť každému primitívu. Táto lekcia učí cestu od nuly, aby ste mali základ pre ktorúkoľvek voľbu.
Overte si porozumenie pred presunom na praktické cvičenie.
1. Potvrdenie je podpísané súkromným Ed25519 kľúčom agenta. Audítor má len verejný kľúč. Môže audítor potvrdenie overiť offline?
2. Útočník upraví pole policy_id potvrdenia, aby tvrdil, že akcia bola riadená prísnejšou politikou. Podpis bol nad pôvodným payloadom. Čo sa stane počas overovania?
3. Prečo príjem obsahuje tool_args_hash a result_hash namiesto surových argumentov a výsledku?
4. Pole previous_receipt_hash spája každý príjem s jeho predchodcom. Ak útočník ticho odstráni jeden príjem uprostred reťazca, čo sa stane neplatným?
5. Príjem prejde overením. Dokazuje to, že agentova akcia bola správna, platná alebo v súlade s politikou?
Otvorte code_samples/18-signed-receipts.ipynb a dokončite všetky štyri časti:
Pokročilá výzva 1: rozšírte schému príjmu o ďalšie pole podľa vlastného výberu (napríklad ID požiadavky na trasovanie), aktualizujte logiku kanonického podpisu tak, aby ho zahŕňala, a potvrďte, že príjem stále prechádza verifikáciou. Potom po podpise pole zmeňte a potvrďte, že overenie zlyhá. Toto vás prinúti pochopiť, ako každý bajt kanonického kódovania prispieva k podpisu.
Pokročilá výzva 2: SHA-256 hašujte dva vaše príjmy naraz (konkatenácia ich kanonických bajtov v deterministickom poradí) a vložte výsledný digest ako nové pole do tretieho príjmu pred jeho podpisom. Overte, že všetky tri príjmy stále prechádzajú verifikáciou. Práve ste vytvorili dôkaz o jedno-krokovom zahrnutí: ktokoľvek s tretím príjmom môže dokázať, že prvé dva existovali v čase jeho podpisu, bez potreby odhaľovať ich obsah. Toto je vzor, ktorý selektívne zverejňovacie príjmy používajú vo veľkom (Merkle záväzky, RFC 6962).
Kryptografické príjmy poskytujú AI agentom auditovateľnú stopu, ktorá je:
Nie sú náhradou za validáciu vstupov, vymáhanie politiky alebo infraštruktúru identity. Sú základom týchto vrstiev. Keď nasadzujete agentov do regulovaných pracovných záťaží, medziorganizáciových workflowov alebo do akéhokoľvek prostredia, kde sa nedá predpokladať, že vás budúci audítor bude dôverovať, príjmy sú spôsob, ako spraviť auditnú stopu čestnou.
Najdôležitejšie ponaučenie: príjmy dokazujú, kto čo povedal a kedy. Nedokazujú, že to, čo bolo povedané, je pravdivé alebo správne. Držte túto odlišnosť pevne. Je to rozdiel medzi čestným systémom pôvodu a zavádzajúcim.
Keď ste pripravení prejsť od tejto lekcie k nasadeniu agentov s podpísanými príjmami v reálnom prostredí:
https://your-org.example.com/.well-known/agent-keys.json.Pripojte sa k Microsoft Foundry Discord, kde sa stretnete s ďalšími študentmi, zúčastníte sa konzultačných hodín a získate odpovede na vaše otázky o AI agentech.
Táto lekcia pokrýva podpísanie jedného príjmu a reťazce hašovaných príjmov. Rovnaké primitíva tvoria viacero pokročilých vzorov, s ktorými sa môžete stretnúť, keď sa vaša správa zrelaxuje:
authorization_*) a po-vykonávací (result_*) diel s nezávislými podpismi, užitočné keď rozhodnutie o autorizácii a pozorovaný výsledok sú produkované rôznymi aktérmi alebo v rôznom čase. Toto sa skladá aditívne nad formát príjmu vyučovaný v tejto lekcii.result_hash. Reálne obsahy sú často bohatšie než výsledok jedného volania nástroja: predrozhodovacie uvažovanie (predpoveď modelu, zvažované možnosti, dôkazy a ich úplnosť, postoj k riziku, reťaz zodpovednosti, výsledok brány) môžu všetky žiť v obsahu, zapečatené jedným príjmom. Toto udržiava formát príjmu minimálny a zároveň umožňuje vývoj schém obsahu podľa domény.signature.alg môže niesť hodnotu ML-DSA-65 (štandard NIST pre post-kvantový podpis), keď budete potrebovať migráciu. Plánujte období prechodného obdobia, počas ktorého budú príjmy dvojmo podpísané.Vytváranie lokálnych AI agentov
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.