ai-agents-for-beginners

Sledujte video lekce: Zabezpečení AI agentů pomocí kryptografických potvrzení

(Video lekce a náhledový obrázek budou přidány týmem Microsoft po sloučení, odpovídající vzoru lekcí 14 / 15.)

Zabezpečení AI agentů pomocí kryptografických potvrzení

Úvod

Tato lekce pokryje:

Cíle učení

Po dokončení této lekce budete umět:

Problém: Auditní stopa vašeho agenta

Představte si, že jste nasadili AI agenta pro Contoso Travel. Agent čte požadavky zákazníků, volá API letů k vyhledání možností a rezervuje místa jménem zákazníka. Za poslední čtvrtletí agent zpracoval 50 000 rezervací.

Dnes přichází auditor. Položí jednoduchou otázku: „Ukažte mi, co váš agent udělal.“

Předáte mu své log soubory. Auditor je prohlédne a položí složitější otázku: „Jak vím, že tyto záznamy nebyly upraveny?“

To je problém auditní stopy. Většina dnešních nasazení agentů spoléhá na:

Žádný z těchto přístupů nemůže odpovědět auditorovi bez požadavku důvěry v někoho (vás, vašeho cloudového poskytovatele, dodavatele databáze). Pro interní použití je tato důvěra často přijatelná. Pro regulované oblasti (finance, zdravotnictví, cokoli podléhající EU AI Act) není.

Kryptografická potvrzení tento problém řeší tím, že každou akci agenta dělají nezávisle ověřitelnou. Auditor nemusí důvěřovat vám. Potřebuje pouze váš veřejný klíč a samotné potvrzení.

Co je kryptografické potvrzení?

Potvrzení je JSON objekt, který zaznamenává, co agent udělal, podepsaný digitálním podpisem.

flowchart LR
    A[Agent vyvolá nástroj] --> B[Vytvořit obsah účtenky]
    B --> C[Kanonicizovat JSON RFC 8785]
    C --> D[Hash SHA-256]
    D --> E[Podpis Ed25519]
    E --> F[Účtenka s podpisem]
    F --> G[Auditor ověřuje offline]
    G --> H{Platnost podpisu?}
    H -- ano --> I[Důkaz viditelnosti manipulace]
    H -- ne --> J[Účtenka zamítnuta]

Minimální potvrzení vypadá 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..."
  }
}

Tři vlastnosti zajišťují funkci:

  1. Podpis. Potvrzení je podepsané bránou agenta pomocí privátního klíče Ed25519. Každý, kdo má odpovídající veřejný klíč, může offline ověřit podpis. Jakákoli manipulace s jakýmkoli polem podpis zneplatní.

  2. Kanonické kódování. Před podpisem je potvrzení serializováno podle JSON Canonicalization Scheme (JCS, RFC 8785). To zajišťuje, že dvě implementace vytvářející stejný logický dokument mají bytově identický výstup. Bez kanonizace by různí JSON serializéři vytvořili pro stejný obsah různé podpisy.

  3. Hashové řetězení. Pole previous_receipt_hash propojuje každé potvrzení s předchozím. Odstranění nebo přeuspořádání jednoho potvrzení přeruší každé potvrzení, které po něm přišlo. Manipulace je viditelná na úrovni řetězce i v případě obejití individuálních podpisů.

Tyto vlastnosti dohromady poskytují tři záruky:

Vytvoření potvrzení v Pythonu

K vytvoření potvrzení nepotřebujete žádnou speciální knihovnu. Kryptografické primitivy jsou široce dostupné a logika je jen několik desítek řádků Pythonu.

Cvičení v code_samples/18-signed-receipts.ipynb detailně projdou celý proces. Shrnutí:

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 nebo načtěte podepisovací klíč (v produkci uložte do trezoru klíčů)
signing_key = signing.SigningKey.generate()
verify_key = signing_key.verify_key

# Sestavte datový rámec účtenky (ještě 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, zahashujte, podepište.
canonical_bytes = canonicalize(payload)
message_hash = hashlib.sha256(canonical_bytes).digest()
signature_bytes = signing_key.sign(message_hash).signature

