লেসন ভিডিও দেখুন: ক্রিপ্টোগ্রাফিক রসীদ দিয়ে AI এজেন্ট সুরক্ষা
(মাইক্রোসফট কন্টেন্ট টিম মার্জের পর লেসন ভিডিও এবং থাম্বনেইল যুক্ত করবে, যা লেসন ১৪ / ১৫ প্যাটার্নের সাথে মেলাবে।)
এই লেসনে আলোচনা করা হবে:
এই লেসন সম্পন্ন করার পরে, আপনি জানতে পারবেন:
ধরা যাক আপনি Contoso Travel-এর জন্য একটি AI এজেন্ট মোতায়েন করেছেন। এজেন্ট গ্রাহকের অনুরোধ পড়ে, ফ্লাইট API কল করে বিকল্প খোঁজে, এবং গ্রাহকের পক্ষ থেকে সিট বুক করে। গত ত্রৈমাসিকে এজেন্ট ৫০,০০০ টি বুকিং প্রক্রিয়া করেছে।
আজ একজন অডিটর আসেন। তারা একটি সহজ প্রশ্ন করেন: “আমার দেখাও তোমার এজেন্ট কী করেছে।”
আপনি আপনার লগ ফাইলগুলি হাতে দেন। অডিটর সেগুলো দেখে আরও কঠিন প্রশ্ন করেন: “কিভাবে আমি নিশ্চিত হবো এই লগগুলো সম্পাদিত হয়নি?”
এটাই অডিট-ট্রেইল সমস্যা। আজকের বেশিরভাগ এজেন্ট মোতায়েন:
এইগুলোর কেউই অডিটরের প্রশ্নের উত্তর দিতে পারে না যদি না অডিটর কাউকে (আপনাকে, আপনার ক্লাউড প্রোভাইডার, ডাটাবেস বিক্রেতা) বিশ্বাস করেন। অভ্যন্তরীণ ব্যবহারের জন্য এই বিশ্বাস প্রায়শই যথেষ্ট। নিয়ন্ত্রিত ওয়ার্কলোডের জন্য (আর্থিক, স্বাস্থ্যসেবা, EU AI আইন অনুসারে) নয়।
ক্রিপ্টোগ্রাফিক রসীদ এই সমস্যা সমাধান করে কারণ প্রতিটি এজেন্ট ক্রিয়াকলাপ স্বাধীনভাবে যাচাইযোগ্য হয়। অডিটরের আপনার প্রতি বিশ্বাস প্রয়োজন হয় না। তাদের প্রয়োজন শুধুমাত্র আপনার পাবলিক কী এবং রসীদ।
রসীদ একটি JSON অবজেক্ট যা এজেন্টের করা কাজ রেকর্ড করে এবং ডিজিটাল সিগনেচার দিয়ে সই করা থাকে।
flowchart LR
A[এজেন্ট একটি টুল আহ্বান করে] --> B[রসিদ পেলোড তৈরি করুন]
B --> C[JSON RFC 8785 ক্যাননিক্যালাইজ করুন]
C --> D[SHA-256 হ্যাশ]
D --> E[Ed25519 স্বাক্ষর]
E --> F[স্বাক্ষরসহ রসিদ]
F --> G[অডিটর অফলাইন যাচাই করেন]
G --> H{স্বাক্ষর বৈধ?}
H -- হ্যাঁ --> I[ভাঙাচোরা-প্রমাণ]
H -- না --> J[রসিদ প্রত্যাখ্যাত]
একটি ন্যূনতম রসীদ এরকম দেখায়:
{
"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..."
}
}
তিনটি বৈশিষ্ট্য কাজটি সম্পাদন করে:
সিগনেচার। রসীদ এজেন্টের গেটওয়ে দ্বারা Ed25519 প্রাইভেট কী দিয়ে সই করা হয়। সংশ্লিষ্ট পাবলিক কী থাকা যেকেউ সিগনেচার অফলাইনে যাচাই করতে পারে। যেকোন ফিল্ডে ছেঁড়াছেঁড়ি সিগনেচারকে অবৈধ করে তোলে।
ক্যানোনিকাল এনকোডিং। সাইন করার আগে, রসীদ JSON ক্যানোনিকালাইজেশন স্কিম (JCS, RFC 8785) ব্যবহার করে সিরিয়ালাইজ করা হয়। এটি নিশ্চিত করে যে দুইটি ইমপ্লিমেন্টেশন একই লজিক্যাল রসীদ উৎপন্ন করলে একই বাইট-পরিচ্ছন্ন আউটপুট তৈরি করবে। ক্যানোনিকালাইজেশন ছাড়া, বিভিন্ন JSON সিরিয়ালাইজার একই সামগ্রীর জন্য ভিন্ন সিগনেচার তৈরি করবে।
হ্যাশ চেইনিং। previous_receipt_hash ফিল্ড প্রতিটি রসীদকে তার পূর্ববর্তী রসীদের সাথে সংযুক্ত করে। একটি রসীদ সরালে বা পুনরায় ক্রম পরিবর্তন করলে পরে আসা প্রতিটি রসীদ ভেঙে যাবে। ছেঁড়াছেঁড়ি চেইন স্তরে দৃশ্যমান হয় এমনকি যদি ব্যক্তিগত সিগনেচারগুলি বায়পাস করা হয়।
একসাথে এই বৈশিষ্ট্য তিনটি নিশ্চয়তা প্রদান করে:
রসীদ তৈরি করতে বিশেষ কোনো লাইব্রেরির প্রয়োজন নেই। ক্রিপ্টোগ্রাফিক প্রিমিটিভস বিস্তৃতভাবে পাওয়া যায় এবং লজিকটি কয়েক ডজন লাইনের পাইথন কোড।
code_samples/18-signed-receipts.ipynb এ চর্চার ধাপগুলো পুরো ফ্লোতে দেখানো হয়েছে। সারাংশ ভার্সন:
import json
import hashlib
import base64
from nacl import signing
from jcs import canonicalize # RFC 8785 কাননিক্যাল 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()}"
# একটি সাইনিং কী তৈরি করুন বা লোড করুন (প্রোডাকশনে, একটি কী ভল্টে সংরক্ষণ করুন)
signing_key = signing.SigningKey.generate()
verify_key = signing_key.verify_key
# রসিদ পে লোড তৈরি করুন (এখনও কোন সিগনেচার নেই)
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,
}
# কাননিক্যালাইজ করুন, হ্যাশ করুন, সাইন করুন।
canonical_bytes = canonicalize(payload)
message_hash = hashlib.sha256(canonical_bytes).digest()
signature_bytes = signing_key.sign(message_hash).signature
# একটি কাঠামোগত সিগনেচার অবজেক্ট সংযুক্ত করুন।
receipt = {
**payload,
"signature": {
"alg": "EdDSA",
"sig": b64url_nopad(signature_bytes),
"public_key": b64url_nopad(bytes(verify_key)),
},
}
এটাই সমগ্র সাইনিং পাইপলাইন। নোটবুকে প্রতিটি ধাপ বিস্তারিত আছে।
যাচাই হল বিপরীত ক্রিয়া:
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:
# স্বাক্ষরটি একটি গঠনমূলক অবজেক্ট: {"alg", "sig", "public_key"}।
sig_obj = receipt.get("signature")
if not sig_obj or sig_obj.get("alg") != "EdDSA":
return False
# যেটি সত্যিই স্বাক্ষরিত হয়েছিল সেই পে-লোডটি পুনর্গঠন করুন (স্বাক্ষর ছাড়াও সবকিছু)।
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
এই ফাংশন একটি রসীদ নেয় এবং সিগনেচার বৈধ হলে True রিটার্ন করে, অন্যথায় False। কোনো নেটওয়ার্ক কল, সার্ভিস ডিপেনডেন্সি নেই, কোনো তৃতীয় পক্ষের উপর বিশ্বাস প্রয়োজন নেই।
ছেঁড়াছেঁড়ি সনাক্ত করার জন্য নোটবুকে:
tool_args_hash ফিল্ডের একটি বাইট পরিবর্তন করা।এটাই প্রমাণ যে রসীদগুলো ট্যাম্পার-ইভিডেন্ট: যেকোনো ছোট পরিবর্তন সিগনেচার ভেঙে দেয়।
একটি সাইন করা রসীদ একটি কাজ সুরক্ষিত করে। রসীদ চেইন একটি ক্রম সুরক্ষিত করে।
flowchart LR
R0[রসিদ 0<br/>উত্পত্তি] --> R1[রসিদ 1]
R1 --> R2[রসিদ 2]
R2 --> R3[রসিদ 3]
R1 -. previous_receipt_hash .-> R0
R2 -. previous_receipt_hash .-> R1
R3 -. previous_receipt_hash .-> R2
প্রতিটি রসীদ পূর্ববর্তী রসীদটির হ্যাশ রেকর্ড করে। একটি চেইনের মধ্য থেকে ২ নম্বর রসীদ ছুটে ফেলার জন্য, একজন আক্রমণকারীকে বা:
previous_receipt_hash ফিল্ড পরিবর্তন করতে হবে (রসীদ ৩-এর সিগনেচার ভেঙে যায়), অথবাযদি প্রাইভেট কী হার্ডওয়্যার কী ভল্টে থাকে এবং আপনি প্রতিটি রসীদ সহ পাবলিক কী প্রকাশ করেন, তাহলে কোনো আক্রমণ অদৃশ্য ছাড়াই সম্ভব নয়।
নোটবুকে দেখানো হয়েছে:
previous_receipt_hash যাচাই করা যে এটি প্রকৃত পূর্ববর্তী রসীদটির হ্যাশ মেলে।এভাবেই আপনি একটি অডিট ট্রেইল তৈরি করেন যা বাহ্যিক অডিটর বিশ্বাস ছাড়াই যাচাই করতে পারে।
এই অংশ লেসনের সবচেয়ে গুরুত্বপূর্ণ। রসীদ শক্তিশালী কিন্তু তাদের ক্ষমতা সীমিত।
রসীদ তিনটি বিষয় প্রমাণ করে:
রসীদ প্রমাণ করে না:
policy_id এর নীতিমালা সত্যিই মূল্যায়ন করা হয়েছে বা পরীক্ষা করলে অনুমতি দিত কিনা। রসীদ যা দাবি করছে সেটাই রেকর্ড করে, পালন করা কি হয়নি।এই সীমা গুরুত্বপূর্ণ কারণ:
একটি সাধারণ ভুল ধারণা হলো “আমাদের রসীদ আছে” মানে “আমাদের শাসিত”। তা নয়। রসীদ হলো ভিত্তি। শাসন হলো সেই ব্যবস্থা যা আপনি তার উপরে তৈরি করেন।
এই লেসনের পাইথন কোড ইচ্ছাকৃতভাবে সহজ করা, যাতে আপনি প্রতিটি লাইন পড়ে সঠিকভাবে বুঝতে পারেন। প্রোডাকশনে আপনার দুটি বিকল্প আছে:
ক্রিপ্টোগ্রাফিক প্রিমিটিভস সরাসরি ব্যবহার করুন। উপরে দেখানো ৫০ লাইন অনেক ব্যবহারকারীর জন্য যথেষ্ট। PyNaCl (Ed25519) এবং jcs প্যাকেজ (ক্যানোনিকাল JSON) ভাল রক্ষণাবেক্ষণ করা ও অডিট করা লাইব্রেরি।
একটি প্রোডাকশন রসীদ লাইব্রেরি ব্যবহার করুন। বেশ কয়েকটি ওপেন-সোর্স প্রকল্প একই প্যাটার্ন অন্যান্য বৈশিষ্ট্য (কী রোটেশন, ব্যাচ যাচাই, JWK সেট বিতরণ, নীতিমালা ইঞ্জিন ইন্টিগ্রেশন) সহ বাস্তবায়ন করে:
draft-farley-acta-signed-receipts) যা বর্তমানে স্ট্যান্ডার্ড প্রক্রিয়াধীন।protect-mcp (npm) এবং @veritasacta/verify (npm) প্যাকেজগুলো Node-ভিত্তিক রসীদ সাইনিং ও অফলাইন যাচাই প্রদান করে, যেকোন MCP সার্ভারকে ট্যাম্পার-ইভিডেন্ট অডিট ট্রেইল দিয়ে মোড়াতে।pip install nobulex) একই Ed25519 + JCS সাইনিং প্যাটার্ন পাইথন-এ LangChain এবং CrewAI ইন্টিগ্রেশনের সাথে দেয়, প্রকাশিত ক্রস-ভ্যালিডেশন টেস্ট ভেক্টরস এবং OWASP PR #2210 এর মাধ্যমে কমপ্লায়েন্স ম্যাপিং দিয়ে।নিজের JWT লাইব্রেরি লেখার এবং পরীক্ষিত একটি ব্যবহার করার তুলনা মত, নিজের রসীদ ইমপ্লিমেন্ট করা এবং একটি লাইব্রেরি ব্যবহার করার সিদ্ধান্তও একই: উভয়ই যুক্তিযুক্ত; লাইব্রেরি সময় বাঁচায় এবং অডিট সারফেস কমায়; from-scratch পন্থা সব প্রিমিটিভ বোঝার সুযোগ দেয়। এই লেসন from-scratch পদ্ধতি শেখায় যাতে যেকোনো পথের জন্য ভিত্তি থাকে।
চর্চার ধাপে যাওয়ার পূর্বে আপনার বোঝামত যাচাই করুন।
১. একটি রসীদ এজেন্টের প্রাইভেট Ed25519 কী দিয়ে সাইন করা হয়। অডিটরের কাছে শুধুমাত্র পাবলিক কী আছে। অডিটার কি রসীদ অফলাইনে যাচাই করতে পারে?
২. একজন আক্রমণকারী একটি রসীদ এর policy_id ফিল্ড পরিবর্তন করে দাবি করে এটি একটি বেশি অনুমতিপ্রদানকারী নীতিমালা দ্বারা শাসিত ছিল। সিগনেচার মূল পে-লোডের উপর ছিল। যাচাইয়ের সময় কী হয়?
৩. রসীদ tool_args_hash এবং result_hash অন্তর্ভুক্ত করে সরাসরি আর্গুমেন্ট এবং ফলাফল না দিয়ে কেন?
৪. previous_receipt_hash প্রতিটি রসীদকে তার পূর্বসূরীর সাথে যুক্ত করে। যদি একজন আক্রমণকারী চেইনের মাঝখান থেকে একটি রসীদ চুপচাপ মুছে ফেলে, তাহলে কী অবৈধ হয়ে যায়?
৫. একটি রসীদ পরিষ্কারভাবে যাচাই করা হয়েছে। এটা কি প্রমাণ করে যে এজেন্টের কাজ সঠিক, সাউন্ড, বা নীতিমালা অনুসারে ছিল?
code_samples/18-signed-receipts.ipynb খুলুন এবং চারটি সেকশন সম্পন্ন করুন:
স্ট্রেচ চ্যালেঞ্জ ২: আপনার দুটি রসিদের SHA-256 হ্যাশ করুন (তাদের ক্যানোনিক্যাল বাইটসমূহ একটি নির্ধারিত ক্রমে সংযুক্ত করুন) এবং তৃতীয় রসিতে স্বাক্ষর করার আগে নতুন ক্ষেত্র হিসেবে প্রাপ্ত ডাইজেস্টটি এমবেড করুন। যাচাই করুন যে সব তিনটি রসিদ এখনও সঠিকভাবে যাচাই হচ্ছে। আপনি ঠিক এখনই একটি এক-ধাপের অন্তর্ভুক্তি প্রমাণ তৈরি করেছেন: তৃতীয় রসিদ যার কাছে আছে সে প্রথম দুইটি রসিদ সই করার সময় অবস্থিত ছিল তা প্রমাণ করতে পারে, তাদের বিষয়বস্তু প্রকাশ না করেই। এইটাই সেই প্যাটার্ন যা নির্বাচিত-বা-চাপান রসিদ বড় পরিসরে ব্যবহার করে (মার্কেল কমিটমেন্ট, RFC 6962)।
ক্রিপ্টোগ্রাফিক রসিদগুলি AI এজেন্টদের জন্য একটি অডিট ট্রেইল প্রদান করে যা:
এসব ইনপুট যাচাই, নীতি প্রয়োগ বা পরিচয় পরিকাঠামোর বিকল্প নয়। এগুলো ঐ স্তরগুলোর ভিত্তি। যখন আপনি নিয়ন্ত্রিত ওয়ার্কলোডে, বহু-সংগঠনমূলক ওয়ার্কফ্লোতে, বা যেকোনো পরিবেশে যেখানে ভবিষ্যতের অডিটর আপনাকে বিশ্বাস করবে না, তখন রসিদই হবে যেভাবে আপনি অডিট ট্রেইলটিকে সৎ রাখতে পারবেন।
সবচেয়ে গুরুত্বপূর্ণ বিষয়: রসিদ প্রমাণ করে কে কি বলেছে, কখন। তারা প্রমাণ করে না যে যা বলা হয়েছে তা সত্য বা সঠিক। এই পার্থক্যটি কঠোরভাবে ধরুন। এটি সৎ উৎস পদ্ধতি এবং বিভ্রান্তিকর একটি ব্যবস্থার মধ্যে পার্থক্য।
এই পাঠ থেকে সন্ন্যাস নেয়ার পর যখন আপনি রসিদ-স্বাক্ষরযুক্ত এজেন্ট বাস্তব পরিবেশে মোতায়েন করবেন:
https://your-org.example.com/.well-known/agent-keys.json।অন্যান্য শিক্ষার্থীদের সাথে সাক্ষাৎ করার জন্য, অফিস আওয়ার এ অংশগ্রহণ করতে, এবং আপনার AI এজেন্ট সম্পর্কিত প্রশ্নের উত্তর পেতে Microsoft Foundry Discord এ যোগ দিন।
এই পাঠে একক-রসিদ সাইনিং এবং হ্যাশ-চেইনযুক্ত সিকুয়েন্স কভার করা হয়েছে। একই প্রিমিটিভগুলো আরও কয়েকটি উন্নত প্যাটার্নে গঠিত যা আপনি আপনার গভর্নেন্স অবস্থান পরিপক্ক হলে দেখতে পারেন:
authorization_*) এবং পর-কর্মসংস্থান (result_*) অর্ধেক আকারে ভাগ করে স্বতন্ত্র স্বাক্ষর নিয়ে, যা সাহায্য করে যখন অনুমোদন সিদ্ধান্ত এবং পর্যবেক্ষিত ফলাফল আলাদা অভিনেতা বা সময়ে উৎপন্ন হয়। এটি এই পাঠে শেখানো রসিদ ফরম্যাটের ওপর অতিরিক্ত সংযোজন।result_hash এ যা কিছু বাইট দেন তা সীল মুদ্রণ করে। বাস্তব পে-লোড প্রায়শই একক টুল কল রেজাল্টের চেয়েও সমৃদ্ধ: পূর্ব-সিদ্ধান্ত যুক্তি(মডেল অনুমান, বিবেচিত বিকল্প, প্রমাণ ও তার সম্পূর্ণতা, ঝুঁকি অবস্থা, দায়িত্ব চেইন, গেট আউটকাম) সবই পে-লোডের ভিতরে থাকতে পারে, যা একটি রসিদ দ্বারা সীলবদ্ধ। এটি রসিদ ফরম্যাটকে নূন্যতম রাখে এবং পে-লোড স্কিমাগুলো ডোমেনভিত্তিক বিকাশের সুযোগ দেয়।signature.alg ক্ষেত্র ML-DSA-65 (নিস্ট পোস্ট-কোয়ান্টাম স্বাক্ষর স্ট্যান্ডার্ড) ধারণ করতে পারে যখন আপনি মাইগ্রেট করতে চান। একটি রূপান্তর সময়ের পরিকল্পনা করুন যেখানে রসিদ দ্বৈত স্বাক্ষরযুক্ত থাকবে।কম্পিউটার ইউজ এজেন্ট নির্মাণ (CUA)
(পাঠক্রম রক্ষণাবেক্ষকদের দ্বারা নির্ধারিত হবে)
অস্বীকৃতি: এই নথিটি AI অনুবাদ পরিষেবা Co-op Translator ব্যবহার করে অনূদিত হয়েছে। যদিও আমরা শুদ্ধতার জন্য চেষ্টা করি, অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল নথিটি তার স্বভাষায় কর্তৃত্বপূর্ণ উৎস হিসেবে বিবেচিত হওয়া উচিত। গুরুত্বপূর্ণ তথ্যের জন্য পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদের ব্যবহারে প্রয়োজনীয় ভুল বোঝাবুঝি বা ভুল ব্যাখ্যার জন্য আমরা দায়বদ্ধ নই।