Nézd meg az oktatóvideót: AI ügynökök biztonságossá tétele kriptográfiai visszaigazolásokkal
(Az oktatóvideót és a bélyegképet a Microsoft tartalomcsapata fogja hozzáadni az összefésülés után, az 14/15-ös leckemintához igazodva.)
Ez a lecke a következőket tárgyalja:
A lecke végére tudni fogod, hogyan:
Képzeld el, hogy telepítettél egy AI ügynököt a Contoso Travel számára. Az ügynök olvassa az ügyfélkéréseket, lekérdezi a járatok API-ját, és lefoglal helyeket az ügyfél nevében. Az elmúlt negyedévben az ügynök 50 000 foglalást kezelt.
Ma megjelenik egy auditor. Egy egyszerű kérdést tesz fel: „Mutasd meg, mit csinált az ügynököd.”
Átadod a naplófájlokat. Az auditor megnézi őket, majd egy nehezebb kérdést tesz fel: „Honnan tudom, hogy ezeket a naplókat nem szerkesztették át?”
Ez az auditnaplózás problémája. A mai legtöbb ügynök telepítés a következőkre támaszkodik:
Ezek egyike sem válaszolja meg az auditor kérdését úgy, hogy az auditor ne kelljen senkiben (benne, a felhőszolgáltatójában vagy adatbázis beszállítójában) bízzon. Belső használatra ez gyakran elfogadható bizalom. Szabályozott munkaterhek esetén (pénzügy, egészségügy, az EU AI törvény hatálya alatt) nem.
A kriptográfiai visszaigazolások ezt úgy oldják meg, hogy az egyes ügynöki műveletek függetlenül ellenőrizhetők. Az auditor nem kell, hogy benned bízzon. Csak az nyilvános kulcsod kell, és maga a visszaigazolás.
A visszaigazolás egy JSON objektum, amely rögzíti, mit csinált az ügynök, digitális aláírással ellátva.
flowchart LR
A[Az ügynök eszközt hív meg] --> B[Készítse el a nyugta adatcsomagot]
B --> C[JSON RFC 8785 kanonizálása]
C --> D[SHA-256 kivonat]
D --> E[Ed25519 aláírás]
E --> F[Aláírással ellátott nyugta]
F --> G[Auditor offline ellenőrzi]
G --> H{Érvényes az aláírás?}
H -- igen --> I[Manipulációbiztos bizonyíték]
H -- nem --> J[Nyugta elutasítva]
Egy minimális visszaigazolás így néz ki:
{
"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..."
}
}
Három tulajdonság végzi a munkát:
Az aláírás. A visszaigazolást az ügynök átjárója írja alá Ed25519 privát kulccsal. Bárki, aki rendelkezik a megfelelő nyilvános kulccsal, offline ellenőrizheti az aláírást. Bármely mező manipulálása érvénytelenné teszi az aláírást.
Kanonikus kódolás. Az aláírás előtt a visszaigazolás a JSON Kanonizációs Sémával (JCS, RFC 8785) kerül sorosításra. Ez biztosítja, hogy két azonos logikai visszaigazolást előállító implementáció bájtpontosan azonos kimenetet adjon. Kanonizáció nélkül különböző JSON szerializálók különböző aláírásokat hoznának létre ugyanarra a tartalomra.
Hash láncolás. A previous_receipt_hash mező minden visszaigazolást összekapcsol az az előtti visszaigazolással. Egy visszaigazolás eltávolítása vagy átrendezése megszakítja minden későbbi visszaigazolás láncolatát. A manipuláció így még akkor is láthatóvá válik a lánc szintjén, ha az egyéni aláírásokat megpróbálják megkerülni.
Ezek a tulajdonságok együtt három garanciát nyújtanak:
Nem szükséges külön könyvtár a visszaigazolás készítéséhez. A kriptográfiai primitívek széles körben elérhetőek, a logika pedig néhány tucatsor Python kód.
A gyakorlati feladatok az code_samples/18-signed-receipts.ipynb fájlban végigvezetnek a teljes folyamaton. Az összefoglaló verzió:
import json
import hashlib
import base64
from nacl import signing
from jcs import canonicalize # RFC 8785 kanonikus 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()}"
# Aláíró kulcs generálása vagy betöltése (éles környezetben tárold kulcstárolóban)
signing_key = signing.SigningKey.generate()
verify_key = signing_key.verify_key
# Az átvételi bizonylat törzsét összeállítani (még nincs aláírás)
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,
}
# Kanonizálás, hash készítése, aláírás.
canonical_bytes = canonicalize(payload)
message_hash = hashlib.sha256(canonical_bytes).digest()
signature_bytes = signing_key.sign(message_hash).signature
# Csatolj egy strukturált aláírási objektumot.
receipt = {
**payload,
"signature": {
"alg": "EdDSA",
"sig": b64url_nopad(signature_bytes),
"public_key": b64url_nopad(bytes(verify_key)),
},
}
Ez az egész aláírási folyamat. A füzet feladatai lépésről lépésre vezetnek végig rajta.
Az ellenőrzés a fordított művelet:
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:
# Az aláírás egy strukturált objektum: {"alg", "sig", "public_key"}.
sig_obj = receipt.get("signature")
if not sig_obj or sig_obj.get("alg") != "EdDSA":
return False
# Állítsuk vissza a ténylegesen aláírt adatsort (mindent az aláírás kivételével).
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
Ez a függvény vesz egy visszaigazolást és visszaadja a True értéket, ha az aláírás érvényes, egyébként False-t. Nincs hálózati hívás, nincs szolgáltatáshoz kötés, és nem kell megbízni harmadik félben.
A manipuláció felismerésének gyakorlati bemutatásához a füzet végigmegy a következő lépéseken:
tool_args_hash mezőben.Ez a gyakorlati bizonyíték, hogy a visszaigazolások manipulációállóak: bármilyen kismértékű módosítás megszakítja az aláírást.
Egyetlen aláírt visszaigazolás egy műveletet véd. Egy visszaigazoláslánc egy sorozatot.
flowchart LR
R0[Bizonylat 0<br/>első] --> R1[Bizonylat 1]
R1 --> R2[Bizonylat 2]
R2 --> R3[Bizonylat 3]
R1 -. previous_receipt_hash .-> R0
R2 -. previous_receipt_hash .-> R1
R3 -. previous_receipt_hash .-> R2
Minden visszaigazolás rögzíti az előző visszaigazolás hash-ét. Ha egy támadó csendben törli a 2-es visszaigazolást, akkor vagy:
previous_receipt_hash mezőjét (ezzel megsérti a 3-as visszaigazolás aláírását), VAGYHa a privát kulcs hardware kulcstárban van, és a nyilvános kulcsot minden visszaigazoláshoz társítod, egyik támadás sem kivitelezhető a felismerés nélkül.
A füzet végigvezeti a következőket:
previous_receipt_hash mezője megegyezik az előző visszaigazolás valós hash-ével.Így készíthetsz auditnaplót, amit egy külső auditor a te megbízásod nélkül ellenőrizhet.
Ez a legfontosabb rész a leckében. A visszaigazolások erősek, de korlátok között.
A visszaigazolások három dolgot bizonyítanak:
A visszaigazolások NEM bizonyítanak:
policy_id-ban hivatkozott szabályzat ténylegesen ki lett értékelve, vagy hogy engedélyezte volna-e ezt a műveletet. A visszaigazolás azt rögzíti, amit állítottak, nem azt, amit betartattak.Ez a határvonal két okból fontos:
Gyakori tévedés azt hinni, hogy „visszaigazolásaink vannak” = „irányítás alatt állunk.” NEM. A visszaigazolás alap. Az irányítás az a rendszer, amit erre építesz.
A lecke Python kódja szándékosan minimális, hogy minden sort elolvashass és pontosan megérts mit csinál. Termelésben két lehetőséged van:
Közvetlenül építeni a kriptográfiai primitívekre. Az fent látott 50 sor sok esetben elegendő. A PyNaCl (Ed25519) és a jcs csomag (kanonikus JSON) jól karbantartott, auditált könyvtárak.
Használni egy termelési visszaigazolás-könyvtárat. Több nyílt forráskódú projekt valósítja meg ugyanezt a mintát további funkciókkal (kulcscsere, tömeges ellenőrzés, JWK készlet terjesztés, integráció szabályzatrendszerekkel):
draft-farley-acta-signed-receipts), amely szabványosítás alatt áll.protect-mcp (npm) és az @veritasacta/verify (npm) csomagok Node-alapú implementációt kínálnak visszaigazolások aláírására és offline ellenőrzésére, céljuk bármely MCP szerver köré tamper-evident auditnapló létrehozása.Annak eldöntése, hogy saját megoldást fejlesztesz vagy könyvtárat használsz, hasonló a saját JWT könyvtár írásának vagy egy kipróbált használatának dilemmajához: mindkét megközelítés értelmes; a könyvtár időt spórol és csökkenti az auditfelületet; a saját megoldás megérteti veled minden primitív lépését. Ez a lecke a saját megoldás útját tanítja, hogy meglegyen az alapod mindkét választáshoz.
Teszteld a tudásod, mielőtt a gyakorlati feladatra lépnél.
1. Egy visszaigazolást az ügynök privát Ed25519 kulcsával írnak alá. Az auditor csak a nyilvános kulccsal rendelkezik. Tudja offline ellenőrizni a visszaigazolást?
2. Egy támadó módosítja a visszaigazolás policy_id mezőjét, hogy engedékenyebb szabályzatot állítson be. Az aláírás az eredeti teherre vonatkozott. Mi történik az ellenőrzés során?
3. Miért tartalmaz a visszaigazolás tool_args_hash és result_hash értéket a nyers argumentumok és eredmény helyett?
4. A visszaigazolások minden egyes lánchoz kapcsolódó previous_receipt_hash mezővel rendelkeznek. Ha egy támadó csendben kitöröl egy visszaigazolást a lánc közepéről, mi lesz érvénytelen?
5. A visszaigazolás tisztán ellenőrzött. Ez bizonyítja-e, hogy az ügynök művelete helyes, megalapozott vagy megfelel a szabályzatnak?
Nyisd meg az code_samples/18-signed-receipts.ipynb fájlt, és végezd el a négy részt:
Extra kihívás 1: egészítsd ki a visszaigazolás sémát egy saját mezővel (például kérésazonosító traceroláshoz), frissítsd a kanonikus aláírási logikát, hogy tartalmazza, és bizonyítsd be, hogy a visszaigazolás még mindig helyesen ellenőrizhető. Ezután módosítsd a mezőt az aláírás után, és erősítsd meg, hogy az ellenőrzés megbukik. Ez kötelezővé teszi számodra, hogy megértsd, miként járul hozzá minden bájt a kanonikus kódolás aláíráshoz. Akadálytúllépő kihívás 2: Használj SHA-256 kivonatot két blokknyugta összefűzéséhez (determinista sorrendben illeszd össze a kanonikus bájtjaikat), majd a kapott kivonatot ágyazd be egy harmadik blokknyugta új mezőjeként az aláírás előtt. Ellenőrizd, hogy mindhárom blokknyugta továbbra is visszaellenőrizhető marad-e. Ezzel épp egy egylépéses beillesztési bizonyítékot hoztál létre: bárki, aki a harmadik blokknyugtával rendelkezik, bizonyíthatja, hogy az első kettő létezett az aláírás időpontjában anélkül, hogy azok tartalmát felfedné. Ez az a minta, amit a válogatott közzétételű blokknyugták széleskörűen használnak (Merkle elkötelezettségek, RFC 6962).
A kriptográfiai blokknyugták auditálási nyomvonalat biztosítanak az AI ügynökök számára, mely:
Nem helyettesítik a bevitel-ellenőrzést, a szabályzat végrehajtását vagy az azonosító infrastruktúrát, hanem ezek alapját képezik. Amikor szabályozott munkafolyamatokban, több szervezet közös munkamenetében vagy olyan környezetben helyezel ügynököket üzembe, ahol egy jövőbeli auditorban nem feltételezhető a bizalom irántad, a blokknyugták biztosítják, hogy az auditálási nyomvonal tisztességes legyen.
A legfontosabb tanulság: a blokknyugták igazolják, hogy ki mit és mikor mondott. Nem bizonyítják, hogy amit mondtak, az igaz vagy helyes volt. Ezt a különbséget szorosan tartsd meg. Ez a különbség egy becsületes eredetiség-rendszer és egy félrevezető között.
Amikor készen állsz arra, hogy a leckéről átállj valódi környezetben üzemelő aláírt blokknyugtás ügynökökre:
https://your-org.example.com/.well-known/agent-keys.json.Csatlakozz a Microsoft Foundry Discord közösséghez, hogy más tanulókkal találkozz, részt vegyél kérdezz-felelek alkalmakon és megválaszold AI ügynökökkel kapcsolatos kérdéseidet.
Ez a lecke a single-receipt aláírást és a hash-láncolt sorozatokat fedi le. Ugyanezek a primitívek több haladó mintába rendeződnek, amelyekkel találkozhatsz, ahogy irányítási gyakorlatod fejlődik:
authorization_*) és utóvégrehajtásra (result_*) osztják, külön aláírásokkal, hasznos, amikor az engedélyezési döntést és a megfigyelt eredményt különböző szereplők vagy külön időpontok állítják elő. Ez az elrendezés ráépül a jelen leckében tanult blokknyugta formátumra.result_hash mezőbe helyezett bájtokat. A valós világban a tartalom gyakran bőségesebb, mint egyetlen eszközhívás eredménye: előzetes döntési érvelés (modell-előrejelzés, megfontolt opciók, bizonyíték és annak teljessége, kockázati helyzet, felelősségi lánc, kapu eredmény) mind beleférhet a tartalomba, amit egy blokknyugta zár le. Ez minimalizálja a blokknyugta formátumát, miközben engedi, hogy a tartalmi sémák területenként fejlődjenek.signature.alg mező hordozhatja az ML-DSA-65 (a NIST poszt-kvantum aláírási szabványa) értéket, amikor migrálni kell. Tervezd meg az átmeneti időszakot, amikor a blokknyugtákat kettős aláírással látod el.Számítógép-használati ügynökök (CUA) építése
(A tananyag-felelősek szerint meghatározandó)
Jogi nyilatkozat: Ez a dokumentum az AI fordítási szolgáltatás, a Co-op Translator segítségével készült. Bár az pontosságra törekszünk, kérjük, vegye figyelembe, hogy az automatikus fordítások hibákat vagy pontatlanságokat tartalmazhatnak. Az eredeti dokumentum az anyanyelvén tekintendő hiteles forrásnak. Fontos információk esetén professzionális emberi fordítást javasolunk. Nem vállalunk felelősséget semmilyen félreértésért vagy téves értelmezésért, amely ebből a fordításból ered.