SSD Nodes Learn 🎉 VPS เริ่ม $4.99/เดือน
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-08-07

วิธีติดตั้ง Open Connector บน VPS สำหรับ AI Agent

เรียนรู้วิธีติดตั้ง Open Connector เพื่อจัดการ Auth Gateway ด้วยตนเอง ช่วยให้ AI Agent เข้าถึง SaaS API ได้ปลอดภัยโดยไม่ต้องเก็บ Token ไว้ในระบบ ลดความเสี่ยงข้อมูลรั่วไหล

สิ่งที่ Open Connector ทำสำหรับ AI agent

การติดตั้ง Open Connector ด้วยตนเองจะสร้างเกตเวย์การยืนยันตัวตน (auth gateway) คั่นกลางระหว่าง AI agent ของคุณกับ API ของซอฟต์แวร์แบบ SaaS ทุกตัวที่ agent เรียกใช้ ทำให้ agent ไม่จำเป็นต้องถือครองโทเค็นของผู้ให้บริการ (provider token) โดยตรง Open Connector เป็นเกตเวย์แบบโอเพนซอร์สจาก OOMOL Lab ภายใต้สัญญาอนุญาต Apache 2.0 ทำงานเป็นคอนเทนเนอร์เดียว เก็บสถานะไว้ในไฟล์ SQLite ไฟล์เดียว และเปิดเผยการทำงานของผู้ให้บริการผ่าน HTTP และ MCP (model context protocol)

ปัญหาจะเริ่มขึ้นเมื่อมีการเชื่อมต่อเป็นตัวที่สอง ผู้ให้บริการแต่ละรายมีขั้นตอน OAuth (open authorization) ของตนเอง มีอายุการใช้งานของ refresh token ที่ต่างกัน และมีชื่อ scope ที่ไม่เหมือนกัน การเชื่อมต่อผู้ให้บริการ 5 รายเข้ากับ agent ด้วยตนเองหมายถึงการต้องเขียน redirect handler 5 ชุด, ระบบจัดเก็บข้อมูลประจำตัว 5 ชุด และลูปการรีเฟรชโทเค็น 5 ชุดที่ต้องทำงานก่อนที่โทเค็นจะหมดอายุ แทบไม่มีใครเขียนโค้ดเหล่านั้นเอง ส่วนใหญ่มักจะสร้าง personal access token ที่มีอายุการใช้งานยาวนานขึ้นมาหนึ่งชุดต่อบริการ แล้วนำไปวางไว้ในไฟล์ตั้งค่าของ agent, ไฟล์ environment หรือแม้แต่ในตัว prompt เอง โทเค็นดังกล่าวจะถูกอ่านได้โดยเครื่องมือทุกตัวที่ agent เรียกใช้ และจะไปปรากฏอยู่ใน transcript ซึ่งเป็นความล้มเหลวที่อธิบายไว้ใน การเก็บความลับให้พ้นจาก AI agents

เกตเวย์การยืนยันตัวตนจะแยกข้อมูลประจำตัวออกเป็นสองส่วน เกตเวย์จะทำหน้าที่จัดเก็บข้อมูลประจำตัวของผู้ให้บริการและดำเนินการตามขั้นตอน OAuth ส่วน agent จะได้รับ runtime token ที่ใช้ได้เฉพาะกับเกตเวย์เท่านั้น เมื่อ agent เรียกใช้การทำงานใดๆ เกตเวย์จะโหลดข้อมูลประจำตัวที่จัดเก็บไว้ขึ้นมา แทรกข้อมูลนั้นลงในคำขอขาออกที่ฝั่งเซิร์ฟเวอร์ และส่งกลับเฉพาะเนื้อหาของผลลัพธ์ (response body) เท่านั้น agent จะไม่ได้รับ access token ของผู้ให้บริการเลย ดังนั้นหาก transcript ของ agent รั่วไหล สิ่งที่คุณเสียไปจะเป็นเพียง runtime token ที่เพิกถอนได้ แทนที่จะเป็นการเข้าถึงบัญชี GitHub ของคุณโดยตรง

