SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-26

AI agent থেকে secret ও API key নিরাপদে রাখুন

একটি tool call-এই agent আপনার API key ফাঁস করতে পারে। আসল key না দিয়ে credential gateway-এর আড়ালে সীমিত-পরিসরের স্বল্পস্থায়ী token ব্যবহার করুন।

AI agent-এর কাছ থেকে secret বাইরে রাখার অর্থ

একটি AI agent হলো একটি সাধারণ Linux process, যা command চালায়। সেই process-এর কাছে থাকা প্রতিটি environment variable তার চালানো code পড়তে পারে। তাই agent-এর environment-এ থাকা একটি API key এমন একটি key, যা agent তার কাছে পৌঁছানো যেকোনো host-এ পাঠাতে পারে। Agent-এর কাছ থেকে secret বাইরে রাখার অর্থ হলো তাকে key না দিয়ে একটি handle দেওয়া: স্বল্পস্থায়ী, সীমাবদ্ধ-পরিসরের token, অথবা এমন একটি placeholder, যা network boundary-তে অন্য কোনো ব্যবস্থা আসল মান দিয়ে প্রতিস্থাপন করে।

এটি কোনো model hostile হয়ে যাওয়ার ঘটনা নয়। প্রক্রিয়াটি আরও সাধারণ। একটি agent এমন web page, README বা issue comment পড়ে যাতে নির্দেশনা থাকে, এবং সেগুলো অনুসরণ করে। কারণ language model-এর কাছে আপনার লেখা text এবং তার fetch করা text-এর মধ্যে কোনো পার্থক্য নেই। এটিই prompt injection। এটি ঘটার পরে ক্ষতির সীমা ঠিক একটি বিষয়ের ওপর নির্ভর করে: process কী পড়তে পারে। আপনি যদি এখনো কোনো boundary নির্ধারণ না করে থাকেন, server-এ coding agent নিরাপদে চালানো এই guide-এর ভিত্তি হিসেবে ব্যবহৃত isolation স্তরগুলো ব্যাখ্যা করে।

সহজ ভাষায় threat model

এটি আপনার agent যে user হিসেবে চলে, সেই user হিসেবে চালান।

tr '\0' '\n' < /proc/self/environ | grep -iE 'key|token|secret|password'

এটি যে প্রতিটি line প্রিন্ট করে, তা একজন অপরিচিত ব্যক্তির server-এ একটি HTTP request-এর মাধ্যমে পৌঁছানোর মতো। এখন agent-এর কাছাকাছি disk-এ কী আছে তা দেখুন।

grep -rIl --exclude-dir=.git -e 'API_KEY' -e 'SECRET' ~/projects
find ~ -maxdepth 3 -name '.env' -o -name 'credentials' -o -name '*.pem'

shell-সহ একটি agent-এর ওই data বাইরে পাঠাতে কোনো জটিল exploit দরকার হয় না। চারটি সাধারণ পথই যথেষ্ট, এবং log-এ চারটিকেই স্বাভাবিক কাজের মতো দেখায়:

  • যেকোনো host-এ outbound curl বা fetch, যেখানে value query string-এ থাকে।
  • এমন একটি repository-তে git commit এবং git push, যেখানে agent লিখতে পারে।
  • একটি package install script, যা agent-এর user হিসেবে নির্বিচারে code চালায়।
  • এমন hostname-এর DNS lookup, যার মধ্যে value থাকে; HTTP egress blocked থাকলেও এটি বাইরে চলে যায়।

শুধু review করে এই ঝুঁকি দূর করা যাবে না। সমাধান হলো, agent-এর নাগালের মধ্যে মূল্যবান কিছু না রাখা।

ওয়ার্কিং ট্রিতে থাকা secret context window-এ থাকা secret

একজন agent ফাইল পড়ে। যে repository-তে সে কাজ করছে, সেখানে থাকা .env file পড়া হবে। একবার পড়া হলে সেটি context window-এ থাকে। অর্থাৎ সেটি transcript-এ, আপনার রাখা যেকোনো log-এ এবং agent পরবর্তী সময়ে যা লিখবে তাতেও থাকতে পারে।