# Připojte strukturovaný objekt podpisu.
receipt = {
    **payload,
    "signature": {
        "alg": "EdDSA",
        "sig": b64url_nopad(signature_bytes),
        "public_key": b64url_nopad(bytes(verify_key)),
    },
}

To je celý proces podepsání. V cvičeních v sešitě projdete každý krok.

Ověření potvrzení a detekce manipulace

Ověření 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 strukturovaný objekt: {"alg", "sig", "public_key"}.
    sig_obj = receipt.get("signature")
    if not sig_obj or sig_obj.get("alg") != "EdDSA":
        return False

    # Zrekonstruujte užitečné zatížení, které bylo skutečně podepsáno (všechno kromě 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

Tato funkce vezme potvrzení a vrátí True, pokud je podpis platný, jinak False. Žádný síťový požadavek, žádná závislost na službě, žádná důvěra v třetí stranu není potřeba.

Pro ukázku detekce manipulace se v sešitě projde:

  1. Vytvoření platného potvrzení a potvrzení jeho platnosti.
  2. Úprava jednoho bytu v poli tool_args_hash.
  3. Znovuovření ověření a zjištění jeho selhání.

To je praktický důkaz, že potvrzení jsou odolná vůči manipulaci: jakákoli úprava, byť malá, podpis zneplatní.

Řetězení potvrzení pro vícekrokové agenty

Jedno podepsané potvrzení chrání jednu akci. Řetězec potvrzení chrání posloupnost.

flowchart LR
    R0[Příjmový doklad 0<br/>genesis] --> R1[Příjmový doklad 1]
    R1 --> R2[Příjmový doklad 2]
    R2 --> R3[Příjmový doklad 3]
    R1 -. předchozí_hash_příjmového_dokladu .-> R0
    R2 -. předchozí_hash_příjmového_dokladu .-> R1
    R3 -. předchozí_hash_příjmového_dokladu .-> R2

Každé potvrzení zaznamenává hash potvrzení před ním. Aby útočník potichu odstranil potvrzení č. 2, musel by:

Pokud je privátní klíč uložen v hardwarovém klíčovém úložišti a veřejný klíč publikujete s každým potvrzením, žádný útok není bez odhalení možný.

Sešit projde:

  1. Vytvoření řetězce ze tří potvrzení.
  2. Ověření, že pole previous_receipt_hash každého potvrzení odpovídá skutečnému hashi předchozího potvrzení.
  3. Manipulaci jednoho potvrzení uprostřed a zjištění, že řetězec je přerušen přesně v tomto místě.

Takto vytvoříte auditní stopu, kterou může externí auditor ověřit bez důvěry ve vás.

Co potvrzení dokazují (a co ne)

Toto je nejdůležitější část lekce. Potvrzení jsou mocná, ale jejich moc je omezená.

Potvrzení dokazují tři věci:

  1. Přiřazení: konkrétní klíč podepsal daný payload.
  2. Integritu: payload se od podpisu nezměnil.
  3. Pořadí: toto potvrzení přišlo po onom potvrzení v hashovém řetězci.

Potvrzení NEdokazují:

  1. Správnost: že akce agenta byla správná. Potvrzení může být podepsáno stejně snadno pro špatnou odpověď jako pro správnou.
  2. Dodržování zásad: že zásada uvedená v policy_id byla skutečně vyhodnocena, nebo že by tuto akci povolila. Potvrzení zaznamenává to, co bylo tvrzeno, ne co bylo skutečně vynuceno.
  3. Identitu nad rámec klíče: potvrzení říká „tento klíč podepsal tento obsah.“ Neříká „tento člověk to autorizoval.“ Pro spojení klíče s osobou nebo organizací je potřeba samostatná identifikační infrastruktura (adresář, registr veřejných klíčů apod.).
  4. Pravdivost vstupů: pokud agent obdrží zmanipulovaný podnět a podle něj jedná, potvrzení věrně zaznamenává tuto akci. Potvrzení jsou závislá na validaci vstupů, nejsou jejich náhradou.

Tato hranice je důležitá ze dvou důvodů:

Častá chyba je předpokládat, že „máme potvrzení“ znamená „jsme řízeni.“ Neznamená. Potvrzení jsou základ. Řízení je systém, který na tom postavíte.