แคตตาล็อกระบุว่ามีผู้ให้บริการมากกว่า 1,000 รายและมีการทำงานที่สร้างไว้ล่วงหน้ามากกว่า 10,000 รายการ ซึ่งเป็นตัวเลขของโครงการเองและไม่ใช่สิ่งที่คุณสามารถตรวจสอบได้จากภายนอก สิ่งที่คุณตรวจสอบได้คือรูปแบบการทำงาน: หนึ่ง HTTP endpoint ต่อหนึ่งการทำงาน, หนึ่งการเชื่อมต่อที่จัดเก็บไว้ต่อหนึ่งผู้ให้บริการ และหนึ่งโทเค็นต่อหนึ่ง agent

เหตุผลที่ควร self-host Open Connector แทนการใช้บริการ connector แบบ hosted

บริการ connector แบบ hosted ทำงานในลักษณะเดียวกันและเป็นผู้เก็บ refresh token สำหรับทุกผู้ให้บริการที่คุณเชื่อมต่อไว้ refresh token ของ Google หรือ GitHub เปรียบเสมือนกุญแจที่มีอายุการใช้งานยาวนานสำหรับเข้าถึงอีเมลและ repository ของคุณ ซึ่งโดยปกติแล้วจะยังคงใช้งานได้แม้จะมีการเปลี่ยนรหัสผ่าน หากระบบของผู้ให้บริการเหล่านั้นถูกเจาะ ข้อมูลของคุณก็จะถูกเจาะไปด้วย การทำ self-hosting จะย้ายบันทึกข้อมูลเหล่านี้ไปเก็บไว้ใน SQLite บนเครื่องที่คุณเช่าและดูแลเอง โดยถูกปิดผนึกด้วยกุญแจที่ไม่เคยถูกส่งออกจากเครื่องของคุณ

จงตระหนักถึงต้นทุนที่ต้องแลกก่อนเริ่มดำเนินการ VPS เครื่องนี้จะกลายเป็นเซิร์ฟเวอร์ที่มีค่าที่สุดที่คุณดูแล เนื่องจากมันเก็บ credential ที่ใช้งานได้จริงของบริการต่างๆ ไว้ในไฟล์เดียว จึงสมควรได้รับการปฏิบัติเช่นเดียวกับโฮสต์ของโปรแกรมจัดการรหัสผ่าน ได้แก่ การใช้ firewall ที่เปิดเฉพาะพอร์ต 443, ไม่ใช้บัญชีผู้ใช้ร่วมกัน, มีการสำรองข้อมูลที่คุณเคยทดสอบกู้คืนจริงมาแล้ว และมีการแจ้งเตือนเมื่อเซิร์ฟเวอร์ไม่ตอบสนอง หากคุณไม่คิดจะวางตู้เก็บรหัสผ่านของคุณไว้บนเครื่องนี้ ก็ไม่ควรติดตั้ง connector ไว้บนเครื่องนี้เช่นกัน

กำหนดเวอร์ชันให้คงที่ก่อนเริ่มติดตั้ง

Open Connector ยังเป็นซอฟต์แวร์ใหม่ repository เริ่มปรากฏครั้งแรกเมื่อวันที่ 29 มิถุนายน 2026 และ ณ วันที่ 1 สิงหาคม 2026 รุ่นล่าสุดที่มีการระบุ tag คือ v1.3.3 ซึ่งเผยแพร่เมื่อวันที่ 30 กรกฎาคม 2026 และมี tag latest กำกับอยู่ด้วย นอกจากนี้ registry ยังเผยแพร่ tag tip ซึ่งสร้างจาก commit ล่าสุดบน main อีกด้วย

สำหรับโปรเจกต์ที่ใหม่ขนาดนี้ tag ที่มีการเปลี่ยนแปลงบ่อยมักจะขยับอยู่เสมอ การใช้ docker compose pull ที่ข้ามไปสองรุ่นอาจทำให้ endpoint ที่ agent ของคุณใช้งานอยู่เกิดการเปลี่ยนแปลง และคุณจะต้องเสียเวลาทั้งคืนเพื่อแก้ไขปัญหาที่เข้าใจว่าเป็นปัญหาของตัว agent เอง ดังนั้นควรตรึง image ไว้ที่ release tag และค่อยอัปเกรดเมื่อคุณตัดสินใจพร้อม หลังจากได้อ่านบันทึกประจำรุ่น (release notes) แล้วเท่านั้น

