Watch the lesson video: Zabezpečení AI agentů pomocí kryptografických potvrzení
(Video lekce a náhled obrázku budou přidány týmem Microsoft pro obsah po sloučení, odpovídající vzoru lekce 14 / 15.)
Tato lekce pokryje:
Po dokončení této lekce budete vědět, jak:
Představte si, že jste nasadili AI agenta pro Contoso Travel. Agent čte zákaznické požadavky, volá API letů pro vyhledání možností a rezervuje sedadla za zákazníka. Za poslední čtvrtletí agent zpracoval 50 000 rezervací.
Dnes přijde auditor. Položí jednoduchou otázku: „Ukažte mi, co váš agent dělal.“
Předáte logy. Auditor se na ně podívá a položí těžší otázku: „Jak vím, že tyto logy nebyly upraveny?“
To je problém auditní stopy. Většina dnešních nasazení agentů spoléhá na:
Žádné z těchto řešení nedokáže odpovědět auditorově otázce bez požadavku, aby auditor někomu důvěřoval (vám, vašemu poskytovateli cloudu, dodavateli databáze). Pro interní použití je tato důvěra často přijateľná. Pro regulované úlohy (finance, zdravotnictví, cokoliv podléhající evropskému zákonu o AI) není.
Kryptografické doklady řeší tento problém tím, že každou akci agenta činí nezávisle ověřitelnou. Auditor vám nemusí důvěřovat. Potřebuje pouze váš veřejný klíč a samotný doklad.
Doklad 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[Normalizovat JSON RFC 8785]
C --> D[SHA-256 haš]
D --> E[Ed25519 podepsat]
E --> F[Účet s podpisem]
F --> G[Auditor ověřuje offline]
G --> H{Je podpis platný?}
H -- ano --> I[Důkaz odolný proti manipulaci]
H -- ne --> J[Účet zamítnut]
Minimální doklad 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, které zajišťují funkčnost:
Podpis. Doklad je podepsán bránou agenta pomocí soukromého klíče Ed25519. Kdokoli s odpovídajícím veřejným klíčem může offline ověřit podpis. Jakákoli manipulace s kterýmkoli polem podpis zneplatní.
Kanonické kódování. Před podpisem se doklad serializuje pomocí JSON Canonicalization Scheme (JCS, RFC 8785). To zajistí, že dvě implementace vytvářející stejný logický doklad vydají bajtově identický výstup. Bez kanonizace by různé JSON serializéry vytvářely různé podpisy pro stejné obsahy.
Řetězení hashů. Pole previous_receipt_hash odkazuje na předchozí doklad. Odstranění nebo přeuspořádání dokladu poruší každý následující doklad. Manipulace se stává viditelnou na úrovni řetězce i pokud jsou jednotlivé podpisy obejity.
Tyto vlastnosti společně poskytují tři záruky:
Nemusíte používat speciální knihovnu na vytvoření dokladu. Kryptografické primitivy jsou běžně dostupné a logika představuje pár desítek řádků Pythonu.
Cvičení v code_samples/18-signed-receipts.ipynb provádí celým postupem. 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()}"
# Generujte nebo načtěte podpisový klíč (v produkci ukládejte do trezoru klíčů)
signing_key = signing.SigningKey.generate()
verify_key = signing_key.verify_key
# Vytvořte obsah účtenky (zatím 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ý podpisový objekt.
receipt = {
**payload,
"signature": {
"alg": "EdDSA",
"sig": b64url_nopad(signature_bytes),
"public_key": b64url_nopad(bytes(verify_key)),
},
}
To je celý proces podepisování. Cvičení v notebooku popisují každý krok.
Ověření je opačné krok:
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še 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 doklad a vrátí True, pokud je podpis platný, jinak False. Žádný síťový dotaz, žádná závislost na službě, žádná důvěra v třetí strany není potřeba.
Pro demonstraci detekce manipulací notebook ukazuje:
tool_args_hash.To je praktický důkaz, že doklady jsou odolné proti manipulacím: jakákoli změna, i malá, zničí podpis.
Jeden podepsaný doklad chrání jednu akci. Řetězec dokladů chrání posloupnost.
flowchart LR
R0[Účet 0<br/>genesis] --> R1[Účet 1]
R1 --> R2[Účet 2]
R2 --> R3[Účet 3]
R1 -. previous_receipt_hash .-> R0
R2 -. previous_receipt_hash .-> R1
R3 -. previous_receipt_hash .-> R2
Každý doklad zaznamenává hash předchozího dokladu. Chcete-li tiše odstranit doklad 2, útočník by musel:
previous_receipt_hash v dokladu 3 (znemožní podpis dokladu 3), NEBOPokud je soukromý klíč uložen v hardwarové klíčové schránce a vy zveřejníte veřejný klíč s každým dokladem, žádný z těchto útoků není bez odhalení realizovatelný.
Notebook ukazuje:
previous_receipt_hash každého dokladu odpovídá skutečnému hashi předchozího dokladu.Takto vytvoříte auditní stopu, kterou může externí auditor ověřit, aniž by vám musel důvěřovat.
Jedná se o nejdůležitější část této lekce. Doklady jsou mocné, ale jejich účinek má hranice.
Doklady dokazují tři věci:
Doklady NEdokazují:
policy_id byla skutečně vyhodnocena nebo by tuto akci povolila. Doklad zaznamenává, co bylo tvrzeno, ne co bylo vynuceno.Tato hranice je důležitá ze dvou důvodů:
Častou chybou je předpokládat, že „když máme doklady,“ znamená to „jsme regulovaní.“ Neznamená. Doklady jsou základ. Regulace je systém, který na nich stavíte.
Python kód v této lekci je záměrně minimalistický, abyste mohli chápat každý řádek a přesně vědět, co se děje. V produkci máte dvě možnosti:
Postavit se přímo na kryptografických primitivech. 50 řádků, které jste viděli, stačí pro mnoho použití. PyNaCl (Ed25519) a balíček jcs (kanonický JSON) jsou dobře udržované a auditované knihovny.
Použít produkční knihovnu na doklady. Několik open-source projektů implementuje stejný vzor s dalšími funkcemi (rotace klíčů, hromadné ověřování, distribuce JWK setu, integrace s motory politik):
draft-farley-acta-signed-receipts), který je právě ve schvalovacím procesu.protect-mcp (npm) a @veritasacta/verify (npm) poskytují Node implementaci podepisování a offline ověřování dokladů, určenou k zabalení jakéhokoli MCP serveru do auditní stopy odolné proti manipulaci.pip install nobulex) poskytuje stejný Ed25519 + JCS podpisový vzor v Pythonu s integracemi LangChain a CrewAI, včetně publikovaných testovacích vektorů a mapování shody přispěného prostřednictvím OWASP PR #2210.Volba mezi psaním vlastního kódu a použitím knihovny je podobná rozhodování mezi vlastní JWT knihovnou a testovanou knihovnou: obojí je rozumné; knihovna šetří čas a snižuje auditní povrch; přístup od nuly vás nutí rozumět každé primitivě. Tato lekce učí přístup od nuly, abyste měli základy pro obě volby.
Otestujte si pochopení před přechodem na praktické cvičení.
1. Doklad je podepsán soukromým klíčem Ed25519 agenta. Auditor má pouze veřejný klíč. Může auditor ověřit doklad offline?
2. Útočník upraví pole policy_id dokladu, aby tvrdil, že byl řízen volnější politikou. Podpis byl ale nad původním payloadem. Co se stane při ověřování?
3. Proč doklad obsahuje tool_args_hash a result_hash místo surových argumetů a výsledku?
4. Pole previous_receipt_hash propojuje každý doklad s jeho předchůdcem. Pokud útočník tiše smaže jeden doklad uprostřed řetězce, co se stane neplatným?
5. Doklad ověřen čistě platný. Znamená to, že akce agenta byla správná, rozumná nebo v souladu s politikou?
Otevřete code_samples/18-signed-receipts.ipynb a dokončete všechna čtyři oddělení:
Rozšiřující výzva 2: Spojte SHA-256 hash dvou svých příjmů (spojte jejich kanonické bajty v deterministickém pořadí) a vložte vzniklý digest jako nové pole do třetího příjmu před jeho podepsáním. Ověřte, že všechny tři příjmy se stále úspěšně ověřují při zpětné kontrole. Právě jste vytvořili důkaz jedním krokem: kdokoli držící třetí příjem může dokázat, že první dva existovaly v době jeho podepsání, aniž by musel odhalit jejich obsah. Toto je vzor, který používají příjmy s výběrovým zveřejněním v rozsáhlém měřítku (Merkleho závazky, RFC 6962).
Kryptografické příjmy poskytují AI agentům auditní stopu, která je:
Nejsou náhradou za ověřování vstupů, prosazování politik nebo infrastrukturu identity. Jsou základem pro tyto vrstvy. Když nasazujete agenty do regulovaných prostředí, pracovních toků přes více organizací nebo do jakéhokoli prostředí, kde nelze předpokládat, že vám budoucí auditor bude důvěřovat, příjmy jsou způsob, jak zajistit poctivost auditní stopy.
Nejdůležitější poznatek: příjmy dokazují, kdo co řekl a kdy. Nedokazují, že to, co bylo řečeno, je pravda nebo správné. Držte toto rozlišení pevně. Je to rozdíl mezi poctivým systémem původu a zavádějícím.
Když jste připraveni přejít od této lekce k nasazení agentů podepsaných příjmy v reálném prostředí:
https://your-org.example.com/.well-known/agent-keys.json.Připojte se na Microsoft Foundry Discord, kde se můžete setkat s dalšími studenty, účastnit se konzultačních hodin a nechat si zodpovědět své otázky ohledně AI agentů.
Tato lekce pokrývá podepisování jednoho příjmu a hashově navázané sekvence. Stejná primitiva tvoří základy několika pokročilejších vzorů, které můžete potkat, jak vaše správní pozice dozrává:
authorization_*) a po vykonání (result_*) s nezávislými podpisy, užitečné když rozhodnutí o autorizaci a zaznamenaný výsledek jsou od různých aktérů nebo v různých časech. Toto se přidává k formátu příjmu vyučovaného v této lekci.result_hash. Reálné užitečné zatížení často obsahuje více než jediný výsledek nástroje: předrozhodovací zdůvodnění (predikce modelu, uvažované možnosti, důkazy a jejich úplnost, stav rizika, řetězec odpovědnosti, rozhodnutí brány) vše může být uvnitř užitečného zatížení, zapečetěné jedním příjmem. To udržuje formát příjmu minimální a zároveň umožňuje vývoj schémat užitečného zatížení podle domény.signature.alg může nést hodnotu ML-DSA-65 (standard NIST pro post-kvantové podpisy), když potřebujete migrovat. Plánujte přechodné období, kdy budou příjmy podepsané oběma způsoby.Budování agentů pro využití počítače (CUA)
(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.