Chiến lược bảo mật mã nguồn mở tại Astral: Bài học từ Ruff, uv và Python

09 tháng 4, 2026·13 phút đọc

Astral, công ty phát triển các công cụ lập trình phổ biến như Ruff và uv, đã chia sẻ chi tiết về quy trình bảo mật của họ nhằm chống lại các cuộc tấn công chuỗi cung ứng. Bài viết đi sâu vào việc củng cố GitHub Actions, quản lý quyền hạn, cô lập thông tin đăng nhập và áp dụng các biện pháp bảo vệ nghiêm ngặt cho quy trình phát hành.

Chiến lược bảo mật mã nguồn mở tại Astral: Bài học từ Ruff, uv và Python

Astral là đơn vị đứng sau những công cụ mà hàng triệu nhà phát triển trên toàn thế giới tin dùng mỗi ngày. Niềm tin đó bao gồm cả sự tin cậy vào tư thế bảo mật của chúng tôi: các nhà phát triển hoàn toàn có lý khi kỳ vọng rằng các công cụ (cũng như quy trình xây dựng, kiểm thử và phát hành chúng) phải an toàn. Sự gia tăng của các cuộc tấn công chuỗi cung ứng, điển hình là các vụ hack gần đây đối với Trivy và LiteLLM, đã khiến cộng đồng nhà phát triển đặt câu hỏi về mức độ tin cậy của các công cụ họ sử dụng.

Vì lý do đó, chúng tôi muốn chia sẻ một số kỹ thuật chúng tôi sử dụng để bảo mật các công cụ của mình, hy vọng rằng chúng sẽ hữu ích cho:

  • Người dùng của chúng tôi, những người muốn hiểu chúng tôi làm gì để giữ hệ thống của họ an toàn;
  • Những người bảo trì khác, các dự án và công ty, những người có thể hưởng lợi từ các kỹ thuật chúng tôi áp dụng;
  • Các nhà phát triển hệ thống CI/CD, để các dự án không cần phải đi theo những con đường không rõ ràng hoặc bỏ qua các tính năng hữu ích chỉ để duy trì quy trình an toàn và mạnh mẽ.

Bảo mật CI/CD

Chúng tôi duy trì tốc độ phát triển trên Ruff, uv và thông qua các quy trình làm việc CI/CD mở rộng chạy trên GitHub Actions. Nếu không có các quy trình này, chúng tôi sẽ gặp khó khăn trong việc xem xét, kiểm thử và phát hành các công cụ với tốc độ và mức độ tự tin mà chúng tôi yêu cầu. Các quy trình CI/CD cũng là một phần quan trọng trong tư thế bảo mật của chúng tôi, cho phép chúng tôi giữ các quy trình phát triển và phát hành quan trọng xa khỏi máy tính cục bộ của nhà phát triển và đặt bên trong các môi trường được kiểm soát, có thể quan sát.

GitHub Actions là lựa chọn hợp lý đối với chúng tôi nhờ sự tích hợp chặt chẽ của nó với GitHub, cùng với sự hỗ trợ trưởng thành cho quy trình đóng góp của cộng đồng: bất kỳ ai muốn đóng góp đều có thể xác minh rằng pull request của họ là chính xác bằng quy trình giống như chúng tôi sử dụng.

Tuy nhiên, nó cũng có mặt trái: GitHub Actions có các mặc định bảo mật kém, và các vi phạm bảo mật như Ultralytics, tj-actions và Nx đều bắt đầu từ những điểm yếu quen thuộc như các yêu cầu bị chiếm quyền kiểm soát (pwn requests).

