ai-agents-for-beginners

Nézze meg az óravideót: AI ügynökök védelme kriptográfiai bizonylatokkal

(Az óravideót és a bélyegképet a Microsoft tartalomcsapata adja hozzá az összefésülés után, az 14/15. lecke mintájának megfelelően.)

AI ügynökök védelme kriptográfiai bizonylatokkal

Bevezetés

Ez az óra a következő témákat fogja érinteni:

Tanulási célok

Az óra elvégzése után tudni fogja, hogyan:

A probléma: Az ügynöke audit nyomvonala

Képzelje el, hogy telepített egy AI ügynököt a Contoso Travel számára. Az ügynök olvassa az ügyfél kéréseit, meghív egy járatok API-t az opciók lekérdezéséhez, és lefoglal helyeket az ügyfél nevében. Az előző negyedévben az ügynök 50 000 foglalást dolgozott fel.

Ma megérkezik egy auditor. Egy egyszerű kérdést tesz fel: “Mutassa meg, mit csinált az ügynöke.”

Átadja a naplófájlokat. Az auditor megnézi azokat, majd egy nehezebb kérdést tesz fel: “Honnan tudom, hogy ezeket a naplókat nem szerkesztették?”

Ez az audit nyomvonali probléma. A mai ügynök telepítések többsége a következőkre támaszkodik:

Ezek egyike sem tud választ adni az auditor kérdésére anélkül, hogy az auditor valakiben megbízzon (Önben, a felhőszolgáltatóban vagy az adatbázis szállítójában). Belső használatra ez az elfogadható megbízhatóság gyakran elegendő. Szabályozott munkafolyamatokhoz (pénzügy, egészségügy, minden, amire az EU AI irányelv vonatkozik) nem az.

A kriptográfiai bizonylatok ezt úgy oldják meg, hogy minden egyes ügynöki művelet függetlenül ellenőrizhetővé válik. Az auditor nem Önben bízik meg, csak a nyilvános kulcsban és magában a bizonylatban.

Mi az a kriptográfiai bizonylat?

Egy bizonylat egy JSON objektum, amely rögzíti, mit tett az ügynök, digitális aláírással ellátva.

flowchart LR
    A[Az ügynök eszközt hív meg] --> B[Nyugta adattermék összeállítása]
    B --> C[JSON kanonizálás RFC 8785 szerint]
    C --> E[Ed25519 aláírás a kanonikus bájtokon]
    E --> F[Aláírt nyugta]
    F --> G[Az auditor offline módon ellenőrzi]
    G --> H{Az aláírás érvényes?}
    H -- yes --> I[Változtatás-ellenálló bizonyíték]
    H -- no --> J[Nyugta elutasítva]

Egy minimális bizonylat í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:

  1. Az aláírás. A bizonylatot 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. A mezők bármilyen manipulációja érvénytelenné teszi az aláírást.

  2. Kanonikus kódolás. Aláírás előtt a bizonylatot a JSON Canonicalization Scheme (JCS, RFC 8785) szerint szerializálják. Ez biztosítja, hogy két implementáció, amely ugyanazt az értelmi bizonylatot állítja elő, bájtazonos outputot generáljon. Kanonikalizáció nélkül különböző JSON szerializálók eltérő aláírásokat állítanának elő azonos tartalomhoz.

  3. Hash-láncolás. A previous_receipt_hash mező összekapcsolja minden bizonylatot az előzővel. Egy bizonylat eltávolítása vagy átrendezése megszakítja az utána következő minden bizonylatot. A manipuláció a láncnál is láthatóvá válik, még ha az egyedi aláírásokat meg is kerülik.

Ezek a tulajdonságok három garanciát nyújtanak:

Bizonylat készítése Pythonban

Nincs szükség külön könyvtárra a bizonylat készítéséhez. A kriptográfiai primitívek széles körben elérhetők, és a logika néhány tucat sor Python.

A gyakorlati gyakorlatok a code_samples/18-signed-receipts.ipynb fájlban lépésről lépésre végigvezetik a teljes folyamatot. A rövid összefoglaló:

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árolja kulcstárban)
signing_key = signing.SigningKey.generate()
verify_key = signing_key.verify_key

# A blokk nyugtázási tartalom összeállítása (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,
}