আগে, agent যে tree-তে কাজ করে সেখানে key রাখা থাকলে:

cd ~/projects/billing
cat .env
# STRIPE_SECRET_KEY=sk_live_...
# DATABASE_URL=postgres://app:hunter2@db.internal:5432/billing

পরে, file-টি agent-এর নাগালের বাইরে সরিয়ে নিলে:

sudo install -d -m 750 -o root -g agent-review /etc/agent-review
sudo install -m 640 -o root -g agent-review ~/projects/billing/.env /etc/agent-review/billing.env
rm ~/projects/billing/.env

working tree-তে file-টি আর না থাকায় agent-এর user সেটি খুলতে পারে না। Agent-এর নিজস্ব config-এর deny rule হলো দ্বিতীয় স্তরের সুরক্ষা, প্রথম স্তর নয়। Claude Code project-এ .claude/settings.json থেকে permission rule পড়ে:

{
  "permissions": {
    "deny": ["Read(./.env)", "Read(./secrets/**)", "Read(./**/*.pem)"]
  }
}

এটি exploration করার সময় agent-এর ভুল করে কোনো file খোলার ঘটনা ঠেকায়। কিন্তু এটি কোনো injected instruction-কে base64 .env চালানো থেকে ঠেকায় না, কারণ সেটি shell command, file read নয়। ওই command চালানোর আগে আপনাকে জিজ্ঞেস করা হবে কি না, তা session-এর permission mode-এর ওপর নির্ভর করে। August 2026-এ auto mode Claude Code-এর default হয়ে যায়। তাই আপনি যে server পর্যবেক্ষণ করছেন না, সেটি prompt ছাড়াই আরও বেশি command চালাতে পারে। একই সীমা agent-এর permission নয়, বরং তার কাজের অভ্যাসকে প্রভাবিত করে এমন যেকোনো কিছুর ক্ষেত্রেও প্রযোজ্য। agent-কে কার্যকর সবচেয়ে ছোট পরিবর্তনে সীমাবদ্ধ রাখা একটি skill run-কে এমন file-এ ঢুকে পড়া থেকে বিরত রাখে, যেগুলো খোলার কোনো কারণ agent-এর ছিল না। তবে এটিও এমন পরামর্শ, যেটি model-কে প্রভাবিত করে পরিবর্তন করানো সম্ভব। Config-কে guardrail এবং filesystem permission-কে দেয়াল হিসেবে বিবেচনা করুন। একই বিভাজন container-এর ভেতরেও প্রযোজ্য: Docker Compose-এ env file এবং secret এই সমস্যার এক স্তর নিচের সংস্করণটি ব্যাখ্যা করে।

প্রতিটি agent-এর জন্য আলাদা unprivileged user দিন

agent আপনার user হিসেবে চললে আপনার SSH key, cloud credential এবং shell history-ও সেটি পেয়ে যায়। আলাদা user তৈরি করতে একটি command লাগে এবং এসবের সম্পূর্ণ access বন্ধ হয়।

sudo adduser --disabled-password --gecos "" agent-review
sudo chmod 700 /home/agent-review
sudo -u agent-review cat ~/.ssh/id_ed25519

শেষের line-টি cat: /home/you/.ssh/id_ed25519: Permission denied সহ fail করবে। এর পরিবর্তে যদি একটি key print হয়, তাহলে আপনার home directory group বা world readable; chmod 700 ~ এটি ঠিক করে। agent user-কে sudo-এ যুক্ত করবেন না এবং তার সত্যিই প্রয়োজন এমন একটি command-এর চেয়ে বিস্তৃত কোনো NOPASSWD rule দেবেন না। VPS-এ least privilege user group এবং sudoers-এর বিস্তারিত ব্যাখ্যা করে। একাধিক session চালালে এই separation বজায় রাখুন, কারণ একটি Claude Code session সরাসরি অন্য session-এ text পাঠাতে পারে, এবং প্রথম session-এ থাকা যেকোনো তথ্য একটি message-এর মাধ্যমে ওই channel পার হতে পারে।