Produkční odkazy

Kód v Pythonu v této lekci je záměrně minimalistický, aby bylo možné každý řádek přečíst a přesně pochopit, co se děje. V produkci máte dvě možnosti:

  1. Postavit se přímo na kryptografických primitivech. Oněch 50 řádků výše je dostačujících pro mnohé případy užití. PyNaCl (Ed25519) a balíček jcs (kanonický JSON) jsou dobře udržované a auditované knihovny.

  2. Použít produkční knihovnu pro potvrzení. Několik open-source projektů implementuje stejný vzor s dalšími funkcemi (rotace klíčů, dávkové ověřování, distribuce JWK Set, integrace s policy enginy):

    • Formát potvrzení použitý v této lekci vychází z IETF Internet-Draftu (draft-farley-acta-signed-receipts), který je v procesu standardizace.
    • Microsoft Agent Governance Toolkit kombinuje potvrzení s rozhodnutími zásad založenými na Cedar; viz Tutorial 33 v příslušném repozitáři pro komplexní příklad.
    • Balíčky protect-mcp (npm) a @veritasacta/verify (npm) poskytují implementaci podepisování a offline ověřování potvrzení pro Node, určenou pro zabalení jakéhokoli MCP serveru s nezměnitelnou auditní stopou.

Volba mezi vlastní implementací a knihovnou je podobná rozhodování mezi psaním vlastní JWT knihovny a použitím otestované knihovny: obě jsou rozumné; knihovna ušetří čas a omezí auditní plochu; vlastní cesta vás přinutí rozumět každému primitivu. Tato lekce učí vlastní cestu, abyste měli základy pro obě varianty.

Kontrola znalostí

Ověřte si porozumění před přechodem na praktické cvičení.

1. Potvrzení je podepsáno privátním klíčem Ed25519 agenta. Auditor má pouze veřejný klíč. Může auditor potvrzení ověřit offline?

Odpověď Ano. Ověření Ed25519 vyžaduje pouze veřejný klíč a podepsaná data. Žádný síťový dotaz, žádná služba, žádná důvěra ve třetí stranu. Toto je vlastnost, která dělá potvrzení užitečnými v offline prostředích, mezi organizacemi nebo v nastavení s nízkou důvěrou.

2. Útočník upraví pole policy_id potvrzení, aby tvrdil, že bylo řízeno volnější zásadou. Podpis byl však spočítán nad původním payloadem. Co se stane při ověření?

Odpověď Ověření selže. Podpis byl spočítán nad kanonickými byty původního payloadu; úprava jakéhokoli pole změní kanonické byty, což změní SHA-256 hash a učiní podpis neplatným. Útočník by potřeboval privátní klíč k vytvoření nového platného podpisu, který nemá.

3. Proč potvrzení zahrnuje tool_args_hash a result_hash místo surových argumentů a výsledku?

Odpověď Dva důvody. Za prvé, potvrzení může být archivováno nebo přenášeno v prostředích, kde únik surového obsahu (osobní údaje, obchodní data) je problém. Hashování udržuje potvrzení malé a obsah soukromý; auditor ověřuje, že hash odpovídá samostatně uložené kopii skutečného obsahu. Za druhé, hashe mají pevnou velikost; potvrzení s hashi je omezené velikostí bez ohledu na velikost vstupů a výstupů.

4. Pole previous_receipt_hash propojuje každé potvrzení s předchozím. Co se stane, když útočník potichu odstraní jedno potvrzení uprostřed řetězce?

Odpověď Každé potvrzení, které po čísle odstraněného přišlo. Jejich pole `previous_receipt_hash` už neodpovídají skutečnému řetězci (protože potvrzení, na které odkazovaly, už neexistuje, nebo řetězec nyní ukazuje na jiného předchůdce). Pro skrytí odstranění by útočník musel znovu podepsat každé následující potvrzení, což vyžaduje privátní klíč.

5. Potvrzení bylo ověřeno bez chyby. Dokazuje to, že akce agenta byla správná, rozumná nebo vyhovující zásadám?

