বিষয়বস্তুতে যান

Master key ও signing key রোটেশন এবং জরুরি প্রবেশাধিকার

সংরক্ষিত credential সুরক্ষাকারী master key রোটেট করুন এবং জরুরি প্রবেশাধিকার ব্যবহার করুন।

Markdown হিসেবে দেখুন

নিয়ন্ত্রণগুলো 21-compliance.md-এর section 14-এ আছে—অডিটর যে নামে সেগুলো চান। এখানে প্রক্রিয়া; এটি যে record তৈরি করে সেগুলোই প্রমাণ।

Key-গুলো

সংরক্ষিত প্রতিটি credential নতুন data encryption key (DEK) দিয়ে seal করা হয়। Master key (KEK) DEK-কে wrap করে, আর master key-এর reference পাশে (key_ref) অথবা packed value-র ভেতরে সংরক্ষিত থাকে। Master key রোটেট করলে DEK আবার wrap হয়। Credential কখনো decrypt বা পুনরায় encrypt করা হয় না।

Setting অর্থ
QUIRE_MASTER_KEY বর্তমান master key: 32 byte, base64। প্রতিটি নতুন secret এর অধীনে wrap হয়
QUIRE_MASTER_KEY_VERSION সংস্করণ label। সেট না থাকলে v1। Key বদলালেই এটি বাড়ান
QUIRE_MASTER_KEY_RETIRED আগে তৈরি secret এখনও যে key-তে থাকতে পারে, সেই পুরোনো key-গুলো v1=<base64>,v0=<base64> আকারে। শুধু read, কখনো write নয়

Web tier, worker এবং bun run kek:rotate command একই তিনটি setting পড়ে। সবখানে মান এক হতে হবে, নইলে একটির seal করা তথ্য অন্যটি খুলতে পারবে না।

QUIRE_MASTER_KEY না থাকলে প্রতিটি subsystem QUIRE_SECRET_KEY থেকে তৈরি key ব্যবহার করতে থাকে। এটি চলতে থাকে, তবে System health page-এ degraded দেখায়; master key সেট করার পরও এটি পড়া যায়, তাই প্রথম rotation-এ সব তথ্য সেখান থেকে সরানো সম্ভব। Process environment পড়তে পারা যে কেউ সব সংরক্ষিত credential decrypt করতে পারে; তাই production install-এ master key secret store-এ এবং database backup থেকে আলাদা রাখা উচিত।

রোটেট করা

Platform console-এর Security, Master key-তে key-এর বয়স দেখা যায়, এবং quire.secrets.master_key.age metric-এও (দিন হিসেবে)। দৈনিক platform.key_age schedule (03:41 UTC) key-এর বয়স 365 দিনে পৌঁছালে platform audit chain-এ reminder লেখে, এরপর rotation না হওয়া পর্যন্ত প্রতি 30 দিনে আবার লেখে। Reminder পেলে এবং key প্রকাশ হয়ে থাকতে পারে এমন যেকোনো সময়ে রোটেট করুন।

  1. নতুন key তৈরি করুন: openssl rand -base64 32।
  2. QUIRE_MASTER_KEY-এ সেটি এবং QUIRE_MASTER_KEY_VERSION-এ পরের label (v2) দিন। পুরোনো key-টি QUIRE_MASTER_KEY_RETIRED-এ v1=<old base64> হিসেবে সরান। দুটির copy এই host ছাড়া অন্য কোথাও রাখুন।
  3. নতুন setting-সহ web tier ও worker deploy করুন। নতুন secret এখন env:QUIRE_MASTER_KEY:v2-এর অধীনে wrap হবে; পুরোনোগুলো এখনও retired key দিয়ে খোলা যাবে।
  4. Audit trail-এ থাকার মতো কারণসহ rotation request করুন:
    • console-এ: Security, Master key, Rotate the master key; অথবা
    • একই environment-সহ shell-এ: bun run kek:rotate request --reason "Annual rotation, ticket SEC-114"।
  5. Worker প্রতি মিনিটে এক অংশ re-wrap করে (scheduler-এর platform.key_rotation schedule) এবং restart-এর পর যেখানে থেমেছিল সেখান থেকে চলে। একবারেই শেষ করতে: bun run kek:rotate run। bun run kek:rotate status দিয়ে অগ্রগতি দেখুন।
  6. Record-এ rotation সম্পন্ন এবং শূন্য অমীমাংসিত ও শূন্য ব্যর্থ দেখালে QUIRE_MASTER_KEY_RETIRED থেকে retired key সরিয়ে আবার deploy করুন। ততক্ষণ এটি রাখুন: যেসব value সরানো যায়নি সেগুলো এখনও পুরোনো key-তে wrap করা।