# A JCS bájtokat kanonizálja és aláírja közvetlenül. A PureEdDSA belsőleg hashel.
canonical_bytes = canonicalize(payload)
signature_bytes = signing_key.sign(canonical_bytes).signature

# Struktúrált aláírási objektum csatolása.
receipt = {
    **payload,
    "signature": {
        "alg": "EdDSA",
        "sig": b64url_nopad(signature_bytes),
        "public_key": b64url_nopad(bytes(verify_key)),
    },
}

Ez a teljes aláírási folyamat. A jegyzetfüzet lépésenként végigvezeti minden részét.

Bizonylat ellenőrzése és manipuláció észlelése

Az ellenőrzés az ellentétes 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 tartalmat (minden, az aláírást kivéve).
    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

Ez a függvény kap egy bizonylatot, és True-t ad vissza, ha az aláírás érvényes, ellenkező esetben False-t. Nincs hálózati hívás, nincs szolgáltatásfüggőség, nem szükséges megbízni harmadik félben.

A manipuláció észlelésének megtekintéséhez a jegyzetfüzet bemutatja:

  1. Érvényes bizonylat készítése és ellenőrzésének megerősítése.
  2. Egy bájt megváltoztatása a tool_args_hash mezőben.
  3. Az ellenőrzés újrafuttatása és az ellenőrzés sikertelenségének megfigyelése.

Ez a gyakorlati bemutató, hogy a bizonylatok manipulációt láthatóvá tesznek: bármilyen módosítás, akár kicsi is, megszakítja az aláírást.

Bizonylatok láncolása több lépéses ügynökök esetén

Egyetlen aláírt bizonylat egy műveletet véd. A bizonylatok láncolata egy szekvenciát véd.

flowchart LR
    R0[Nyugta 0<br/>kezdete] --> R1[Nyugta 1]
    R1 --> R2[Nyugta 2]
    R2 --> R3[Nyugta 3]
    R1 -. previous_receipt_hash .-> R0
    R2 -. previous_receipt_hash .-> R1
    R3 -. previous_receipt_hash .-> R2

Minden bizonylat rögzíti az előző bizonylat hash-ét. Egy támadó ahhoz, hogy a 2. bizonylatot csendben eltávolítsa, vagy:

Ha a privát kulcs hardveres kulcstárolóban van, és közzéteszi a nyilvános kulcsot minden bizonylattal, egyik támadás sem kivitelezhető észrevétel nélkül.

A jegyzetfüzet bemutatja:

  1. Három bizonylat láncolatának létrehozása.
  2. Annak ellenőrzése, hogy minden bizonylat previous_receipt_hash megegyezik az előző bizonylat valódi hash-ével.
  3. Egy bizonylat manipulálása a lánc közepén, és a lánc pontosan ott megszakad.

Így készíthet audit nyomvonalat, amelyet egy külső auditor ellenőrizhet anélkül, hogy Önben bíznia kellene.

Mit bizonyítanak a bizonylatok (és mit nem)

Ez a lecke legfontosabb része. A bizonylatok erőteljesek, de korlátok között.

A bizonylatok három dolgot bizonyítanak:

  1. Hozzárendelés: egy adott kulcs aláírt egy adott feldolgozandó tartalmat.
  2. Integritás: a tartalom nem változott az aláírás óta.
  3. Sorrendiség: ez a bizonylat a hash láncban az után keletkezett.

A bizonylatok NEM bizonyítanak:

  1. Helyesség: hogy az ügynök művelete helyes volt. Egy bizonylat ugyanúgy aláírható hibás válaszra is, mint helyesre.
  2. Szabályzati megfelelőség: hogy a policy_id-ban hivatkozott szabályzatot ténylegesen alkalmazták-e, vagy hogy engedélyezte volna-e ezt a műveletet, ha ellenőrizték volna. A bizonylat azt rögzíti, amit állítottak, nem azt, amit végrehajtottak.
  3. Személyazonosság a kulcson túl: a bizonylat csak annyit mond, “ez a kulcs írta alá ezt a tartalmat.” Nem mondja azt, hogy “ez az ember engedélyezte ezt.” Egy kulcs személyhez vagy szervezethez kötése külön identitás infrastruktúrát igényel (pl. címtár, nyilvános kulcs regiszter).
  4. A bemenetek valóságtartalma: ha az ügynök manipulált parancsot kap, és annak alapján cselekszik, a bizonylat hűen rögzíti a műveletet. A bizonylatok a bemeneti ellenőrzés után, nem helyettesei annak.