การติดตั้ง Open Connector หลัง TLS บน VPS ของคุณเอง

ก่อนที่คอนเทนเนอร์จะเริ่มทำงาน คุณต้องมีสิ่งต่อไปนี้:

  • Docker พร้อมปลั๊กอิน Compose บน Ubuntu 24.04 หรือเวอร์ชันที่ใกล้เคียงกัน
  • ชื่อโฮสต์ที่มี A record ชี้มายัง VPS นี้ ตัวอย่างเช่น connect.example.com
  • Reverse proxy ที่ทำ TLS (transport layer security) termination สำหรับชื่อโฮสต์นั้นอยู่แล้ว
  • รหัสลับแบบสุ่มสองชุด ซึ่งจะสร้างขึ้นในขั้นตอนด้านล่าง

บทความ Traefik reverse proxy สำหรับแอป Docker Compose หลายตัว ครอบคลุมการตั้งค่าฝั่งพร็อกซี ส่วนขั้นตอนการจัดการใบรับรองทั้งหมดสำหรับแอปเดียว สามารถดูได้ในคู่มือ n8n บน VPS ด้วย Docker และ HTTPS

ให้สร้างรหัสลับก่อน 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

คัดลอกทั้งสองค่าลงในโปรแกรมจัดการรหัสผ่านของคุณทันที ก่อนการเริ่มทำงานครั้งแรก Encryption key ไม่มีช่องทางกู้คืน และเหตุผลระบุไว้ในรายการข้อผิดพลาดด้านล่าง

ตอนนี้ให้สร้าง 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:

การเปลี่ยนแปลงแรกคือการระบุเวอร์ชัน (pinned tag) แทนการใช้ latest ส่วนที่สองคือพอร์ต ไฟล์ต้นฉบับประกาศใช้ 3000:3000 ซึ่งเป็นการผูกพอร์ตกับทุกอินเทอร์เฟซบนโฮสต์ Docker จะเขียนพอร์ตที่ประกาศไว้ลงในตาราง NAT (network address translation) ก่อนที่ ufw filter chain จะเห็นแพ็กเก็ต ดังนั้น ufw deny 3000 จึงไม่สามารถปิดพอร์ตนั้นได้ ซึ่งเป็นกับดักที่อธิบายไว้ใน เหตุใดพอร์ตของ Docker จึงข้าม ufw การเขียน 127.0.0.1:3000:3000 จะเป็นการประกาศพอร์ตบน loopback interface เท่านั้น และ reverse proxy ของคุณจะเชื่อมต่อจากโฮสต์เดียวกัน

:? จะระบุว่าตัวแปรแต่ละตัวจำเป็นต้องมี ดังนั้น stack จะปฏิเสธการเริ่มทำงานหาก .env หายไป แทนที่จะเริ่มทำงานโดยไม่มีการเข้ารหัสข้อมูลประจำตัว การเก็บค่าไว้ใน .env แทนที่จะใส่ในไฟล์ compose เป็นรูปแบบที่แนะนำใน ไฟล์ env และ secrets ของ Docker Compose

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 หมายความว่าการแมปพอร์ตยังคงเป็นแบบต้นฉบับ และเกตเวย์กำลังตอบรับการเชื่อมต่อจากอินเทอร์เน็ตโดยตรง หากการตรวจสอบ health check แจ้งว่า Connection refused หมายความว่าคอนเทนเนอร์ยังไม่เริ่มฟังพอร์ต ดังนั้นให้ตรวจสอบ log ก่อนที่จะแก้ไขพร็อกซี

Traefik labels สำหรับบริการเดียวกัน
    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 ต้องตรงกับชื่อ resolver ในไฟล์ static config ของ Traefik มิฉะนั้นเราเตอร์จะทำงานโดยไม่มีใบรับรอง

เหตุผลที่ OAuth บังคับให้คุณต้องมี hostname จริง

