আমাদের আগের পোস্টে সম্পর্কে CI/CD Pipelines, আমরা দেখেছি কীভাবে হ্যাক করতে হয় CI/CD যে দৃশ্যকল্প সম্ভবতঃ সুরক্ষিত ছিল।
চলুন আগের পোস্টে আমাদের মূল বক্তব্যটি স্মরণ করি: আমরা কিছু দিয়ে শুরু করেছিলাম pipeline যেটি ঝুঁকিপূর্ণ ছিল পরোক্ষ বিষক্রিয়া Pipeline ফাঁসি (আই-পিপিই) এবং, এটি ঠিক করার জন্য, আমরা বিভক্ত করার সিদ্ধান্ত নিয়েছি pipeline দুটি ভাগে:
- 1 ম pipeline (বিল্ড সিআই), যা ডি-পিপিই এবং আই-পিপিই-এর জন্য নিরাপদ, পিআর কোড চেকআউট করবে, বিল্ড তৈরি করবে এবং একটি আর্টিফ্যাক্ট জেনারেট করবে।
- ২ য় pipeline (টেস্ট সিআই), যা ডি-পিপিই এবং আই-পিপিই-এর জন্যও নিরাপদ, বেস কোড চেকআউট করবে (শেল স্ক্রিপ্ট পরিবর্তন এড়ানোর জন্য) এবং আর্টিফ্যাক্টের উপর মূল স্ক্রিপ্টগুলো এক্সিকিউট করবে।
- টেস্ট সিআই সিঙ্ক্রোনাইজ করতে pipeline বিল্ড সিআই (Build CI) এর পরে চালানোর জন্য pipeline, আমরা ব্যবহার করেছি ওয়ার্কফ্লো_রান ট্রিগার
আমরা এটিকে সিনারিও #৩ নাম দিয়েছি।

যদিও, আমরা সেই পোস্টে যেমন উল্লেখ করেছি, অন্যান্য সমাধানও রয়েছে, আমরা শিক্ষাগত কারণে এই “সমাধানটি” প্রয়োগ করার সিদ্ধান্ত নিয়েছি, যাতে আমরা দুর্বলতাগুলোর গভীরে প্রবেশ করতে পারি। CI/CD pipelines.
এরপরে, আমরা দেখলাম কীভাবে এই পরিস্থিতিটি হ্যাক করা যায় প্রত্নবস্তুটিকে বিষাক্ত করাএকেই আমরা বলি আর্টিফ্যাক্ট পয়জনিংঅর্থাৎ পরিবর্তন (হ্যাক) করার ক্ষমতা pipeline একটি যুক্তি পরিবর্তন করে pipeline প্রত্নবস্তু।
এই পদ্ধতিতে সমস্যাটা কী? আমরা দেখেছি যে, সমস্যাটি তখনই দেখা দেয় যখন কোনো ব্যবহারকারী একটি নতুন “তৈরি” করে। pipeline.
যদি কোনো ব্যবহারকারী একটি নতুন পিআর খোলে pipelineগিটহাব তা কার্যকর করবে pipeline (কিছু শর্ত সাপেক্ষে, যেমনটা আমরা দেখেছি) পদে).
এরপর ব্যবহারকারী একটি নতুন তৈরি করতে পারবেন। pipeline Build CI-এর সাথে একই নামে!! হ্যাঁ, এটা আশ্চর্যজনক, কিন্তু GitHub আপনাকে দুটি তৈরি করার অনুমতি দেয়। pipelineএকই নামের আরও আছে!!
যখন ব্যবহারকারী এই পরিবর্তনগুলো সহ একটি PR খোলেন, “নতুন” pipeline কার্যকর করা হবে (একটি বিষাক্ত আর্টিফ্যাক্ট আপলোড করা) এবং Deploy CI pipeline এর পরে এটি কার্যকর করা হবে, যার ফলে "সংশোধিত" শেল স্ক্রিপ্টটি "মূল" শেল স্ক্রিপ্টটিকে ওভাররাইট করবে। pipeline কর্মক্ষেত্র। সুতরাং, এই “সমাধান” I-PPE দুর্বলতা এড়াতে পারে না (যেমনটি আমরা নীচে দেখতে পাচ্ছি)।