Dưới đây là một số việc chúng tôi làm để bảo mật quy trình CI/CD:

  • Cấm các kích hoạt nguy hiểm: Chúng tôi cấm nhiều trình kích hoạt nguy hiểm và kém an toàn nhất của GitHub, chẳng hạn như pull_request_targetworkflow_run, trên toàn bộ tổ chức GitHub của mình. Các trình kích hoạt này gần như không thể sử dụng an toàn và những kẻ tấn công liên tục tìm cách lạm dụng chúng, vì vậy chúng tôi đơn giản là không cho phép chúng tồn tại.
  • Ghim (Pin) hành động theo commit: Chúng tôi yêu cầu tất cả các hành động phải được ghim vào các commit cụ thể (thay vì thẻ hoặc nhánh, có thể thay đổi được). Ngoài ra, chúng tôi đối chiếu chéo các commit này để đảm bảo chúng khớp với trạng thái kho lưu trữ đã phát hành thực tế và không phải là commit giả mạo.
  • Hạn chế quyền hạn: Chúng tôi giới hạn quyền hạn cho quy trình làm việc và công việc ở nhiều nơi: chúng tôi mặc định quyền chỉ đọc ở cấp độ tổ chức và thêm vào đó, chúng tôi bắt đầu mọi quy trình làm việc với permissions: {} và chỉ mở rộng quyền hạn đó trên cơ sở từng công việc.
  • Cô lập bí mật: Chúng tôi cô lập các bí mật GitHub Actions của mình ở mọi nơi có thể: thay vì sử dụng bí mật cấp độ tổ chức hoặc kho lưu trữ, chúng tôi sử dụng môi trường triển khai và các bí mật cụ thể cho môi trường. Điều này cho phép chúng tôi hạn chế thêm phạm vi ảnh hưởng của một sự cố tiềm ẩn.

Để thực hiện những việc này, chúng tôi tận dụng các cài đặt của chính GitHub, cũng như các công cụ như zizmor (để phân tích tĩnh) và pinact (để ghim tự động).

Bảo mật kho lưu trữ và tổ chức

Ngoài các quy trình CI/CD, chúng tôi còn thực hiện một số bước để hạn chế cả khả năng và tác động của việc bị xâm phạm tài khoản và kho lưu trữ trong tổ chức Astral:

  • Giới hạn tài khoản đặc quyền: Chúng tôi giới hạn số lượng tài khoản có vai trò quản trị viên và các vai trò có quyền cao khác, hầu hết các thành viên tổ chức chỉ có quyền đọc và ghi đối với các kho lưu trữ họ cần làm việc.
  • Thực thi 2FA mạnh: Chúng tôi thực thi các phương thức 2FA mạnh cho tất cả thành viên của tổ chức Astral, vượt quá mặc định của GitHub là yêu cầu bất kỳ phương thức 2FA nào. Điều này yêu cầu tất cả thành viên phải có phương thức 2FA không yếu hơn TOTP.
  • Quy tắc bảo vệ nhánh: Chúng tôi áp dụng quy tắc bảo vệ nhánh trên phạm vi toàn tổ chức: các thay đổi đối với nhánh chính không thể force-push và phải luôn đi qua một pull request. Chúng tôi cũng cấm tạo các mẫu nhánh cụ thể (như advisory-*internal-*) để ngăn chặn việc tiết lộ công việc bảo mật quá sớm.
  • Quy tắc bảo vệ thẻ: Chúng tôi áp dụng các quy tắc bảo vệ thẻ ngăn việc tạo thẻ phát hành cho đến khi triển khai phát hành thành công, với việc triển khai phát hành bị chặn bởi sự phê duyệt thủ công của ít nhất một thành viên khác trong nhóm.

Cuối cùng, chúng tôi cấm quản trị viên kho lưu trữ bỏ qua tất cả các biện pháp bảo vệ trên. Tất cả các biện pháp bảo vệ của chúng tôi đều được thực thi ở cấp độ tổ chức, nghĩa là kẻ tấn công quản lý xâm phạm tài khoản có quyền truy cập quản trị viên vào một kho lưu trữ cụ thể vẫn sẽ không thể tắt các điều khiển của chúng tôi.

Tự động hóa

Có một số việc mà GitHub Actions có thể làm nhưng không thể làm một cách an toàn, chẳng hạn như để lại nhận xét trên các vấn đề và pull request của bên thứ ba. Hầu hết thời gian, tốt hơn là nên từ bỏ các tính năng này, nhưng trong một số trường hợp, chúng là một phần có giá trị trong quy trình làm việc của chúng tôi.