Odpověď Ne. Platné potvrzení dokazuje tři věci: přiřazení (tento klíč podepsal tento obsah), integritu (obsah se nezměnil) a pořadí (potvrzení přišlo po onom potvrzení). Nedokazuje, že akce byla správná, že zásada uvedená v `policy_id` byla skutečně vyhodnocena, nebo že agent dodržel všechna pravidla. Potvrzení činí chování agenta auditovatelné, ne nutně správné. Toto je nejdůležitější hranice lekce.

Praktické cvičení

Otevřete code_samples/18-signed-receipts.ipynb a dokončete všechny čtyři sekce:

  1. Sekce 1: Podepište své první potvrzení a ověřte ho.
  2. Sekce 2: Manipulujte s potvrzením a sledujte neúspěšné ověření.
  3. Sekce 3: Vytvořte řetězec ze tří potvrzení a ověřte integritu řetězce.
  4. Sekce 4: Použijte vzor na agenta postaveného na Microsoft Agent Frameworku: zabalte volání nástroje do podepisování potvrzení a poté potvrzení nezávisle ověřte.

Rozšiřující výzva 1: rozšiřte schéma potvrzení o další pole dle vlastního výběru (například ID požadavku pro trasování), aktualizujte kanonickou logiku podepisování tak, aby pole zahrnovala, a potvrďte, že potvrzení projde ověřením. Pak pole po podpisu upravte a ověřte, že ověření selže. Tento postup vás donutí pochopit, jak každý byte kanonického kódování přispívá k podpisu. Výzva k rozšíření 2: SHA-256-hashujte spolu dva své účtenky (spojte jejich kanonické bajty v deterministickém pořadí) a vložte výsledný digest jako nové pole do třetí účtenky před jejím podepsáním. Ověřte, že všechny tři účtenky stále projdou zpětnou kontrolou. Právě jste vytvořili jednostupňový důkaz začlenění: kdokoli s třetí účtenkou může dokázat, že první dvě existovaly v době jejího podepsání, aniž by bylo třeba odhalovat jejich obsah. Toto je vzor, který selektivně-odhalovací účtenky používají v měřítku (Merkleho závazky, RFC 6962).

Závěr

Kryptografické účtenky poskytují AI agentům auditní stopu, která je:

Nejsou náhradou za validaci vstupu, vynucování politiky nebo identitní infrastrukturu. Jsou základem těchto vrstev. Když nasazujete agenty do regulovaných pracovních zátěží, vícestupňových pracovních procesů nebo jakéhokoliv prostředí, kde nelze předpokládat důvěru budoucího auditora, účtenky jsou způsob, jak udržet auditní stopu poctivou.

Nejdůležitější poznatek: účtenky dokazují, kdo co řekl a kdy. Nedokazují, že to, co bylo řečeno, je pravda nebo správné. Držte tuto odlišnost pevně. Je to rozdíl mezi poctivým systémem provenience a klamavým.

Kontrolní seznam pro produkci

Když jste připraveni postoupit z této lekce na nasazení agentů podepsaných účtenkami do reálného prostředí:

Máte více otázek ohledně zabezpečení AI agentů?

Připojte se k Microsoft Foundry Discord, kde se setkáte s ostatními studenty, zúčastníte se konzultačních hodin a získáte odpovědi na své otázky ohledně AI agentů.

Za hranicí této lekce

Tato lekce pokrývá podepisování jedné účtenky a sekvence řetězených hashů. Stejná primitiva se skládají do několika pokročilejších vzorů, se kterými se můžete setkat, až vaše správa dozraje:

Další zdroje

Předchozí lekce

Budování agentů pro používání počítače (CUA)

Následující lekce

(Bude určeno správci kurikula)


Prohlášení o omezení odpovědnosti: Tento dokument byl přeložen pomocí AI překladatelské služby Co-op Translator. Přestože usilujeme o co největší přesnost, mějte prosím na paměti, že automatizované překlady mohou obsahovat chyby nebo nepřesnosti. Originální dokument v jeho mateřském jazyce by měl být považován za autoritativní zdroj. Pro kritické informace se doporučuje profesionální lidský překlad. Nejsme odpovědní za jakékoli nedorozumění nebo nesprávné interpretace vzniklé použitím tohoto překladu.