সমস্যাগুলো কী? অন্তত, কয়েকটি বিষয় তো আছেই:
- প্রথমত, কীভাবে নিশ্চিত হওয়া যাবে যে বিল্ড প্রক্রিয়ায় কোনো রকম কারসাজি করা হয়নি? এই পরিস্থিতিতে, দূষিত ব্যবহারকারী তাদের ব্যবহার করে উদ্দিষ্ট বিল্ড প্রক্রিয়াটি পরিবর্তন করতে সক্ষম হয়েছে। pipeline একটি বিষাক্ত প্রত্নবস্তু তৈরি করতে।
- দ্বিতীয়ত, আমরা কীভাবে কোনো প্রত্নবস্তুর উৎস নির্ণয় করতে পারি?
এই প্রশ্নগুলো আমাদেরকে এর আলিঙ্গনে নিক্ষেপ করে। সফটওয়্যার অ্যাটেস্টেশন ডোমেইন!!
সফটওয়্যার অ্যাটেস্টেশন
An প্রত্যায়ন একটি টুকরা উপাত্ত প্রতিনিধিত্বমূলক একটি ঘটনার প্রমাণবাস্তব জগতে, আমরা সাধারণত এগুলোকে বলি সার্টিফিকেশন.
উদাহরণস্বরূপ, যখন কোনো ল্যাব আপনার রক্ত পরীক্ষা করে, তখন পরীক্ষা সংক্রান্ত তথ্য রেকর্ড ও প্রত্যয়িত করা হয়। রক্ত পরীক্ষার ফলাফলগুলো হলো প্রতিপাদ্য এবং অনুসরণযোগ্য.

আমাদের আইটি ডোমেনের কাছাকাছি হলে, আপনি অনুমান করতে পারবেন যে এই প্রক্রিয়াটির অনুবাদ, উদাহরণস্বরূপ, একটি কম্পাইলেশন প্রক্রিয়া কেমন হবে।

কম্পাইলেশন সার্ভার পরিবেশ ও টুলস, উপকরণ (সোর্স কোড), এবং উৎপাদিত বস্তু/আর্টিফ্যাক্ট (বাইনারি কোড) সম্পর্কিত তথ্য এই ধরনের প্রত্যয়নের অংশ হবে।
স্পষ্টতই, বিশ্বাসযোগ্যতা প্রদানের জন্য সত্যায়নটি অবশ্যই একজন অনুমোদিত (প্রমাণিত ও অখণ্ডনীয়) সত্যায়নকারী দ্বারা প্রস্তুত হতে হবে।
সম্ভবত, আপনাদের মধ্যে কেউ কেউ ভাবছেন... এবং সেটা কী? স্বাক্ষর এবং সত্যায়নের মধ্যে পার্থক্য?
কোড স্বাক্ষর এবং প্রত্যয়ন
উচ্চ স্তরে, একটি স্বাক্ষর একটি কী পেয়ার এবং একটি আর্টিফ্যাক্ট ব্যবহার করে এটি তৈরি করা হয়। কী পেয়ারটিতে একটি পাবলিক কী এবং একটি প্রাইভেট কী থাকে।