cloud VPS-এ আরও একটি boundary যোগ করা উচিত। instance metadata service একটি নির্দিষ্ট link-local address-এ response দেয় এবং প্রায়ই যে কোনো অনুরোধকারীকে role credential প্রদান করে।

sudo iptables -A OUTPUT -m owner --uid-owner agent-review -d 169.254.169.254 -j REJECT

agent-এর দিক থেকে এটি পরীক্ষা করুন। sudo -u agent-review curl -s --max-time 3 http://169.254.169.254/ কিছুই print করবে না এবং non-zero exit status-এ শেষ হবে, কারণ packet-টি box ছাড়ার আগেই reject হয়।

সীমান্তে credential injection করুন

এই সমস্যার কার্যকর সমাধান হলো credential injection। agent কখনো আসল key ধারণ করে না। এটি একটি local gateway-এর মাধ্যমে request পাঠায়, এবং gateway request বাইরে পাঠানোর সময় placeholder-এর বদলে আসল secret বসায়। secret gateway-এর storage-এ থাকে। এটি ভিন্ন process-এ এবং ভিন্ন user-এর মালিকানায় থাকে।

OneCLI এর একটি open source implementation। এটি Apache-2.0 license-এর অধীনে প্রকাশিত এবং agent-এর পাশে container হিসেবে চলে। July 2026 অনুযায়ী project-এ এই setup নথিভুক্ত আছে:

git clone https://github.com/onecli/onecli.git
cd onecli
docker compose -f docker/docker-compose.yml up -d --wait

dashboard port 10254-এ এবং gateway port 10255-এ listen করে। আপনি একবার আসল credential সংরক্ষণ করবেন। এরপর প্রতিটি agent-কে key-এর পরিবর্তে একটি placeholder value এবং তার নিজস্ব scoped access token দেবেন। agent এই token একটি Proxy-Authorization header-এ পাঠায়। gateway host ও path ব্যবহার করে outbound request-এর সঙ্গে সঠিক credential মিলিয়ে নেয়, সংশ্লিষ্ট credential decrypt করে এবং placeholder-এর জায়গায় সেটি বসায়। agent-এর environment-এ চুরি করার মতো কোনো তথ্য থাকে না।

এখানে encryption মূল বিষয় নয়। মূল বিষয় হলো, “এই agent কী ব্যবহার করেছে এবং কখন ব্যবহার করেছে”—এই প্রশ্নের উত্তর একটি log query-তে পাওয়া যায়। ছয়টি environment-এর কোনটিতে key-এর copy ছিল তা অনুমান না করে আপনি একটি audit trail পরীক্ষা করতে পারেন।

গোপন তথ্য environment-এ নয়, process-কে দিন

আপনি যদি agent-কে systemd-এর অধীনে চালান, তাহলে environment variable-এর কোনো প্রয়োজন নেই। LoadCredential= গোপন তথ্যটি এমন একটি private directory-তে রাখে, যা শুধু ওই service পড়তে পারে। Unit file-এ এটি %d হিসেবে এবং process-এর ভিতরে $CREDENTIALS_DIRECTORY হিসেবে প্রকাশিত হয়। মানটি কখনো /proc/<pid>/environ-এ দেখা যায় না। তাই ps eww এটি দেখাতে পারে না। Service বন্ধ হলে directory-টিও মুছে যায়।

প্রথমে credential-টি machine-এর জন্য encrypt করুন। এই command-গুলো systemd documentation থেকে নেওয়া এবং systemd 250 বা পরবর্তী সংস্করণে কাজ করে। এর মধ্যে Ubuntu 24.04 এবং Debian 13 অন্তর্ভুক্ত:

