Watch the lesson video: Mengamankan Agen AI dengan Resi Kriptografi
(Video pelajaran dan thumbnail akan ditambahkan oleh tim konten Microsoft setelah penggabungan, sesuai pola pelajaran 14 / 15.)
Pelajaran ini akan membahas:
Setelah menyelesaikan pelajaran ini, Anda akan tahu bagaimana untuk:
Bayangkan Anda telah menerapkan agen AI untuk Contoso Travel. Agen tersebut membaca permintaan pelanggan, memanggil API penerbangan untuk mencari opsi, dan memesan kursi atas nama pelanggan. Kuartal lalu, agen memproses 50.000 pemesanan.
Hari ini datang seorang auditor. Mereka bertanya pertanyaan sederhana: “Tunjukkan apa yang dilakukan agen Anda.”
Anda menyerahkan file log Anda. Auditor melihatnya dan mengajukan pertanyaan yang lebih sulit: “Bagaimana saya tahu log ini tidak diedit?”
Ini adalah masalah jejak audit. Sebagian besar penerapan agen hari ini bergantung pada:
Tidak satu pun dari ini bisa menjawab pertanyaan auditor tanpa mengharuskan auditor mempercayai seseorang (Anda, penyedia cloud Anda, vendor basis data Anda). Untuk penggunaan internal, kepercayaan itu sering dapat diterima. Untuk beban kerja yang diatur (keuangan, kesehatan, apapun yang tunduk pada Undang-undang AI UE), tidak demikian.
Resi kriptografi menyelesaikan ini dengan membuat setiap tindakan agen dapat diverifikasi secara mandiri. Auditor tidak perlu mempercayai Anda. Mereka hanya memerlukan kunci publik Anda dan resi itu sendiri.
Resi adalah objek JSON yang merekam apa yang dilakukan agen, ditandatangani dengan tanda tangan digital.
flowchart LR
A[Agent memanggil alat] --> B[Membangun payload tanda terima]
B --> C[Kanonalikan JSON RFC 8785]
C --> D[Hash SHA-256]
D --> E[Tanda tangan Ed25519]
E --> F[Tanda terima dengan tanda tangan]
F --> G[Auditor memverifikasi secara offline]
G --> H{Tanda tangan valid?}
H -- ya --> I[Bukti tamper-evident]
H -- tidak --> J[Tanda terima ditolak]
Resi minimal terlihat seperti ini:
{
"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..."
}
}
Tiga properti yang melakukan pekerjaan:
Tanda tangan. Resi ditandatangani oleh gateway agen menggunakan kunci privat Ed25519. Siapa saja dengan kunci publik yang sesuai dapat memverifikasi tanda tangan secara offline. Pemalsuan pada bidang apa pun akan membatalkan tanda tangan.
Pengodean kanonik. Sebelum menandatangani, resi diserialisasi menggunakan Skema Kanonisasi JSON (JCS, RFC 8785). Ini memastikan bahwa dua implementasi yang menghasilkan resi logis yang sama menghasilkan output byte-identik. Tanpa kanonisasi, serializer JSON berbeda akan menghasilkan tanda tangan berbeda untuk konten yang sama.
Penghubungan hash. Kolom previous_receipt_hash menghubungkan setiap resi ke yang sebelumnya. Menghapus atau mengubah urutan resi akan merusak setiap resi yang datang setelahnya. Pemalsuan menjadi terlihat pada tingkat rantai meskipun tanda tangan individual dilewati.
Ketiga properti ini bersama-sama memberikan tiga jaminan:
Anda tidak memerlukan pustaka khusus untuk membuat resi. Primitif kriptografi tersedia secara luas dan logikanya hanya beberapa puluh baris Python.
Latihan langsung dalam code_samples/18-signed-receipts.ipynb membahas alur lengkap. Versi rangkuman:
import json
import hashlib
import base64
from nacl import signing
from jcs import canonicalize # RFC 8785 JSON kanonik
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()}"
# Hasilkan atau muat kunci tanda tangan (di produksi, simpan di gudang kunci)
signing_key = signing.SigningKey.generate()
verify_key = signing_key.verify_key
# Bangun muatan struk (belum ada tanda tangan)
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,
}
# Kanonkan, hash, tanda tangani.
canonical_bytes = canonicalize(payload)
message_hash = hashlib.sha256(canonical_bytes).digest()
signature_bytes = signing_key.sign(message_hash).signature
# Lampirkan objek tanda tangan terstruktur.
receipt = {
**payload,
"signature": {
"alg": "EdDSA",
"sig": b64url_nopad(signature_bytes),
"public_key": b64url_nopad(bytes(verify_key)),
},
}
Itulah keseluruhan pipeline penandatanganan. Latihan dalam notebook membahas setiap langkah.
Verifikasi adalah operasi kebalikan:
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:
# Tanda tangan adalah objek terstruktur: {"alg", "sig", "public_key"}.
sig_obj = receipt.get("signature")
if not sig_obj or sig_obj.get("alg") != "EdDSA":
return False
# Rekonstruksi payload yang sebenarnya ditandatangani (semua kecuali tanda tangan).
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
Fungsi ini menerima resi dan mengembalikan True jika tanda tangan valid, False jika tidak. Tidak ada panggilan jaringan, tidak ada ketergantungan layanan, tidak perlu mempercayai pihak ketiga manapun.
Untuk melihat deteksi pemalsuan dalam praktik, notebook membahas:
tool_args_hash.Ini adalah demonstrasi praktis bahwa resi tahan pemalsuan: modifikasi apa pun, sekecil apa pun, merusak tanda tangan.
Satu resi bertanda tangan melindungi satu tindakan. Rantai resi melindungi sebuah urutan.
flowchart LR
R0[Penerimaan 0<br/>awal] --> R1[Penerimaan 1]
R1 --> R2[Penerimaan 2]
R2 --> R3[Penerimaan 3]
R1 -. previous_receipt_hash .-> R0
R2 -. previous_receipt_hash .-> R1
R3 -. previous_receipt_hash .-> R2
Setiap resi merekam hash dari resi sebelumnya. Untuk menghapus resi ke-2 secara diam-diam, penyerang harus:
previous_receipt_hash pada resi ke-3 (merusak tanda tangan resi ke-3), ATAUJika kunci privat ada dalam tempat penyimpanan kunci perangkat keras dan Anda menerbitkan kunci publik dengan setiap resi, tidak ada serangan yang layak dilakukan tanpa terdeteksi.
Notebook membahas:
previous_receipt_hash setiap resi cocok dengan hash aktual resi sebelumnya.Begitulah Anda membuat jejak audit yang dapat diverifikasi oleh auditor eksternal tanpa harus mempercayai Anda.
Ini adalah bagian terpenting dari pelajaran ini. Resi kuat tetapi kekuatannya terbatas.
Resi membuktikan tiga hal:
Resi TIDAK membuktikan:
policy_id benar-benar dievaluasi, atau bahwa kebijakan tersebut akan mengizinkan tindakan ini jika diperiksa. Resi merekam apa yang diklaim, bukan apa yang ditegakkan.Batas ini penting karena dua alasan:
Kesalahan umum adalah menganggap bahwa “kita punya resi” berarti “kita diatur.” Tidak demikian. Resi adalah fondasi. Tata kelola adalah sistem yang Anda bangun di atasnya.
Kode Python dalam pelajaran ini sengaja minimal agar Anda bisa membaca setiap baris dan memahami persis apa yang terjadi. Dalam produksi, Anda punya dua opsi:
Membangun langsung pada primitif kriptografi. 50 baris yang Anda lihat di atas sudah cukup untuk banyak kasus penggunaan. PyNaCl (Ed25519) dan paket jcs (JSON kanonik) adalah pustaka yang terawat baik dan diaudit.
Menggunakan pustaka resi produksi. Beberapa proyek open-source mengimplementasikan pola yang sama dengan fitur tambahan (rotasi kunci, verifikasi batch, distribusi JWK Set, integrasi dengan mesin kebijakan):
draft-farley-acta-signed-receipts) yang sedang diproses sebagai standar.protect-mcp (npm) dan @veritasacta/verify (npm) menyediakan implementasi Node untuk penandatanganan resi dan verifikasi offline, untuk membungkus server MCP mana pun dengan jejak audit tahan pemalsuan.Keputusan antara membangun sendiri dan menggunakan pustaka mencerminkan keputusan antara menulis pustaka JWT sendiri dan menggunakan yang sudah teruji: keduanya masuk akal; pustaka menghemat waktu dan mengurangi permukaan audit; pendekatan dari nol memaksa Anda memahami setiap primitif. Pelajaran ini mengajarkan jalur dari nol sehingga Anda memiliki fondasi untuk kedua pilihan.
Uji pemahaman Anda sebelum melanjutkan ke latihan praktik.
1. Resi ditandatangani dengan kunci privat Ed25519 agen. Auditor hanya memiliki kunci publik. Bisakah auditor memverifikasi resi secara offline?
2. Penyerang memodifikasi kolom policy_id resi untuk mengklaim bahwa tindakan diatur oleh kebijakan yang lebih permisif. Tanda tangan dibuat atas muatan asli. Apa yang terjadi saat verifikasi?
3. Mengapa resi menyertakan tool_args_hash dan result_hash daripada argumen dan hasil mentah?
4. Kolom previous_receipt_hash menghubungkan setiap resi ke pendahulunya. Jika penyerang secara diam-diam menghapus satu resi di tengah rantai, apa yang menjadi tidak valid?
5. Resi selesai diverifikasi dengan bersih. Apakah itu membuktikan bahwa tindakan agen benar, tepat, atau patuh kebijakan?
Buka code_samples/18-signed-receipts.ipynb dan selesaikan keempat bagian:
Tantangan tambahan 1: perpanjang skema resi dengan kolom tambahan pilihan Anda sendiri (misalnya, ID permintaan untuk pelacakan), perbarui logika penandatanganan kanonik untuk menyertakannya, dan pastikan resi masih dapat lolos verifikasi bolak-balik. Kemudian ubah kolom itu setelah tanda tangan dan pastikan verifikasi gagal. Ini memaksa Anda memahami bagaimana setiap byte pengodean kanonik berkontribusi pada tanda tangan. Tantangan Stretch 2: SHA-256-hash dua tanda terima Anda bersama-sama (gabungkan byte kanonik mereka dalam urutan deterministik) dan sematkan ringkasan yang dihasilkan sebagai bidang baru pada tanda terima ketiga sebelum menandatanganinya. Verifikasi bahwa ketiga tanda terima tersebut masih dapat diproses bolak-balik. Anda baru saja membangun bukti inklusi satu langkah: siapa pun yang memegang tanda terima ketiga dapat membuktikan bahwa dua tanda terima pertama ada pada saat ditandatangani, tanpa perlu mengungkapkan isinya. Inilah pola yang digunakan tanda terima pengungkapan selektif dalam skala besar (komitmen Merkle, RFC 6962).
Tanda terima kriptografis memberikan agen AI jejak audit yang:
Mereka bukan pengganti untuk validasi input, penegakan kebijakan, atau infrastruktur identitas. Mereka adalah fondasi untuk lapisan-lapisan tersebut. Ketika Anda menerapkan agen ke dalam beban kerja yang diatur, alur kerja multi-organisasi, atau pengaturan di mana auditor masa depan tidak dapat diasumsikan mempercayai Anda, tanda terima adalah cara Anda membuat jejak audit menjadi jujur.
Pengambilan poin paling penting: tanda terima membuktikan siapa yang mengatakan apa dan kapan. Mereka tidak membuktikan bahwa apa yang dikatakan itu benar atau tepat. Pegang perbedaan itu dengan ketat. Ini adalah perbedaan antara sistem asal-usul yang jujur dan yang menyesatkan.
Saat Anda siap untuk naik tingkat dari pelajaran ini ke mengerahkan agen yang ditandatangani tanda terima di lingkungan nyata:
https://your-org.example.com/.well-known/agent-keys.json.Bergabunglah dengan Microsoft Foundry Discord untuk bertemu dengan pelajar lain, menghadiri jam kantor, dan mendapatkan jawaban atas pertanyaan Agen AI Anda.
Pelajaran ini mencakup penandatanganan tanda terima tunggal dan urutan berantai hash. Primitif yang sama menyusun beberapa pola lanjutan yang mungkin Anda temui seiring kematangan sikap tata kelola Anda:
authorization_*) dan setengah pasca-eksekusi (result_*) dengan tanda tangan independen, berguna ketika keputusan otorisasi dan hasil yang diamati dibuat oleh aktor berbeda atau pada waktu berbeda. Ini dapat disusun secara tambahan di atas format tanda terima yang diajarkan dalam pelajaran ini.result_hash. Payload dunia nyata sering kali lebih kaya daripada hasil panggilan alat tunggal: penalaran pra-keputusan (prediksi model, opsi yang dipertimbangkan, bukti dan kelengkapannya, sikap risiko, rantai akuntabilitas, hasil gerbang) semua dapat hidup di dalam payload yang disegel oleh satu tanda terima. Ini menjaga format tanda terima minimal sembari memungkinkan skema payload berkembang per domain.signature.alg dapat membawa ML-DSA-65 (standar tanda tangan pasca-kuantum NIST) ketika Anda perlu melakukan migrasi. Rencanakan periode transisi di mana tanda terima ditandatangani ganda.Building Computer Use Agents (CUA)
(Akan ditentukan oleh pemelihara kurikulum)
Penafian: Dokumen ini telah diterjemahkan menggunakan layanan terjemahan AI Co-op Translator. Meskipun kami berupaya untuk mencapai akurasi, harap diketahui bahwa terjemahan otomatis mungkin mengandung kesalahan atau ketidakakuratan. Dokumen asli dalam bahasa aslinya harus dianggap sebagai sumber yang sah. Untuk informasi penting, disarankan menggunakan terjemahan profesional oleh manusia. Kami tidak bertanggung jawab atas kesalahpahaman atau penafsiran yang keliru yang timbul dari penggunaan terjemahan ini.