OOMOL_CONNECT_ORIGIN คือการตั้งค่าที่ผู้ใช้มักข้ามไป และการข้ามขั้นตอนนี้จะทำให้ OAuth ทำงานผิดพลาดในลักษณะที่ดูเหมือนเป็นบั๊กของผู้ให้บริการ ตัว runtime จะสร้าง redirect URI จาก origin นั้นในรูปแบบ <origin>/oauth/callback หากไม่ได้ตั้งค่าไว้ origin จะมีค่าเริ่มต้นเป็น http://localhost:3000 ส่งผลให้ runtime ส่ง redirect URI ไปยังผู้ให้บริการเป็น http://localhost:3000/oauth/callback ในขณะที่แอป OAuth ของคุณลงทะเบียนไว้เป็น https://connect.example.com/oauth/callback สตริงทั้งสองชุดไม่ตรงกัน GitHub จึงตอบกลับมาว่า:

The redirect_uri MUST match the registered callback URL for this application.

ผู้ให้บริการ OAuth จะ redirect เบราว์เซอร์กลับไปยัง URI ดังกล่าว ซึ่งหมายความว่ามันต้องเป็นที่อยู่ที่โลกภายนอกสามารถเข้าถึงได้ และผู้ให้บริการจะปฏิเสธ http:// สำหรับทุกกรณีที่ไม่ใช่ localhost นี่คือเหตุผลทั้งหมดที่การติดตั้งนี้จำเป็นต้องมี hostname และใบรับรอง (certificate) ให้ตั้งค่า origin ก่อนการเริ่มทำงานครั้งแรก เนื่องจากค่านี้จะถูกอ่านในขณะเริ่มต้นระบบ: หลังจากแก้ไข .env หรือ compose.yaml แล้ว ให้รัน docker compose up -d อีกครั้งเพื่อนำการตั้งค่าไปใช้

เชื่อมต่อผู้ให้บริการรายแรกของคุณผ่าน OAuth

สร้างแอป OAuth ที่ฝั่งผู้ให้บริการก่อน สำหรับ GitHub ให้ไปที่ Settings จากนั้นไปที่ Developer settings ตามด้วย OAuth Apps และ New OAuth App กำหนด URL สำหรับ callback การอนุญาตให้เป็น https://connect.example.com/oauth/callback เก็บ client ID และ client secret ไว้

ทุกการเรียก /api จะต้องใช้ admin token ดังนั้นให้ export ค่านี้ไว้สำหรับ session ของ shell ครั้งหนึ่ง

export ADMIN_TOKEN='paste-the-admin-token'
curl -s https://connect.example.com/api/oauth/configs \
  -H "authorization: Bearer $ADMIN_TOKEN"

รายการดังกล่าวจะแสดง redirect URI ที่ runtime คาดหวังสำหรับผู้ให้บริการแต่ละราย ซึ่งเป็นวิธีตรวจสอบที่รวดเร็วที่สุดว่าค่า origin ที่คุณตั้งไว้มีผลแล้ว หากยังคงแสดงค่าเป็น localhost แสดงว่า container กำลังทำงานด้วยค่าเดิม และขั้นตอน OAuth จะล้มเหลวในขั้นตอนสุดท้าย

จัดเก็บ client credentials จากนั้นเริ่มการอนุญาต

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 ให้เปิด URL ดังกล่าวในเบราว์เซอร์ อนุมัติขอบเขต (scopes) แล้วผู้ให้บริการจะส่งเบราว์เซอร์กลับไปยัง /oauth/callback ซึ่ง runtime จะทำการแลกเปลี่ยน code และจัดเก็บ credential ไว้ เว็บคอนโซลที่ origin ของคุณจะดำเนินการตามขั้นตอนเดียวกันผ่านฟอร์ม โดยใช้ admin token เดียวกัน สำหรับผู้ให้บริการที่ใช้ API key แบบปกติจะข้ามขั้นตอนเหล่านี้ทั้งหมด โดยการใช้ PUT /api/connections/<service> ร่วมกับ {"authType":"api_key","values":{"apiKey":"..."}} จะเป็นการจัดเก็บ key โดยตรง

กำหนด runtime token ให้กับ agent แต่ละตัว แทนการใช้ credential

Agent จะยืนยันตัวตนกับ gateway โดยใช้ runtime token ซึ่งสร้างขึ้นผ่าน admin 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"}'