echo -n 'sk-example-value' > /tmp/plain.txt
sudo systemd-creds encrypt --name=api_key /tmp/plain.txt /etc/credstore/api_key.cred
shred -u /tmp/plain.txt
sudo systemd-run -P --wait -p LoadCredentialEncrypted=api_key:/etc/credstore/api_key.cred \
  systemd-creds cat api_key

শেষ command-টি sk-example-value প্রদর্শন করে। এর মাধ্যমে নিশ্চিত হওয়া যায় যে encrypted file-টি এই host-এ decrypt করা যায়। এরপর unit-এ সেটি উল্লেখ করুন:

[Service]
User=agent-review
LoadCredentialEncrypted=api_key:/etc/credstore/api_key.cred
Environment=AGENT_KEY_FILE=%d/api_key
ExecStart=/usr/local/bin/agent-worker

প্রয়োজনের সময় আপনার agent code $AGENT_KEY_FILE-এ file-টি open করবে। File পড়ার কাজটি একটি নির্দিষ্ট মুহূর্তে হয়। Environment variable process-এর পুরো lifetime জুড়ে থাকে এবং process যে প্রতিটি child তৈরি করে, সেখানেও থাকে।

দীর্ঘমেয়াদি key-এর পরিবর্তে স্বল্পমেয়াদি token ব্যবহার করুন

মেয়াদ শেষ হয় না এমন একটি cryptographic key কয়েক মাস পরে log বা transcript-এ প্রকাশ পেলেও তখনও বৈধ থাকে। কোনো service session token দিলে সেটিই ব্যবহার করুন এবং কাজের জন্য যত কম lifetime সম্ভব সেট করুন।

aws sts assume-role \
  --role-arn arn:aws:iam::123456789012:role/agent-readonly \
  --role-session-name agent-review \
  --duration-seconds 900

AWS STS (security token service) সর্বনিম্ন 15 মিনিটের lifetime গ্রহণ করে। সাধারণত একটি agent task-এর জন্য এটিই যথেষ্ট। GitHub-এর ক্ষেত্রে agent user-এর জন্য আলাদা gh login দিন এবং এমন fine-grained token ব্যবহার করুন, যার scope শুধু সেই single repository-তে সীমাবদ্ধ যেখানে agent কাজ করে। এতে ওই session-এর মধ্যে gh auth token চালালে এমন credential ফেরত আসে, যা অন্য কোনো resource-এ access করতে পারে না। প্রথমে resource অনুযায়ী scope সীমাবদ্ধ করুন, তারপর সময় অনুযায়ী।

যাচাই করুন, তারপর যাচাই চালিয়ে যান

কোনো agent-এর setup পরিবর্তন করার পরে তিনটি check চালানো উচিত। এগুলো নিজের user হিসেবে নয়, agent-এর user হিসেবে চালান।

sudo -u agent-review env | grep -iE 'key|token|secret'
sudo -u agent-review ls -la /home/you/ 2>&1 | head -3
sudo -u agent-review curl -s -o /dev/null -w '%{http_code}\n' --max-time 5 https://api.github.com/user

প্রথম command-টি একেবারেই কোনো output দেবে না। দ্বিতীয়টি ls: cannot open directory '/home/you/': Permission denied দেখাবে। তৃতীয়টি জানাবে agent-এর network path কোন identity উপস্থাপন করছে। Gateway pattern-এর উদ্দেশ্যই হলো এই প্রশ্নের উত্তর দেওয়া: 401 মানে agent নিজের কোনো GitHub credential বহন করছে না, আর 200 মানে এটি একটি credential বহন করছে। তাই কোন token ব্যবহৃত হচ্ছে তা আপনার জানা উচিত। আপনি unattended agent চালালে VPS-এ AI agent-এর খরচ নিয়ন্ত্রণ করা অংশে এই access limit-এর সঙ্গে সামঞ্জস্যপূর্ণ budget limit ব্যাখ্যা করা হয়েছে।

FAQ

আমি কি শুধু মডেলকে বিশ্বাস করতে পারি যে এটি আমার key ফাঁস করবে না?