Ez a határvonal két okból fontos:

Gyakori tévedés azt hinni, hogy “van bizonylatunk” azt jelenti, hogy “megfelelünk.” Ez nem igaz. A bizonylatok alapot adnak. A szabályozás az a rendszer, amelyet erre építünk.

Bizonyítása, hogy egy ember jóváhagyta az adott műveletet

A fenti 3. pont megérdemel egy külön szakaszt: egy művelet bizonylat azt mondja, “ez a kulcs írta alá ezt a tartalmat,” sosem azt, hogy “egy ember engedélyezte ezt.” Magas kockázatú műveleteknél (visszatérítések, törlések, átutalások) a szabályozási keretrendszerek egyre inkább kifejezetten ezt a hiányzó igazolást követelik meg, amely előállítható ugyanazokkal az eszközökkel, amelyeket ebben a leckében már használt.

A folytató jegyzetfüzet, a code_samples/human-authorization-receipts.ipynb egy második típusú bizonylatot, a human.approval.v1-et ad hozzá, amely ugyanabban a boríték formában van, mint a lecke bizonylatai (tipizált csomag, amelyet Ed25519 ír alá kanonikus JCS bájtokon, az aláírás objektum a bájtokon kívül). Egy névvel ellátott jóváhagyó írja alá a teljes kanonikus műveletet és annak hash-ét a végrehajtás előtt; az ügynök műveleti bizonylata hordozza a ugyanazt a műveleti hash-t és egy parent_approval_ref-et, a jóváhagyás bizonylatának receipt_hash-ét, ugyanazzal a konvencióval, mint a láncban az előző bizonylat hash-e, previous_receipt_hash. Egy verify_chain mindkét artefaktumot ellenőrzi külön állított kulcsnyilvántartások alatt (jóváhagyó kulcsok vs ügynök kulcsok), így a kódút közös, de a hatóságok soha nem.

A tulajdonság, amelyet így kapunk, gondosan megfogalmazva: az ember jóváhagyta ezt az adott műveletet, és az ügynök pontosan ezt az engedélyezett műveletet hajtotta végre. A jegyzetfüzet elutasítási eset tesztjei teszik megalapozottá ezt a tulajdonságot:

Minden hiba elutasítással jár, egyedi okkal, így az auditor meg tudja különböztetni, hogy lejárt-e a hatóság, vagy változott-e a végrehajtott művelet. A jegyzetfüzet által tanított szabály: egy aláírt jóváhagyás nem hatóság önmagában. A hatóság csak akkor áll fenn, ha mindkét bizonylat ugyanahhoz a kanonikus művelethez kötött a végrehajtás idején. Az emberi jóváhagyás bizonylata oktatási kompozíció, amelyet ez az óra definiál, nem a draft-farley-acta-signed-receipts által definiált bizonylattípus.

Gyártási hivatkozások