การตอบกลับจะประกอบด้วย token ที่ขึ้นต้นด้วย oct_ ให้สร้าง token หนึ่งชุดต่อหนึ่ง agent และตั้งชื่อตาม agent นั้นๆ เนื่องจากหากคุณเพิกถอน token ที่ระบุตัวตนไม่ได้ จะหมายถึงการเพิกถอน token ทั้งหมด จากนั้น agent จะเรียกใช้งาน action ต่างๆ ผ่าน 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":{}}'

การตอบกลับที่ถูกต้องจะเป็น envelope ที่มีฟิลด์ success เป็น true โดยมี payload ของผู้ให้บริการอยู่ภายใต้ data ทั้งนี้ GitHub token จะไม่ปรากฏอยู่ในส่วนใดของการตอบกลับ สำหรับ MCP client ให้ชี้ไปที่ https://connect.example.com/mcp โดยใช้ bearer header เดียวกัน ซึ่ง gateway จะนำเสนอเครื่องมือสำหรับการค้นหา เช่น search_actions และ execute_action แทนที่จะเป็นเครื่องมือหนึ่งรายการต่อหนึ่ง API เพื่อช่วยให้รายการเครื่องมือของ agent มีขนาดเล็ก การรัน MCP server บน VPS ครอบคลุมถึงฝั่ง client ของการเชื่อมต่อดังกล่าว

ตรวจสอบอีกครั้งก่อนที่คุณจะสรุปงานนี้ ให้ลองเรียก action ซ้ำโดยลบ header authorization ออก เนื่องจากคู่มือเริ่มต้นใช้งานของโปรเจกต์มีการเรียก /v1 โดยไม่มี bearer ใดๆ ดังนั้นการติดตั้งที่ไม่ได้กำหนดค่า runtime auth ไว้จะอนุญาตให้ใครก็ตามที่เข้าถึงพอร์ตได้สามารถสั่งดำเนินการ action ต่างๆ ได้ หากการเรียกโดยไม่ยืนยันตัวตนของคุณสำเร็จ คุณมีทางเลือกสองทางคือ กำหนดค่า runtime token แล้วตรวจสอบว่าการเรียกแบบไม่ระบุตัวตนล้มเหลว หรือจำกัดการเข้าถึง /api, /v1 และ /mcp ที่ reverse proxy ให้เหลือเพียงที่อยู่ IP ของ agent ของคุณเท่านั้น มีเพียง /oauth/callback เท่านั้นที่ต้องเปิดให้สาธารณะเข้าถึงได้ เนื่องจากเป็นเส้นทางเดียวที่จำเป็นสำหรับการ redirect เบราว์เซอร์ของผู้ให้บริการ

จำกัดรายการคำสั่งให้เหลือเพียงสิ่งที่เอเจนต์จำเป็นต้องใช้

เกตเวย์ที่มีผู้ให้บริการจำนวนมากอยู่เบื้องหลังถือเป็นช่องทางที่กว้างเกินไปสำหรับการส่งต่อให้โมเดลภาษา การควบคุมสองส่วนจะช่วยจำกัดขอบเขตนี้ให้แคบลง

OOMOL_CONNECT_ALLOWED_ACTIONS รับค่าเป็นรายการ allowlist ที่คั่นด้วยเครื่องหมายจุลภาคและรองรับ service.* และ * ส่วน OOMOL_CONNECT_BLOCKED_ACTIONS คือ denylist ซึ่งจะมีลำดับความสำคัญสูงสุด การตั้งค่า allowlist เป็น github.get_current_user,github.list_issues หมายความว่าคำสั่งอื่นทั้งหมดจะถูกปฏิเสธไม่ว่าเอเจนต์จะร้องขอสิ่งใดก็ตาม ซึ่งเป็นจุดตัดสินระหว่างความผิดพลาดทั่วไปกับเหตุการณ์ความปลอดภัยร้ายแรง โทเค็นขณะรันไทม์ (runtime tokens) จะมีกฎการทำงานของตัวเองเพิ่มเติมจากกฎส่วนกลาง และรายการ allowedProxies ของโทเค็นจะเริ่มต้นด้วยค่าว่าง ดังนั้น POST /v1/proxy/:service จะถูกปฏิเสธจนกว่าคุณจะอนุญาตให้ใช้งาน จุดเชื่อมต่อพร็อกซี (proxy endpoint) นั้นจะส่งคำขอแบบดิบไปยังผู้ให้บริการพร้อมแนบข้อมูลรับรองของคุณไปด้วย ดังนั้นควรปล่อยให้ว่างไว้เว้นแต่จะมีเอเจนต์เฉพาะเจาะจงที่จำเป็นต้องใช้งาน