না, কারণ এই threat model-এ আক্রমণকারী মডেল নয়। Agent web page, repository এবং issue tracker থেকে text পড়ে, আর সেই text-এ instruction থাকতে পারে। মডেল তার নিজের instruction এবং fetch করা text-এর মধ্যে নির্ভরযোগ্যভাবে পার্থক্য করতে পারে না। মডেল সঠিক সিদ্ধান্ত নেবে—এমন নিয়ন্ত্রণ প্রথম convincing injected instruction-এর সময়ই ব্যর্থ হবে। তাই নিয়ন্ত্রণটি operating system বা network স্তরে থাকতে হবে।

Agent-এর secret-এর জন্য environment variable কি সত্যিই এত খারাপ?

একটি নির্দিষ্ট কারণে এগুলো খারাপ: এগুলো inherited হয়। Agent যে প্রতিটি child process চালায়, সেটি একটি copy পায়। এর মধ্যে build script, test runner এবং যেকোনো package install hook-ও রয়েছে। একই user-এর মাধ্যমে /proc/<pid>/environ ব্যবহার করেও variable পড়া যায়। তাই agent কোনো variable নিজে pass না করলেও agent যে program চালায়, সেটি variable পড়তে পারে। ব্যবহারের সময় file পড়লে, LoadCredential= বা gateway ব্যবহার করে exposure কেবল সেই সময়ের মধ্যে সীমিত রাখা যায়।

Vault-এ secret রাখলে কি একাই এই সমস্যা সমাধান হয়?

শুধু আংশিকভাবে। Vault storage-এর সমস্যা সমাধান করে। আপনি নিজে সেই vault host করলে সেটিকেও আলাদাভাবে harden করতে হবে, কারণ Vaultwarden server সাধারণত তার admin token বা backup file-এর মাধ্যমে breach হয়, এতে থাকা encrypted item-এর মাধ্যমে নয়। তবে শেষ ধাপের সমস্যা এটি সমাধান করে না। কোনো কিছু vault থেকে secret নিয়ে agent-কে environment variable হিসেবে দিলে আপনি আবার আগের অবস্থায় ফিরে যান। আসল বিষয় হলো substitution কে করছে। Agent secret fetch করলে secret agent-এর কাছেই থাকে। Gateway বা init system agent-এর process-এর বাইরে substitution করলে agent কখনো secret ধরে না।

কোনো agent ইতিমধ্যে কিছু leak করেছে কি না তা কীভাবে বুঝব?

সাধারণত ঘটনার পরে তা নিশ্চিতভাবে জানা যায় না। এটাই gateway ব্যবহারের পক্ষে যুক্তি। Gateway ছাড়া আপনার evidence shell history, agent-এর transcript এবং outbound connection log-এ ছড়িয়ে থাকে। এগুলোর মধ্যে outbound connection log আপনি সম্ভবত রাখছেন না। Credential gateway থাকলে credential ব্যবহারের প্রতিটি ঘটনা agent identity এবং timestamp-সহ একটি line-এ নথিভুক্ত হয়। Leak হয়েছে বলে সন্দেহ হলে আগে key rotate করুন, পরে investigation করুন। Rotation সস্তা; নিশ্চিততা নয়।

আজ আমার ন্যূনতম কী করা উচিত?

প্রতিটি .env file agent যে directory-গুলোতে কাজ করে, সেগুলো থেকে সরিয়ে নিন। প্রতিটি agent-এর জন্য একটি করে unprivileged user তৈরি করুন। এই দুটি পরিবর্তন করতে প্রায় দশ মিনিট লাগে এবং সবচেয়ে সাধারণ পথ বন্ধ করে। সেই পথে agent এমন একটি credential file পড়ে, যার code-এর পাশে থাকার কোনো কারণ ছিল না। Gateway এবং short-lived token পরের ধাপ, প্রথম ধাপ নয়। একই starting point যেকোনো agent runtime-এর ক্ষেত্রেই প্রযোজ্য, যার মধ্যে VPS-এ autonomous agent নিরাপদে চালানো অন্তর্ভুক্ত।