এই পর্বে যা শিখবেন
- কোনটি secret, কোনটি config, আর secret সাধারণত কোন পাঁচ পথে ফাঁস হয়
- KMS-এর key policy, grant আর audit trail, আর envelope encryption-এর পুরো পথ
- Data-key caching-এ KMS বিল কতটা কমে, আর তার দাম কী
- Rotation কী করে আর কী করে না, crypto-erasure কখন চলে
- Downtime ছাড়া database password বদলানো আর ফাঁস হওয়া key সামলানো
১ · Secret কী, আর সেটি কোন পথে বেরিয়ে যায়
একটি কাল্পনিক অনলাইন বাজার অ্যাপের কথা ভাবুন। ডেভেলপার তাড়াহুড়োয় database password কোডে লিখে দিলেন। কোড গেল Git-এ, Git থেকে Docker image-এ, image থেকে দশটি server-এ। এখন সেই একটি password কোথায় কোথায় আছে, কেউ বলতে পারে না।
Secret হলো এমন যেকোনো তথ্য, যা হাতে পেলেই কেউ আপনার পরিচয়ে কিছু করতে পারে। Database password, API key, access key, TLS private key, SSH key, webhook signing secret, OAuth client secret, সবই secret. চেনার সহজ পরীক্ষা হলো, “এটি প্রকাশ্যে ছাপা হলে কি আজই কিছু বদলাতে হবে?” উত্তর হ্যাঁ হলে সেটি secret.
বাড়ির ঠিকানা সবাই জানতে পারে, কিন্তু তালার চাবি পারে না। ঠিকানা হলো config, চাবি হলো secret. আর চাবি হারালে নতুন চাবি বানানোই যথেষ্ট নয়, তালাটিই বদলাতে হয়। Secret-এর বেলাতেও তাই।
Secret সাধারণত হ্যাকিং করে চুরি হয় না, ভুল জায়গায় পড়ে থাকে। পাঁচটি পথ বারবার দেখা যায়:
| পথ | কীভাবে ঘটে | ঠিক উপায় |
|---|---|---|
| Repository | Commit-এ .env; পরে মুছলেও history-তে থেকে যায় | Secret scanning, push-এ বাধা |
| Container বা VM image | Build-এ কপি করা ফাইল আগের layer-এ রয়ে যায় | Build-এ secret নয়; চলার সময় আনা |
| Log | Debug log-এ পুরো request, header বা connection string | Log-এ redaction; token লেখা বন্ধ |
| Environment dump | Crash report বা debug page-এ সব environment variable, CI-এর env আউটপুট | Dump-এ ছাঁকনি; CI-এ masking |
| User data | Boot script-এ password; metadata থেকে পড়া যায় | শুধু secret-এর নাম রাখা (পর্ব ১৬) |
Git-এ secret ফাঁসের পুরো বিবরণ আছে Git নিরাপত্তা পর্বে। এখানে আমরা দেখব cloud-এ কীভাবে secret রাখা আর চালানো হয়।
২০১৯ সালে NDSS সম্মেলনে Meli, McNiece আর Reaves-এর গবেষণা “How Bad Can It Git?” দেখায়, public GitHub-এ দিনে হাজার হাজার নতুন secret ফাঁস হচ্ছিল। আর ২০২১ সালের Codecov ঘটনায় প্রতিষ্ঠানটির প্রকাশিত বিবরণ অনুযায়ী, Docker image বানানোর একটি ভুল থেকে একটি credential বেরিয়ে যায়। সেটি দিয়ে তাদের upload script বদলে গ্রাহকদের CI-এর environment variable বাইরে পাঠানো হয়।
২ · Encryption-এর তিন অবস্থা — রাখা, পথে আর ব্যবহারে
Secret রাখার আগে encryption কী পাহারা দেয়, তা বুঝে নিন। Plaintext হলো খোলা ডেটা, আর ciphertext হলো key ছাড়া অর্থহীন ডেটা। ডেটা তিন অবস্থায় থাকে, আর প্রতিটির পাহারা আলাদা। AES, HMAC আর public key-এর গণিত Cryptography-র ভিত্তি পর্বে আছে। এখানে শুধু মনে রাখুন, AES হলো symmetric encryption: একই key দিয়ে লক আর খোলা।
রাখা অবস্থায়
Encryption at rest ডিস্ক, snapshot আর backup-এর ডেটা পাহারা দেয়। ডিস্ক চুরি গেলেও ডেটা পড়া যায় না।
Disk, bucket, databaseপথে থাকা অবস্থায়
Encryption in transit network-এর ডেটা পাহারা দেয়, সাধারণত TLS দিয়ে। মাঝখানের কেউ পড়তে বা বদলাতে পারে না। বিস্তারিত TLS ও HTTPS পর্বে।
TLS, VPNব্যবহারের সময়
Encryption in use চলতে থাকা memory পাহারা দেয়। এটি confidential computing-এর এলাকা: CPU-র ভেতরের সুরক্ষিত অঞ্চল।
Provider ও CPU-ভেদে আলাদাEncryption at rest কী ঠেকায় না: অনুমতি থাকা পরিচয়কে। আপনার app-এর role ফাঁস হলে আক্রমণকারী সেই role হয়েই ডেটা চাইবে, আর cloud নিজে থেকেই decrypt করে দেবে। ডিস্ক encrypted, তবু ডেটা বেরিয়ে গেল। Encryption অনুমতির বিকল্প নয়, সঙ্গী। অনুমতির হিসাব পর্ব ৩২ · IAM policy evaluation-এ।
৩ · KMS — যে চাবি ঘর ছাড়ে না
ডেটা encrypt করলে নতুন প্রশ্ন আসে, key কোথায় রাখবেন? Key ডেটার পাশে রাখলে তালার পাশে চাবি ঝুলিয়ে রাখার মতো হয়। KMS (Key Management Service) এর উত্তর। এটি provider-এর চালানো একটি service, যা key রাখে আর আপনার হয়ে key ব্যবহার করে। মূল কথা হলো, key আপনার কাছে আসে না, আপনার অনুরোধ key-এর কাছে যায়।
ব্যাংকের সিলমোহর ভাবুন। কর্মকর্তা সিলটি কাউকে দেন না। আপনি কাগজ নিয়ে যান, তিনি পরিচয় দেখেন, খাতায় নাম লেখেন, তারপর নিজের হাতে সিল মারেন। KMS-ও তাই করে: পরিচয় যাচাই, log, তারপর কাজ।
KMS-এর চারটি অংশ জানলেই বাকিটা সহজ হয়:
- Key যা বের হয় না: সাধারণ KMS key-এর গোপন অংশ provider-এর সুরক্ষিত hardware-এর বাইরে খোলা অবস্থায় আসে না। আপনি পাঠান ডেটা, ফেরত পান ফল। Provider ও key-এর ধরনভেদে এর ব্যতিক্রম থাকতে পারে, যেমন নিজের আনা key material.
- Key policy: কে এই key ব্যবহার করবে আর কে পরিচালনা করবে, তার নিয়ম। AWS-এ প্রতিটি key-এর নিজের policy থাকে, আর সেটি অনুমতি না দিলে IAM policy একা যথেষ্ট নয়। Google Cloud আর Azure-এ একই কাজ হয় key-এর ওপর IAM বা role দিয়ে।
- Grant: AWS-এর শব্দ। একটি service বা role-কে নির্দিষ্ট কাজের সাময়িক অনুমতি, যা policy না বদলে দেওয়া আর ফেরত নেওয়া যায়। যেমন disk service-কে শুধু ওই volume-এর জন্য key ব্যবহারের অধিকার।
- Audit trail: প্রতিটি key ব্যবহার audit log-এ যায়: কে, কখন, কোন key, কোন কাজ, সফল কি না। Password একবার পড়লে কোনো চিহ্ন থাকে না, কিন্তু KMS-এর প্রতিটি decrypt-এর চিহ্ন থাকে।
কাজের ভাগ আলাদা রাখুন। যিনি key পরিচালনা করেন (rotation, মুছে ফেলা), তিনি ডেটা decrypt করবেন না। আর যে app decrypt করে, সে key মুছতে পারবে না। নিচের key policy অংশে app শুধু দুটি কাজ পায়:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AppUsesKeyOnly",
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::123456789012:role/shop-app" },
"Action": ["kms:GenerateDataKey", "kms:Decrypt"],
"Resource": "*",
"Condition": {
"StringEquals": { "kms:ViaService": "s3.ap-south-1.amazonaws.com" }
}
}
]
}এখানে "Resource": "*" দেখে ঘাবড়াবেন না: key policy-তে এর মানে শুধু এই key. kms:ViaService বলছে, অনুরোধ আসতে হবে S3-র মাধ্যমে। সম্পূর্ণ policy-তে key পরিচালকের জন্য আলাদা statement-ও লাগে, নইলে key নিজেই অচল হয়ে যেতে পারে।
| ধারণা | AWS | Azure | Google Cloud |
|---|---|---|---|
| Key service | AWS KMS | Key Vault | Cloud KMS |
| Key-এর অনুমতি | Key policy, grant, IAM | Azure RBAC বা access policy | Key-এর ওপর IAM |
| ব্যবহারের log | CloudTrail | Azure Monitor diagnostic log | Cloud Audit Logs |
| Secret service | Secrets Manager | Key Vault secrets | Secret Manager |
| HSM সেবা | CloudHSM | Managed HSM | Cloud HSM |
৪ · Envelope encryption — খামের ভেতরে চাবি
KMS-কে সব ডেটা পাঠিয়ে encrypt করালে তিনটি সমস্যা হয়। KMS সরাসরি শুধু ছোট ডেটা নেয় (AWS-এ লেখার সময়ে symmetric key-এ প্রায় ৪ KB). ১০ GB ফাইল network-এ আনা-নেওয়া ধীর। আর প্রতিটি কাজে KMS-এর ডাক পড়লে বিলও বাড়ে। সমাধান হলো envelope encryption.
গুদামঘরের প্রতিটি আলমারির আলাদা তালা। প্রতিটি চাবি একটি খামে ভরে সিল করে আলমারির গায়েই সেঁটে দেওয়া হলো। সিল খুলতে পারেন শুধু ব্যাংকের কর্মকর্তা। আলমারি হাজারটি হোক, সিল থাকে একটিই, আর সেটি ব্যাংক ছাড়ে না। খামসহ আলমারি চুরি হলেও খাম খোলা যাবে না।
চাবি থাকে দুই স্তরে। Data key (DEK) ডেটাকে encrypt করে, আর প্রতিটি object বা ছোট দলের জন্য আলাদা হতে পারে। Key-encryption key (KEK) শুধু data key-কে encrypt করে, আর KMS-এর ভেতরে থাকে। Encrypt করা data key-কে বলে wrapped key, যা ciphertext-এর পাশেই নিরাপদে রাখা যায়।
চাবির স্তর — ওপরেরটি নিচেরটিকে পাহারা দেয়
Envelope encryption key hierarchy
এবার একটি বিল লেখা আর পড়ার পুরো পথ দেখুন। মানগুলো নিচের খেলনা কোড থেকে নেওয়া, আসল key এত ছোট হয় না।
| App-এর memory | |
| Storage | |
| Audit log | |
| ফল |
- Data key চাওয়া। App নিজের role দিয়ে KMS-কে বলল, একটি নতুন data key দিন। KMS অনুমতি দেখে log-এ লিখল।
- দুই কপি। KMS ফেরত দিল একই key-এর দুই রূপ: plain
72d14497আর KEK দিয়ে লক করাfe6cda93. KEK নিজে KMS-এর ভেতরেই রইল। - App-এর ভেতরে encrypt. বিলটি app নিজেই plain key দিয়ে encrypt করল। ১০ GB ফাইল হলেও KMS-এ কিছু যায় না।
- রেখে দেওয়া আর মোছা। Ciphertext আর wrapped key পাশাপাশি storage-এ গেল। Plain key memory থেকে মুছে ফেলা হলো। Storage-এ এখন কোনো খোলা key নেই।
- পড়ার শুরু। পরে অন্য একটি app instance object আনল। Wrapped key সাথেই এলো, তবে এটি এখনো লক করা।
- খাম খোলার অনুরোধ। App wrapped key পাঠাল KMS-এ। KMS আবার অনুমতি দেখল, আর log-এ
Decrypt OKযোগ হলো। প্রতিটি পড়ার চিহ্ন এভাবেই থাকে। - পড়া শেষ। KMS plain key ফেরত দিল, app memory-তে decrypt করল, ফল
bill-1042 BDT 750. তারপর plain key মুছে গেল। - অনুমতি নেই।
intern-roleএকই wrapped key পাঠাল। KMS ফিরিয়ে দিল, আর এই ব্যর্থ চেষ্টাও log-এ রইল। Storage পড়তে পারলেও key ছাড়া ciphertext অর্থহীন।
এবার নিজে চালান। এখানে KMS একটি ছোট object. XOR-এর এই খেলনা cipher আসল encryption নয়, শুধু পথটি দেখানোর জন্য। বাস্তবে AES-256-GCM-এর মতো পরীক্ষিত algorithm ব্যবহার হয়।
// Envelope flow with a TOY XOR cipher. XOR with a short key is NOT real encryption.
const hex = b => b.map(x => x.toString(16).padStart(2, '0')).join('');
const xor = (bytes, key) => bytes.map((b, i) => b ^ key[i % key.length]);
const bytesOf = s => [...s].map(c => c.charCodeAt(0));
const textOf = b => b.map(c => String.fromCharCode(c)).join('');
function mulberry32(a) { return () => { a = (a + 0x6D2B79F5) | 0;
let t = Math.imul(a ^ (a >>> 15), 1 | a); t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; }
const rand = mulberry32(33);
const newKey = () => Array.from({ length: 4 }, () => Math.floor(rand() * 256));
const kms = { kek: newKey(), allowed: new Set(['app-role']), audit: [],
check(who, op) { const ok = this.allowed.has(who);
this.audit.push(`${who} ${op} ${ok ? 'OK' : 'DENIED'}`);
if (!ok) throw new Error('AccessDenied'); },
generateDataKey(who) { this.check(who, 'GenerateDataKey'); const plain = newKey();
return { plain, wrapped: xor(plain, this.kek) }; },
decrypt(who, wrapped) { this.check(who, 'Decrypt'); return xor(wrapped, this.kek); } };
function write(text) { const dk = kms.generateDataKey('app-role');
const stored = { wrapped: dk.wrapped, data: xor(bytesOf(text), dk.plain) };
console.log('plain data key', hex(dk.plain), '(wiped after use)');
return stored; }
function read(who, obj) { return textOf(xor(obj.data, kms.decrypt(who, obj.wrapped))); }
const bill = write('bill-1042 BDT 750');
console.log('stored wrapped ', hex(bill.wrapped));
console.log('stored data ', hex(bill.data));
console.log('read by app-role:', read('app-role', bill));
try { read('intern-role', bill); } catch (e) { console.log('read by intern-role:', e.message); }
console.log('audit trail:\n ' + kms.audit.join('\n '));stored data আর stored wrapped-এর কোনোটিতে খোলা key নেই, তবু read by app-role: bill-1042 BDT 750 এলো। কারণ app-এর হয়ে KMS খাম খুলেছে। read by intern-role: AccessDenied দেখায়, একই ciphertext হাতে থাকলেও অনুমতি ছাড়া কিছু হয় না। শেষের তিন লাইনের audit trail-এ ব্যর্থ চেষ্টাও আছে: intern-role Decrypt DENIED.
কেন এটি বড় আকারে চলে
- গতি: ডেটার কাজ app-এর পাশেই হয়, আর AES দ্রুত। KMS শুধু ছোট key নিয়ে কাজ করে।
- ক্ষতির সীমা: একটি data key ফাঁস হলে শুধু তার ডেটা খোলা হয়, সব নয়। এটি blast radius ছোট রাখে।
- সহজ re-wrap: KEK বদলাতে ডেটা ছুঁতে হয় না, শুধু খাম নতুন করে সিল করলেই চলে।
শেষেরটির হিসাব দেখুন। ধরে নিই ১ PB ডেটায় ১ কোটি object. সেকেন্ডে ১ GB গতিতে পুরো ডেটা নতুন করে encrypt করতে লাগবে 10¹⁵ ÷ 10⁹ = 10⁶ সেকেন্ড, মানে প্রায় ১১.৬ দিন। অন্যদিকে সেকেন্ডে ১,০০০টি KMS call-এ ১ কোটি wrapped key বদলাতে লাগবে 10,000 সেকেন্ড, মানে প্রায় ২.৮ ঘণ্টা।
Re-wrap কখন যথেষ্ট নয়: রুটিন বদলের জন্য re-wrap ঠিক আছে। কিন্তু data key নিজেই ফাঁস হলে, বা কেউ পুরোনো KEK দিয়ে খাম খুলে ফেলেছে সন্দেহ হলে, খাম বদলে লাভ নেই। তখন নতুন data key দিয়ে ডেটা আবার encrypt করতে হবে।
গোপন রাখা আর বদল ধরা আলাদা কাজ
Encryption ডেটা লুকায়, কিন্তু ডেটা কেউ বদলেছে কি না, তা আলাদা প্রশ্ন। AES-GCM-এর মতো AEAD এই দুটি কাজ একসাথে করে। Python-এর standard library-তে AES নেই, তাই নিচের কোডে শুধু বদল ধরার অংশটি HMAC দিয়ে দেখানো হলো। এটি encryption নয়, ডেটা খোলাই থাকে।
# Integrity only: HMAC detects a change, it hides nothing.
# Python's standard library has no AES, so this is NOT encryption.
import hashlib
import hmac
KEY = b"demo-key-not-a-real-secret" # fake, for this demo only
def tag(context, body):
message = context.encode() + b"\n" + body
return hmac.new(KEY, message, hashlib.sha256).hexdigest()
def verify(context, body, expected):
return hmac.compare_digest(tag(context, body), expected)
body = b"bill-1042 amount=750"
saved_tag = tag("tenant=dhaka-shop", body)
print("body stays readable:", body.decode())
print("tag:", saved_tag[:16], "...", len(saved_tag) * 4, "bits")
print("same body :", verify("tenant=dhaka-shop", body, saved_tag))
changed = b"bill-1042 amount=150"
print("amount changed :", verify("tenant=dhaka-shop", changed, saved_tag))
print("moved to tenant 2:", verify("tenant=khulna-shop", body, saved_tag))
KEY = b"another-demo-key"
print("different key :", verify("tenant=dhaka-shop", body, saved_tag))body stays readable লাইনই প্রমাণ যে কিছু লুকানো হয়নি। amount changed : False মানে টাকার অঙ্ক বদলানো ধরা পড়েছে। moved to tenant 2: False বেশি কৌতূহলের: ডেটা অক্ষত, শুধু অন্য গ্রাহকের ঘরে সরানো হয়েছে, তাও ধরা পড়ল। KMS-এর encryption context একই ধারণা, যেখানে ciphertext একটি নির্দিষ্ট প্রসঙ্গে বাঁধা থাকে। compare_digest ব্যবহার হয়েছে কারণ এটি সময়ের পার্থক্য থেকে তথ্য ফাঁস হতে দেয় না।
৫ · KMS call-এর বিল আর data-key caching
Envelope encryption ডেটা KMS-এ পাঠায় না, কিন্তু প্রতিটি object-এ একটি KMS call করলে বিল আর গতি দুটোই ভোগায়। Data-key caching-এ app একটি data key কিছুক্ষণ memory-তে রেখে অনেক object-এ ব্যবহার করে। হিসাব দেখি। সব দাম ধরে নেওয়া, আসল দাম provider-এর pricing পাতায় দেখুন।
- ধরে নিই KMS-এর দাম প্রতি ১০,০০০ call-এ $০.০৩
- চাপ সেকেন্ডে ১০০টি object, ১০টি app instance-এ সমান ভাগে (প্রতিটিতে সেকেন্ডে ১০টি)
- ৩০ দিনের মাস = 2,592,000 সেকেন্ড; প্রতিটি instance-এর নিজের data key
| Cache মেয়াদ | |
| KMS call/মাস | |
| KMS বিল | |
| KMS call/সেকেন্ড | |
| এক key-এ object |
- Cache নেই। প্রতি object-এ একটি call: ২৫.৯২ কোটি call, বিল ২৫,৯২০ × $০.০৩ = $৭৭৭.৬০. আবার সেকেন্ডে ১০০ call KMS-এর quota-ও ছুঁতে পারে। তবে এক key-এ ডেটা মাত্র একটি object.
- ১ মিনিট। ১০টি instance প্রতি মিনিটে একটি করে call করে: ৪,৩২,০০০ call, বিল প্রায় $১.৩০. বিল প্রায় ৬০০ ভাগের ১ ভাগ হলো। কিন্তু এক key এখন ১০ × ৬০ = ৬০০টি object ঢাকে।
- ৫ মিনিট। ৮৬,৪০০ call, বিল প্রায় $০.২৬. এক key ঢাকে ১০ × ৩০০ = ৩,০০০ object. সাধারণ কাজে এই ধরনের মেয়াদ একটি ভালো শুরু, তবে নিজের ঝুঁকি মেপে ঠিক করুন।
- ১ ঘণ্টা। ৭,২০০ call, বিল প্রায় $০.০২. আগের ধাপের চেয়ে সাশ্রয় মাত্র ২৪ সেন্ট, কিন্তু এক key এখন ৩৬,০০০ object ঢাকে, আর plain key এক ঘণ্টা memory-তে থাকে। এই সাশ্রয় এমন ঝুঁকির যোগ্য নয়।
সূত্রটি হলো, মাসিক call = instance × মাসের সেকেন্ড ÷ cache-এর মেয়াদ। দাম নিজের সংখ্যায় বসিয়ে নিন। Provider-ও এই সমস্যা দেখেছে: S3-র Bucket Key একটি bucket-স্তরের মধ্যবর্তী key রেখে KMS call কমায়। AWS Encryption SDK-তেও data-key caching-এর ব্যবস্থা আছে।
Cache-এর দাম টাকায় নয়, ঝুঁকিতে। মেয়াদ, object-সংখ্যা আর ব্যবহারের পরিমাণ, তিনটিরই সীমা রাখুন। পড়ার দিকেও cache কাজ করে কেবল একই wrapped key হলে, কারণ প্রতিটি আলাদা wrapped key-এর জন্য আলাদা Decrypt লাগে। আর KMS-এর audit log-এ তখন প্রতিটি object-এর চিহ্ন থাকে না।
৬ · কার হাতে চাবি, rotation আর crypto-erasure
Provider-managed থেকে external key
| ধরন | কে নিয়ন্ত্রণ করে | কখন |
|---|---|---|
| Provider-managed key | Provider; আপনি শুধু চালু করেন | সাধারণ ডেটা, কম ঝামেলা |
| Customer-managed key | আপনি: policy, rotation, বন্ধ করা, মোছা | নিয়ন্ত্রণ আর audit দরকার হলে; ক্ষমতার সাথে ভুলের ঝুঁকিও আপনার |
| BYOK | Key material আপনি বানিয়ে KMS-এ আনেন | Key-এর উৎস নিয়ে নিয়মের চাহিদা থাকলে |
| External key | Key থাকে cloud-এর বাইরে আপনার ব্যবস্থায় | কড়া সার্বভৌমত্বের চাহিদায়; সেবা, নাম আর সীমা provider-ভেদে আলাদা |
External key-এর দাম আছে। বাইরের ব্যবস্থা বন্ধ হলে cloud-এর ডেটাও অচল হয়, আর প্রতিটি call-এ latency বাড়ে। তাই এটি শুধু তখনই নিন, যখন নিয়মে সত্যিই দরকার।
HSM (Hardware Security Module) হলো key রাখার জন্য বানানো আলাদা hardware. কেউ খুলতে চাইলে এটি key নষ্ট করে দিতে পারে, আর key-এর কাজ এর ভেতরেই হয়। অনেক provider-এর সাধারণ KMS-এর পেছনেও HSM থাকে, তবে তা বহু গ্রাহকে ভাগ করা। নিজস্ব HSM নেওয়া হয় নিয়মের চাপে, আর এতে পরিচালনার ঝামেলা বাড়ে। মান যাচাইয়ের সাধারণ মানদণ্ড হলো FIPS 140.
Key rotation — কী করে আর কী করে না
Key rotation মানে KEK-এর ভেতরের key material বদলানো। AWS KMS-এ automatic rotation-এ key-এর ID একই থাকে, আর পুরোনো material decrypt-এর জন্য রয়ে যায়। ডিফল্ট মেয়াদ এক বছর, তবে লেখার সময়ে ৯০ থেকে ২,৫৬০ দিনের মধ্যে ঠিক করা যায়। Google Cloud KMS-এ এটি নতুন key version, আর Azure Key Vault-এ rotation policy. Ciphertext-এ লেখা থাকে কোন version লেগেছে, তাই পুরোনো ডেটা পড়া চলতেই থাকে।
| Rotation করে | Rotation করে না |
|---|---|
| নতুন ডেটায় নতুন key material ব্যবহার করে | পুরোনো ডেটা নতুন করে encrypt করে না |
| এক key material-এ ঢাকা ডেটার পরিমাণ সীমিত রাখে | ফাঁস হওয়া পুরোনো material-কে অকেজো করে না |
| নিয়মের চাহিদা মেটাতে সাহায্য করে | কার অনুমতি আছে, তা বদলায় না |
| পুরোনো ciphertext পড়া চালু রাখে | ফাঁস হওয়া role বা password ঠিক করে না |
Crypto-erasure — চাবি মুছলে ডেটা শেষ
Backup, replica আর snapshot-এ ছড়ানো ডেটা খুঁজে খুঁজে মোছা কঠিন। Crypto-erasure-এ ডেটা নয়, key নষ্ট করা হয়। Key না থাকলে সব ciphertext অর্থহীন। NIST SP 800-88 (Rev. 1, ২০১৪) একে “Cryptographic Erase” নামে স্বীকৃতি দেয়। প্রতি গ্রাহকে আলাদা key থাকলে একজনের ডেটা এভাবে মুছে ফেলা যায়, অন্যদের গায়ে হাত না দিয়েই।
এই পথ একমুখী। তাই provider সাধারণত অপেক্ষার সময় রাখে: AWS-এ লেখার সময়ে ৭ থেকে ৩০ দিন, Azure-এ soft-delete, Google Cloud-এ destroy-এর আগে নির্ধারিত সময়। আগে key বন্ধ করে দেখুন কেউ অভিযোগ করে কি না, তারপর মোছার সূচি দিন। মোছার অধিকার খুব কম মানুষকে দিন, আর এই কাজে alarm রাখুন। Key মোছার ক্ষমতা ফাঁস হলে তা ডেটা নষ্ট করার ক্ষমতাও হয়ে দাঁড়ায়।
৭ · Secret manager — চলার সময় আনা, config আর dynamic credential
KMS key পাহারা দেয়, কিন্তু database password-এর মতো জিনিস কে রাখবে? Secret manager হলো secret রাখার service. ভেতরে সে সাধারণত KMS দিয়েই encrypt করে। সাথে দেয় version, অনুমতি, log আর rotation-এর ব্যবস্থা।
Config নাকি secret
Twelve-Factor App-এর পরীক্ষাটি কাজের: কোডটি এখনই open source করা গেলে কোনো credential কি ফাঁস হবে? Database-এর ঠিকানা config, password secret. ফিচার চালু-বন্ধের flag config, signing key secret. Config থাকে config-এ, secret থাকে secret manager-এ, আর দুটির অনুমতি আলাদা হয়।
Environment variable config-এর জন্য ভালো। Secret-এর জন্য এটি একটি আপস, কারণ crash dump, debug page, child process আর docker inspect-এ তা দেখা যেতে পারে। সম্ভব হলে app নিজে secret manager থেকে সরাসরি memory-তে আনুক, বা ফাইল হিসেবে tmpfs-এ পাক।
চলার সময় আনা
App-এর কাছে কোনো secret থাকে না, থাকে একটি পরিচয়, যেমন instance role. সেই পরিচয়ে app চালু হওয়ার সময় secret-টি পড়ে। সব provider-এ পথ একই:
aws secretsmanager get-secret-value \
--secret-id shop/db-password \
--query SecretString --output textaz keyvault secret show \
--vault-name shop-vault --name db-password \
--query value --output tsvgcloud secrets versions access latest \
--secret=shop-db-passwordvault kv get -field=password secret/shop/dbএই কমান্ডগুলো উদাহরণ মাত্র। আসল ব্যবহারে আউটপুট কখনো log-এ বা terminal-এর history-তে রাখবেন না, আর secret-এর নামই শুধু কোডে থাকবে। নিজে চেষ্টা করলে cloud-এ খরচ হতে পারে, তাই কাজ শেষে পরীক্ষার secret মুছে দিন। HashiCorp Vault (২০১৫) provider-নিরপেক্ষ বিকল্প। ২০২৩ সালে এর license BSL-এ বদলায়, আর সেখান থেকে open source OpenBao fork জন্ম নেয়। Kubernetes-এ secret-এর আলাদা গল্প আছে পর্ব ৪৭-এ, আর CI-এ OIDC পর্ব ৬১-এ।
App-এ cache করার নিয়ম
প্রতিটি request-এ secret manager ডাকলে বিল বাড়ে, গতি কমে, আর সেটি বন্ধ হলে পুরো app থেমে যায়। তাই app secret memory-তে রাখে, এই নিয়মে:
- শুধু memory-তে রাখুন, ফাইল বা log-এ নয়
- একটি TTL দিন, যেমন ১০ মিনিট, আর instance-ভেদে একটু আগে-পরে refresh করুন, যাতে সবাই একসাথে না ডাকে
- Login ব্যর্থ হলে একবার তাজা মান এনে আবার চেষ্টা করুন
- Secret manager সাময়িক বন্ধ থাকলে পুরোনো মানে চলতে থাকুন, আর alert দিন
Dynamic credential — যে password নিজেই মরে যায়
স্থির password যত নিরাপদে রাখুন, সেটি মাসের পর মাস বৈধ থাকে। Dynamic secret অন্য পথ নেয়: app চাইলে Vault সেই মুহূর্তে database-এ একটি নতুন user বানায়, ১ ঘণ্টার মেয়াদে। মেয়াদ শেষে user মুছে যায়।
$ vault read database/creds/shop-app
Key Value
--- -----
lease_id database/creds/shop-app/EXAMPLE123
lease_duration 1h
lease_renewable true
password EXAMPLE-not-real
username v-shop-app-EXAMPLEএটি নমুনা আউটপুট, version-ভেদে আলাদা হতে পারে। লাভ তিনটি: ফাঁস হলেও মেয়াদ অল্প, প্রতিটি instance-এর user আলাদা বলে log-এ কে কী করল বোঝা যায়, আর সন্দেহ হলে একটি lease বাতিল করলেই চলে। দাম হলো, database-এ user তৈরি-মোছার চাপ বাড়ে, আর Vault একটি বাড়তি নির্ভরতা হয়। Cloud-এর database-এ IAM দিয়ে স্বল্পমেয়াদি login-ও একটি বিকল্প, যা provider-ভেদে আলাদা।
৮ · Downtime ছাড়া rotation — একসাথে দুটি বৈধ version
Password একবারে বদলালে কী হয়? Database-এ নতুন password বসল, কিন্তু app-এর cache-এ এখনো পুরোনোটি। নতুন connection খুলতে গেলেই login ব্যর্থ। সমাধান হলো secret rotation-এর সময় কিছুক্ষণ দুটি version-ই বৈধ রাখা।
অফিসের গেটের তালা বদলানোর সময় একদিনেই পুরোনো চাবি বাতিল করলে যে কর্মী ছুটিতে ছিলেন, তিনি আটকা পড়বেন। তাই কিছুদিন দুই চাবিই চলে, সবার হাতে নতুন চাবি পৌঁছালে পুরোনোটি বন্ধ হয়।
PostgreSQL-এ লেখার সময়ে একটি user-এর একসাথে দুটি password থাকে না, তাই সাধারণ পথ হলো দুটি user পালা করে ব্যবহার করা। MySQL ৮.০.১৪ থেকে এক user-এ দুটি password রাখা যায় (RETAIN CURRENT PASSWORD). Secrets Manager-এ এই পথের নাম alternating users, আর version-এর লেবেল থাকে AWSCURRENT, AWSPENDING, AWSPREVIOUS.
| মিনিট | |
| DB-তে বৈধ | |
| Secret দেখায় | |
| Instance a | |
| Instance b | |
| Instance c | |
| Login ব্যর্থ |
- শুরু। Database-এ user
blueসক্রিয়। Secret তার password দেখাচ্ছে, আর a, b, c তিনটি instance-ই সেটি cache করে রেখেছে। - নতুন version তৈরি। একই অনুমতিতে
greenবানানো বা তার password বদলানো হলো। নতুন মান pending লেবেলে রাখা হলো, আরgreenদিয়ে login পরীক্ষা করা হলো। এখনো কেউ এটি ব্যবহার করছে না। - পালাবদল। Secret এখন
greenদেখায়। Instance-গুলো এখনোblue-তে, তবেblueবৈধ থাকায় কিছুই ভাঙেনি। - Instance a নতুন মান পেল। নিজের সময়ে refresh করে a এখন
green-এ। দুই user একসাথে চলছে। - Instance b নতুন মান পেল। মিশ্র অবস্থা স্বাভাবিক। দুটি version বৈধ রাখার কারণ এটাই।
- Instance c নতুন মান পেল। সবাই
green-এ। তবে তা ধরে না নিয়ে database-এর log-এblue-এর নতুন login শূন্য কি না দেখুন। blueবন্ধ। Overlap ১৫ মিনিট, যা TTL ১০ মিনিটের বেশি। আগে শুধু বন্ধ করা হলো, মোছা নয়, যাতে দরকারে ফেরা যায়। ব্যর্থতা শূন্য।- পরের rotation. এবার
blueনতুন password পেয়ে অপেক্ষায় থাকবে, আর পালা উল্টে যাবে। দুই user এভাবে চক্রে চলে।
নিয়মটি ছোট: overlap ≥ cache-এর TTL + rollout-এর সময় + নিরাপত্তার ফাঁক। নিচের সিমুলেটরে ঘড়ি নকল, আর instance-গুলো ২, ৬ আর ৯ মিনিটে refresh করে। প্রথমবার overlap ১৫ মিনিট, দ্বিতীয়বার ৫ মিনিট।
// Two-version password rotation on a simulated clock (minutes, no real time).
// Each app instance re-reads the secret every TTL minutes, at its own offset.
const TTL = 10;
const instances = [['a', 2], ['b', 6], ['c', 9]];
function simulate(overlap) {
console.log(`--- old password removed ${overlap} min after the switch (TTL ${TTL})`);
const cached = { a: 'v1', b: 'v1', c: 'v1' };
let failedMinutes = 0;
for (let t = 0; t <= 14; t++) {
const events = [];
// t = 0: v2 is added to the database, then the secret manager points to v2
const valid = t < overlap ? ['v1', 'v2'] : ['v2'];
if (t === 0) events.push('v2 added, secret now points to v2');
if (t === overlap) events.push('v1 removed from database');
for (const [name, offset] of instances) {
if (t % TTL === offset && cached[name] !== 'v2') {
cached[name] = 'v2';
events.push(`${name} refreshes to v2`);
}
}
const bad = instances.map(i => i[0]).filter(n => !valid.includes(cached[n]));
if (bad.length) failedMinutes += bad.length;
if (events.length || bad.length) {
const fails = bad.length ? ` | LOGIN FAILS: ${bad.join(',')}` : '';
console.log(`t=${String(t).padStart(2)} ${events.join('; ') || '-'}${fails}`);
}
}
console.log(`failed instance-minutes: ${failedMinutes}`);
}
simulate(15);
simulate(5);প্রথম ভাগ শেষ হয় failed instance-minutes: 0-তে। দ্বিতীয় ভাগে t= 5 v1 removed from database | LOGIN FAILS: b,c: a আগেই নতুন মান পেয়েছে, কিন্তু b আর c নয়। c-র ব্যর্থতা চলে t= 8 পর্যন্ত, আর মোট failed instance-minutes: 5. একটি সত্য মনে রাখুন: database সাধারণত login-এর সময়ই password দেখে, তাই খোলা connection অনেক সময় চলতে থাকে। ফলে সমস্যা ধরা পড়ে পরে, connection pool নতুন connection খুললে। তাই মাঝরাতের “হঠাৎ” outage-ও আসলে দিনের বেলার rotation থেকে আসতে পারে।
৯ · Secret ফাঁস হলে — খোঁজা, বাতিল, বদল, তদন্ত
আগে ধরার ব্যবস্থা রাখুন। Commit-এর আগে আর CI-তে secret scanning চলে। আসল scanner-এ অনেক নিয়ম আর এলোমেলোতা মাপার ব্যবস্থা থাকে, তবে মূল ধারণা নিচের script-এই আছে। ফাইলের সব মান নকল, আর AKIAIOSFODNN7EXAMPLE হলো AWS-এর documentation-এর নমুনা।
set -euo pipefail
# All values below are fake. AKIAIOSFODNN7EXAMPLE is AWS's documentation sample.
cat > app.env <<'EOF'
APP_NAME=shop-api
LOG_LEVEL=info
PASSWORD_MIN_LENGTH=12
DB_PASSWORD=Fake-Passw0rd-123
DB_PASSWORD_REF=secret:shop/db-password
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
DATABASE_URL=postgres://app:fakepass@db.example.internal:5432/shop
API_TOKEN=${API_TOKEN}
-----BEGIN EXAMPLE PRIVATE KEY-----
EOF
PATTERNS='AKIA[0-9A-Z]{16}|BEGIN [A-Z ]*PRIVATE KEY|://[^:/]+:[^@]+@|(PASSWORD|SECRET|TOKEN)[A-Z_]*='
ALLOW='_REF=|_LENGTH=|=\$\{'
# Never print the full value: keep the first 4 characters, mask the rest.
mask() { sed -E 's/(=.{4})[^ ]*/\1****/; s#(://[^:]+:)[^@]+@#\1****@#'; }
hits=$(grep -nE "$PATTERNS" app.env | grep -vE "$ALLOW" || true)
echo "findings:"
printf '%s\n' "$hits" | mask
echo "total: $(printf '%s\n' "$hits" | grep -c . || true)"
echo "skipped as safe:"
grep -nE "$ALLOW" app.env | cut -d= -f1total: 4, মানে চারটি লাইন ধরা পড়েছে: 4:DB_PASSWORD=Fake****, access key, connection string আর private key-এর শিরোনাম। মান ঢেকে ছাপা হয়েছে, কারণ scanner-এর আউটপুটও log-এ যায়। skipped as safe-এ আছে PASSWORD_MIN_LENGTH, DB_PASSWORD_REF আর API_TOKEN: প্রথমটি সংখ্যা, দ্বিতীয়টি শুধু নাম, তৃতীয়টি বাইরে থেকে আসা মানের জায়গা। এই তালিকা না থাকলে ভুল সতর্কতায় মানুষ scanner উপেক্ষা করা শিখে যায়। Pattern-এর বাইরের secret এটি ধরবে না, তাই scanner একটি স্তর মাত্র।
ফাঁস হয়ে গেলে একটি মূল নিয়ম: secret মোছা নয়, secret অকেজো করাই সমাধান। Public repo-তে গেলে ধরে নিন সেটি ইতিমধ্যে কেউ পড়েছে। নিচের ঘটনাটি কাল্পনিক, আর ধাপগুলো শুধু প্রতিরক্ষার।
| সময় | |
| পুরোনো key | |
| নতুন পরিচয় | |
| পুরোনো session | |
| জানা ক্ষতি |
- সতর্কতা। Scanner জানাল, CI-এর একটি access key public repo-তে গেছে ১০:০০-তে। এটি আসল কি না, তর্ক নয়, আসল ধরেই incident খোলা হলো।
- ক্ষমতা বোঝা। Key-টি কী করতে পারে, তা IAM-এ দেখা হলো: artifact bucket-এ পড়া আর লেখা, সব bucket-এর তালিকা দেখা, আর পুরোনো ভুলে রয়ে যাওয়া কিছু IAM অনুমতি। Key-এর মান কোনো chat বা ticket-এ পেস্ট করা হলো না।
- বদল। CI-এর জন্য নতুন পরিচয় তৈরি করে pipeline-এ বসানো হলো। Key বন্ধ করলে কী ভাঙবে, তা এভাবে আগেই সামলানো গেল। আক্রমণের চিহ্ন থাকলে এই ধাপের অপেক্ষা না করে সাথে সাথে বন্ধ করা হতো।
- বাতিল। পুরোনো key বন্ধ করা হলো, মোছা নয়। মুছলে তদন্তের সূত্র আর ফেরার পথ দুটোই কঠিন হয়।
- পুরোনো session. Key বন্ধ হলেও তা দিয়ে আগে নেওয়া temporary credential মেয়াদ পর্যন্ত চলতে পারে। তাই সেগুলোও বাতিল করা হলো। এই ধাপটি অনেকেই ভুলে যান।
- Audit. Audit log-এ key-এর ID ধরে খোঁজা হলো, শুধু ফাঁসের পর থেকে নয়, আগের সময়ও। একটি অচেনা IP থেকে
ListBucketsপাওয়া গেল। - পরিষ্কার। ওই পরিচয় দিয়ে বানানো একটি অচেনা IAM user, তার key আর role খুঁজে সরানো হলো। Bucket-এ থাকা অন্য secret-ও পড়া হয়ে থাকতে পারে, তাই সেগুলোও বদলানো হলো।
- শিক্ষা। এখন Git history পরিষ্কার, পুরোনো key মোছা আর postmortem. CI-তে স্থায়ী key-এর বদলে স্বল্পমেয়াদি পরিচয় আর push-এর আগে scanning বসল। History পরিষ্কার আগে করলে কোনো লাভ হতো না।
আরও গভীরে: Data key বারবার ব্যবহারের একটি গাণিতিক সীমাও আছে। NIST SP 800-38D (২০০৭) অনুযায়ী AES-GCM-এ এলোমেলো 96-bit nonce ব্যবহার করলে এক key-এ প্রায় 2³²টির বেশি encryption করা উচিত নয়, কারণ nonce মিলে গেলে নিরাপত্তা ভাঙে। HSM-এর মান FIPS 140-3 (২০১৯) পুরোনো 140-2-এর জায়গা নিচ্ছে। Vault-এর unseal key ভাগ করতে Shamir-এর secret sharing (১৯৭৯) ব্যবহার হয়, যেখানে নির্দিষ্ট সংখ্যক ভাগ এক হলেই key মেলে।
পরীক্ষা ও ইন্টারভিউতে:
- Envelope encryption কেন? বড় ডেটা KMS-এ না পাঠিয়ে দ্রুত encrypt করা, আর প্রতিটি ডেটার key আলাদা রাখা।
- KEK rotate হলে পুরোনো ডেটা? আগের মতোই থাকে; পুরোনো material দিয়ে পড়া যায়।
- Config আর secret-এর পার্থক্য? প্রকাশ পেলে নিরাপত্তা ভাঙলে সেটি secret.
- Downtime ছাড়া rotation? দুটি version বৈধ রাখা; overlap, TTL আর rollout-এর চেয়ে বড়।
- Key ফাঁস হলে প্রথম কাজ? History মোছা নয়, key বাতিল আর বদল; তারপর log দেখা।
১০ · AI-এর যুগে secret আর KMS
AI খুব দ্রুত key policy আর rotation script লিখে দেয়। কিন্তু নিরাপত্তার ভুল চলতে চলতে ধরা পড়ে না, পড়ে ক্ষতির পরে।
| AI-এর সাধারণ ভুল | কেন বিপদ | যা করবেন |
|---|---|---|
কোডে বা .env.example-এ আসল-দেখতে secret | Commit হলেই ফাঁস | শুধু secret-এর নাম; scanner চালানো |
kms:* বা Principal: "*" | App key মুছতেও পারে | শুধু দরকারি action; policy পড়ে দেখা |
| Password একবারে বদলানো | Cache-এর জন্য login ব্যর্থ | দুটি version আর overlap |
| Key মোছার script, সতর্কতা ছাড়া | ডেটা চিরতরে হারায় | আগে বন্ধ করা, পরে সূচি |
| নিজের লেখা crypto, ভুল mode | দেখতে ঠিক, আসলে ভাঙা | পরীক্ষিত library, AES-GCM |
| নেই এমন flag বা পুরোনো API | Script মাঝপথে ভাঙে | Official docs, পরীক্ষার environment |
| KMS call-এর খরচ উপেক্ষা | চাপ বাড়লে বিল আর throttling | Call গোনা, budget alert |
AI-কে কাজ দিন, কিন্তু সীমা বলে দিন। Prompt-এ কখনো আসল secret, key বা account ID দেবেন না।
AI-এর লেখা secret-এর কাজ ব্যবহারের আগে
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।
প্র ০১সব ডেটা encrypted ছিল, তবু লক্ষ লক্ষ রেকর্ড চুরি হলো কীভাবে? Encryption at rest আসলে কার বিরুদ্ধে?
২০১৯ সালের Capital One ঘটনা এর সবচেয়ে আলোচিত উদাহরণ। আদালতের নথি আর প্রকাশিত বিশ্লেষণ অনুযায়ী, একটি ভুল-সাজানো web application firewall-এর মধ্য দিয়ে আক্রমণকারী server-এর metadata সেবা থেকে একটি role-এর অস্থায়ী credential পান। সেই role-এর বহু S3 bucket পড়ার অনুমতি ছিল। S3 তাই স্বাভাবিক নিয়মেই ডেটা decrypt করে দেয়। এখানে encryption ভাঙা হয়নি, এড়িয়ে যাওয়াও হয়নি। Cloud শুধু একজন অনুমোদিত অনুরোধকারীর কাজ করেছে।
এটি বুঝতে threat model আলাদা করুন। Server-side encryption ঠেকায় ডিস্ক চুরি, ভুলে ফেলে দেওয়া hardware, আর storage স্তরের সরাসরি পড়া। এটি ঠেকায় না ভুল অনুমতি বা চুরি হওয়া পরিচয়।
Customer-managed key কিছুটা বাড়তি দেয়াল বানায়, কারণ তখন bucket-এর অনুমতির সাথে key-এর অনুমতিও লাগে। Role-কে শুধু bucket পড়তে দিলে কিন্তু key না দিলে ডেটা আসে না। আর audit log-এ হঠাৎ বিপুল Decrypt দেখা যায়, যা একটি ভালো alarm হতে পারে। তবে একই role-কে দুটোই দিলে কোনো লাভ নেই।
এই ঘটনার পরে AWS ২০১৯ সালের শেষে IMDSv2 আনে, যা metadata সেবায় এ ধরনের অনুরোধ কঠিন করে (পর্ব ১৬). শিক্ষা হলো, প্রতিটি role-এর ক্ষমতা ছোট রাখুন, সংবেদনশীল ডেটায় আলাদা key দিন, আর অস্বাভাবিক পড়ায় alarm বসান।
আরেকটি ভুল ধারণা হলো, “bucket encrypted” লেখা দেখলেই নিশ্চিন্ত হওয়া। Audit-এ আসল প্রশ্ন হওয়া উচিত, এই ডেটা কোন কোন পরিচয় খোলা অবস্থায় পেতে পারে, আর তা কি সত্যিই দরকার? এই তালিকা ছোট হলে একটি চুরি হওয়া পরিচয়ের ক্ষতিও ছোট হয়।
মূল উপলব্ধি: Encryption প্রশ্ন করে “ডিস্ক কার হাতে?”, আর IAM প্রশ্ন করে “কে চাইছে?” চুরি হওয়া পরিচয়ের বিরুদ্ধে প্রথমটি কাজ করে না।
প্র ০২Secret manager-এ ঢুকতেও তো একটি চাবি লাগে। তাহলে সেই প্রথম চাবিটি কোথায় রাখবেন?
একে বলে secret zero সমস্যা। সব secret একটি সিন্দুকে রাখলেন, কিন্তু সিন্দুকের চাবি app কোথা থেকে পাবে? সেটি কোডে রাখলে আগের জায়গাতেই ফিরে গেলেন। এই চক্র ভাঙার একমাত্র পথ হলো, গোপন কিছু জানা থেকে সরে নিজে কে, তা প্রমাণ করা-য় যাওয়া।
Cloud-এ platform নিজেই সাক্ষী হয়। VM চালু করার সময় provider জানে এটি কোন VM, তাই সে metadata সেবার মাধ্যমে instance role-এর স্বল্পমেয়াদি credential দেয়। App কোনো স্থায়ী secret ধরে না। Kubernetes-এ pod-এর service account token আর cloud-এর identity federation একই কাজ করে। CI-তে OIDC token দিয়ে pipeline প্রমাণ করে সে কোন repo আর কোন branch থেকে চলছে (পর্ব ৬১)। Azure-এ managed identity আর Google Cloud-এ attached service account একই ধারণার ভিন্ন নাম।
Cloud-এর বাইরে, যেমন নিজের data centre-এ, এটি কঠিন, কারণ সাক্ষী নেই। তখন SPIFFE-এর মতো workload identity মান বা TPM-এর মতো hardware পরিচয় ব্যবহার হয়। Vault-এর ক্ষেত্রেও প্রশ্ন একই, তার নিজের master key কে খুলবে? উত্তর হলো Shamir-এর ভাগ করা চাবি দিয়ে কয়েকজন মানুষ, অথবা auto-unseal, যেখানে cloud KMS সেই কাজ করে। অর্থাৎ শেষে কোথাও একটি বিশ্বাসের ভিত্তি থাকেই।
বাস্তবে এই ভিত্তিকে যত ছোট আর ভালোভাবে পাহারা দেওয়া যায়, ততই ভালো। মানুষের ল্যাপটপে থাকা স্থায়ী key-ও এই শিকলের দুর্বল জায়গা, তাই মানুষের জন্যও SSO আর স্বল্পমেয়াদি session ব্যবহার করুন।
এর আরেকটি লাভ হলো, চুরি করার মতো স্থায়ী কিছু থাকে না। Credential ফাঁস হলেও মেয়াদ অল্প, আর সেটি শুধু ওই পরিচয়ের সীমিত অনুমতিটুকুই দেয়। ফলে secret রাখার জায়গা কমে, আর পাহারার কাজও সহজ হয়।
মূল উপলব্ধি: Secret-এর সমস্যা আরেকটি secret দিয়ে মেটে না। মেটে পরিচয় দিয়ে, যার সাক্ষী platform নিজে।
প্র ০৩KMS বন্ধ হয়ে গেলে কী হবে? নিরাপত্তার একটি service কি পুরো সিস্টেমের একক ব্যর্থতার বিন্দু হয়ে গেল?
হ্যাঁ, একটি কঠিন নির্ভরতা তৈরি হয়। Encrypted volume নিয়ে VM চালু হতে key লাগে। নতুন object পড়তে Decrypt লাগে। Autoscaling-এ নতুন instance চালু হতে secret লাগে। KMS বা secret manager বন্ধ হলে হয়তো চলতে থাকা app টিকে থাকবে, কিন্তু নতুন কিছু চালু হবে না। সবচেয়ে খারাপ সময়ে, অর্থাৎ বিপর্যয় সামলাতে যখন নতুন server দরকার, ঠিক তখনই এটি ভোগাতে পারে।
ঝুঁকি কমানোর কয়েকটি উপায় আছে। প্রথমত, cache: data key আর secret-এর সীমিত মেয়াদের cache সাময়িক বন্ধে app-কে বাঁচিয়ে রাখে। দ্বিতীয়ত, region: KMS key সাধারণত একটি region-এ বাঁধা, তাই অন্য region-এ backup পড়তে সেখানেও key লাগবে। Key হারালে backup-ও হারাল। পর্ব ২৪-এর disaster recovery পরিকল্পনায় তাই key-কেও হিসাবে রাখুন। AWS-এর multi-Region key এই কাজ সহজ করে, তবে অন্য provider-এর ব্যবস্থা আলাদা।
তৃতীয়ত, অন্য account: backup যদি আলাদা account-এ রাখেন, কিন্তু তার key মূল account-এ থাকে, তবে account হারালে backup-ও অচল। চতুর্থত, পরীক্ষা: চলতে থাকা সিস্টেমে key-এর অনুমতি সরিয়ে দেখুন কী ভাঙে, অবশ্যই পরীক্ষার environment-এ।
আর ভুলে যাবেন না, ব্যর্থতার বড় উৎস সব সময় provider নয়। অনেক সময় নিজের key policy-র ভুল, ভুলে key বন্ধ করা, বা হঠাৎ চাপে throttling থেকেও একই ফল হয়। তাই Decrypt ব্যর্থতার হারে alert রাখুন।
নকশার সময় নিজেকে জিজ্ঞেস করুন, KMS এক ঘণ্টা বন্ধ থাকলে কোন কাজ চলবে আর কোনটি থামবে? চলতে থাকা instance, নতুন instance, backup পুনরুদ্ধার আর rotation, চারটি আলাদা করে লিখুন। এই উত্তর runbook-এ থাকলে সংকটের সময় নতুন করে ভাবতে হয় না।
মূল উপলব্ধি: Key-কে ডেটার মতোই গুরুত্ব দিন। আপনার availability আর recovery-র হিসাব key-এর availability-এর চেয়ে বেশি হতে পারে না।
প্র ০৪নিয়মিত rotation কি সত্যিই ফাঁস ঠেকায়? তাহলে স্বল্পমেয়াদি secret-এর পক্ষে এত জোর কেন?
Rotation ফাঁস ঠেকায় না, ফাঁসের আয়ু কমায়। একটি key ফাঁসের পর যতক্ষণ বৈধ থাকে, ততক্ষণই ক্ষতির জানালা খোলা। ৯০ দিনে rotation মানে সবচেয়ে খারাপ ক্ষেত্রে ৯০ দিনের জানালা। আর dynamic credential-এ সেটি এক ঘণ্টা।
২০২৩ সালের Storm-0558 ঘটনা এই বিষয়ে আলোচিত। Microsoft-এর প্রকাশিত বিবরণ আর মার্কিন Cyber Safety Review Board-এর ২০২৪ সালের প্রতিবেদন অনুযায়ী, একটি পুরোনো consumer signing key দিয়ে token জাল করে কিছু সরকারি ও অন্য প্রতিষ্ঠানের email-এ ঢোকা হয়। Key-টি বহু বছরের পুরোনো ছিল বলে জানা যায়। কীভাবে key-টি চুরি হলো, তা নিয়ে Microsoft-এর প্রথম ধারণা ছিল একটি crash dump, পরে তারা জানায় এর সরাসরি প্রমাণ নেই। তাই কারণটিকে নিশ্চিত ধরবেন না। তবে key-এর দীর্ঘ আয়ু যে ঝুঁকি বাড়ায়, সেই শিক্ষাটি নিশ্চিত।
অন্যদিকে, নিয়মিত rotation-এর নিজের ঝুঁকিও আছে। হাতে করা rotation ভুলে ভরা, আর প্রতিটি বদল একটি outage-এর সুযোগ। তাই মানুষের password-এর ক্ষেত্রে NIST SP 800-63B জোর করে নিয়মিত বদলাতে বলা থেকে সরে এসেছে, কারণ মানুষ দুর্বল ধরনের বদল করে। মেশিনের secret-এ অবস্থা উল্টো: স্বয়ংক্রিয় হলে rotation সস্তা, আর পরীক্ষিত হলে ফাঁসের সময় দ্রুত বদলানো যায়।
এর সবচেয়ে বড় লাভ অভ্যাস। যে দল মাসে একবার নিরাপদে rotate করে, ফাঁসের রাতে সে আতঙ্কে পড়ে না। আর যে key কখনো বদলানো হয়নি, সেটি কোথায় কোথায় ব্যবহার হচ্ছে, কেউ জানে না।
মূল উপলব্ধি: লক্ষ্য rotation-এর তারিখ নয়। লক্ষ্য হলো secret-এর আয়ু এত ছোট করা, আর বদলানো এত সহজ করা, যাতে ফাঁসকে বিপর্যয় না হয়ে রুটিন ঘটনা মনে হয়।
প্র ০৫Customer-managed key নিলেই কি provider আপনার ডেটা পড়তে পারে না? “চাবি আমার হাতে” কথাটির আসল মানে কী?
এখানে একটি বড় ভুল ধারণা আছে। Customer-managed key মানে key-এর নিয়ম আপনার হাতে: কে ব্যবহার করবে, কখন বদলাবে, কখন বন্ধ হবে। কিন্তু key থাকে provider-এর KMS-এ, আর ডেটা decrypt হয় provider-এর পরিকাঠামোতে। Server-side encryption-এ কাজের সময় plaintext সেই service-এর memory-তে থাকে। তাই এটি মূলত নিয়ন্ত্রণ আর audit-এর ব্যবস্থা, প্রযুক্তিগতভাবে provider-কে পুরোপুরি বাদ দেওয়ার ব্যবস্থা নয়। Provider-এর কর্মীদের প্রবেশ ঠেকাতে তারা নিজেদের নিয়ন্ত্রণ আর audit-এর কথা বলে, যা একটি বিশ্বাসের প্রশ্ন।
এরপরের ধাপ হলো external key, যেখানে key cloud-এর বাইরে থাকে, আর আপনি চাইলে যেকোনো মুহূর্তে সংযোগ কেটে দিতে পারেন। এতে “বন্ধ করার” ক্ষমতা পান, তবে ব্যবহারের সময় data key তো service-এর কাছেই পৌঁছায়। আরও এগিয়ে client-side encryption: ডেটা আপনার নিজের মেশিনে encrypt হয়, আর cloud শুধু ciphertext দেখে। এতে provider সত্যিই পড়তে পারে না। কিন্তু দাম বড়: cloud-এর search, analytics আর অনেক managed সুবিধা তখন আর ডেটার ভেতরে কাজ করে না।
Confidential computing আরেকটি পথ নিচ্ছে, যেখানে কাজ চলে CPU-র সুরক্ষিত অঞ্চলে, আর memory-ও encrypted. তবে এর আগেও এই ধরনের hardware-এ গবেষকরা দুর্বলতা দেখিয়েছেন, তাই এটিকেও চূড়ান্ত উত্তর ভাববেন না।
Data localisation-এর নিয়মে অনেকে key-কে সমাধান ভাবেন। বাংলাদেশে ব্যক্তিগত উপাত্ত সুরক্ষা আইন, ২০২৬ (পর্ব ৩৫) আর অন্য দেশের নিয়ম নিজের ক্ষেত্রের আইনজ্ঞের সাথে মিলিয়ে নিন, কারণ এসব নিয়ম বদলায়।
তাই গ্রাহককে প্রতিশ্রুতি দেওয়ার আগে নিজের নকশায় plaintext-এর পথ কাগজে এঁকে দেখুন: কোন service, কোন memory আর কোন log-এ সেটি দেখা দেয়।
মূল উপলব্ধি: প্রশ্নটি “key কার?” নয়। প্রশ্নটি হলো “plaintext কোথায় কোথায় দেখা দেয়, আর সেই জায়গা কে নিয়ন্ত্রণ করে?”
অনুশীলন
এগুলোর কোনোটিতেই cloud account লাগবে না। সব দাম ধরে নেওয়া।
-
খরচের হিসাব: সেকেন্ডে ৩০০টি object, ২০টি instance-এ সমান ভাগে। KMS-এর দাম ধরে নিই প্রতি ১০,০০০ call-এ $০.০৩, মাস ৩০ দিনের। Cache ছাড়া মাসিক বিল কত? ২ মিনিটের data-key cache-এ বিল কত, আর এক key-এ কতটি object পড়ে?
Cache ছাড়া: 300 × 2,592,000 = 777,600,000 call. 777,600,000 ÷ 10,000 = 77,760; × $0.03 = $2,332.80.
২ মিনিটের cache: 20 × 2,592,000 ÷ 120 = 432,000 call. 43.2 × $0.03 = প্রায় $1.30.
এক key-এ: প্রতিটি instance-এ সেকেন্ডে 300 ÷ 20 = 15টি, তাই 15 × 120 = 1,800টি object.
-
নকশা সমালোচনা: একটি দলের ব্যবস্থা এমন: database password আছে
user-data-তে; সব app একই database user ব্যবহার করে; KMS key-এর policy-তে app-এরkms:*; rotation হয় “যখন কেউ মনে করে”; backup অন্য region-এ, কিন্তু key শুধু মূল region-এ। পাঁচটি সমস্যা আর তাদের সমাধান লিখুন।- User data: metadata আর template-এ পড়া যায়। Password secret manager-এ রাখুন, instance role দিয়ে পড়ুন।
- একই user: log-এ কে কী করল বোঝা যায় না, আর একটি ফাঁসে সব app আক্রান্ত। প্রতিটি app-এর আলাদা user বা dynamic credential দিন।
kms:*: app key মুছতেও পারে। শুধুGenerateDataKeyআরDecryptদিন।- হাতে rotation: সময়মতো হবে না। দুটি version-সহ স্বয়ংক্রিয় rotation বসান।
- Key এক region-এ: সেই region বন্ধ হলে backup পড়া যাবে না। Backup region-এও key রাখুন আর পুনরুদ্ধারের মহড়া দিন।
-
আউটপুট অনুমান করুন: Two-version timeline কোডের শেষ লাইনটি
simulate(7);করলে সেই ভাগের শেষ চারটি লাইন কী হবে? আগে নিজে লিখুন, তারপর বদলে চালিয়ে মিলিয়ে নিন।a আর b আগেই নতুন মান পেয়েছে, শুধু c বাকি। c refresh করে
t=9-এ, তাই ব্যর্থতা দুই মিনিট:t= 7 v1 removed from database | LOGIN FAILS: c t= 8 - | LOGIN FAILS: c t= 9 c refreshes to v2 failed instance-minutes: 2 -
অবস্থা অনুমান করুন: একটি KMS key K-এর ক্রম: (১) K দিয়ে object A লেখা; (২) K rotate; (৩) K দিয়ে object B লেখা; (৪) K বন্ধ (disable); (৫) K আবার চালু; (৬) K মুছে ফেলা, অপেক্ষার সময় শেষ। প্রতিটি ধাপের পরে A আর B পড়া যাবে কি?
- (১) পরে: A পড়া যায়।
- (২) আর (৩) পরে: A আর B দুটোই পড়া যায়। A পুরোনো material-এ, B নতুনটিতে; ID একই।
- (৪) পরে: কোনোটিই নয়, তবে ডেটা নষ্ট হয়নি।
- (৫) পরে: দুটোই আবার পড়া যায়।
- (৬) পরে: কোনোটিই নয়, আর কখনো নয়। সব key material চলে গেছে। এটিই crypto-erasure.
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমPublic repo-তে একটি cloud access key ফাঁস হলে করণীয় সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- ফাঁসটি আসল ধরে incident খোলা আর key-এর ক্ষমতা বোঝা
- নতুন পরিচয় বসানো
- পুরোনো key বন্ধ করা আর তার session বাতিল করা
- Audit log-এ key-এর সব ব্যবহার দেখা আর ক্ষতি সরানো
- Git history পরিষ্কার করা আর ভবিষ্যতের ব্যবস্থা নেওয়া
Envelope encryption-এ ciphertext-এর পাশে storage-এ কোনটি রাখা হয়?
- খোলা data key
- KEK দিয়ে লক করা data key
- KEK-এর একটি কপি
- App-এর access key
একটি KMS key-এ automatic rotation চালু হলো। আগের বছরের encrypted object-গুলোর কী হবে?
- সব object নিজে থেকে নতুন key-এ encrypt হবে
- পড়া যাবে না, আবার আপলোড করতে হবে
- আগের মতোই থাকবে আর পুরোনো material দিয়ে পড়া যাবে
- ৭ দিন পরে মুছে যাবে
৫টি app instance, প্রতিটি নিজের data key ৩০০ সেকেন্ড cache করে। ৩০ দিনের মাসে KMS call কতটি?
- 43,200
- 8,640
- 216,000
- 86,400
একটি bucket-এ server-side encryption চালু। কোন ঘটনাটি এই encryption একা ঠেকাতে পারে না?
- Data centre থেকে একটি ডিস্ক চুরি
- পুরোনো hardware ঠিকমতো নষ্ট না করে বাতিল করা
- Storage স্তর থেকে সরাসরি byte পড়া
- অনুমতি থাকা একটি role-এর credential চুরি হওয়া
App secret ১৫ মিনিট cache করে, আর নতুন version সব জায়গায় ছড়াতে আরও ৫ মিনিট লাগে। পুরোনো password বন্ধের আগে সবচেয়ে কম কত অপেক্ষা করা উচিত?
- ১৫ মিনিট
- ২০ মিনিট, সাথে একটু বাড়তি সময়
- ৫ মিনিট
- অপেক্ষা লাগে না
Environment variable আর secret manager নিয়ে কোন কথাটি সবচেয়ে ঠিক?
- Environment variable সব সময় encrypted থাকে, তাই secret-এর জন্য সবচেয়ে নিরাপদ
- সব config-ই secret manager-এ রাখা উচিত
- Config-এর জন্য environment variable ভালো, তবে secret সেখানে ফাঁসের ঝুঁকি বাড়ায়
- Base64 করে রাখলে কোডেও secret রাখা নিরাপদ
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- Secret কোড, image, log আর user data-তে নয়। থাকবে secret manager-এ, আর app পড়বে নিজের পরিচয় দিয়ে।
- KMS-এর key বাইরে আসে না। প্রতিটি ব্যবহারে অনুমতি যাচাই হয়, আর audit log-এ চিহ্ন থাকে।
- Envelope encryption: data key ডেটা লক করে, KEK data key লক করে। Cache বিল কমায়, তবে এক key-এর ঝুঁকি বাড়ায়।
- Rotation পুরোনো ডেটা বদলায় না; key মুছলে ডেটা শেষ (crypto-erasure).
- Downtime ছাড়া বদলাতে দুটি version; overlap ≥ TTL + rollout. ফাঁস হলে আগে বাতিল, তারপর তদন্ত, শেষে history.
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ৩৪ · Cloud নিরাপত্তার ভিত্তি — misconfiguration, audit log আর defense in depthপরবর্তী পর্বভুল সাজানো খুঁজে বের করা আর নিরাপত্তার স্তর।
- ক্লাউড কম্পিউটিং ও DevOps · কোর্স হোম৮১টি পর্বপুরো কোর্সের রোডম্যাপ।
- Cryptography-র ভিত্তিগভীরে যানAES, nonce, hash, HMAC আর hybrid encryption-এর ভেতরের যুক্তি।
- Git নিরাপত্তাপাশের ট্র্যাকCommit-এ secret ফাঁস ঠেকানো আর ফাঁসের পরে history সামলানো।
- System Design · নিরাপত্তার নকশাপাশের ট্র্যাকবড় সিস্টেমের নকশায় নিরাপত্তার সিদ্ধান্ত।