ব্যবহারকারী প্রাইভেট কী ব্যবহার করে কোনো আর্টিফ্যাক্টে স্বাক্ষর করেন এবং অন্যরা তখন পাবলিক কী ব্যবহার করে সেই স্বাক্ষর যাচাই করতে পারেন। প্রাইভেট কী অবশ্যই গোপন রাখতে হবে, কিন্তু পাবলিক কী ব্যাপকভাবে বিতরণ করা হয়।
স্বাক্ষর ব্যবহার করা যেতে পারে প্রমাণ করতে যে প্রাইভেট কী-এর ধারক আর্টিফ্যাক্টটিতে স্বাক্ষর করার জন্য প্রাইভেট কী-টি ব্যবহার করেছেন।.
স্বাক্ষর প্রমাণ করবেন না
- ব্যবহারকারীর উদ্দেশ্য প্রত্নবস্তুটিতে স্বাক্ষর করতে (তারা প্রতারিত হতে পারতেন), অথবা
- ব্যবহারকারীর যেকোনো কিছু করার অভিপ্রায় প্রত্নবস্তু সম্পর্কে নির্দিষ্ট দাবি
সঙ্গে সার্টিফিকেটসরাসরি কোনো আর্টিফ্যাক্টে স্বাক্ষর করার পরিবর্তে, ব্যবহারকারীরা এক ধরনের দলিল যে তাদের উদ্দেশ্য তুলে ধরে প্রত্নবস্তুতে স্বাক্ষর করার পিছনে এবং যেকোনো নির্দিষ্ট দাবি এই স্বাক্ষরের অংশ হিসেবে তৈরি করা হচ্ছে।
ইন-টোটো অ্যাটেস্টেশন ফ্রেমওয়ার্ক
সবচেয়ে সাধারণ কাঠামোটি হল সম্পূর্ণ প্রত্যয়ন কাঠামো
- সংজ্ঞা দেয় standard প্রত্যয়নের ফর্ম্যাট যেগুলো বিষয়বস্তুকে, অর্থাৎ বর্ণিত প্রত্নবস্তুগুলোকে, প্রত্নবস্তুটি সম্পর্কিত প্রমাণীকৃত মেটাডেটার সাথে সংযুক্ত করে।
- একটি সেট প্রদান করে পূর্ব-নির্ধারিত বিধেয় সফটওয়্যার সরবরাহ শৃঙ্খল জুড়ে এবং জুড়ে প্রমাণীকৃত মেটাডেটা যোগাযোগের জন্য
চলুন অ্যাটেস্টেশন ফরম্যাটটি সম্পর্কে বিস্তারিত আলোচনা করা যাক।
An স্বীকৃতি ইহা একটি ডিজিটালভাবে স্বাক্ষরিত নথি ধারণকৃত বিবৃতি।
সার্জারির বিবৃতি প্রত্যয়নের মধ্যবর্তী স্তর, যা এটিকে একটি নির্দিষ্ট বিষয়ের সাথে আবদ্ধ করে। বিষয় এবং প্রকারগুলি দ্ব্যর্থহীনভাবে চিহ্নিত করা ভবিষ্যদ্বাণী:
- বিষয়: ক আর্টিফ্যাক্টটির ক্রিপ্টোগ্রাফিকভাবে সুরক্ষিত রেফারেন্স (সাধারণত হ্যাশের মাধ্যমে), এবং
- পূর্বাভাস দেয়নির্দিষ্ট একটি সেট দাবি সেই আর্টিফ্যাক্ট সম্পর্কিত যেকোনো কিছুকে একটি বিবৃতি বলা হয়। এই দাবিগুলো ব্যবহার করে আপনি যা কিছু ভাবতে পারেন, তার সবকিছুই প্রকাশ করা (এবং পরে প্রমাণ করা) যেতে পারে! এগুলো ম্যানুয়াল অনুমোদন, আর্টিফ্যাক্টের উৎস, স্বয়ংক্রিয় পরীক্ষার ফলাফল, একটি অডিট ট্রেইল বা আরও অনেক কিছু উপস্থাপন করতে পারে!
যখন এই বিবৃতিটি ক্রিপ্টোগ্রাফিকভাবে স্বাক্ষরিত হয়, তখন এটিকে একটি হিসাবে উল্লেখ করা হয় স্বীকৃতি

এইভাবে, উদাহরণস্বরূপ, অ্যালিস একটি প্রত্নবস্তু সম্পর্কে একটি বিবৃতি তৈরি করে এবং তার ব্যক্তিগত কী ব্যবহার করে তাতে স্বাক্ষর করে একটি প্রত্যয়নপত্র তৈরি করে।
- বব তখন পারে স্বাক্ষর যাচাই করুন সেই প্রত্যয়নে, তাকে অনুমতি দিয়ে দাবিগুলো বিশ্বাস করতে ভিতরে.
বব তখন সেই দাবিগুলো ব্যবহার করতে পারে। সিদ্ধান্ত নিতে এই নিদর্শনটি ব্যবহারের অনুমতি দেওয়া হবে কি না।

