Open Connector self-host করার নিয়ম ও সুবিধা
আপনার নিজস্ব VPS-এ Open Connector সেটআপ করে AI agent-এর নিরাপত্তা নিশ্চিত করুন। SaaS token লিক হওয়া রোধ করতে TLS origin, OAuth callback এবং SQLite ব্যাকআপ কনফিগার করুন।
AI agent-এর জন্য Open Connector যা করে
Open Connector self-host করলে এটি আপনার AI agent এবং তাদের কল করা প্রতিটি software as a service (SaaS) API-এর মাঝে একটি auth gateway হিসেবে কাজ করে, ফলে agent-এর কাছে কখনোই কোনো provider token থাকে না। এটি OOMOL Lab-এর একটি open source gateway, যা Apache 2.0 লাইসেন্সের অধীনে প্রকাশিত। এটি একটি container হিসেবে চলে, একটি মাত্র SQLite ফাইলে এর state জমা রাখে এবং HTTP ও MCP (model context protocol)-এর মাধ্যমে provider action-গুলো উন্মুক্ত করে।
দ্বিতীয় integration-এর সময় থেকেই সমস্যার শুরু হয়। প্রতিটি provider-এর নিজস্ব OAuth (open authorization) flow, নিজস্ব refresh token-এর মেয়াদ এবং নিজস্ব scope নাম থাকে। হাতে কলমে পাঁচটি provider-কে একটি agent-এর সাথে যুক্ত করার অর্থ হলো পাঁচটি redirect handler, পাঁচটি credential store এবং পাঁচটি refresh loop তৈরি করা, যা token-এর মেয়াদ শেষ হওয়ার আগেই কার্যকর হতে হবে। প্রায় কেউই এই কোড লিখতে চায় না। তারা প্রতিটি service-এর জন্য একটি দীর্ঘমেয়াদী personal access token তৈরি করে এবং সেটি agent config, environment file বা সরাসরি prompt-এ বসিয়ে দেয়। এরপর সেই token-টি agent-এর চালানো প্রতিটি tool-এর কাছে পাঠযোগ্য হয়ে ওঠে এবং তা transcript-এ জমা হয়, যা AI agent থেকে গোপনীয়তা রক্ষা নিবন্ধে বর্ণিত ব্যর্থতার কারণ।
একটি auth gateway credential-কে দুই ভাগে বিভক্ত করে। gateway-টি provider credential জমা রাখে এবং OAuth flow পরিচালনা করে। agent একটি runtime token পায় যা শুধুমাত্র gateway-এর বিপরীতে বৈধ। যখন agent কোনো action কল করে, gateway তখন সংরক্ষিত credential লোড করে, সেটিকে server side-এ outbound request-এর সাথে যুক্ত করে এবং শুধুমাত্র response body-টি ফেরত পাঠায়। agent কখনোই provider access token পায় না, তাই agent transcript ফাঁস হয়ে গেলেও আপনার GitHub account-এর পরিবর্তে কেবল একটি বাতিলযোগ্য runtime token-এর ক্ষতি হয়।
এর catalog-এ 1,000-এর বেশি provider এবং 10,000-এর বেশি prebuilt action থাকার বিজ্ঞাপন দেওয়া হয়, যা প্রকল্পটির নিজস্ব পরিসংখ্যান এবং বাইরে থেকে যাচাইযোগ্য নয়। আপনি যা যাচাই করতে পারেন তা হলো এর গঠন: প্রতিটি action-এর জন্য একটি HTTP endpoint, প্রতিটি provider-এর জন্য একটি সংরক্ষিত connection এবং প্রতিটি agent-এর জন্য একটি token।
কেন একটি hosted connector service ব্যবহার না করে Open Connector self-host করবেন
একটি hosted connector service একই কাজ করে এবং এটি আপনার সংযুক্ত প্রতিটি provider-এর refresh token নিজের কাছে জমা রাখে। Google বা GitHub-এর একটি refresh token হলো আপনার মেইল এবং রিপোজিটরির দীর্ঘস্থায়ী চাবিকাঠি, যা সাধারণত পাসওয়ার্ড পরিবর্তনের পরেও কার্যকর থাকে। তাদের নিরাপত্তা বিঘ্নিত হলে তা আপনার নিরাপত্তার জন্য হুমকি হয়ে দাঁড়ায়। Self-hosting-এর মাধ্যমে আপনি এই তথ্যগুলো আপনার নিজের ভাড়া করা এবং পরিচালিত মেশিনের SQLite ডেটাবেসে রাখতে পারেন, যা এমন একটি চাবিকাঠি দিয়ে সুরক্ষিত থাকে যা কখনোই আপনার সার্ভারের বাইরে যায় না।
কাজ শুরু করার আগে এর খরচ সম্পর্কে সচেতন হোন। এই VPS-টি আপনার পরিচালিত সবচেয়ে গুরুত্বপূর্ণ সার্ভারে পরিণত হবে। এটি একটি ফাইলে ডজনখানেক সার্ভিসের কার্যকর credentials জমা রাখে, তাই এটিকে একটি password manager host-এর মতো গুরুত্ব দিন: এমন একটি firewall ব্যবহার করুন যা শুধুমাত্র 443 পোর্ট উন্মুক্ত রাখে, কোনো shared login রাখবেন না, এমন একটি ব্যাকআপ রাখুন যা আপনি অন্তত একবার পুনরুদ্ধার করে দেখেছেন এবং সার্ভার সাড়া দেওয়া বন্ধ করলে যেন সতর্কতা পাওয়া যায়, তার ব্যবস্থা রাখুন। আপনি যদি আপনার পাসওয়ার্ড ভল্ট এই বক্সে না রাখেন, তবে connector-টিও এখানে রাখবেন না।
কোনো কিছু ইনস্টল করার আগে একটি নির্দিষ্ট ভার্সন পিন করুন
Open Connector একটি নতুন প্রজেক্ট। এর রিপোজিটরি প্রথম প্রকাশিত হয় 29 জুন 2026 তারিখে এবং 1 আগস্ট 2026 পর্যন্ত সর্বশেষ ট্যাগ করা রিলিজ হলো v1.3.3, যা 30 জুলাই 2026 তারিখে প্রকাশিত হয়েছে এবং এতে latest ট্যাগটিও রয়েছে। রেজিস্ট্রি একটি tip ট্যাগও প্রকাশ করে, যা main-এর সর্বশেষ কমিট থেকে তৈরি।
এত নতুন একটি প্রজেক্টে পরিবর্তনশীল ট্যাগগুলো ঘনঘন পরিবর্তিত হয়। একটি docker compose pull যা দুটি রিলিজের ব্যবধান অতিক্রম করে, তা আপনার এজেন্টের ওপর নির্ভরশীল কোনো এন্ডপয়েন্ট পরিবর্তন করে দিতে পারে। তখন আপনাকে পুরো সন্ধ্যা ব্যয় করতে হবে এটিকে এজেন্টের সমস্যা হিসেবে ডিবাগ করার জন্য। ইমেজটিকে একটি রিলিজ ট্যাগের সাথে পিন করুন এবং রিলিজ নোট পড়ার পর আপনার সুবিধামতো সময়ে তা আপগ্রেড করুন।
আপনার নিজস্ব VPS-এ TLS-এর পেছনে Open Connector ডেপ্লয় করা
কন্টেইনার শুরু করার আগে আপনার যা প্রয়োজন:
- Ubuntu 24.04 বা সমমানের কোনো সিস্টেমে Docker এবং Compose প্লাগইন
- একটি হোস্টনাম যার A রেকর্ড এই VPS-এর দিকে নির্দেশ করে, উদাহরণস্বরূপ
connect.example.com - একটি রিভার্স প্রক্সি যা ইতিমধ্যে সেই হোস্টনামের জন্য TLS (transport layer security) টার্মিনেট করছে
- নিচে তৈরি করা দুটি র্যান্ডম সিক্রেট
একাধিক Docker Compose অ্যাপের জন্য Traefik রিভার্স প্রক্সি গাইডে প্রক্সি সাইডটি কভার করা হয়েছে। একটি অ্যাপের জন্য শুরু থেকে শেষ পর্যন্ত একই সার্টিফিকেট কনফিগারেশনের বিস্তারিত Docker এবং HTTPS সহ VPS-এ n8n গাইডে রয়েছে।
প্রথমে সিক্রেটগুলো তৈরি করুন। এনক্রিপশন কি (encryption key) সংরক্ষিত ক্রেডেনশিয়ালগুলোকে সুরক্ষিত রাখে। অ্যাডমিন টোকেন (admin token) ওয়েব কনসোল এবং পুরো /api সারফেসকে রক্ষা করে। এগুলোর কোনো ডিফল্ট মান নেই এবং এগুলো ছাড়া রানটাইম শুরু হয়ে যাবে, যা কাম্য নয়।
mkdir -p ~/open-connector && cd ~/open-connector
umask 077
printf 'OOMOL_CONNECT_ENCRYPTION_KEY=%s\n' "$(openssl rand -base64 32)" > .env
printf 'OOMOL_CONNECT_ADMIN_TOKEN=%s\n' "$(openssl rand -base64 32)" >> .env
chmod 600 .envপ্রথমবার শুরু করার আগেই উভয় মান আপনার পাসওয়ার্ড ম্যানেজারে কপি করে রাখুন। এনক্রিপশন কি-এর কোনো রিকভারি পাথ নেই এবং এর কারণ নিচে ব্যর্থতার তালিকায় দেওয়া হয়েছে।
এখন compose.yaml তৈরি করুন। এটি আপস্ট্রিম উদাহরণের চেয়ে দুটি জায়গায় আলাদা এবং উভয়ই গুরুত্বপূর্ণ।
services:
connector:
image: ghcr.io/oomol-lab/open-connector:v1.3.3
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
volumes:
- connector-data:/app/data
environment:
OOMOL_CONNECT_DATA_DIR: /app/data
OOMOL_CONNECT_ORIGIN: "https://connect.example.com"
OOMOL_CONNECT_ENCRYPTION_KEY: "${OOMOL_CONNECT_ENCRYPTION_KEY:?set this in .env}"
OOMOL_CONNECT_ADMIN_TOKEN: "${OOMOL_CONNECT_ADMIN_TOKEN:?set this in .env}"
volumes:
connector-data:প্রথম পরিবর্তনটি হলো latest-এর পরিবর্তে একটি নির্দিষ্ট ট্যাগ ব্যবহার করা। দ্বিতীয়টি হলো পোর্ট। আপস্ট্রিম ফাইলটি 3000:3000 পাবলিশ করে, যা হোস্টের প্রতিটি ইন্টারফেসের সাথে বাইন্ড হয়। Docker তার পাবলিশ করা পোর্টগুলোকে NAT (network address translation) টেবিলে লিখে রাখে, যা ufw ফিল্টার চেইন দেখার আগেই প্যাকেট গ্রহণ করে। তাই ufw deny 3000 সেই পোর্ট বন্ধ করতে পারে না, যা কেন Docker পোর্ট ufw বাইপাস করে-এ বর্ণিত একটি ফাঁদ। 127.0.0.1:3000:3000 লিখলে তা শুধুমাত্র লুপব্যাক ইন্টারফেসে পাবলিশ হয় এবং আপনার রিভার্স প্রক্সি একই হোস্ট থেকে সংযোগ স্থাপন করে।
:? প্রতিটি ভেরিয়েবলকে প্রয়োজনীয় হিসেবে চিহ্নিত করে, তাই .env অনুপস্থিত থাকলে স্ট্যাকটি শুরু হতে অস্বীকার করে, যা ক্রেডেনশিয়াল এনক্রিপ্ট না করে শুরু হওয়া থেকে রক্ষা করে। কম্পোজ ফাইলে মানগুলো না রেখে .env-এ রাখা হলো Docker Compose env ফাইল এবং সিক্রেট-এর আদর্শ পদ্ধতি।
docker compose up -d
docker compose logs -n 30 connector
curl -s http://127.0.0.1:3000/health
sudo ss -tlnp | grep 3000রানটাইম চালু হলে /health, { "ok": true }-এর উত্তর দেয়। ss অবশ্যই 127.0.0.1:3000 প্রিন্ট করবে। যদি 0.0.0.0:3000 লেখা কোনো লাইন দেখেন, তার মানে পোর্ট ম্যাপিং এখনও আপস্ট্রিম সেটিংসেই আছে এবং গেটওয়ে সরাসরি পুরো ইন্টারনেটের প্রশ্নের উত্তর দিচ্ছে। হেলথ চেক-এ 'Connection refused' আসার মানে হলো কন্টেইনারটি এখনও লিসেন করছে না, তাই প্রক্সিতে হাত দেওয়ার আগে লগগুলো পড়ুন।
একই সার্ভিসের জন্য Traefik লেবেল
labels:
- "traefik.enable=true"
- "traefik.http.routers.connector.rule=Host(`connect.example.com`)"
- "traefik.http.routers.connector.entrypoints=websecure"
- "traefik.http.routers.connector.tls.certresolver=le"
- "traefik.http.services.connector.loadbalancer.server.port=3000"যখন Traefik একই হোস্টে Docker-এ চলে, তখন এই সার্ভিসটিকে Traefik নেটওয়ার্কের সাথে যুক্ত করুন এবং ports: ব্লকটি মুছে ফেলুন। কারণ Traefik ইন্টারনাল নেটওয়ার্কের মাধ্যমেই কন্টেইনারে পৌঁছাতে পারে এবং হোস্টের জন্য কোনো পোর্ট পাবলিশ করার প্রয়োজন হয় না। certresolver=le অবশ্যই আপনার Traefik স্ট্যাটিক কনফিগারেশনের রিজলভার নামের সাথে মিলতে হবে, অন্যথায় রাউটারটি কোনো সার্টিফিকেট ছাড়াই চালু হবে।
কেন OAuth-এর জন্য একটি প্রকৃত hostname থাকা বাধ্যতামূলক
OOMOL_CONNECT_ORIGIN হলো সেই সেটিং যা মানুষ এড়িয়ে যায়, এবং এটি এড়িয়ে গেলে OAuth এমনভাবে ভেঙে পড়ে যে মনে হয় এটি কোনো প্রোভাইডারের ত্রুটি। রানটাইম সেই origin থেকে তার redirect URI তৈরি করে, যা <origin>/oauth/callback ফরম্যাটে থাকে। যদি এটি সেট করা না থাকে, তবে origin ডিফল্ট হিসেবে http://localhost:3000 গ্রহণ করে। ফলে রানটাইম প্রোভাইডারের কাছে http://localhost:3000/oauth/callback redirect URI পাঠায়, অথচ আপনার OAuth অ্যাপে https://connect.example.com/oauth/callback নিবন্ধিত থাকে। এই দুটি স্ট্রিং ভিন্ন হওয়ায় GitHub নিচের উত্তরটি দেয়:
The redirect_uri MUST match the registered callback URL for this application.একটি OAuth প্রোভাইডার ব্রাউজারকে সেই URI-তে ফেরত পাঠায়, যার অর্থ হলো এটি এমন একটি ঠিকানা হতে হবে যা বাইরের জগত থেকে অ্যাক্সেস করা যায়। প্রোভাইডাররা localhost ছাড়া অন্য যেকোনো কিছুর জন্য সাধারণ http:// গ্রহণ করে না। এই কারণেই এই ডেপ্লয়মেন্টের জন্য একটি hostname এবং একটি certificate প্রয়োজন। প্রথমবার স্টার্ট করার আগেই origin সেট করুন, কারণ এই মানটি স্টার্টআপের সময় পড়া হয়: .env বা compose.yaml এডিট করার পর, এটি কার্যকর করতে পুনরায় docker compose up -d চালান।
আপনার প্রথম প্রোভাইডারকে OAuth-এর মাধ্যমে সংযুক্ত করুন
প্রথমে প্রোভাইডারের সাইটে OAuth অ্যাপ তৈরি করুন। GitHub-এর ক্ষেত্রে পাথটি হলো Settings, এরপর Developer settings, তারপর OAuth Apps, এবং সবশেষে New OAuth App। authorization callback URL হিসেবে https://connect.example.com/oauth/callback সেট করুন। client ID এবং client secret সংরক্ষণ করে রাখুন।
প্রতিটি /api কলে একটি admin token থাকে, তাই শেল সেশনের জন্য এটি একবার export করে নিন।
export ADMIN_TOKEN='paste-the-admin-token'
curl -s https://connect.example.com/api/oauth/configs \
-H "authorization: Bearer $ADMIN_TOKEN"এই তালিকাটি প্রতিটি প্রোভাইডারের জন্য রানটাইম যে redirect URI আশা করে তা প্রদর্শন করে, যা আপনার কনফিগারেশন কার্যকর হয়েছে কি না তা যাচাই করার দ্রুততম উপায়। যদি এটি এখনও localhost দেখায়, তবে কন্টেইনারটি পুরনো ভ্যালু নিয়ে চলছে এবং OAuth ফ্লো শেষ ধাপে গিয়ে ব্যর্থ হবে।
client credentials সংরক্ষণ করুন, তারপর একটি authorization শুরু করুন।
curl -s -X PUT https://connect.example.com/api/oauth/configs/github \
-H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' \
-d '{"clientId":"...","clientSecret":"..."}'
curl -s -X POST https://connect.example.com/api/oauth/authorizations \
-H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' \
-d '{"service":"github"}'দ্বিতীয় কলটি একটি authorizationUrl প্রদান করে। এটি ব্রাউজারে ওপেন করুন, স্কোপগুলো অনুমোদন করুন, এবং প্রোভাইডার ব্রাউজারকে /oauth/callback-এ ফেরত পাঠাবে, যেখানে রানটাইম কোডটি বিনিময় করে credential সংরক্ষণ করবে। আপনার অরিজিনে থাকা ওয়েব কনসোলটি একই admin token ব্যবহার করে একটি ফর্মের মাধ্যমে এই ধাপগুলো সম্পন্ন করে। যে প্রোভাইডারগুলো সাধারণ API key ব্যবহার করে তারা এই প্রক্রিয়াটি এড়িয়ে যায়: {"authType":"api_key","values":{"apiKey":"..."}}-এর সাথে PUT /api/connections/<service> ব্যবহার করে সরাসরি কি (key) সংরক্ষণ করা যায়।
প্রতিটি এজেন্টকে একটি রানটাইম টোকেন দিন, কখনোই ক্রেডেনশিয়াল দেবেন না
এজেন্ট একটি রানটাইম টোকেনের মাধ্যমে গেটওয়েতে অথেন্টিকেট করে, যা অ্যাডমিন API তৈরি করে।
curl -s -X POST https://connect.example.com/api/runtime-tokens \
-H "authorization: Bearer $ADMIN_TOKEN" \
-H 'content-type: application/json' \
-d '{"name":"research-agent"}'প্রতিক্রিয়ার সাথে একটি টোকেন থাকে যা oct_ দিয়ে শুরু হয়। প্রতিটি এজেন্টের জন্য একটি করে টোকেন ইস্যু করুন এবং সেই এজেন্টের নামানুসারে সেটির নামকরণ করুন, কারণ যে টোকেন আপনি শনাক্ত করতে পারবেন না তা বাতিল করার অর্থ হলো সবগুলো টোকেন বাতিল করা। এরপর এজেন্ট সাধারণ HTTP-এর মাধ্যমে অ্যাকশন কল করে।
curl -s -X POST https://connect.example.com/v1/actions/github.get_current_user \
-H "authorization: Bearer oct_..." \
-H 'content-type: application/json' \
-d '{"input":{}}'একটি সঠিক উত্তরের ক্ষেত্রে এটি একটি এনভেলপ হিসেবে আসে যার success ফিল্ডটি true, এবং প্রোভাইডার পেলোডটি data-এর অধীনে থাকে। GitHub টোকেনটি সেই প্রতিক্রিয়ার কোথাও থাকে না। একটি MCP ক্লায়েন্টের জন্য, সেটিকে একই বিয়ারার হেডারসহ https://connect.example.com/mcp-এর দিকে নির্দেশ করুন, এবং গেটওয়ে প্রতিটি API-এর জন্য একটি টুলের পরিবর্তে search_actions এবং execute_action-এর মতো ডিসকভারি টুল অফার করে, যা এজেন্টের টুলের তালিকা ছোট রাখে। VPS-এ MCP সার্ভার চালানো এই সংযোগের ক্লায়েন্ট অংশটি কভার করে।
এটি শেষ করার আগে আরও একটি চেক করুন। authorization হেডারটি মুছে ফেলে অ্যাকশন কলটি পুনরায় করুন। প্রজেক্টের নিজস্ব কুইকস্টার্ট কোনো বিয়ারার ছাড়াই /v1 কল করে, তাই কোনো রানটাইম অথ কনফিগার না করা থাকলে যে কেউ পোর্টটিতে পৌঁছাতে পারলে অ্যাকশনগুলো এক্সিকিউট করতে পারবে। যদি আপনার আনঅথেন্টিকেটেড কলটি সফল হয়, তবে আপনার কাছে দুটি উপায় আছে: রানটাইম টোকেন কনফিগার করুন এবং নিশ্চিত করুন যে অ্যানোনিমাস কলটি এখন ব্যর্থ হচ্ছে, অথবা রিভার্স প্রক্সিতে /api, /v1 এবং /mcp-কে শুধুমাত্র আপনার এজেন্টের আইপি ঠিকানার জন্য সীমাবদ্ধ করুন। শুধুমাত্র /oauth/callback-কে সবার জন্য উন্মুক্ত রাখতে হবে, কারণ এটিই একমাত্র পথ যা প্রোভাইডারের ব্রাউজার রিডাইরেক্টের জন্য প্রয়োজন।
এজেন্টের প্রয়োজনীয় কাজের তালিকা সীমিত করুন
হাজারো প্রোভাইডারসহ একটি গেটওয়ে ল্যাঙ্গুয়েজ মডেলের জন্য অনেক বড় একটি সারফেস এরিয়া তৈরি করে। যখন মডেলটি এমন টেক্সট পড়া শুরু করে যা সে নিজে লেখেনি, তখন এই ঝুঁকি আরও বেড়ে যায়। কারণ আপনার নিজের SearXNG ইনস্ট্যান্স থেকে আসা ওয়েব সার্চের ফলাফল এমন সব নির্দেশনা বহন করতে পারে যা এজেন্টের হাতে থাকা যেকোনো অ্যাকশনের ওপর প্রভাব ফেলতে পারে। যে সংযম একটি কোডিং এজেন্টকে সবচেয়ে ছোট কার্যকর পরিবর্তনটি করতে বাধ্য করে, সেই একই সংযম তার পারমিশনের ক্ষেত্রেও প্রযোজ্য: এজেন্টকে কেবল সেই কয়েকটি কাজের অনুমতি দিন যা তার কাজের জন্য প্রয়োজন, এর বাইরে কিছুই নয়। দুটি কন্ট্রোল এই পরিধিকে সংকুচিত করে।
OOMOL_CONNECT_ALLOWED_ACTIONS একটি কমা-সেপারেটেড অ্যালাউ-লিস্ট গ্রহণ করে এবং এটি service.* ও * বুঝতে পারে। OOMOL_CONNECT_BLOCKED_ACTIONS হলো ডিনাই-লিস্ট, এবং ডিনাই-লিস্টের সিদ্ধান্তই চূড়ান্ত। অ্যালাউ-লিস্টকে github.get_current_user,github.list_issues-এ সেট করার অর্থ হলো, এজেন্ট যাই চাক না কেন, অন্য সব অ্যাকশন প্রত্যাখ্যান করা হবে; এটিই একটি সাধারণ ভুল এবং একটি বড় সিকিউরিটি ইনসিডেন্টের মধ্যে পার্থক্য গড়ে দেয়। রানটাইম টোকেনগুলো গ্লোবাল রুলগুলোর পাশাপাশি নিজস্ব অ্যাকশন রুল বহন করে এবং এদের allowedProxies লিস্ট ডিফল্টভাবে খালি থাকে। তাই আপনি অনুমতি না দেওয়া পর্যন্ত POST /v1/proxy/:service প্রত্যাখ্যান করা হবে। এই প্রক্সি এন্ডপয়েন্টটি আপনার ক্রেডেনশিয়ালসহ একটি র-রিকোয়েস্ট প্রোভাইডারের কাছে পাঠিয়ে দেয়, তাই কোনো নির্দিষ্ট এজেন্টের প্রয়োজন না হলে এটি খালি রাখুন।
OOMOL_CONNECT_ALLOW_PRIVATE_NETWORK ডিফল্টভাবে false থাকে, যা কোনো সেলফ-হোস্টেড প্রোভাইডার কানেকশনকে প্রাইভেট অ্যাড্রেসের দিকে নির্দেশ করা থেকে বিরত রাখে, যেমন 169.254.169.254-এ থাকা ক্লাউড মেটাডেটা সার্ভিস বা একই নেটওয়ার্কে থাকা আপনার ডাটাবেস। এটি বন্ধ রাখুন। শুধুমাত্র আপনার নিজের হোস্ট করা কোনো প্রোভাইডারের জন্য এটি চালু করুন।
প্রতিটি টোকেন ধারণকারী বক্সের ব্যাকআপ নিন
দুটি বিষয় গুরুত্বপূর্ণ এবং একটি ছাড়া অন্যটি অকেজো। connector-data ভলিউমের ভেতরে /app/data/connect.sqlite-এ থাকা ডেটাবেসটি সিল করা ক্রেডেনশিয়ালগুলো ধারণ করে। .env-এ থাকা এনক্রিপশন কি (key) সেগুলোকে আনসিল করে। কি (key) ছাড়া ভলিউমের ব্যাকআপ কোনো কাজে আসে না, আবার ভলিউম ছাড়া কি (key)-ও কোনো কাজে আসে না। তাই কি (key)-টিকে আপনার পাসওয়ার্ড ম্যানেজারে রাখুন এবং ভলিউমটিকে আপনার নিয়মিত ব্যাকআপ রোটেশনে অন্তর্ভুক্ত করুন।
SQLite ফাইলটি কপি করার সময় কন্টেইনারটি বন্ধ রাখুন, কারণ রাইট অপারেশনের সময় নেওয়া কপিটি ডেটাবেস করাপ্ট বা অকেজো করে দিতে পারে।
docker volume ls | grep connector-data
docker compose stop connector
docker run --rm -v open-connector_connector-data:/data -v "$PWD":/backup alpine \
tar czf /backup/connector-data.tgz -C /data .
docker compose start connectorভলিউমের নাম হলো আপনার প্রজেক্ট ডিরেক্টরি এবং _connector-data-এর সমষ্টি, তাই প্রথম কমান্ডটি সেখানে দেওয়া হয়েছে: আসল নামটি তৃতীয় কমান্ডে পেস্ট করুন। VPS থেকে restic ব্যাকআপ ব্যবহার করে আর্কাইভটি VPS থেকে সরিয়ে নিন। এটি আর্কাইভটিকে সার্ভার থেকে বের হওয়ার আগেই এনক্রিপ্ট করে ফেলে, কারণ ওই আর্কাইভটিই হলো ক্রেডেনশিয়াল স্টোর।
রানটাইম অডিট রেকর্ড হিসেবে সাম্প্রতিক অ্যাকশন রানগুলো জমা রাখে, যা ডিফল্টভাবে 5,000টি। ফলে কনসোল আপনাকে জানাতে পারে কোন এজেন্ট কখন কী চালিয়েছে। কোনো এজেন্ট অস্বাভাবিক আচরণ করলে সবার আগে সেই লগটি পড়ুন। এছাড়া https://connect.example.com/health-এ একটি Uptime Kuma স্ট্যাটাস পেজ যুক্ত করুন। গেটওয়ে সাড়া দেওয়া বন্ধ করলে এজেন্টগুলো বিভ্রান্তিকর আচরণ শুরু করে। গেটওয়ে ডাউন আছে কি না তা জানা থাকলে এজেন্টের আউটপুট পড়ার সময় এক ঘণ্টা বেঁচে যায়।
কী কী সমস্যা হতে পারে এবং আপনি যে বার্তাগুলো দেখবেন
redirect_uri_mismatch প্রোভাইডারের ক্ষেত্রে। অরিজিন এবং রেজিস্টার করা কলব্যাক URL ভিন্ন। /api/oauth/configs থেকে প্রাপ্ত সঠিক স্ট্রিংটি প্রোভাইডারের অ্যাপ সেটিংসের সাথে মিলিয়ে দেখুন, যার মধ্যে https এবং http-এর মধ্যকার পার্থক্য এবং কোনো trailing slash আছে কি না তা যাচাই করুন।
প্রতিটি /api কল 401 রিটার্ন করে। অ্যাডমিন টোকেন হেডারটি অনুপস্থিত অথবা ভুল বানান লেখা হয়েছে। হেডারটি হলো Authorization: Bearer <token>, এবং ওয়েব কনসোল একই টোকেন দাবি করে।
কন্টেইনার চলছে, কিন্তু ক্রেডেনশিয়ালগুলো প্লেইন টেক্সটে আছে। এটি তখন ঘটে যখন OOMOL_CONNECT_ENCRYPTION_KEY কন্টেইনারে পৌঁছায় না, কারণ রানটাইম ক্রেডেনশিয়াল রেকর্ডগুলোকে এনক্রিপ্ট না করেই সংরক্ষণ করে, অথচ তার উচিত ছিল স্টার্ট হতে অস্বীকার করা। আপনার নিজের ইন্সটলেশনটিতে এটি পরীক্ষা করুন: এমন একটি API কি (key) দিয়ে প্রোভাইডার কানেক্ট করুন যা আপনি চিনতে পারেন, তারপর ডাটাবেসে সেটি সার্চ করুন।
docker compose cp connector:/app/data/connect.sqlite /tmp/connect.sqlite
grep -c 'github_pat_' /tmp/connect.sqlite
shred -u /tmp/connect.sqliteফলাফল 0-এর বেশি হলে বুঝতে হবে কি (key) কার্যকর হয়নি, তাই নিশ্চিত করুন যে .env ফাইলটি compose.yaml-এর একই ডিরেক্টরিতে আছে এবং docker compose config সেই ভ্যালুটি দেখাচ্ছে। কি (key) সেট করা থাকলে, একই সার্চে 0 আসবে, কারণ রেকর্ডটি AES-256-GCM (অ্যাডভান্সড এনক্রিপশন স্ট্যান্ডার্ড, 256-বিট কি, গ্যালোইস/কাউন্টার মোড) দিয়ে সিল করা থাকে।
রিস্টোরের পর কিছুই ডিক্রিপ্ট হচ্ছে না। এনক্রিপশন কি (key) পরিবর্তিত হয়েছে অথবা হারিয়ে গেছে। ডিজাইনের কারণেই এটি ডাটার পাশে লেখা থাকে না, তাই কোনো রিকভারি পাথ নেই এবং কোনো সাপোর্ট টিকিটও এখানে সাহায্য করতে পারবে না। প্রতিটি প্রোভাইডার পুনরায় কানেক্ট করুন। রোটেশন একটি আলাদা কি (key) ভেরিয়েবল এবং রানটাইমের একটি ডাটা কমান্ডের মাধ্যমে সমর্থিত, তাই কোনো কিছু রোটেট করার আগে বর্তমান রিলিজ নোটগুলো পড়ে নিন।
এজেন্ট এমন একটি অ্যাকশনের নামসহ এরর দিচ্ছে যা সে ক্যাটালগে দেখতে পায়। ডিসকভারি এবং এক্সিকিউশন আলাদা বিষয়। একটি অ্যাকশন search_actions-এ দেখা যেতে পারে, কিন্তু তবুও সেটি OOMOL_CONNECT_ALLOWED_ACTIONS, ডেনলিস্ট, অথবা সেই রানটাইম টোকেনের নিজস্ব নিয়মের কারণে প্রত্যাখ্যাত হতে পারে।
আপগ্রেড। ভলিউম ব্যাকআপ নিন, ইমেজ ট্যাগটি নতুন রিলিজে এডিট করুন, তারপর docker compose pull && docker compose up -d চালান। মাইগ্রেশন লাইনের জন্য docker compose logs -n 50 connector পর্যবেক্ষণ করুন, এবং পুনরায় বিশ্বাস করার আগে হেলথ চেক ও একটি বাস্তব অ্যাকশন চালিয়ে দেখুন। রোলব্যাক করার অর্থ হলো পুরনো ট্যাগটি ফিরিয়ে আনা, যা কেবল তখনই কাজ করে যদি আপনি সেটি পিন করে রাখেন।
FAQ
Open Connector সেলফ-হোস্ট করার জন্য কি আমার পাবলিক ডোমেইন প্রয়োজন?
যেসব প্রোভাইডার API key ব্যবহার করে, তাদের জন্য প্রয়োজন নেই: 127.0.0.1-এ একটি গেটওয়ে থাকলেই চলে। তবে OAuth-এর ক্ষেত্রে বাস্তবে এটি প্রয়োজন। প্রোভাইডার আপনার ব্রাউজারকে আপনার callback URL-এ রিডাইরেক্ট করে, তাই সেই URL-কে পাবলিক ইন্টারনেট থেকে রিজলভ হতে হয় এবং প্রোভাইডাররা localhost ছাড়া সাধারণ http:// গ্রহণ করে না। প্রথমবার স্টার্ট করার আগেই OOMOL_CONNECT_ORIGIN-কে আপনার https:// হোস্টনামে সেট করুন এবং প্রোভাইডারের OAuth অ্যাপে <origin>/oauth/callback রেজিস্টার করুন।
আমি যদি Open Connector এনক্রিপশন কি (key) হারিয়ে ফেলি তবে কী হবে?
সংরক্ষিত ক্রেডেনশিয়ালগুলো আর ডিক্রিপ্ট করা যাবে না এবং এটি পুনরুদ্ধারের কোনো উপায় নেই। নিরাপত্তার খাতিরে এই কি (key) কখনোই ডেটার সাথে সংরক্ষণ করা হয় না, যাতে ডেটাবেস যার হাতেই থাকুক না কেন, কেউ তা পড়তে না পারে—এমনকি আপনি নিজেও না। আপনার একমাত্র উপায় হলো একটি নতুন কি (key) সেট করা এবং প্রতিটি প্রোভাইডারের সাথে পুনরায় সংযোগ স্থাপন করা। কি (key)-টিকে একটি পাসওয়ার্ড ম্যানেজারে এবং ডেটাবেসকে আপনার ব্যাকআপ রোটেশনে রাখুন, কারণ রিস্টোর করার জন্য উভয়ই প্রয়োজন।
আমার AI এজেন্ট কি প্রোভাইডার অ্যাক্সেস টোকেন দেখতে পায়?
গেটওয়ের মাধ্যমে কল করার সময় পায় না। এজেন্ট oct_ দিয়ে শুরু হওয়া একটি রানটাইম টোকেন দিয়ে অথেন্টিকেট করে এবং গেটওয়ে সার্ভারে আউটবাউন্ড রিকোয়েস্টের সাথে প্রোভাইডারের ক্রেডেনশিয়াল যুক্ত করে দেয়, শুধুমাত্র রেসপন্সটি ফেরত পাঠায়। দুটি ক্ষেত্রে এই নিরাপত্তা ব্যবস্থা কাজ করে না: /v1/proxy/:service এন্ডপয়েন্ট, যা আপনার ক্রেডেনশিয়ালসহ raw রিকোয়েস্ট ফরওয়ার্ড করে (এ কারণেই এর গ্র্যান্টগুলো খালি থাকে), এবং নিজে থেকে এজেন্টে API key পেস্ট করা, যা গেটওয়েকে পুরোপুরি এড়িয়ে যায়।
গেটওয়ে কি পাবলিক ইন্টারনেট থেকে অ্যাক্সেসযোগ্য হওয়া উচিত?
শুধুমাত্র /oauth/callback অ্যাক্সেসযোগ্য হওয়া প্রয়োজন। কন্টেইনার পোর্টটিকে 127.0.0.1-এ পাবলিশ করুন যাতে Docker-এর NAT রুলগুলো আপনার ফায়ারওয়ালের বাইরে এটিকে উন্মুক্ত করতে না পারে এবং এর সামনে একটি রিভার্স প্রক্সি বসান। এরপর কোনো authorization হেডার ছাড়া একটি অ্যাকশন কল টেস্ট করুন। যদি এটি সফল হয়, তবে প্রক্সিতে /api, /v1 এবং /mcp-কে আপনার এজেন্টের ব্যবহৃত অ্যাড্রেসগুলোতে সীমাবদ্ধ করুন, যতক্ষণ না শুধুমাত্র অথেন্টিকেটেড কলগুলো কাজ করছে।
Open Connector কি প্রোডাকশন ব্যবহারের জন্য প্রস্তুত?
এটি Apache 2.0 লাইসেন্সভুক্ত এবং দ্রুত পরিবর্তিত হচ্ছে: রিপোজিটরিটির আবির্ভাব ঘটে 29 জুন 2026 এবং v1.3.3 রিলিজ হয় 30 জুলাই 2026-এ, তাই এই গাইডের প্রতিটি ভার্সন নম্বরকে 1 আগস্ট 2026-এর একটি স্ন্যাপশট হিসেবে বিবেচনা করুন। এটিকে সবসময় নির্দিষ্ট রিলিজ ট্যাগে চালান, কখনোই latest বা tip-এ চালাবেন না। প্রতিটি আপগ্রেডের আগে রিলিজ নোটগুলো পড়ুন এবং এমন একটি ভলিউম ব্যাকআপ রাখুন যা আপনি অন্তত একবার রিস্টোর করে দেখেছেন। আপনার নিজস্ব সার্ভারের জন্য এর ডিজাইনটি বেশ কার্যকর, এখানে ঝুঁকি হলো ভার্সনের দ্রুত পরিবর্তন, আর্কিটেকচার নয়।