Ennek az órának a Python kódja szándékosan minimális, hogy minden sort elolvashasson és pontosan értse, mi történik. Éles környezetben két lehetősége van:

  1. Közvetlenül a kriptográfiai primitívekre építkezik. A fent látott 50 sor sok esetben elegendő. A PyNaCl (Ed25519) és a jcs csomag (kanonikus JSON) jól karbantartott és auditált könyvtárak.

  2. Használ egy éles bizonylat könyvtárat. Több nyílt forráskódú projekt valósítja meg ugyanazt a mintát további funkciókkal (kulcscsere, tömeges ellenőrzés, JWK készlet terjesztés, integráció a szabályzat motorokkal):

    • Az aláírási folyamat az IETF független internetes tervezetének (Internet-Draft) JCS és aláírási hatókör konvencióit használja (draft-farley-acta-signed-receipts, 02. revízió). A lecke lapos oktató bizonylata különbözik a tervezet {payload, signature} borítékától és nem konform megvalósításként jelenik meg. A tervezet közzétesz egy megosztott konformancia csomagot (agent-governance-testvectors) a formátum célzott megvalósításaihoz.
    • A Microsoft Agent Governance Toolkit a bizonylatokat Cedar-alapú szabályzati döntésekkel összefűzi; az ehhez kapcsolódó 33. oktatóanyagban látható egy végponttól végpontig példa.
    • A protect-mcp (npm) és @veritasacta/verify (npm) csomagok Node-alapú megvalósítást kínálnak bizonylat aláíráshoz és offline ellenőrzéshez, céljuk MCP szerverek tamper-evidens audit nyomvonalának becsomagolása, beleértve egy tárgyalt co-sign (együtt aláírás) folyamatot is, ahol egy szüneteltetett művelet jóváhagyási bizonylatot bocsát ki, amely a műveleti hash-hez kötött (desktop folyamatban WebAuthn-támogatással), ugyanaz a jóváhagyási bizonylat minta, mint az emberi jóváhagyás jegyzetfüzetben.
    • A nobulex Python SDK (pip install nobulex) ugyanazt az Ed25519 + JCS aláírási mintát nyújtja Pythonban LangChain és CrewAI integrációkkal, publikált keresztezési tesztvektorokkal és megfelelés térképezéssel, amelyet a OWASP PR #2210 járult hozzá.

Az, hogy sajátot készít vagy könyvtárat használ, hasonló döntés, mint JWT könyvtár esetén: mindkettő ésszerű; a könyvtár időt spórol és csökkenti az audit felületet; a nulláról építkezés arra kényszerít, hogy minden primitívát megértsen. Ez az óra az alapoktól induló utat tanítja, hogy mindkét választás alapját ismerje.

Tudásellenőrzés

Tesztelje megértését, mielőtt a gyakorlati feladathoz lép.

1. Egy bizonylatot az ügynök Ed25519 privát kulcsával írnak alá. Az auditor csak a nyilvános kulccsal rendelkezik. Tudja az auditor offline ellenőrizni a bizonylatot?

Válasz Igen. Az Ed25519 ellenőrzéshez csak a nyilvános kulcs és az aláírt bájtok szükségesek. Nincs hálózati hívás, nincs szolgáltatásfüggőség. Ez az a tulajdonság, amely hasznossá teszi a bizonylatokat légmentesen leválasztott, több szervezetet átfogó vagy alacsony bizalmi audit környezetben.

2. Egy támadó módosítja a bizonylat policy_id mezőjét, azt állítva, hogy egy engedékenyebb szabályzat irányította. Az aláírás a eredeti adatokon alapult. Mi történik az ellenőrzés során?

Válasz Az ellenőrzés sikertelen. Az aláírás az eredeti adathordozó kanonikus bájtjain alapult; bármely mező módosítása megváltoztatja azokat a bájtokat, ami az aláírás érvénytelenségét eredményezi. A támadónak szüksége lenne a privát kulcsra, hogy új érvényes aláírást készítsen, amit azonban nem birtokol.

3. Miért tartalmaz a blokk tool_args_hash és result_hash mezőket a nyers argumentumok és eredmény helyett?

Válasz Két ok miatt. Először is, szükség lehet arra, hogy a blokkot archiválják vagy továbbítsák olyan környezetben, ahol a nyers tartalom (személyes adatok, üzleti adatok) kiszivárgása problémát okoz. A hash-elés kicsiben tartja a blokkot és védi a tartalmat; az auditornak elegendő ellenőriznie, hogy a hash megfelel egy külön tárolt másolatnak. Másodszor, a hashek fix méretűek; a hash-eket tartalmazó blokk mérete korlátos, függetlenül attól, hogy az inputok vagy outputok milyen nagyok voltak.

4. A previous_receipt_hash mező minden blokkot az elődjéhez köt. Ha egy támadó csendben töröl egy blokkot egy lánc közepéről, mi lesz érvénytelen?

Válasz Minden blokk, amely a törölt blokk után következik. Az ő `previous_receipt_hash` mezőik már nem illeszkednek a tényleges lánchoz (mert a hivatkozott blokk már nem létezik, vagy a lánc más elődöt mutat). A törlés elrejtéséhez a támadónak újra kellene írnia és aláírnia minden későbbi blokkot, amihez a privát kulcs szükséges.