Trong những trường hợp sau, chúng tôi sử dụng astral-sh-bot để cô lập an toàn các nhiệm vụ này bên ngoài GitHub Actions: GitHub gửi cho chúng tôi cùng dữ liệu sự kiện mà GitHub Actions sẽ nhận được, nhưng với sự kiểm soát nhiều hơn và ít trạng thái ngầm định hơn.

Tuy nhiên, GitHub App vẫn có một điểm bắt kẹt: một ứng dụng không loại bỏ bất kỳ thông tin đăng nhập nhạy cảm nào cần thiết cho một thao tác, nó chỉ chuyển chúng vào một môi trường không trộn lẫn mã và dữ liệu lan rộng như GitHub Actions. Do đó, điều cần thiết là phải coi sự phát triển của GitHub App với tư duy bảo mật giống như bất kỳ sự phát triển phần mềm nào khác.

Chúng tôi nhận thấy rằng mô hình GitHub App hoạt động tốt cho chúng tôi và chúng tôi khuyên nó cho những người bảo trì và dự án khác có nhu cầu tương tự. Nhược điểm chính của nó nằm ở sự phức tạp: nó yêu cầu phát triển và lưu trữ một GitHub App, thay vì viết một quy trình làm việc mà GitHub điều phối cho bạn.

Bảo mật phát hành

Cho đến nay, chúng tôi đã đề cập đến các khía cạnh liên quan chặt chẽ đến GitHub, với tư cách là máy chủ nguồn cho các công cụ của Astral. Nhưng nhiều người dùng của chúng tôi cài đặt các công cụ thông qua các cơ chế khác, chẳng hạn như PyPI, Homebrew và hình ảnh Docker của chúng tôi. Các kênh phân phối này thêm một "liên kết" khác vào chuỗi cung ứng ẩn dụ và yêu cầu sự xem xét riêng biệt:

  • Xuất bản tin cậy (Trusted Publishing): Ở mọi nơi có thể, chúng tôi sử dụng Trusted Publishing để xuất bản lên các sổ đăng ký (như PyPI, crates.io và NPM). Kỹ thuật này loại bỏ nhu cầu về thông tin đăng nhập sổ đăng ký tồn tại lâu dài, từ đó giảm thiểu một trong những nguồn phổ biến nhất của việc chiếm đoạt gói.
  • Chứng thực Sigstore: Ở mọi nơi có thể (hiện tại là các bản phát hành hình ảnh nhị phân và Docker của chúng tôi), chúng tôi tạo các chứng thực dựa trên Sigstore. Các chứng thực này thiết lập liên kết có thể xác minh mật mã giữa bản phát hành và quy trình tạo ra nó.
  • Bản phát hành bất biến: Chúng tôi sử dụng tính năng bản phát hành bất biến của GitHub để ngăn chặn sửa đổi sau khi xây dựng các bản dựng mà chúng tôi xuất bản trên GitHub. Điều này giải quyết một kỹ thuật chuyển hướng phổ biến của kẻ tấn công, trong đó các bản dựng đã xuất bản trước đó được thay thế bằng các bản dựng độc hại.
  • Không sử dụng bộ nhớ đệm: Chúng tôi không sử dụng bộ nhớ đệm để cải thiện thời gian xây dựng trong quá trình phát hành, để ngăn chặn kẻ tấn công xâm phạm các bản dựng của chúng tôi thông qua cuộc tấn công đầu độc bộ nhớ đệm GitHub Actions.

Để giảm thiểu rủi ro kẻ tấn công phát hành một phiên bản độc hại mới của các công cụ, chúng tôi sử dụng một chồng các biện pháp bảo vệ trên quy trình phát hành của mình:

  • Quy trình phát hành được cô lập trong một môi trường triển khai GitHub chuyên dụng.
  • Để kích hoạt môi trường phát hành, công việc kích hoạt phải được phê duyệt bởi ít nhất một thành viên có đặc quyền khác của tổ chức Astral. Điều này giảm thiểu rủi ro một tài khoản nổi loạn hoặc bị xâm phạm có thể phát hành bản phát hành độc hại.
  • Chúng tôi sử dụng quy tắc bảo vệ thẻ để ngăn chặn việc tạo thẻ của bản phát hành cho đến khi triển khai phát hành thành công.

Bảo mật phụ thuộc