OOMOL_CONNECT_ALLOW_PRIVATE_NETWORK มีค่าเริ่มต้นเป็น false ซึ่งจะป้องกันไม่ให้การเชื่อมต่อกับผู้ให้บริการที่โฮสต์เอง (self-hosted provider) ชี้ไปยังที่อยู่ส่วนตัว เช่น บริการ metadata ของคลาวด์บน 169.254.169.254 หรือฐานข้อมูลของคุณที่อยู่ในเครือข่ายเดียวกัน ควรปิดการตั้งค่านี้ไว้ และเปิดใช้งานเฉพาะสำหรับผู้ให้บริการที่คุณโฮสต์ด้วยตนเองเท่านั้น

สำรองข้อมูลกล่องที่เก็บโทเค็นทั้งหมด

มีสองสิ่งที่สำคัญ และแต่ละอย่างจะไร้ประโยชน์หากขาดอีกสิ่งหนึ่ง ฐานข้อมูลที่ /app/data/connect.sqlite ภายในโวลุ่ม connector-data ทำหน้าที่เก็บข้อมูลประจำตัวที่ถูกปิดผนึกไว้ ส่วนคีย์การเข้ารหัสที่อยู่ใน .env จะทำหน้าที่ปลดล็อกข้อมูลเหล่านั้น การสำรองข้อมูลโวลุ่มโดยไม่มีคีย์จะไม่สามารถกู้คืนสิ่งใดได้ และการมีคีย์โดยไม่มีโวลุ่มก็ไม่สามารถกู้คืนสิ่งใดได้เช่นกัน ดังนั้นคีย์ควรถูกเก็บไว้ในโปรแกรมจัดการรหัสผ่านของคุณ และโวลุ่มควรถูกรวมอยู่ในรอบการสำรองข้อมูลปกติ

ให้หยุดการทำงานของ container ในขณะที่คุณคัดลอกไฟล์ 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 รายการ เพื่อให้คอนโซลสามารถบอกคุณได้ว่าเอเจนต์ใดทำงานอะไรและเมื่อใด บันทึกนั้นคือสิ่งแรกที่ควรตรวจสอบเมื่อเอเจนต์มีพฤติกรรมผิดปกติ นอกจากนี้ ให้ชี้ หน้าสถานะ Uptime Kuma ไปที่ https://connect.example.com/health ด้วย เมื่อเกตเวย์หยุดตอบสนอง เอเจนต์จะล้มเหลวในรูปแบบที่สร้างความสับสน และการทราบว่าเกตเวย์ล่มจะช่วยประหยัดเวลาในการอ่านผลลัพธ์จากเอเจนต์ไปได้นับชั่วโมง

สิ่งที่มักจะเกิดข้อผิดพลาดและข้อความที่คุณจะพบ

redirect_uri_mismatch ที่ผู้ให้บริการ ต้นทางและ URL ของ callback ที่ลงทะเบียนไว้ไม่ตรงกัน ให้เปรียบเทียบสตริงที่แน่นอนจาก /api/oauth/configs กับการตั้งค่าแอปของผู้ให้บริการ รวมถึงตรวจสอบ https เทียบกับ http และเครื่องหมายทับ (trailing slash) ที่อาจมีอยู่

ทุกการเรียก /api ส่งค่ากลับเป็น 401 ส่วนหัวของ admin token หายไปหรือสะกดผิด ส่วนหัวดังกล่าวคือ Authorization: Bearer <token> และเว็บคอนโซลจะเรียกขอโทเค็นเดียวกันนี้