প্রত্যয়ন কি প্রত্নবস্তু বিষক্রিয়া সমাধানে সাহায্য করতে পারে?
অ্যাটেস্টেশন-এর এই পরিচিতির পর, চলুন আমাদের মূল সমস্যায় ফিরে যাই। অ্যাটেস্টেশন কীভাবে আমাদের সমস্যা সমাধানে, অর্থাৎ আর্টিফ্যাক্ট পয়জনিং এড়াতে সাহায্য করতে পারে?
ক্ষতিকারক ব্যবহারকারী “অফিসিয়াল” প্রক্রিয়াটিকে পাশ কাটিয়ে, অর্থাৎ তার নিজের প্রযুক্তি ব্যবহার করে একটি আর্টিফ্যাক্ট তৈরি করতে সক্ষম হয়েছিল। pipeline আর্টিফ্যাক্টটি তৈরি করতে।
এটা চমৎকার হবে যদি আমরা প্রমাণ করতে পারি যে ডাউনলোড করা আর্টিফ্যাক্টগুলো অফিসিয়াল সফটওয়্যার দিয়ে তৈরি করা হয়েছে। pipelineএটাকে আমরা “টেম্পারিং পয়েন্ট” বলতে পারি এমন বিষয়ের মাত্র একটি উদাহরণ, কিন্তু এরকম আরও অনেক থাকতে পারে।

উপরের ছবিতে যেমন দেখতে পাচ্ছেন, কারসাজির সুযোগ একাধিক। এভাবে, ভোক্তা pipeline (আমাদের উদাহরণে টেস্ট CI) অবশ্যই মূল্যায়ন করতে হবে নির্মাণ প্রক্রিয়ার অখণ্ডতা পাশাপাশি প্রত্নবস্তুটির অখণ্ডতা.
আমাদের উদাহরণে, একটি নতুন (বিষাক্ত) বস্তু প্রবর্তন করে বিষাক্ত নিদর্শনটি তৈরি করা হয়েছে। pipeline যা বিল্ড প্রক্রিয়ায় হস্তক্ষেপ করে। কিন্তু ক্ষতিকারক ব্যবহারকারী নিম্নলিখিত কাজগুলো করতে সক্ষম হতে পারত:
- চেক আউট করার পরে কোডটি পরিবর্তন করুন SCM একটি ক্ষতিকারক বাইনারি তৈরি করতে
- কম্পাইলেশনের মাধ্যমে উৎপাদিত সঠিক বাইনারিটিকে অন্য কোনো ক্ষতিকারক বাইনারি দিয়ে প্রতিস্থাপন করুন।
- আর্টিফ্যাক্ট রেজিস্ট্রি লঙ্ঘন করুন এবং অন্য কোনো উপায়ে তৈরি একটি বিষাক্ত আর্টিফ্যাক্ট আপলোড করুন।
- ইত্যাদি।
যেমনটি দেখতে পাচ্ছেন, এখানে একাধিক “বিকৃতি” করার স্থান থাকতে পারে।
এখানে গুরুত্বপূর্ণ কী? স্পষ্টতই, সেই সমস্ত “টেম্পারিং” পয়েন্টগুলোকে রক্ষা করা। কিন্তু, শেষ পর্যন্ত, সবচেয়ে গুরুত্বপূর্ণ হলো... যাতে প্রত্নবস্তুটির ‘ভোক্তা’ সেটির অখণ্ডতা মূল্যায়ন করতে পারেন এবং সেটি নিয়ে অগ্রসর হবেন কি না, সে বিষয়ে সিদ্ধান্ত নিতে পারেন।
আমরা পারি একটি প্রত্নবস্তুর অখণ্ডতা মূল্যায়ন করুন দুইভাবে।
একটি হলো মূল্যায়ন করে উৎস প্রত্নবস্তুটির।
একটি তৈরি করে উৎস প্রমাণপত্রআমরা আর্টিফ্যাক্টটি সম্পর্কে প্রয়োজনীয় মেটাডেটা (যা যথাযথভাবে প্রমাণীকৃত এবং অখণ্ডনীয়) প্রদান করি। নিম্নলিখিত উদাহরণগুলিতে, আমরা ব্যবহার করব জাইজেনি সল্ট (Software Attestations Layer for Trust), সফটওয়্যার অ্যাটেস্টেশন তৈরি, নিবন্ধন এবং যাচাই করার উপাদান।

