Ogled učnega videa: Zavarovanje AI agentov s kriptografskimi potrdili
(Učni video in sličica bosta dodana s strani Microsoftove ekipe za vsebino po združitvi, v skladu z vzorcem lekcij 14 / 15.)
Ta lekcija bo zajemala:
Po zaključku te lekcije boste znali:
Predstavljajte si, da ste uvedli AI agenta za Contoso Travel. Agent bere zahteve strank, kliče API za lete, da poišče možnosti, in rezervira sedeže v imenu strank. V preteklem četrtletju je agent obdelal 50.000 rezervacij.
Danes pride inšpektor. Postavi preprosto vprašanje: “Pokažite mi, kaj je vaš agent storil.”
Izročite mu datoteke z dnevniki. Inšpektor jih pregleda in zastavi težje vprašanje: “Kako vem, da ti dnevniki niso bili urejani?”
To je problem revizijske sledi. Večina današnjih uvedb agentov se zanaša na:
Nobeden od teh ne more odgovoriti na vprašanje inšpektorja brez, da bi moral inšpektor z nekom zaupati (vam, vašemu ponudniku oblaka, vašemu prodajalcu podatkovne baze). Za interno uporabo je to pogosto sprejemljivo. Za regulirane delovne obremenitve (finance, zdravstvo, karkoli po EU AI zakonu) ni.
Kriptografska potrdila to rešujejo tako, da vsakemu dejanju agenta omogočajo neodvisno preverljivost. Inšpektor vam ne rabi zaupati. Potrebuje samo vaš javni ključ in samo potrdilo.
Potrdilo je JSON objekt, ki beleži, kaj je agent storil, podpisan z digitalnim podpisom.
flowchart LR
A[Agent pokliče orodje] --> B[Zgradi uporabniški račun]
B --> C[Kanoniziraj JSON RFC 8785]
C --> E[Podpiši kanonične bajte Ed25519]
E --> F[Račun s podpisom]
F --> G[Revizor preveri brez povezave]
G --> H{Je podpis veljaven?}
H -- yes --> I[Dokaz o nepoškodovani spremembi]
H -- no --> J[Račun zavrnjen]
Minimalno potrdilo izgleda takole:
{
"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 lastnosti opravljajo delo:
Podpis. Potrdilo podpiše agentov prehod s pomoči zasebnega ključa Ed25519. Kdor koli ima ustrezen javni ključ, lahko podpis preveri brez povezave. Vsaka manipulacija katerega koli polja razveljavi podpis.
Kanonično kodiranje. Pred podpisovanjem se potrdilo seralizira z uporabo sheme JSON Canonicalization Scheme (JCS, RFC 8785). To zagotavlja, da dve implementaciji, ki ustvarita isto logično potrdilo, ustvarita bitno identičen izhod. Brez kanonizacije bi različni JSON seralizatorji ustvarili različne podpise za isto vsebino.
Veriženje z zgoščenkami. Polje previous_receipt_hash povezuje vsako potrdilo s prejšnjim. Odstranitev ali prerazporeditev potrdila prekine vsako potrdilo, ki sledi. Manipulacija postane vidna na nivoju verige, tudi če se posamezni podpisi spregledajo.
Te lastnosti skupaj zagotavljajo tri zagotovila:
Za ustvarjanje potrdila ne potrebujete posebne knjižnice. Kriptografski primitivni gradniki so široko dostopni, logika pa je le nekaj deset vrstic Pythona.
Praktične vaje v code_samples/18-signed-receipts.ipynb vas vodijo skozi celoten postopek. Povzetek:
import json
import hashlib
import base64
from nacl import signing
from jcs import canonicalize # RFC 8785 kanonični 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()}"
# Ustvari ali naloži podpisni ključ (v produkciji shrani v zakladnico ključev)
signing_key = signing.SigningKey.generate()
verify_key = signing_key.verify_key
# Zgradi vsebino potrdila (še brez podpisa)
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,
}
# Kanoniziraj in neposredno podpiši JCS bajte. PureEdDSA znotraj uporablja hash funkcije.
canonical_bytes = canonicalize(payload)
signature_bytes = signing_key.sign(canonical_bytes).signature
# Pripni strukturirano podpisno objekt.
receipt = {
**payload,
"signature": {
"alg": "EdDSA",
"sig": b64url_nopad(signature_bytes),
"public_key": b64url_nopad(bytes(verify_key)),
},
}
To je celoten podpisni potek. Vaje v zvezku pojasnjujejo vsak korak.
Preverjanje je obratna operacija:
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 strukturiran objekt: {"alg", "sig", "public_key"}.
sig_obj = receipt.get("signature")
if not sig_obj or sig_obj.get("alg") != "EdDSA":
return False
# Rekonstruiraj šeprto, ki je bila dejansko podpisana (vse razen podpisa).
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
Ta funkcija sprejme potrdilo in vrne True, če je podpis veljaven, sicer False. Brez klicev v omrežje, brez odvisnosti od storitev, brez zaupanja v tretjo osebo.
Za praktični vpogled v zaznavanje manipulacij zvezek prikazuje:
tool_args_hash.To je praktični dokaz, da so potrdila odporna na manipulacijo: vsaka sprememba, tudi najmanjša, prekine podpis.
Enotno podpisano potrdilo varuje eno dejanje. Veriga potrdil varuje niz dejanj.
flowchart LR
R0[Potrdilo 0<br/>geneza] --> R1[Potrdilo 1]
R1 --> R2[Potrdilo 2]
R2 --> R3[Potrdilo 3]
R1 -. previous_receipt_hash .-> R0
R2 -. previous_receipt_hash .-> R1
R3 -. previous_receipt_hash .-> R2
Vsako potrdilo beleži zgoščeno vrednost potrdila pred njim. Za tiho odstranitev potrdila 2 bi napadalec moral:
previous_receipt_hash potrdila 3 (kar prekine podpis potrdila 3), ALIČe je zasebni ključ shranjen v strojni ključavnici in javni ključ objavite z vsakim potrdilom, nobeden od napadov ni izvedljiv brez zaznave.
Zvezek prikazuje:
previous_receipt_hash vsakega potrdila ustreza dejanski zgoščeni vrednosti prejšnjega potrdila.Tako ustvarite revizijsko sled, ki jo lahko zunanji inšpektor preveri brez zaupanja v vas.
To je najpomembnejši del te lekcije. Potrdila so močna, a njihova moč je omejena.
Potrdila dokazujejo tri stvari:
Potrdila NE dokazujejo:
policy_id, dejansko ocenjena, ali da bi ta dejanja dovolila ob preverjanju. Potrdilo beleži, kaj je bilo trjeno, ne kaj je bilo izvršeno.Ta meja je pomembna iz dveh razlogov:
Pogosta napaka je meniti, da “imeti potrdila” pomeni “imeti upravljanje.” Ne pomeni. Potrdila so osnova. Upravljanje je sistem, ki ga zgradite na tej podlagi.
Tretja točka zgoraj je vredna lastnega razdelka: potrdilo o dejanju pravi “ta ključ je podpisal to vsebino,” nikoli pa “ta človek je to odobril.” Za visoko tveganje (vračila, izbrisi, bančna nakazila) pravila upravljanja vse bolj zahtevajo prav tisto izjavo, ki manka, in lahko se jo izdela z istimi gradniki, ki ste jih že sestavili v tej lekciji.
Nadaljnji zvezek code_samples/human-authorization-receipts.ipynb dodaja drugo vrsto potrdila, human.approval.v1, v isti obliki ovojnice kot potrdila v tej lekciji (tipiziran vsebnik, podpisan z Ed25519 preko kanoničnih JCS bajtov, z objektom signature zunaj podpisanih bajtov). Imenovani odobritel podpisuje celotno kanonično dejanje in njegov zgošček pred izvedbo; potrdilo dejanja agenta vsebuje isti zgošček dejanja in parent_approval_ref, tj. receipt_hash odobritve, isti konvencijski pristop kot previous_receipt_hash v verigi, ki ste jo zgradili zgoraj. Ena funkcija verify_chain preveri oba artefakta z ločeno fiksiranima registrov ključev (ključ avtorizatorja zoper ključe agenta), tako da je koda skupna, a oblasti nikoli niso.
Lastnost, ki jo to prinaša, je previdno izražena: človek je odobril točno to dejanje in agent je izvedel ravno to odobreno dejanje. Zvezkove zavrnitve so tisto, kar to lastnost naredi resnično, ne samo trditev:
Vsaka napaka se zavrne z različnim razlogom, tako lahko inšpektor ob branju zavrnitve ve, ali je pooblastilo zastaralo ali se je dejanje spremenilo. Pravilo, ki se ga zvezek nauči: podpisana odobritev sama po sebi ni pooblastilo. Pooblastilo obstaja le, če sta obe potrdili še vezani na isto kanonično dejanje ob času izvedbe. Potrdilo o odobritvi človeka je izobraževalna sestava, ki jo definira ta lekcija, ne pa vrsta potrdila, določena v draft-farley-acta-signed-receipts.
Python koda v tej lekciji je namenoma minimalna, da lahko preberete vsako vrstico in natančno razumete, kaj se dogaja. V produkciji imate dve možnosti:
Gradite neposredno na kriptografskih primitivih. 50 vrstic, ki ste jih videli zgoraj, je dovolj za številne primere uporabe. PyNaCl (Ed25519) in paket jcs (kanonični JSON) so dobro vzdrževani in pregledani knjižnici.
Uporabite produkcijsko knjižnico za potrdila. Več odprtokodnih projektov implementira isti vzorec z dodatnimi funkcijami (rotacija ključev, skupinska preverba, distribucija JWK seta, integracija s politiki):
draft-farley-acta-signed-receipts, revizija 02). Učna ploska potrdila se razlikujejo od ovojnice {payload, signature} osnutka in niso predstavljena kot skladna implementacija. Osnutek objavlja skupen komplet testov skladnosti (agent-governance-testvectors) za implementacije, ki ciljajo na njegov podatkovni format.protect-mcp (npm) in @veritasacta/verify (npm) zagotavljata izvedbo podpisovanja in preverjanja potrdil v Node.js-ju, namenjeno zaščiti kateregakoli MCP strežnika s sledljivim in odporenim na manipulacijo revizijskim sledom, vključno s tokom za so-podpisovanje, kjer premorjeno dejanje izdaja potrdilo o odobritvi, vezano na zgošček dejanja (podprto z WebAuthn v namiznem toku), enak vzorec potrdila o odobritvi kot v zgornjem zvezku za avtentikacijo človeka.pip install nobulex) ponuja isti vzorec podpisovanja Ed25519 + JCS v Pythonu z LangChain in CrewAI integracijami, vključno z objavljenimi testnimi vektorji za križno preverjanje in pripisom skladnosti prek OWASP PR #2210.Odločitev med lastno implementacijo in uporabo knjižnice je podobna odločitvi med pisanjem lastne knjižnice JWT ali uporabo preizkušene: obe sta razumni; knjižnica prihrani čas in zmanjša površino revizije; lastna pot pa vas prisili, da razumete vsak primitiv. Ta lekcija uči pot od začetka, da boste imeli osnovo za obe možnosti.
Preizkusite svoje razumevanje pred nadaljevanjem na praktično vajo.
1. Potrdilo je podpisano z agentovim zasebnim ključen Ed25519. Inšpektor ima samo javni ključ. Ali lahko inšpektor preveri potrdilo brez povezave?
2. Napadalec spremeni polje policy_id v potrdilu, da trdi, da je bilo potrdilo podvrženo bolj permisivni politiki. Podpis je bil na izvirnem vsebniku. Kaj se zgodi pri preverjanju?
3. Zakaj račun vključuje tool_args_hash in result_hash namesto surovih argumentov in rezultata?
4. Polje previous_receipt_hash povezuje vsak račun s predhodnikom. Če napadalec tiho izbriše en račun sredi verige, kaj postane neveljavno?
5. Račun se preveri brez napak. Ali to dokazuje, da je bilo dejanje agenta pravilno, pravilno izvedeno ali skladno s politiko?
Odprite code_samples/18-signed-receipts.ipynb in dokončajte vse štiri odseke:
Razširjeni izziv 1: razširite shemo računa z dodatnim poljem po lastni izbiri (na primer ID zahteve za sledenje), posodobite kanonično logiko podpisa, da ga vključi, in potrdite, da račun še vedno prehaja preverjanje. Nato po podpisu polje spremenite in potrdite, da preverjanje ne uspe. To vas prisili, da razumete, kako vsak bajt kanonične kodirane vsebine prispeva k podpisu.
Razširjeni izziv 2: Za SHA-256 združite dva svoja računa skupaj (združite njune kanonične bajte v determinističnem vrstnem redu) in dobljen digest vdelajte kot novo polje na tretjem računu pred podpisom. Preverite, da vsi trije računi še vedno uspešno prehajajo preverjanje. Pravkar ste zgradili dokaz o vključitvi v enem koraku: vsak, ki ima tretji račun, lahko dokaže, da sta prva dva obstajala ob času podpisa, ne da bi razkril vsebino. To je vzorec, ki ga uporabljajo računi z izbirno razkritjem v velikem obsegu (Merkle zaveze, RFC 6962).
Kriptografski računi dajejo AI agentom revizijsko sled, ki je:
Ne nadomeščajo preverjanja vhodnih podatkov, uveljavljanja politik ali identitetne infrastrukture. So temelj za te plasti. Ko uvajate agente v regulirane delovne obremenitve, v delovne procese več organizacij ali katerekoli okolje, kjer ni mogoče predpostaviti, da vam bo bodoči revizor zaupal, so računi način, kako narediti revizijsko sled pošteno.
Najpomembnejše sporočilo: računi dokazujejo, kdo je kaj rekel in kdaj. Ne dokazujejo, da je bilo povedano res ali pravilno. Ta razlikovanje držite trdno. To je razlika med poštenim sistemom izvora in zavajajočim.
Ko ste pripravljeni napredovati iz te lekcije k uvajanju agentov s podpisanimi računi v resničnem okolju:
https://your-org.example.com/.well-known/agent-keys.json.Pridružite se Microsoft Foundry Discord, da se povežete z drugimi učečimi, obiskujete uradne ure in dobite odgovore na vaša vprašanja o AI agentih.
Ta lekcija pokriva podpis posameznega računa in verižne sekvence z zgoščenkami. Enake primitive sestavljajo več naprednih vzorcev, s katerimi se lahko srečate, ko vaš upravljalski okvir dozori:
authorization_*) in po izvajanju (result_*) z neodvisnimi podpisi, uporabno, ko odločitev o pooblastilu in opažen rezultat izvajata različni entiteti ali ob različnih časih. To dodano sestoji na formatu računa, predstavljenem v tej lekciji.result_hash. Dejanske vsebine so pogosto bogatejše od enega rezultata klica orodja: lahko vključujejo predhodna razmišljanja (napoved modela, upoštevane možnosti, dokazi in njihova popolnost, tveganja, veriga odgovornosti, izid prehoda), vse zaprto z enim računom. Tako je format računa minimalen, a lahko sheme vsebine rastejo po domenah.signature.alg lahko nosi ML-DSA-65 (NIST standard po kvantni dobi), ko potrebujete migracijo. Načrtujte prehodno obdobje, ko so računi podpisani z obema algoritmoma.Ustvarjanje lokalnih AI agentov
Omejitev odgovornosti: Ta dokument je bil preveden z uporabo AI prevajalske storitve Co-op Translator. Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da avtomatizirani prevodi lahko vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za kritične informacije je priporočljiv strokovni človeški prevod. Ne odgovarjamo za morebitna nesporazume ali napačne interpretacije, ki izhajajo iz uporabe tega prevoda.