Job কোনগুলো পরীক্ষা করে

যে store-এ wrap করা DEK থাকে তার সবগুলো: SEALED_STORES-এ থাকা store (apps/worker/src/key-rotation.ts)। Control database-এর store সেখানেই পরীক্ষা হয়; organisation-এর store-গুলো row-level security-র অধীনে একবারে একটি organisation ধরে পরীক্ষা হয়, যে database-এ সেটি আছে সেখানেই—তাই নির্দিষ্ট database-এ আবদ্ধ tenant তার সেই database-এই rotate হয়। তালিকায় উল্লেখ নেই এমন wrapped-key column যোগ হলে একটি test ব্যর্থ হয়; credential review কোনো sealed column শনাক্ত করলেও তালিকায় না থাকলে আরেকটি test ব্যর্থ হয়।

Record

  • ops.key_rotation: প্রতি rotation-এ একটি row, যেখানে কারণ, কে request করেছেন, অবস্থা এবং মোট হিসাব (re-wrapped, ইতিমধ্যে বর্তমান, অমীমাংসিত, ব্যর্থ) থাকে।
  • ops.key_rotation_progress: পরীক্ষা হওয়া প্রতিটি store ও scope-এ একটি row, যেখানে পড়া যায়নি এমন key reference ও প্রতিটির অধীনে থাকা value-র সংখ্যা থাকে। আবার শুরু করা rotation এগুলো এড়িয়ে যায়।
  • Platform audit chain: platform/key_rotation_request (কারণসহ), প্রতি store-এর গণনাসহ একটি করে platform/key_rotation_store, এবং platform/key_rotation_complete অথবা platform/key_rotation_fail; reminder-এর জন্য platform/key_age_reminder।
  • Metric: quire.secrets.master_key.age এবং quire.secrets.rewrap.outstanding (শেষ rotation-এ সরানো যায়নি এমন value)।

Value অমীমাংসিত থাকলে

অমীমাংসিত value এমন key reference-এর অধীনে wrap করা, যা এই installation-এর কাছে নেই, অথবা এর column যে format প্রতিশ্রুতি দেয় তা মেলে না। Progress record-এ reference দেখা যায় (যেমন env:QUIRE_MASTER_KEY:v0 (unreadable))। সেই key-টি QUIRE_MASTER_KEY_RETIRED-এ ফিরিয়ে দিয়ে আবার rotation চালান, অথবা key চিরতরে হারিয়ে গেলে প্রতিষ্ঠানের administrator-কে credential আবার দিতে বলুন: সেটি বর্তমান key-তে seal হবে। ব্যর্থ rotation-এ record-এ error দেখা যায়; কারণ ঠিক করে আবার request করুন।

Signing key

Master key থেকে আলাদা: প্রতিটি প্রতিষ্ঠান নিজস্ব RSA key দিয়ে OpenID Connect token ও LTI message sign করে, যা /.well-known/jwks.json-এ প্রকাশ করা হয়। এখানে operator-এর কিছু করার দরকার নেই। ঘণ্টায় একবার চলা platform.signing_keys schedule বর্তমান key-এর 90 দিন পূর্ণ হওয়ার সাত দিন আগে পরের key প্রকাশ করে; এক সপ্তাহ পর নতুনটি sign করা শুরু করে এবং পুরোনোটি retiring হয়; আরও 90 দিন পরে পুরোনোটি মুছে key set থেকে সরে যায়। প্রতিটি ধাপ platform audit chain-এ platform/signing_key_advance entry হয়।

প্রকাশের পরপরই প্রতিষ্ঠানের key বদলাতে চাইলে, যেমন key উন্মুক্ত হয়ে গেলে:

  • console-এ: Security, Master key, Publish a new signing key (platform/keys_manage দরকার); অথবা
  • worker-এর environment-সহ shell-এ: bun run kek:rotate signing-keys rotate --tenant <slug or id> --reason "Key exposed, INC-3310". bun run kek:rotate signing-keys status প্রতিটি প্রতিষ্ঠানের key-কে stage অনুযায়ী তালিকাভুক্ত করে।