คอนเทนเนอร์ทำงานได้ แต่ข้อมูลรับรอง (credentials) อยู่ในรูปแบบข้อความธรรมดา (plain text) นี่คือสิ่งที่เกิดขึ้นเมื่อ 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 หมายความว่าคีย์นั้นไม่มีผล ให้ตรวจสอบว่า .env อยู่ในไดเรกทอรีเดียวกับ compose.yaml และ docker compose config แสดงค่าที่ถูกต้อง เมื่อตั้งค่าคีย์เรียบร้อยแล้ว การค้นหาแบบเดิมจะส่งค่ากลับเป็น 0 เนื่องจากบันทึกข้อมูลถูกปิดผนึกด้วย AES-256-GCM (มาตรฐานการเข้ารหัสขั้นสูง, คีย์ 256 บิต, โหมด Galois/counter)

ไม่มีข้อมูลใดถอดรหัสได้หลังจากการกู้คืน คีย์การเข้ารหัสถูกเปลี่ยนหรือสูญหาย โดยการออกแบบแล้วคีย์จะไม่ถูกบันทึกไว้ข้างข้อมูล ดังนั้นจึงไม่มีช่องทางการกู้คืนและไม่มีตั๋วสนับสนุนใดที่จะช่วยได้ คุณต้องเชื่อมต่อผู้ให้บริการใหม่ทั้งหมด การหมุนเวียนคีย์ (rotation) รองรับผ่านตัวแปรคีย์แยกต่างหากและคำสั่งจัดการข้อมูลในรันไทม์ ดังนั้นโปรดอ่านบันทึกประจำรุ่น (release notes) ปัจจุบันก่อนที่คุณจะหมุนเวียนคีย์ใดๆ

เอเจนต์ได้รับข้อผิดพลาดที่ระบุถึงการกระทำที่ปรากฏในแคตตาล็อก การค้นพบ (discovery) และการดำเนินการ (execution) แยกออกจากกัน การกระทำหนึ่งอาจปรากฏใน search_actions แต่ยังคงถูกปฏิเสธโดย OOMOL_CONNECT_ALLOWED_ACTIONS, โดยรายการที่ถูกบล็อก (denylist) หรือโดยกฎของโทเค็นรันไทม์นั้นเอง

การอัปเกรด ให้สำรองข้อมูลวอลุ่ม แก้ไขแท็กอิมเมจเป็นรุ่นใหม่ จากนั้นใช้ docker compose pull && docker compose up -d ให้เฝ้าสังเกต docker compose logs -n 50 connector เพื่อดูบรรทัดการย้ายข้อมูล (migration) และเรียกใช้การตรวจสอบสถานะ (health check) รวมถึงการดำเนินการจริงหนึ่งครั้งก่อนที่คุณจะเชื่อมั่นในระบบอีกครั้ง การย้อนกลับ (rolling back) หมายถึงการใส่แท็กเดิมกลับเข้าไป ซึ่งจะทำได้ก็ต่อเมื่อคุณได้ตรึง (pin) แท็กนั้นไว้แล้วเท่านั้น

FAQ

ฉันจำเป็นต้องมี public domain เพื่อ self-host Open Connector หรือไม่?

สำหรับผู้ให้บริการที่ใช้ API key นั้นไม่จำเป็น: gateway บน 127.0.0.1 ก็เพียงพอแล้ว แต่สำหรับการใช้งาน OAuth นั้นจำเป็นในทางปฏิบัติ เนื่องจากผู้ให้บริการจะเปลี่ยนเส้นทางเบราว์เซอร์ไปยัง callback URL ของคุณ ดังนั้น URL นั้นจะต้องสามารถเข้าถึงได้จากอินเทอร์เน็ตสาธารณะ และผู้ให้บริการมักปฏิเสธการใช้ http:// ที่ไม่ใช่ localhost ให้ตั้งค่า OOMOL_CONNECT_ORIGIN เป็น hostname ของ https:// ก่อนการเริ่มทำงานครั้งแรก และลงทะเบียน <origin>/oauth/callback ในแอป OAuth ของผู้ให้บริการ

จะเกิดอะไรขึ้นหากฉันทำ encryption key ของ Open Connector หาย?

