กลยุทธ์ความปลอดภัยโอเพนซอร์สของ Astral
(astral.sh)- Astral ผู้พัฒนาเครื่องมืออย่าง Ruff, uv, ty ที่นักพัฒนาทั่วโลกใช้งาน ยึดถือ ความปลอดภัยและความน่าเชื่อถือ ของทุกผลิตภัณฑ์เป็นคุณค่าหลัก
- เพื่อตอบสนองต่อ การโจมตีซัพพลายเชนที่เพิ่มขึ้น ในช่วงหลัง Astral ได้เปิดเผย เทคนิคภายในเพื่อเสริมความปลอดภัย ตลอดกระบวนการ build, deploy และ release
- ใน CI/CD ที่อิง GitHub Actions มีการใช้ระบบป้องกันหลายชั้น เช่น การตรึงแฮช, สิทธิ์ขั้นต่ำ, การแยกข้อมูลลับ
- ในขั้นตอน release มีการใช้ Trusted Publishing, Sigstore attestations, Immutable Releases เป็นต้น เพื่อรับประกัน ความสมบูรณ์ของการเผยแพร่
- Astral ตั้งเป้ายกระดับ มาตรฐานความปลอดภัยของระบบนิเวศโอเพนซอร์สโดยรวม และสร้าง ระบบป้องกันที่ยั่งยืน ผ่านแนวทางเหล่านี้
แนวทางความปลอดภัยโอเพนซอร์สของ Astral
- Astral พัฒนาเครื่องมืออย่าง Ruff, uv, ty ที่มีนักพัฒนาหลายล้านคนทั่วโลกใช้งาน และยึดถือ ความปลอดภัยและความน่าเชื่อถือ ของเครื่องมือเหล่านี้เป็นคุณค่าหลัก
- เมื่อการโจมตีซัพพลายเชนเพิ่มขึ้นจากกรณีอย่างการแฮ็ก Trivy และ LiteLLM ล่าสุด Astral จึงเปิดเผยเทคนิคความปลอดภัยภายในที่ใช้รับประกันความปลอดภัยของเครื่องมือและกระบวนการ build/deploy ของตน
- มีการแบ่งปัน แนวปฏิบัติด้านความปลอดภัยที่ดี ที่ทั้งผู้ใช้ ผู้ดูแลโอเพนซอร์ส และนักพัฒนาระบบ CI/CD สามารถนำไปอ้างอิงได้
ความปลอดภัยของ CI/CD
- Astral ใช้ เวิร์กโฟลว์ CI/CD ขนาดใหญ่ บน GitHub Actions เพื่อทำให้การพัฒนาและการเผยแพร่เป็นอัตโนมัติ และใช้สิ่งนี้เป็นองค์ประกอบสำคัญของความปลอดภัย
- ทำให้การ build และ test เกิดขึ้นใน สภาพแวดล้อมที่ควบคุมและสังเกตการณ์ได้ แทนที่จะเป็นบนเครื่อง local
- โดยตระหนักว่าการตั้งค่าความปลอดภัย ค่าเริ่มต้นของ GitHub Actions ยังอ่อนแอ จึงมีการเสริมความแข็งแกร่งดังนี้
- ห้ามใช้ trigger ที่มีความเสี่ยงทั้งหมด เช่น
pull_request_target,workflow_run - ตรึง action ทุกตัวไว้กับ commit hash (SHA) ที่ระบุชัดเจน และตรวจสอบข้ามกันว่ามี impostor commit หรือไม่
- ใช้ทั้งเครื่องมือตรวจสอบของ zizmor อย่าง
unpinned-uses,impostor-commitควบคู่กับนโยบายของ GitHub - ตรึงแฮชทั้งกราฟการพึ่งพา รวมถึง action แบบ dependency ทางอ้อมที่ไม่สามารถตรึงแฮชได้โดยตรง
- ห้ามใช้ trigger ที่มีความเสี่ยงทั้งหมด เช่น
- เนื่องจากการตรึงแฮชเพียงอย่างเดียวยังไม่เพียงพอ จึงใช้ การตรวจสอบด้วยมือเพื่อค้นหาข้อบกพร่องด้านความไม่เปลี่ยนแปลง และหากจำเป็นก็ร่วมมือกับโปรเจ็กต์ต้นน้ำเพื่อแก้ไข
- ตัวอย่าง: ทำการแมป URL ดาวน์โหลดไบนารีกับแฮชและ ฝังไว้แบบไม่เปลี่ยนแปลง
- สิทธิ์ของ workflow ถูกจำกัดเป็น อ่านอย่างเดียวโดยค่าเริ่มต้น และให้เฉพาะสิทธิ์ขั้นต่ำที่จำเป็นในระดับแต่ละ job
- GitHub Secrets ถูกจัดการเป็น ตัวแปรสภาพแวดล้อมสำหรับการ deploy ที่แยกตาม environment เพื่อไม่ให้งาน test/lint เข้าถึงข้อมูลลับสำหรับ release ได้
- เครื่องมือเสริมที่ใช้คือ zizmor (วิเคราะห์แบบสแตติก) และ pinact (ตรึงแฮชอัตโนมัติ)
ความปลอดภัยของ repository และองค์กร
- ภายในองค์กร Astral มีการ ลดจำนวนบัญชีที่มีสิทธิ์ผู้ดูแลระบบให้เหลือน้อยที่สุด และสมาชิกส่วนใหญ่จะมีสิทธิ์อ่าน/เขียนเฉพาะ repository ที่จำเป็น
- กำหนดให้สมาชิกทุกคนใช้ การยืนยันตัวตนแบบสองขั้นตอน (2FA) ที่แข็งแรง โดยอย่างน้อยต้องเป็นระดับ TOTP ขึ้นไป
- หาก GitHub อนุญาตเฉพาะวิธีที่ต้านทานฟิชชิงได้ (WebAuthn, Passkeys) ก็พร้อมเปลี่ยนทันที
- ใช้ กฎป้องกัน branch กับทั้งองค์กร
- branch
mainไม่อนุญาต force push และทุกการเปลี่ยนแปลงต้องผ่าน PR เท่านั้น - ห้ามสร้าง branch ตามแพตเทิร์นเฉพาะ เช่น
advisory-*,internal-*
- branch
- ใช้ กฎป้องกัน tag เพื่อให้สร้าง tag ได้เฉพาะหลังเผยแพร่ release สำเร็จเท่านั้น
- ห้ามแก้ไขหรือลบ tag และ release ทำได้จาก branch
mainเท่านั้น
- ห้ามแก้ไขหรือลบ tag และ release ทำได้จาก branch
- แม้แต่ผู้ดูแล repository ก็ไม่สามารถข้ามกฎป้องกันได้ โดยการป้องกันทั้งหมดถูกบังคับใช้ในระดับองค์กร
- Astral เผยแพร่ชุดกฎเหล่านี้เป็น gist เพื่อให้โปรเจ็กต์อื่นนำไปอ้างอิงได้
ระบบอัตโนมัติ
- บน GitHub Actions ไม่สามารถทำงานบางอย่างได้อย่างปลอดภัย เช่น การเขียนคอมเมนต์บน PR จากบุคคลที่สาม
- เพื่อแก้ปัญหานี้ Astral ใช้ astral-sh-bot GitHub App เพื่อจัดการ event อย่างปลอดภัยนอก Actions
- GitHub App จะรับข้อมูล event เดียวกัน แต่ทำงานใน สภาพแวดล้อมที่แยกโค้ดออกจากข้อมูล
- อย่างไรก็ตาม App เองก็ ไม่ได้ตัดความจำเป็นของ credential ที่มีความอ่อนไหวออกไป
- ยังอาจมีช่องโหว่เช่น SQLi, prompt injection ได้ จึงต้อง พัฒนาด้วยมาตรฐานความปลอดภัยระดับเดียวกับซอฟต์แวร์ทั่วไป
- การใช้ App ไม่ได้หมายความว่า การรันโค้ดที่ไม่เชื่อถือจะปลอดภัยโดยอัตโนมัติ
- แนวทาง GitHub App ให้ประโยชน์ด้านความปลอดภัย แต่เพิ่มความซับซ้อน
- ต้องพัฒนาและโฮสต์ App เอง ซึ่งอาจเป็นภาระสำหรับนักพัฒนารายบุคคลหรือโปรเจ็กต์ขนาดเล็ก
- เฟรมเวิร์ก Gidgethub สำหรับ Python ช่วยให้การพัฒนาง่ายขึ้น
- Astral มีแผน เปิดซอร์ส astral-sh-bot และแนะนำ บทเรียนของ Mariatta เป็นเอกสารอ้างอิง
ความปลอดภัยของ release
- เครื่องมือของ Astral ถูกแจกจ่ายผ่านหลายช่องทางนอกเหนือจาก GitHub เช่น PyPI, Homebrew, Docker image
- เพื่อป้องกันการโจมตีซัพพลายเชน มีการดำเนินการดังนี้
- ใช้ Trusted Publishing เพื่อตัดความจำเป็นของ credential สำหรับ registry
-
สร้าง attestations บนพื้นฐานของ Sigstore เพื่อรับประกัน ความเชื่อมโยงเชิงเข้ารหัส ระหว่างผลลัพธ์จากการ build กับ workflow
- ใช้ฟีเจอร์ Immutable Releases ของ GitHub เพื่อป้องกันการแก้ไขหลังเผยแพร่
- ไม่ใช้ build cache เพื่อปิดกั้นการโจมตีแบบ cache poisoning
- กระบวนการ release ถูกแยกไว้ใน deployment environment เฉพาะ
- เมื่อต้องเปิดใช้งาน environment สำหรับ release จะ ต้องได้รับการอนุมัติจากสมาชิกทีมคนอื่น เพื่อป้องกัน release ที่เป็นอันตรายจากการยึดบัญชีเพียงบัญชีเดียว
- ใช้ environment
release-gateและ การส่งต่อการอนุมัติผ่าน GitHub App เพื่อคงการอนุมัติหลายขั้น - สามารถสร้าง tag ได้เฉพาะหลัง release สำเร็จเท่านั้น
- ตัวติดตั้งแบบสแตนด์อโลน (standalone installer) ตรวจสอบความสมบูรณ์ของไบนารีด้วย checksum ที่ฝังมาในตัว
- หลัง release งานอย่างการอัปเดตเอกสาร, version manifest, pre-commit hook จะทำผ่าน บัญชีบอตเฉพาะและ PAT ที่แยกสิทธิ์อย่างละเอียด
- ในอนาคตมีแผนเพิ่ม code signing สำหรับ macOS และ Windows
ความปลอดภัยของ dependency
- Astral ใช้ Dependabot และ Renovate เพื่อจัดการการอัปเดต dependency และการแจ้งเตือนช่องโหว่
- มีการกำหนดช่วง cooldown เพื่อหน่วงการอัปเดตทันทีหลังมี release ใหม่ ช่วยลดความเสี่ยงจากการโจมตีซัพพลายเชนชั่วคราว
- Renovate รองรับการตั้งค่า cooldown แยกตามกลุ่ม และมีการผ่อนปรนกับ dependency ภายในของตนเอง
- มีการ ร่วมมือและช่วยงานด้านความปลอดภัยอย่างต่อเนื่อง กับโปรเจ็กต์ต้นน้ำสำคัญ
- ตัวอย่าง: มีส่วนช่วยเสริมความปลอดภัย CI/CD ให้กับ apache/opendal-reqsign
- ร่วมมือกับ Python Packaging Authority, Python Security Response Team และองค์กรอื่นเพื่อแบ่งปันข้อมูลด้านความปลอดภัย
- พิจารณาการเพิ่ม dependency ใหม่อย่างรอบคอบ และผลักดันการลด dependency ที่ไม่จำเป็น
- โดยเฉพาะการ หลีกเลี่ยง dependency ที่มี binary blob และปิดฟีเจอร์ที่ไม่จำเป็น
- ให้การสนับสนุนทางการเงินกับโปรเจ็กต์โอเพนซอร์สสำคัญผ่าน OSS Fund
บทสรุปและข้อคิดสำคัญ
- ความปลอดภัยของโอเพนซอร์สเป็น ปัญหาที่ผสมกันทั้งด้านเทคนิคและสังคม และต้องรับมืออย่างต่อเนื่อง
- หลักการสำคัญที่ Astral เน้นย้ำ
- ตระหนักถึงข้อจำกัดของ CI/CD และเมื่อหลีกเลี่ยงไม่ได้ให้ใช้วิธีแยกภายนอก เช่น GitHub App
- กำจัดและลด credential ระยะยาวให้มากที่สุด พร้อมใช้ Trusted Publishing และการยืนยันตัวตนผ่าน OIDC
- เสริมความแข็งแรงให้กระบวนการ release ด้วยกฎการอนุมัติ, tag, branch และ Immutable Release
- รักษาการรับรู้เรื่อง dependency อยู่เสมอ และใช้ทั้งเครื่องมือกับความร่วมมือเพื่อยกระดับความปลอดภัยของโปรเจ็กต์ต้นน้ำไปพร้อมกัน
- Astral จะประเมินและปรับปรุงเทคนิคเหล่านี้อย่างต่อเนื่อง และ พัฒนาระบบป้องกันให้ทันต่อพฤติกรรมของผู้โจมตีที่เปลี่ยนแปลงไป
สรุปเชิงอรรถ
- PEP 740 ของ PyPI อนุญาตให้อัปโหลด attestations ได้ แต่ปัจจุบันยังไม่เข้ากันกับการทำ Trusted Publishing ของ Astral จึงยังรอการนำมาใช้
- checksum ภายในสคริปต์ติดตั้งมีประสิทธิภาพจำกัดเมื่อรัน
curl ... | bashโดยตรง แต่ มีประโยชน์เมื่อ vendoring ภายใน CI/CD
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ดูเหมือนว่าการใช้ CI ของ GitHub ให้ปลอดภัยต้องผ่านหลายขั้นตอนเกินไป
ถ้าโครงสร้างเป็นแบบนี้ ก็คิดว่าแทบเป็นไปไม่ได้เลยที่จะ ใช้งานให้ปลอดภัยในเชิงความมั่นคง
มันให้ความรู้สึกว่าการจะสร้าง supply chain security บนระบบที่แม้แต่หลักพื้นฐานอย่างการแยกสิทธิ์หรือการแยกส่วนยังทำไม่ได้ ก็เป็นเรื่องฝืนธรรมชาติ
แต่การตั้งค่าละเอียดอ่อนมากจนไม่ดูเป็นแนวทางที่ขยายต่อได้ ถ้าค่าเริ่มต้นปลอดภัยขึ้นกว่านี้ น่าจะดีขึ้นมาก
พออ่านบทความจบแล้วก็รู้สึกว่า ความซับซ้อนแบบนี้อาจเป็นปัญหาเชิงแก่นของพื้นที่นี้เองก็ได้
ส่วนใหญ่ ไม่รองรับ immutable release และถึงรองรับก็ยังมีโครงสร้างที่ดึงเวอร์ชันใหม่อัตโนมัติ เลยเสี่ยงต่อการถูกโจมตี
ถ้าจะให้ปลอดภัยจริง ต้องจัดการ dependency ที่ผ่านการตรวจสอบแล้วใน registry ภายในของตัวเองแบบตรึงเวอร์ชัน แต่เรื่องแบบนั้นคงมีแค่ระดับ Google เท่านั้นที่ทำได้
ไบนารี uv ของ stagex ที่ทีมเราสร้าง เป็นตัวเดียวในโลกที่ build ด้วย full source bootstrap และ deterministic artifact ที่มีลายเซ็นหลายชุดครบถ้วน
ใช้ระบบลายเซ็นบนสมาร์ตการ์ดที่เชื่อมกับ web of trust อายุ 25 ปีและคีย์มากกว่า 5000 คีย์
แต่ที่น่าหงุดหงิดคือ อาสาสมัครกลับจริงจังกับ supply chain security มากกว่าเสียอีก
ต่อให้เครื่องมืออย่าง OpenClaw ทำให้คีย์และซีเคร็ตหลุด ผู้ใช้ก็ยังใช้มันอยู่ดี
คุณพยายามลด attack surface แต่ตลาดกลับขยายมันออกไปเรื่อย ๆ
ถ้าไม่มีอาสาสมัคร โปรเจกต์อย่าง Debian ก็คงไม่มีอยู่จริง แข่งกันด้วยผลลัพธ์ที่ดีกว่าน่าจะดีกว่าการบ่น
ถ้าสุดท้ายแล้วยังเป็นการแจกจ่ายผลลัพธ์ที่บุคคลที่สาม build มา ก็ยังไม่ชัดว่า threat model คืออะไร
build ของ uv ทั้งหมดมาจาก resolution ที่ถูกล็อกไว้ และแจก artifact ที่มีลายเซ็นอยู่แล้ว คุณค่าของ commit ที่เซ็นด้วยชุดตัวตนอีกแบบจึงไม่ชัดเจน
OpenAI เลยไม่มีเหตุผลจำเป็นที่จะต้องจ่ายเงินเพื่อยกระดับ supply chain security
เข้าใจคำวิจารณ์เชิงเทคนิคนะ แต่ถ้าจะโยนความรับผิดให้ OpenAI ทั้งหมดในจังหวะเวลานี้ก็ดูเกินไป
เผื่อไว้เป็นข้อมูลว่า Trusted Publishing ของ PyPI นั้น William Woodruff กับทีม Trail of Bits เป็นคนช่วยกันทำ
อยากถามทีม Astral ว่าจัดการอย่างไรกับการที่ทุ่มเทขนาดนี้ แต่ก็ยังต้องพึ่ง GitHub อย่างมาก
ถ้า GitHub ถูกแฮ็ก หรือมีบั๊กจนค่าตั้งเปลี่ยนไป จะรับมืออย่างไร?
ระบบนิเวศโอเพนซอร์สมีความยืดหยุ่นสูง แต่ การ sandbox โค้ดจากบุคคลที่สาม ยังอ่อนอยู่มาก
เวลาพูดถึง uv มักจะเน้นข้อดีว่าใช้จัดการ Python หลายเวอร์ชันได้ง่าย แต่ในอีกมุมก็หมายถึงมันถูกรันบนเครื่องโฮสต์โดยแทบไม่มีการแยกส่วน ซึ่งทำให้รู้สึกไม่สบายใจ
ปัญหาใหญ่ของ supply chain ตอนนี้คือมีเครื่องมือและ dependency จำนวนมากที่ ถูกดาวน์โหลดโดยไม่มีการตรวจสอบแหล่งที่มา
เพราะแบบนี้ฉันเลยกำลังพัฒนา asfaload ซึ่งเป็นโซลูชันตรวจสอบไฟล์แบบ multisig ที่เป็นโอเพนซอร์ส
เป็นโครงสร้างที่ช่วยป้องกันเหตุการณ์แบบ axios ได้
ต่อให้ตรึง GitHub Actions ด้วย commit SHA ก็ยังเสี่ยงอยู่ดีถ้า action นั้นไปดึง dependency อื่นต่อ
ทางแก้จริง ๆ คือ เป็นเจ้าของโค้ดเองโดยตรง ใน CI pipeline หรือไม่ก็ fork มาแล้วดูแลเอง
เราตรวจสอบทุก action และถ้ามี dependency ที่เปลี่ยนแปลงได้ก็จะปรับแก้หรือหาตัวแทน (ฉันอยู่ Astral)
การดูแลทั้งสแตกเองทั้งหมดปลอดภัยที่สุด แต่ไม่สมจริง
การตรึง hash เป็นมาตรการเพิ่มความปลอดภัยที่แทบได้มาฟรี
สุดท้ายสิ่งสำคัญคือการรู้ให้ชัดว่าคุณกำลังเชื่อใจอะไรอยู่บ้าง
จากกรณีของ Trivy และ litellm เมื่อไม่นานมานี้ จะเห็นได้ว่าจำเป็นต้องมี คู่มือความปลอดภัยของกระบวนการ release จริง ๆ
คำแนะนำในบทความนี้นำไปใช้ได้จริงและทำได้ทันที
แก่นของ supply chain security ขึ้นอยู่กับว่าค่าเริ่มต้นของแพลตฟอร์มที่เราใช้นั้นปลอดภัยแค่ไหน
เป็นภาพรวมที่ยอดเยี่ยม น่าจะกลายเป็น แหล่งอ้างอิง ที่มีประโยชน์สำหรับโปรเจกต์โอเพนซอร์สอื่น ๆ ด้วย
ฉันดูแล
repomaticซึ่งเป็น Python CLI และเครื่องมือ reusable workflowมันมีแนวปฏิบัติด้านความปลอดภัยส่วนใหญ่จากบทความนี้เป็นค่าเริ่มต้นอยู่แล้ว
เป้าหมายคือการสร้างสภาพแวดล้อมที่ ความปลอดภัยเป็นค่าเริ่มต้น
หลังจากอ่านบทความนี้แล้ว ฉันได้เพิ่มการตรวจนโยบายการอนุมัติ PR จาก fork เข้าไป
รายละเอียดดูได้ที่ GitHub repository