5. Egy blokk tisztán ellenőrzött. Vajon ez bizonyítja, hogy az ügynök művelete helyes, megalapozott vagy megfelel a szabályzatnak?

Válasz Nem. Egy érvényes blokk három dolgot igazol: hozzárendelhetőséget (ez a kulcs írta alá ezt a tartalmat), sértetlenséget (a tartalom nem változott), és sorrendet (ez a blokk az adott blokk után érkezett). Nem bizonyítja, hogy a művelet helyes volt, hogy a `policy_id`-ban nevezett szabályzatot valóban kiértékelték, vagy hogy az ügynök betartotta az összes szabályt. A blokkok az ügynök viselkedését vizsgálhatóvá teszik, de nem feltétlenül helyessé. Ez a leckében a legfontosabb határvonal.

Gyakorlati feladat

Nyissa meg a code_samples/18-signed-receipts.ipynb fájlt és fejezze be a négy részt:

  1. 1. rész: Írja alá az első blokkot és ellenőrizze.
  2. 2. rész: Manipulálja a blokkot és figyelje meg az ellenőrzés kudarcát.
  3. 3. rész: Építsen egy három blokkos láncot és ellenőrizze a lánc épségét.
  4. 4. rész: Alkalmazza mintaként egy Microsoft Agent Framework-kel épített ügynöknél: csomagolja eszközhívást blokk-aláírásba, majd külön ellenőrizze a blokkot.

Haladó feladat 1: Bővítse a blokk sémáját egy saját választott mezővel (például nyomkövetési kérésazonosítóval), frissítse a kanonikus aláírási logikát, hogy ezt is tartalmazza, és győződjön meg róla, hogy a blokk továbbra is helyesen ellenőrződik. Ezután módosítsa a mezőt aláírás után, és győződjön meg róla, hogy az ellenőrzés megbukik. Ez arra készteti, hogy megértse, hogyan járul hozzá a kanonikus kódolás minden bájtja az aláíráshoz.

Haladó feladat 2: Készítsen SHA-256-at két blokkjára együttesen (kanonikus bájtjaikat determinisztikus sorrendben összefűzve), majd ágyazza be a keletkezett digest-et egy harmadik blokk új mezőjeként aláírás előtt. Ellenőrizze, hogy mindhárom blokk továbbra is helyesen ellenőrződik. Ezzel egy egylépéses befogadási bizonyítékot épített: aki a harmadik blokkot birtokolja, igazolhatja, 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, amelyet a kiválasztó közzétételi blokkok nagy léptékben használnak (Merkle-elköteleződések, RFC 6962).

Összefoglalás

A kriptográfiai blokkok olyan audit nyomot adnak az AI ügynököknek, amely:

Nem helyettesítik a bemeneti ellenőrzést, szabályzatvégrehajtást vagy identitásinfrastruktúrát. Ezek ezek alapját képezik. Amikor ügynököket telepít szabályozott környezetbe, több szervezetes munkafolyamatokba vagy bármilyen olyan helyzetbe, ahol a jövőbeni auditor nem feltételezhetően bízik önben, a blokkok teszik az audit nyomot őszintévé.

A legfontosabb tanulság: a blokkok bizonyítják, ki, mit, mikor mondott. Nem bizonyítják, hogy az elmondott igaz vagy helyes volt. Ezt a különbséget szorosan tartsa szem előtt. Ez a különbség egy becsületes eredettörténeti rendszer és egy megtévesztő között.

Éles üzem checklist

Amikor készen áll arra, hogy a leckéből továbblépve éles környezetben telepítsen blokk-aláírásos ügynököket:

Van még kérdése az AI ügynökök biztonságáról?

Csatlakozzon a Microsoft Foundry Discord közösséghez, találkozzon más tanulókkal, vegyen részt hivatalos fogadóórákon, és kapja meg AI ügynökök kérdéseire a válaszokat.

A lecke utáni fejlesztések

Ez a lecke egyetlen blokk aláírását és hash láncolt sorozatokat mutat be. Ugyanazok a primitívek számos fejlettebb mintává állnak össze, amelyekkel találkozhat, ahogy irányítási környezete fejlődik:

További források

Előző lecke

Helyi AI ügynökök létrehozása


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.