Cuối cùng nhưng không kém phần quan trọng là câu hỏi về các phụ thuộc. Giống như hầu hết mọi phần mềm hiện đại, các công cụ của chúng tôi phụ thuộc vào hệ sinh thái của các phụ thuộc bên thứ ba (cả trực tiếp và gián tiếp). Dưới đây là một số việc chúng tôi làm để đo lường và giảm thiểu rủi ro thượng nguồn:

  • Quản lý phụ thuộc: Chúng tôi sử dụng các công cụ quản lý phụ thuộc như Dependabot và Renovate để giữ cho các phụ thuộc của mình được cập nhật và thông báo cho chúng tôi khi các phụ thuộc chứa các lỗ hổng đã biết.
  • Thời gian chờ (Cooldowns): Nói chung, chúng tôi sử dụng thời gian chờ kết hợp với các công cụ trên để tránh cập nhật phụ thuộc ngay sau khi phát hành mới, vì đây là lúc các phụ thuộc bị xâm phạm tạm thời có khả năng ảnh hưởng đến chúng tôi nhất.
  • Kết nối xã hội: Chúng tôi duy trì các kết nối xã hội với nhiều phụ thuộc thượng nguồn của mình và thực hiện cả các đóng góp thường xuyên và bảo mật với họ (bao gồm cả các bản sửa lỗi cho quy trình CI/CD và phát hành của chính họ).
  • Thận trọng khi thêm phụ thuộc: Chúng tôi bảo thủ khi thêm các phụ thuộc mới và tìm cách loại bỏ các phụ thuộc ở nơi thực tế và gây ít gián đoạn nhất cho người dùng. Chúng tôi cố gắng tránh các phụ thuộc giới thiệu các binary blob và xem xét kỹ lưỡng các tính năng của phụ thuộc để vô hiệu hóa chức năng mà chúng tôi không cần hoặc không mong muốn.

Lời kết

Bảo mật mã nguồn mở là một vấn đề khó, một phần vì thực chất nó là nhiều vấn đề (một số kỹ thuật, một số xã hội) ngụy tạo thành một vấn đề duy nhất. Chúng tôi đã đề cập đến nhiều kỹ thuật chúng tôi sử dụng để giải quyết vấn đề này, nhưng bài viết này không bao giờ là một danh sách đầy đủ. Nó cũng không phải là một danh sách tĩnh: những kẻ tấn công là những người tham gia động trong quá trình bảo mật và các biện pháp phòng vệ nhất thiết phải phát triển để đáp ứng các kỹ thuật thay đổi của họ.

Với điều đó trong tâm trí, chúng tôi muốn nhắc lại một số điểm được đề cập ở trên xứng đáng được chú ý nhất:

  • Tôn trọng giới hạn của CI/CD: cực kỳ hấp dẫn khi làm mọi thứ trong CI/CD, nhưng có một số việc mà CI/CD (đặc biệt là GitHub Actions) đơn giản là không thể làm một cách an toàn. Đối với những việc này, thường tốt hơn là nên từ bỏ chúng hoàn toàn, hoặc cô lập chúng bên ngoài CI/CD với một GitHub App hoặc tương tự.
  • Cô lập và loại bỏ thông tin đăng nhập tồn tại lâu dài: hình thức lây lan phổ biến nhất sau khi bị xâm phạm là lạm dụng thông tin đăng nhập tồn tại lâu dài. Ở mọi nơi có thể, hãy loại bỏ các thông tin đăng nhập này hoàn toàn (ví dụ: với Trusted Publishing hoặc các cơ chế xác thực dựa trên OIDC khác).
  • Tăng cường quy trình phát hành: nếu bạn đang trên GitHub, hãy sử dụng môi trường triển khai, sự phê duyệt, bộ quy tắc thẻ và nhánh, cũng như các bản phát hành bất biến để giảm bớt mức độ tự do mà kẻ tấn công có trong trường hợp chiếm đoạt tài khoản hoặc xâm phạm kho lưu trữ.
Bài viết được tổng hợp và biên soạn bằng AI từ các nguồn tin tức công nghệ. Nội dung mang tính tham khảo. Xem bài gốc ↗