ข้อมูลประจำตัวที่จัดเก็บไว้จะไม่สามารถถอดรหัสได้ และไม่มีวิธีใดในการกู้คืน คีย์นี้ถูกออกแบบมาให้ไม่ถูกจัดเก็บไว้พร้อมกับข้อมูล เพื่อป้องกันไม่ให้ผู้ที่เข้าถึงฐานข้อมูลอ่านข้อมูลได้ รวมถึงตัวคุณเองด้วย ทางเลือกเดียวของคุณคือการตั้งค่าคีย์ใหม่และเชื่อมต่อกับผู้ให้บริการทุกรายใหม่อีกครั้ง ควรเก็บคีย์ไว้ในโปรแกรมจัดการรหัสผ่านและเก็บฐานข้อมูลไว้ในระบบสำรองข้อมูลของคุณ เพราะการกู้คืนระบบจำเป็นต้องใช้ทั้งสองอย่าง

AI agent ของฉันสามารถมองเห็น access token ของผู้ให้บริการได้หรือไม่?

ไม่สามารถมองเห็นได้เมื่อเรียกใช้งานผ่าน gateway ตัว agent จะยืนยันตัวตนด้วย runtime token ที่ขึ้นต้นด้วย oct_ และ gateway จะแทรกข้อมูลประจำตัวของผู้ให้บริการลงในคำขอขาออกที่ฝั่งเซิร์ฟเวอร์ โดยส่งกลับมาเฉพาะผลลัพธ์เท่านั้น มีสองกรณีที่ทำให้คุณสมบัตินี้ถูกยกเลิก: คือ endpoint /v1/proxy/:service ซึ่งส่งต่อคำขอแบบดิบโดยแนบข้อมูลประจำตัวของคุณไปพร้อมกัน (ซึ่งเป็นเหตุผลว่าทำไมสิทธิ์การเข้าถึงจึงเริ่มต้นเป็นค่าว่าง) และการนำ API key ไปวางในตัว agent โดยตรง ซึ่งเป็นการข้ามการทำงานของ gateway ไปโดยสิ้นเชิง

gateway ควรเข้าถึงได้จากอินเทอร์เน็ตสาธารณะหรือไม่?

เฉพาะ /oauth/callback เท่านั้นที่ควรเข้าถึงได้ ให้เปิดพอร์ต container บน 127.0.0.1 เพื่อให้กฎ NAT ของ Docker ไม่เปิดเผยพอร์ตออกไปนอก firewall ของคุณ และวาง reverse proxy ไว้ด้านหน้า จากนั้นให้ทดสอบการเรียกใช้งานหนึ่งครั้งโดยไม่มี header authorization หากสำเร็จ ให้จำกัด /api, /v1 และ /mcp ที่ตัว proxy ให้เหลือเพียงที่อยู่ IP ที่ agent ของคุณใช้งาน จนกว่าจะเหลือเพียงการเรียกใช้งานที่ผ่านการยืนยันตัวตนเท่านั้นที่ทำงานได้

Open Connector พร้อมสำหรับการใช้งานในระดับ production แล้วหรือยัง?

ซอฟต์แวร์นี้ใช้สัญญาอนุญาต Apache 2.0 และมีการพัฒนาอย่างรวดเร็ว: repository ปรากฏขึ้นเมื่อวันที่ 29 มิถุนายน 2026 และ v1.3.3 ได้รับการปล่อยออกมาเมื่อวันที่ 30 กรกฎาคม 2026 ดังนั้นให้ถือว่าหมายเลขเวอร์ชันทุกรายการในคู่มือนี้เป็นเพียงภาพรวม ณ วันที่ 1 สิงหาคม 2026 เท่านั้น ให้รันซอฟต์แวร์โดยล็อกเวอร์ชันไว้ที่ release tag ห้ามใช้ latest หรือ tip โดยเด็ดขาด ให้อ่านบันทึกการเปลี่ยนแปลง (release notes) ก่อนการอัปเกรดทุกครั้ง และเก็บสำรองข้อมูล volume ที่คุณเคยทดสอบการกู้คืนมาแล้วอย่างน้อยหนึ่งครั้ง การออกแบบนี้มีความมั่นคงสำหรับเซิร์ฟเวอร์ที่คุณดูแลเอง และความเสี่ยงหลักอยู่ที่การเปลี่ยนแปลงเวอร์ชันที่รวดเร็ว ไม่ใช่ที่ตัวสถาปัตยกรรม