নতুন key সঙ্গে সঙ্গে প্রকাশিত হয় এবং সাত দিন পর, পুরোনোটি retiring হলে, sign শুরু করে। এক সপ্তাহের ব্যবধান ইচ্ছাকৃত: relying party-গুলো key set cache করে; ব্যবধান ছোট হলে একই সময়ে সব tool ব্যর্থ হতে পারে। ইতিমধ্যে sign করা token যাচাই চলতে দিতে retiring key আরও 90 দিন key set-এ থাকে। Key উন্মুক্ত হওয়ায় আরও আগে বিশ্বাস করা বন্ধ করতে হলে operator নিজের database access দিয়ে পরিবর্তনের record অনুসারে এর row মুছতে পারেন (break-glass access শুধু read-এর জন্য); এরপর সেটি দিয়ে sign করা token verification-এ ব্যর্থ হবে। জোরপূর্বক rotation কারণসহ audit chain-এ platform/signing_key_rotate হিসেবে লেখা হয়। নতুন key wrap করতে worker-এর web tier-এর মতোই QUIRE_MASTER_KEY setting দরকার; master key-এর bun run kek:rotate অন্য সবকিছুর সঙ্গে signing key-ও re-wrap করে (oauth_signing_key SEALED_STORES-এ আছে)।

Production-এ জরুরি প্রবেশাধিকার

কেউ production-এ স্থায়ী access রাখেন না। কোনো কাজ অপেক্ষা করতে না পারলে owner জরুরি access grant দেন: Platform console, Security, Break-glass access।

  • Grant-এর scope থাকে (একটি প্রতিষ্ঠান অথবা platform registry), incident বা ticket উল্লেখ করা অন্তত 20 character-এর কারণ থাকে এবং 5 থেকে 240 মিনিটের সময়সীমা থাকে। এটি নিজে মেয়াদোত্তীর্ণ হয়: প্রতিটি statement-এর সময় clock দেখে যাচাই করা হয়।
  • যিনি grant দিচ্ছেন সেই owner-কেও দেওয়া যায়, অথবা অন্য owner-কে (দুই-ব্যক্তির পদ্ধতি)। যাঁকে দেওয়া হয়েছে শুধু তিনিই ব্যবহার করতে পারেন। দেওয়ার জন্য platform/break_glass_issue এবং ব্যবহারের জন্য platform/break_glass_use দরকার; default-এ উভয় অনুমতিই শুধু owner-এর।
  • Database login দিয়ে নয়, gateway দিয়ে statement চলে: শুধু read, একবারে একটি, নির্দিষ্ট প্রতিষ্ঠান বা control registry-র মধ্যে সীমিত, পাঁচ সেকেন্ড timeout এবং সর্বোচ্চ 500 row। Binary value-র আকার দেখানো হয়।
  • Platform audit chain-এ grant দেওয়া (কারণসহ), প্রত্যাহার, চালানোর আগে প্রতিটি statement (platform/break_glass_statement, প্রত্যাখ্যাত হলে ফল denied) এবং প্রতিটি result (platform/break_glass_result) রেকর্ড হয়। ops.break_glass_statement-এ audit entry ID থাকে, তাই grant-এর record-এর সঙ্গে audit entry যুক্ত করা যায়।
  • Write করার সুযোগ নেই। Release-এর জন্য অপেক্ষা করতে না পারা পরিবর্তন এই product-এর বাইরে operator-এর নিজস্ব database access ও নিজস্ব change record দিয়ে করতে হয়; সেই record-এ এখানে ব্যবহৃত incident reference উল্লেখ করা উচিত।

কেন database credential দেবেন না: Postgres login চাওয়া session-এর চেয়েও বেশি সময় টিকে থাকে, application-নির্ভর row-level security এড়িয়ে যায় এবং এই product-এর audit chain-এ লিখতে পারে না; ফলে server log কেউ পাঠালে ততটুকুই statement audit হয়। Gateway access-এর চারপাশের অভ্যাস না করে audit trail-কে access-এর অন্তর্নিহিত বৈশিষ্ট্য করে।

Audit request-এর উত্তর দিতে নির্দিষ্ট সময়ের grant তালিকাভুক্ত করুন (Break-glass access), statement ও audit entry ID দেখতে grant-এর history খুলুন এবং platform audit chain-এর entry পড়ুন (bun run audit:verify --platform প্রমাণ করে chain অক্ষত আছে)।

নেভিগেশন

খুঁজতে লিখুন…

↑↓ নেভিগেট করুন↵ নির্বাচন করুনEsc বন্ধ করুন