- name: Building ...
run: |
# mvn will compile and create target/MyApp.war
mvn clean package
- name: Generating provenance
run: |
#!/usr/bin/env bash
shopt -s expand_aliases
alias salt=$PWD/salt_pro/xygeni_salt/salt
echo " "
echo "-----------"
echo "Generating Provenance with CLI ..."
salt at slsa \
--basedir ${GITHUB_WORKSPACE}/target \
--key="${PRIVATE_KEY}" \
--public-key=${GITHUB_WORKSPACE}/Test1_public.pem \
--key-password=${KEY_PASSWD} \
--output-unsigned=${GITHUB_WORKSPACE}/cli_provenance_${PIPELINE}_unsigned.json \
--pipeline ${PIPELINE} --pretty-print \
--file ./MyApp.war
উপরের কোডে আপনি দেখতে পাচ্ছেন, একটি ধাপ আছে যা war ফাইলটি তৈরি করে এবং দ্বিতীয় ধাপে . উৎস প্রমাণপত্রএটা করতে, pipeline প্রাইভেট কী ব্যবহার করে এবং অ্যাটেস্টেশনে পাবলিক কী-ও অন্তর্ভুক্ত করে।
পর্দার আড়ালে, জাইজেনির লবণ কমান্ডটি অ্যাটেস্টেশনটি সংরক্ষণ করে। খতিয়ান (যা একটি প্রত্যয়ন রেজিস্ট্রি নামেও পরিচিত,) নথি আমাদের ক্ষেত্রে (কিন্তু আপনি অন্য যেকোনোটি ব্যবহার করতে পারেন)। সেটা করা হয়েছে, ভোক্তা pipeline জাইজেনিস অন্তর্ভুক্ত করতে পারে যাচাইকরণ ইঞ্জিন প্রত্নবস্তুটির উৎস যাচাই করা এবং এর অখণ্ডতা মূল্যায়ন করা।
- name: 'Verifying the attestation'
run: |
#!/usr/bin/bash
echo " "
echo "-------"
# Calculate sha256sum for the artifact
SHA_SUM=$(sha256sum ./MyApp.war | cut -f1 -d ' ')
# Recover the attestation Id from the sha256sum
ATT_ID=$(echo $(salt -q registry search --digest sha256:$SHA_SUM --format json) | jq -r .[-1].gitoidSha256)
echo " "
echo "-------"
# Download the provenance attestation
echo "Downloading the provenance attestation ..."
salt -q reg get --id=$ATT_ID --format=json > ${GITHUB_WORKSPACE}/provenance_kk.signed.json
echo " "
echo "-------"
echo "Verifying provenance ..."
salt verify \
--basedir ${GITHUB_WORKSPACE} \
--attestation=${GITHUB_WORKSPACE}/provenance_kk.signed.json \
--public-key=${GITHUB_WORKSPACE}/Test1_public.pem \
--file ./MyApp.war
যাচাইকরণ প্রক্রিয়াটি মূল্যায়ন করে:
- সার্জারির আর্টিফ্যাক্টের sha256sum বৈধ (অর্থাৎ সেই “বিষয়টি” সম্পর্কে একটি প্রত্যয়ন রয়েছে), এবং
- সার্জারির প্রত্যয়ন যথাযথভাবে প্রমাণীকৃত। (এটি যথাযথ ব্যক্তিগত কী ব্যবহার করে তৈরি করা হয়েছে)
এই যাচাই প্রক্রিয়ার মাধ্যমে তখন মূল্যায়ন করা যায় যে প্রত্নবস্তু এবং প্রত্যয়নপত্র উভয়ই বৈধ।
কিন্তু, যেমনটা আপনার মনে আছে, আমাদের ক্ষেত্রে আর্টিফ্যাক্টটি একটি “ক্ষতিকর” উদ্দেশ্যপ্রণোদিত কারণে তৈরি হয়েছিল। pipeline (অর্থাৎ মূলটি নয়, বরং একটি পরিবর্তিত রূপ) pipelineতাহলে আমাদের আরও একটি দিক যাচাই করতে হবে: তা হলো নিদর্শনটি "মূল" দ্বারা তৈরি করা হয়েছে pipelineঅন্য কোনোটি নয়।
সেটা করার জন্য, ওই শর্তটি যাচাই করতে শুধু একটি সহজ লাইন যোগ করুন, উদাহরণস্বরূপ:
echo " "
echo "-------"
# Download the provenance attestation
echo "Downloading the provenance attestation ..."
salt -q reg get --id=$ATT_ID --format=json > ${GITHUB_WORKSPACE}/provenance_kk.signed.json
WFR=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json |base64 -d | jq -r .predicate.buildDefinition.internalParameters.environment.GITHUB_WORKFLOW_REF)
echo $WFR | grep cicd_top10_3_salt\/.github\/workflows\/build.yml
এই অতিরিক্ত যাচাইকরণটি ব্যর্থ হবে যদি আর্টিফ্যাক্টটি আমাদের "নিরাপদ" দ্বারা তৈরি না হয়ে থাকে। pipeline.
যদি আর্টিফ্যাক্টটি আমাদের মূল দ্বারা তৈরি করা হয়ে থাকে pipeline (cicd_top10_3_salt/.github/workflows/build.yml) ফাইলে grep কমান্ডটি সফল হবে, অন্যথায় এটি ব্যর্থ হবে, যার ফলে সমস্যা তৈরি হবে। pipeline এবং পরবর্তী সকল পদক্ষেপ বাতিল করা হচ্ছে।
"নির্মাতা" pipeline এটি যাচাই করার জন্য টেম্পারিংয়ের মাত্র একটি দিক, কিন্তু যেমনটা আগে উল্লেখ করা হয়েছে, আরও কিছু টেম্পারিংয়ের দিক আছে যা আমাদের যাচাই করা উচিত।
উদাহরণ স্বরূপ, রিপো চেকআউটের পরে এবং বিল্ড কমান্ডের আগে যদি সোর্স কোডে কোনো পরিবর্তন করা হয়ে থাকে, তাহলে কী হবে? এক্ষেত্রে, যে কোডটি বিল্ড করতে হবে তা সংরক্ষিত কোডের মতো নয়। SCM.
প্রতিটি ধাপে উপাদানটির হ্যাশগুলো পরীক্ষা করলেই এই টেম্পারিং পয়েন্টটি যাচাই করা যায়।
SHA_ATT_MATERIAL=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json | base64 -d | jq -r .predicate.attestations[0].predicate.materials[].digest[])
SHA_STEP_MATERIAL=$(jq -r .payload ${GITHUB_WORKSPACE}/provenance_kk.signed.json | base64 -d | jq -r .predicate.attestations[3].predicate.materials[0].digest[])
উপসংহার
সংক্ষেপে, একটি সফটওয়্যার অ্যাটেস্টেশন এটি কোনো সফটওয়্যার সম্পর্কে করা একটি প্রতিপাদন, অর্থাৎ কোনো সফটওয়্যার আর্টিফ্যাক্ট বা সফটওয়্যার আর্টিফ্যাক্টসমূহের সংগ্রহ সম্পর্কে একটি প্রমাণীকৃত বিবৃতি (মেটাডেটা)।
সফটওয়্যার অ্যাটেস্টেশন হলো র আর্টিফ্যাক্ট/কোড সাইনিং-এর একটি সাধারণ রূপ। অ্যাটেস্টেশন হলো একটি স্বাক্ষরিত নথি (একটি নির্দিষ্ট ফরম্যাটে, সাধারণত JSON-ভিত্তিক) যা কোনো আর্টিফ্যাক্টের সাথে মেটাডেটা সংযুক্ত করে। এগুলি প্রতিটি বিল্ড ধাপে ইনপুট (উপকরণ) এবং আউটপুট (উৎপাদিত আর্টিফ্যাক্ট)-এর মধ্যে সংযোগকারী প্রমাণ হিসেবে কাজ করে।
অ্যাটেস্টেশনগুলো চূড়ান্ত সফটওয়্যার আর্টিফ্যাক্ট তৈরির জন্য গৃহীত পদক্ষেপগুলোর একটি যাচাইযোগ্য রেকর্ড প্রদান করে, যার মধ্যে প্রতিটি ধাপের জন্য প্রয়োজনীয় ইনপুট উপকরণ এবং চালিত বিল্ড কমান্ডগুলো অন্তর্ভুক্ত থাকে।
পরিশেষে, আমাদের বিল্ড প্রক্রিয়ার বিভিন্ন অখণ্ডতা যাচাই করার জন্য সফটওয়্যার অ্যাটেস্টেশন একটি চমৎকার পদ্ধতি।
সিরিজটি শেষ করেছেন? চিন্তা করবেন না! নির্দ্বিধায় ফিরে যেতে পারেন।বিষাক্ত Pipeline মৃত্যুদণ্ড (PPE)অথবা অন্য যেকোনো পোস্ট যা আপনার আগ্রহ আবার জাগিয়ে তোলে!
সাথে থাকুন, আমরা সফটওয়্যার অ্যাটেস্টেশন নিয়ে বিস্তারিত আলোচনা করব এবং build security পরবর্তী ব্লগ পোস্টগুলিতে।







