8 phút

Những cổng pull request nào cho tác nhân nên chặn việc hợp nhất?

Dùng bảy cổng pull request có thể đo lường để chặn mã không an toàn: kiểm thử, CodeQL, phụ thuộc, bí mật, phân quyền, di chuyển dữ liệu và hoàn tác.

Những cổng pull request nào cho tác nhân nên chặn việc hợp nhất?

Một tác nhân có thể tạo ra bản diff gọn gàng, mô tả thuyết phục và đoạn mã qua được vòng duyệt nhanh, nhưng ứng dụng vẫn có thể bị phơi bày hoặc không thể khôi phục. Vì vậy, quyết định hợp nhất phải dựa trên bằng chứng mà kho lưu trữ đo được, không dựa vào mức độ tự tin của tác nhân hay kích thước bản vá.

Tôi dùng bảy cổng chặn: kiểm thử, CodeQL, đánh giá phụ thuộc, quét bí mật, kiểm tra phân quyền, diễn tập di chuyển dữ liệu và xác minh hoàn tác. Mỗi cổng trả lời một câu hỏi khác nhau về sự cố. Một bộ kiểm thử xanh không thể chứng minh gói mới an toàn, còn kết quả phân tích tĩnh sạch không nói gì về việc một đợt di chuyển cơ sở dữ liệu có khóa bảng bận rộn nhất hay không.

Các cổng này áp dụng như nhau cho thay đổi của con người và tác nhân. Tác nhân thay đổi số lượng, tốc độ và kiểu sai sót, nhưng đó không phải lý do để có một luồng riêng yếu hơn. Nếu thay đổi được đề xuất không thể cung cấp bằng chứng như mọi pull request khác, nó chưa sẵn sàng để hợp nhất.

Một cổng phải tạo ra bằng chứng, không phải lời khuyên

Một cổng hợp nhất phải trả về kết quả đạt hoặc không đạt có thể tái tạo cho đúng commit sẽ đi vào nhánh được bảo vệ. Bình luận «hãy xem xét phụ thuộc này» là lời khuyên. Một kiểm tra bắt buộc xác định gói, phiên bản, cảnh báo và ngưỡng mức độ nghiêm trọng là bằng chứng.

Sự khác biệt này quan trọng vì nhiều tính năng bảo mật mặc định chỉ báo cáo sau thời điểm ra quyết định hữu ích. Trình quét có thể tạo cảnh báo, gửi email hoặc mở issue trong khi nút hợp nhất vẫn khả dụng. Khi đó, đội ngũ nói việc quét đã «được bật» dù nó không thể chặn thay đổi. Với mỗi cổng, hãy xác minh bốn đặc tính:

  • Nó chạy trên commit đầu hiện tại của pull request.
  • Bảo vệ nhánh yêu cầu kết quả có tên của nó.
  • Công việc bị bỏ qua, hết thời gian hoặc gặp sự cố không được tính là đạt.
  • Kết quả ghi đủ chi tiết để tái tạo quyết định.

Giữ chính sách trong kho lưu trữ. Một tệp kê khai nhỏ giúp việc duyệt dễ hơn một tập hợp cài đặt chỉ quản trị viên biết:

merge_gates:
  tests: required
  codeql: required
  dependency_review: required
  secret_scan: required
  authorization: required
  migration_rehearsal: required_when_changed
  rollback_verification: required

Giá trị required_when_changed không phải kẽ hở. Nó có nghĩa cổng trước tiên phát hiện tệp liên quan, sau đó hoặc thực hiện diễn tập hoặc ghi kết quả «không áp dụng» sạch. Đừng để bộ lọc đường dẫn khiến một kiểm tra bắt buộc mãi ở trạng thái chờ, và đừng để tác nhân tự quyết định thay đổi rủi ro của mình được miễn.

Ghim quyền của workflow ở mức tối thiểu cho từng công việc. Mã pull request là đầu vào không đáng tin, kể cả khi nhánh thuộc tổ chức của bạn. Một cổng để lộ token ghi hoặc bí mật sản xuất cho đoạn mã nó kiểm tra có thể tạo ra vấn đề còn nghiêm trọng hơn vấn đề cần phát hiện.

Hãy bảo vệ danh tính của kiểm tra cẩn thận như chính logic của nó. Quy tắc nhánh thường yêu cầu tên trạng thái, nên hai workflow có thể báo cùng tên có thể khiến một công việc yếu hơn đáp ứng quy tắc. Đặt tên riêng cho công việc chính sách, hạn chế người có thể sửa workflow của nó và yêu cầu chủ sở hữu tệp đó duyệt. Khi hàng đợi hợp nhất tạo commit hợp nhất mới, hãy chạy lại các cổng trên commit đó hoặc dùng tính năng nền tảng liên kết kết quả với bản sửa đổi trong hàng đợi. Bằng chứng cho commit đầu của hôm qua không phải bằng chứng cho lần hợp nhất hôm nay.

Hãy coi cấu hình cổng cũng là mã nhạy cảm. Pull request thay đổi ngưỡng, bỏ đường dẫn, hạ cấp gói truy vấn hoặc thêm ngoại lệ sẽ thay đổi ý nghĩa của mọi kết quả xanh về sau. Hiển thị rõ diff chính sách và yêu cầu một người bảo trì hiểu biện pháp kiểm soát bị tác động. Tác nhân có thể đề xuất thay đổi đó, nhưng không được đi qua dễ hơn chỉ vì nó sửa cơ chế đánh giá mình.

Kiểm thử chặn các lỗi hồi quy có thể quan sát

Cổng kiểm thử phải chặn mọi thay đổi làm hỏng hành vi đã chỉ định trên các phiên bản runtime và cơ sở dữ liệu được hỗ trợ. Nó phải chạy với cùng đầu vào xây dựng mà commit hợp nhất sẽ dùng, gồm phụ thuộc đã khóa, tệp được tạo, cờ tính năng và trạng thái schema.

Tác nhân đặc biệt giỏi thỏa mãn khẳng định gần nhất. Chúng có thể thêm phương án dự phòng để một kiểm thử xanh trong khi làm hỏng xử lý lỗi, phân trang, đồng thời hoặc hợp đồng API liền kề. Hãy yêu cầu pull request thêm hoặc sửa kiểm thử khi thay đổi hành vi, nhưng đừng đánh giá chất lượng bằng số dòng kiểm thử mới. Hãy xem kiểm thử có thất bại nếu phần triển khai bị xóa hoặc hoàn tác hay không.

Một cổng kiểm thử hữu ích có các lớp với tên riêng:

  • Kiểm thử đơn vị cho logic cục bộ và các trường hợp biên.
  • Kiểm thử tích hợp cho hợp đồng cơ sở dữ liệu, hàng đợi, bộ đệm và dịch vụ bên ngoài.
  • Kiểm thử hợp đồng cho dạng yêu cầu và phản hồi công khai.
  • Một kiểm tra khói nhỏ với bản dựng đã đóng gói.

Chạy kiểm thử không ổn định đến khi xác định nguyên nhân thay vì tự động thử lại đến lúc xanh. Một lần thử lại có thể thu thập bằng chứng chẩn đoán, nhưng trạng thái cuối phải cho thấy lỗi ban đầu. Nếu không, tác nhân có thể hợp nhất mã mà đặc tính duy nhất được chứng minh là đôi lúc hoạt động.

Kiểm tra khói phải khởi động bản dựng, gọi một endpoint sức khỏe và một luồng ghi có ý nghĩa, rồi dừng sạch. Kiểm thử mã nguồn mà không khởi động ứng dụng đã đóng gói sẽ bỏ sót tệp thiếu, mặc định môi trường sai, di chuyển dữ liệu hỏng và lỗi hoảng loạn khi khởi động. Với dịch vụ web, có thể ghi kết quả ở dạng ngắn gọn:

{"commit":"abc123","build":"pass","startup_ms":842,"health":200,"write_read_cycle":"pass"}

Đừng đặt một tỷ lệ độ bao phủ chung làm cổng chính. Độ bao phủ có thể cho thấy thay đổi chưa được kiểm thử, nhưng kho lưu trữ vẫn có thể đạt tỷ lệ cao với các khẳng định yếu. Hãy chặn theo bộ kiểm thử bắt buộc và hành vi đã thay đổi, sau đó dùng biến động độ bao phủ làm bằng chứng khi duyệt.

Bảo vệ kiểm thử khỏi phần triển khai mà nó đánh giá. Nếu pull request vừa đổi quy tắc vừa viết lại khẳng định để chấp nhận kết quả mới, bộ kiểm thử có thể đạt trong khi hợp đồng âm thầm dịch chuyển. Hãy yêu cầu người duyệt so sánh kiểm thử đã thay đổi với API công khai, issue hoặc tiêu chí chấp nhận. Với trình phân tích, trình xác thực, logic thanh toán và kiểm tra truy cập, hãy thêm kiểm thử đột biến hoặc một tập nhỏ đầu vào cố ý sai. Câu hỏi hữu ích là bộ kiểm thử có từ chối một triển khai sai hợp lý hay không, không phải tác nhân có thể làm triển khai do chính nó viết thỏa các khẳng định cũng do nó viết hay không.

Giữ lại hiện vật kiểm thử khi cổng thất bại. Lưu hạt giống gây lỗi cho kiểm thử ngẫu nhiên, ảnh cơ sở dữ liệu chính xác, nhật ký dịch vụ đã loại bỏ bí mật và lệnh tái tạo lần chạy. Trạng thái không có dữ liệu tái tạo sẽ buộc tác nhân hoặc kỹ sư tiếp theo quay lại phỏng đoán. Giới hạn thời gian lưu hiện vật theo quy tắc dữ liệu của kho lưu trữ, và không bao giờ tải ảnh chụp sản xuất lên chỉ vì nó giúp tái tạo lỗi dễ hơn.

CodeQL chặn các đường đi mã dẫn đến lỗ hổng đã biết

Cổng CodeQL phải chặn phát hiện mới có độ tin cậy cao trong các ngôn ngữ và hiện vật được tạo mà CodeQL thực sự phân tích. Nó không nên ngụ ý kết quả sạch chứng minh toàn bộ ứng dụng an toàn.

GitHub mô tả CodeQL là biên dịch mã thành cơ sở dữ liệu có thể truy vấn và chạy truy vấn trên đó. Mô hình này hữu ích vì nó theo dõi dữ liệu qua mã thay vì chỉ khớp văn bản đáng ngờ. Nó cũng bị giới hạn bởi hỗ trợ ngôn ngữ, thành công khi xây dựng, lựa chọn truy vấn và mã có mặt lúc phân tích. Nếu quá trình xây dựng cơ sở dữ liệu âm thầm bỏ một dịch vụ, kết quả xanh bao phủ ít hơn người duyệt tưởng.

Dùng workflow với ngôn ngữ rõ ràng và chính sách truy vấn cố định:

name: codeql
on: [pull_request]
permissions:
  contents: read
  security-events: write
jobs:
  analyze:
    strategy:
      matrix:
        language: [javascript-typescript, go]
    steps:
      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
          queries: security-extended
      - uses: github/codeql-action/autobuild@v3
      - uses: github/codeql-action/analyze@v3

Trong kho lưu trữ thực tế, hãy ghim action của bên thứ ba vào các digest commit đã được duyệt. Thẻ giúp ví dụ dễ đọc, nhưng thẻ có thể thay đổi mở rộng ranh giới tin cậy của công việc bảo mật bắt buộc.

Hãy quyết định điều gì bị chặn trước khi cảnh báo đầu tiên xuất hiện. Tôi thường chặn phát hiện mới ở ngưỡng mức độ nghiêm trọng và độ chính xác mà kho lưu trữ đã thống nhất, còn nợ cũ vẫn hiển thị trong baseline. Chặn mọi kết quả lịch sử ngay ngày đầu khuyến khích việc gạt bỏ hàng loạt. Bỏ qua mọi kết quả hiện có mãi mãi tạo ra điểm mù vĩnh viễn. Hãy giao chủ sở hữu và hạn xử lý cho baseline.

Kiểm tra tập tệp đã phân tích khi dịch vụ, ngôn ngữ hoặc lệnh xây dựng thay đổi. Pull request đưa vào ứng dụng di động mới, resolver được tạo hoặc backend riêng có thể cần thêm trình phân tích hoặc bước xây dựng. «CodeQL đạt» chỉ có ý nghĩa khi người duyệt nói được CodeQL đã kiểm tra gì.

Tách biệt lỗi phân tích với phân tích sạch. Nếu autobuild không thể biên dịch gói, công việc phải báo lỗi hạ tầng hoặc cấu hình, không phải không có phát hiện. Lưu nhật ký tạo cơ sở dữ liệu và số tệp nguồn được phân tích theo ngôn ngữ. So sánh số đó với nhánh cơ sở và đánh dấu mức giảm lớn không giải thích được. Cách này bắt được một lỗi phổ biến: chỉnh sửa bản dựng loại trừ mô-đun có lỗ hổng, phân tích nhanh hơn và kiểm tra bảo mật xanh vì nó thấy ít mã hơn.

Duyệt việc loại bỏ cảnh báo như thay đổi chính sách, không phải dọn dẹp. Một dương tính giả cần lời giải thích cụ thể gắn với đường đi mã và truy vấn. Bình luận chặn phải hẹp, có chủ sở hữu và hiển thị trong diff pull request. Loại trừ toàn kho cho tệp được tạo có thể phù hợp, nhưng trước tiên hãy xác định không có mẫu được bảo trì thủ công hoặc đầu vào trình tạo nào nằm trong thư mục đó.

Đánh giá phụ thuộc chặn rủi ro trước khi cài đặt

Đánh giá phụ thuộc phải chặn pull request khi diff phụ thuộc đưa vào một gói hoặc phiên bản vi phạm chính sách rõ ràng. Chính sách có thể gồm mức độ nghiêm trọng của cảnh báo đã biết, giấy phép bị cấm, nguồn gói không mong muốn và phụ thuộc trực tiếp được thêm mà không có chủ sở hữu.

Cổng này khác với cảnh báo lỗ hổng của kho lưu trữ. Cảnh báo cho biết nhánh có phụ thuộc dễ tổn thương. Đánh giá phụ thuộc hỏi liệu pull request này có làm đồ thị phụ thuộc tệ hơn không. Tính năng đánh giá phụ thuộc của GitHub so sánh tệp khai báo và lockfile trong pull request, giúp quyết định đúng lúc và có thể quy trách nhiệm.

Yêu cầu lockfile nhất quán. Nếu tác nhân sửa package.json nhưng không sửa lockfile, hoặc sửa lockfile mà không có thay đổi tệp khai báo tương ứng, công việc phải thất bại. Lệnh cài đặt phân giải phiên bản mới trong CI khiến kết quả không xác định và có thể kiểm tra đồ thị khác với đồ thị người duyệt đã thấy.

Một chính sách ngắn gọn có thể là:

dependency_policy:
  fail_on_severity: high
  deny_licenses:
    - AGPL-3.0
  allow_sources:
    - registry.npmjs.org
    - proxy.golang.org
  require_owner_for_direct_additions: true

Danh sách giấy phép chính xác là quyết định pháp lý và sản phẩm, không phải giá trị để sao chép mù quáng. Điều hữu ích là kho lưu trữ công bố nó và kiểm tra in ra gói đã kích hoạt quy tắc.

Đừng tự động phê duyệt một gói chỉ vì tên của nó giống thư viện được gợi ý. Tác nhân có thể bịa tên gói, chọn fork bị bỏ rơi hoặc thêm một client lớn cho một tiện ích nhỏ. Kết quả duyệt nên cho thấy các gói trực tiếp và bắc cầu mới, registry nguồn, phiên bản đã phân giải, giấy phép và trạng thái cảnh báo. Khi đó, người duyệt có thể hỏi mã hiện có hay phụ thuộc nhỏ hơn đã giải quyết vấn đề chưa.

Đóng theo hướng an toàn nếu dịch vụ phụ thuộc không thể tạo diff. Nguồn cảnh báo không khả dụng có thể là lý do giữ việc hợp nhất lại, không phải biến sự không chắc chắn thành kiểm tra xanh. Quy trình khẩn cấp có thể cho phép người bảo trì được chỉ định bỏ qua có ghi nhận, kèm lý do gắn với commit.

Kiểm tra hành vi cài đặt trong công việc cô lập, chỉ cho phép mạng đến registry được phê duyệt. Script vòng đời và plugin xây dựng thực thi mã trong lúc cài đặt, nên một gói có thể nguy hiểm dù ứng dụng không bao giờ import nó. Ghi nhận liệu phụ thuộc mới có thêm script cài đặt, tệp nhị phân gốc hoặc registry lạ hay không. Đừng chạy công việc đó với thông tin xác thực xuất bản, token đám mây hay bộ đệm gói có quyền ghi dùng chung với các bản dựng đáng tin.

Mã được đưa thẳng vào và ảnh container cũng thuộc cùng quyết định, dù việc duyệt tệp khai báo thông thường có thể bỏ sót. So sánh digest ảnh, tên ảnh cơ sở, Git submodule và archive được đưa vào kho. Yêu cầu digest bất biến cho đầu vào phát hành. Thẻ thân thiện như latest khiến pull request không thể tái tạo về sau vì byte có thể đổi mà không có diff khác.

Quét bí mật phải kiểm tra diff và lịch sử của nó

Kiểm tra khôi phục trước khi phát hành
Khả năng triển khai, chụp nhanh và hoàn tác của Koder.ai hỗ trợ buổi diễn tập khôi phục mà cổng hợp nhất cần có.

Quét bí mật phải chặn khi pull request đưa vào mẫu thông tin xác thực hoặc bí mật còn hoạt động đã được xác minh, kể cả chuỗi đó nằm trong fixture kiểm thử, tệp đã xóa, gói được tạo hoặc commit trước đó của pull request.

Bảo vệ khi đẩy và quét pull request giải quyết các vấn đề liên quan nhưng khác nhau. Bảo vệ khi đẩy có thể chặn bí mật được nhận diện trước khi nó đến máy chủ từ xa. Cổng pull request kiểm tra nội dung đã đến và có thể bao phủ người đóng góp hoặc loại token mà bảo vệ khi đẩy bỏ sót. Cảnh báo không có bảo vệ nhánh sẽ không chặn hợp nhất.

Quét toàn bộ dải commit so với nhánh cơ sở, không chỉ hệ thống tệp cuối cùng. Một tác nhân có thể thêm token ở commit này và xóa ở commit sau, nhưng token vẫn nằm trong lịch sử Git và có thể đã đến nhật ký hoặc bộ đệm. Hãy xem đó là đã bị lộ. Thu hồi hoặc luân chuyển thông tin xác thực, xóa nó khỏi lịch sử được đề xuất và chạy lại kiểm tra.

Dùng fixture tổng hợp không thể xác thực. Fixture phải tự nhận diện rõ và khớp mẫu kiểm thử được xác định cục bộ, thay vì sao chép hình dạng khóa đám mây thật. Danh sách cho phép quá rộng rất nguy hiểm vì kẻ tấn công và sự cố đều sẽ tìm thấy thư mục bị bỏ qua. Giữ ngoại lệ chính xác, được duyệt và gần cấu hình trình phát hiện.

Kết hợp bộ phát hiện theo mẫu với kiểm tra entropy và, khi nhà cung cấp hỗ trợ an toàn, xác minh thông tin xác thực. Khớp mẫu ít rủi ro mạng và lộ dữ liệu hơn nhưng bỏ sót token tùy chỉnh. Xác minh có thể giảm không chắc chắn, nhưng nó gửi một phần bí mật ứng viên đến dịch vụ khác và không bao giờ được chạy với endpoint không đáng tin do pull request cung cấp. Ghi rõ bộ phát hiện nào xác minh, bộ nào chạy cục bộ và dữ liệu nào rời CI.

Quét các dạng mã hóa phổ biến và đầu ra được tạo mà không coi mọi chuỗi ngẫu nhiên là thông tin xác thực. Base64, mã hóa URL và bundle đã thu nhỏ có thể che bí mật từng xuất hiện rõ trong bước nguồn. Đặt ngưỡng chặn dựa trên fixture đã kiểm thử, rồi duyệt cập nhật trình phát hiện như các thay đổi chính sách khác. Trình quét quá ồn khiến người bảo trì quen bỏ qua kết quả, còn trình quét im lặng tạo ra sự tự tin sai.

Đầu ra cổng cần vị trí mà không làm lộ dữ liệu:

{"result":"fail","detector":"generic-api-token","commit":"abc123","path":"config/dev.env","line":7,"fingerprint":"sha256:8f2c..."}

Không bao giờ in toàn bộ chuỗi khớp vào nhật ký CI hoặc bình luận pull request. Che sau khi trình quét đã xuất đầu ra có thể quá muộn vì hệ thống nhật ký, thông báo và hiện vật công việc có thể sao chép nó.

Quét bí mật không thay thế việc duyệt quyền kho lưu trữ. Workflow có thể đọc thông tin xác thực sản xuất mà không đưa nó vào diff, và tác nhân có thể sửa công việc triển khai để đánh cắp nó. Giữ bí mật ngoài công việc pull request, hạn chế quyền workflow và yêu cầu con người duyệt thay đổi đối với định nghĩa CI.

Kiểm tra phân quyền chứng minh hành động bị cấm vẫn bị cấm

Cổng phân quyền phải chứng minh mọi thao tác được bảo vệ đều từ chối tác nhân không phù hợp và cho phép tác nhân dự kiến tại ranh giới dịch vụ. Kiểm thử đăng nhập đơn thuần không kiểm tra phân quyền.

Các đội ngũ thường nhầm lẫn giữa xác thực, phân quyền và khả năng hiển thị trên giao diện. Xác thực xác định ai gửi yêu cầu. Phân quyền quyết định danh tính đó có được thực hiện hành động này trên đối tượng này không. Ẩn nút quản trị trong React không thay đổi quyết định nào trên API Go. Nếu backend chấp nhận yêu cầu, ứng dụng vẫn bị phơi bày.

Lập ma trận quyền cho endpoint và hành động nghiệp vụ đã thay đổi. Giữ nó đủ nhỏ để duyệt, nhưng phải gồm ranh giới quyền sở hữu và đối tượng thuê:

read_private_project:
  anonymous: deny
  member: deny
  other_tenant: deny
  owner: allow
  admin: allow
update_project:
  anonymous: deny
  other_tenant: deny
  owner: allow

Tạo kiểm thử từ ma trận này hoặc mã hóa các trường hợp điều khiển bởi bảng tương đương bằng ngôn ngữ dịch vụ. Mọi trường hợp từ chối phải gọi trình xử lý thật với mã định danh thực tế. Mock thay thế middleware phân quyền có thể chứng minh route hoạt động trong khi bỏ qua biện pháp kiểm soát cần kiểm tra.

Kiểm tra quyền truy cập cấp đối tượng, không chỉ vai trò. Hai người dùng đều có thể có vai trò member nhưng thuộc các tổ chức khác nhau. Thay đổi mã định danh tài nguyên và mã định danh đối tượng thuê độc lập để phát hiện tham chiếu trực tiếp đến đối tượng không an toàn. Cũng cần kiểm tra endpoint hàng loạt, xuất dữ liệu, công việc nền và GraphQL resolver, vì chúng thường bỏ qua kiểm tra được viết cho REST handler thông thường.

Cho cổng thất bại khi route được bảo vệ mới không có ánh xạ chính sách. Việc đó biến thiếu phân quyền từ linh cảm của người duyệt thành lỗi đo lường được. Giữ mặc định ở máy chủ là từ chối. Quy tắc cho phép rõ ràng dễ kiểm tra hơn mã rải rác chỉ từ chối vài trường hợp xấu đã biết.

Tác nhân thường tái sử dụng handler gần đó và giữ luồng thành công nhưng làm mất kiểm tra quyền sở hữu. Ma trận quyền làm thiếu sót này lộ ra. Nó cũng cho người duyệt một hợp đồng ổn định khi vai trò hoặc quy tắc đối tượng thuê đổi sau này.

Thực hiện kiểm tra phân quyền sau khi chuẩn hóa đầu vào. Chuẩn hóa chữ hoa chữ thường, định dạng mã định danh thay thế, tham số truy vấn trùng lặp và tham chiếu đối tượng lồng nhau có thể đưa yêu cầu tương đương qua các đường mã khác nhau. Kiểm tra endpoint trực tiếp cùng mọi route theo lô hoặc import đến cùng thao tác. Nếu worker nền thực hiện lần ghi cuối, hãy truyền ngữ cảnh tác nhân và đối tượng thuê vào công việc thay vì coi worker là người dùng đáng tin có toàn quyền.

Ghi quyết định dự kiến và quy tắc chính sách tạo ra nó, nhưng tránh làm lộ dữ liệu đối tượng riêng tư trong nhật ký. Một lỗi hữu ích nêu lớp tác nhân, hành động, lớp đối tượng và trạng thái dự kiến. Nó không đổ token truy cập hoặc bản ghi đầy đủ. Bằng chứng đó giúp người duyệt phân biệt fixture kiểm thử hỏng với thay đổi đặc quyền thực sự.

Diễn tập di chuyển dữ liệu đo khóa và khả năng đảo ngược

Giúp mã được tạo có thể kiểm tra
Xuất mã nguồn giúp người duyệt kiểm tra thay đổi ứng dụng bằng chính các trình quét dùng cho mã do con người viết.

Cổng di chuyển dữ liệu phải áp dụng mọi thay đổi schema được đề xuất cho một bản sao có đặc điểm sản xuất, chạy kiểm tra tương thích và ghi lại thời lượng, khóa cũng như hành vi hoàn tác trước khi hợp nhất. Một đợt di chuyển thành công trên cơ sở dữ liệu kiểm thử trống chứng minh rất ít.

Dùng ảnh chụp đã được làm sạch hoặc tập dữ liệu được tạo với kích thước bảng, chỉ mục, ràng buộc và độ lệch tương tự. Dữ liệu sản xuất chính xác không thuộc hạ tầng pull request. Mục tiêu là tái tạo áp lực vận hành mà không sao chép bản ghi cá nhân hay bí mật.

Diễn tập đúng trình tự triển khai. Nếu các bản ứng dụng cũ vẫn hoạt động khi di chuyển chạy, hãy kiểm tra mã cũ với schema mới và mã mới với schema chuyển tiếp. Thêm cột cho phép rỗng thường tương thích. Đổi tên cột trong một bước có thể làm hỏng mọi phiên bản cũ vẫn phục vụ lưu lượng.

Ghi bằng chứng trong kết quả máy có thể đọc:

{"migration":"20260727_add_project_state","apply_ms":18420,"max_lock_ms":310,"old_app_probe":"pass","new_app_probe":"pass","down":"pass"}

Đặt ngưỡng theo từng cơ sở dữ liệu và loại bảng. Khóa 300 mili giây có thể vô hại với bảng này nhưng gây gián đoạn với bảng khác. Người duyệt cần thấy giới hạn đã chọn cạnh kết quả đo được, cùng phiên bản cơ sở dữ liệu dùng trong diễn tập.

Với PostgreSQL, kiểm tra các thao tác ghi lại bảng, xác thực ràng buộc hoặc xây dựng chỉ mục trong khi chặn ghi. Ưu tiên thay đổi mở rộng rồi thu hẹp: thêm dạng mới, triển khai mã dùng được cả hai dạng, backfill theo lô có kiểm soát, chuyển thao tác đọc, rồi xóa dạng cũ ở thay đổi sau. Một pull request thêm rẻ hơn ứng biến trong lúc sự cố.

Không phải mọi đợt di chuyển đều có thao tác down an toàn. Xóa cột làm mất dữ liệu và đảo ngược biến đổi có thể không rõ ràng. Trong các trường hợp đó, cổng phải yêu cầu quy trình khôi phục theo hướng tiếp tục triển khai và điểm khôi phục bản sao lưu đã được kiểm thử. Gọi một đợt di chuyển không thể đảo ngược là «an toàn để hoàn tác» chỉ vì có tệp down là không trung thực.

Kiểm tra thử lại và lỗi một phần. Triển khai có thể dừng sau khi tạo chỉ mục nhưng trước khi ghi nhận di chuyển hoàn tất, lần thử tiếp theo không được làm hỏng trạng thái hoặc thất bại mãi mãi. Ngắt diễn tập tại ranh giới có kiểm soát, chạy lại và xác minh schema cùng sổ di chuyển khớp nhau. Với backfill dài, hãy chứng minh các lô tiếp tục từ con trỏ đã ghi và chạy một lô hai lần không nhân đôi hay xóa dữ liệu.

Kiểm tra tác động đến đĩa và sao chép bên cạnh thời gian trôi qua. Việc ghi lại bảng có thể dùng dung lượng tạm, tăng write ahead log và làm replica chậm sau khi thao tác chính có vẻ hoàn tất. Cổng không cần dự báo sản xuất hoàn hảo, nhưng nên ghi các đại lượng này trên tập dữ liệu diễn tập và so sánh với giới hạn do chủ sở hữu cơ sở dữ liệu chọn. Không có bằng chứng đó, một đợt di chuyển cục bộ nhanh vẫn có thể làm cạn kiệt dung lượng sản xuất.

Xác minh hoàn tác phải chạy đường khôi phục

Diễn tập hoàn tác trên bản triển khai
Triển khai ứng dụng, tạo bản chụp nhanh và xác minh khả năng hoàn tác của Koder.ai với trạng thái đại diện.

Cổng hoàn tác phải triển khai ứng viên trong môi trường cô lập, tạo trạng thái đại diện, kích hoạt phương thức hoàn tác được hỗ trợ và chứng minh phiên bản trước vẫn phục vụ đọc ghi chính xác. Kế hoạch hoàn tác bằng văn bản không phải xác minh.

Tách hoàn tác ứng dụng khỏi hoàn tác dữ liệu. Chuyển lưu lượng về tệp nhị phân trước có thể mất vài giây, còn đảo ngược một thay đổi schema hay biến đổi dữ liệu phá hủy có thể là không thể. Cổng phải báo cả hai. Nếu ứng dụng cũ không chạy được với schema mới, đánh dấu ứng viên không thể đảo ngược và yêu cầu kế hoạch triển khai theo giai đoạn.

Một trình tự thực tế là:

  1. Triển khai commit main hiện tại và nạp bản ghi đại diện.
  2. Nâng cấp lên bản dựng pull request và thực hiện các luồng đã thay đổi.
  3. Tạo bản ghi mới ở trạng thái đã nâng cấp.
  4. Khôi phục hiện vật trước hoặc ảnh chụp bằng cơ chế đã ghi nhận.
  5. Chạy kiểm tra đọc, ghi, hàng đợi và công việc nền.

Kiểm tra nên giữ mã định danh hiện vật, mã định danh ảnh chụp, dấu thời gian và kết quả kiểm tra. Nó không nên giữ thông tin xác thực hoặc dữ liệu khách hàng đã sao chép. Đo thời gian khôi phục làm bằng chứng cho mục tiêu vận hành của chính bạn, không phải lời hứa chung.

Ảnh chụp chỉ hữu ích nếu có người chứng minh chúng chứa mọi thứ ứng dụng cần. Tệp, lưu trữ đối tượng, trạng thái hàng đợi, thay đổi schema và tác động bên ngoài có thể nằm ngoài ảnh chụp máy chủ. Liệt kê các ranh giới đó trong kết quả. Khoản thanh toán, email hoặc webhook đã gửi không thể thu hồi bằng cách khôi phục cơ sở dữ liệu.

Làm kiểm tra hoàn tác mạnh hơn kiểm tra sức khỏe. Đọc một bản ghi tạo trước khi nâng cấp, đọc một bản ghi tạo sau đó, cập nhật cả hai khi tương thích cho phép và xử lý công việc hàng đợi do mỗi phiên bản ứng dụng tạo. So sánh đầu ra người dùng thấy được, không chỉ mã trạng thái. Máy chủ trả 200 nhưng làm mất trường mới hoặc đọc sai enum thì chưa khôi phục.

Kiểm tra cơ chế người trực vận hành dùng. Nếu hoàn tác sản xuất yêu cầu chọn hiện vật, khôi phục ảnh chụp hoặc đổi lưu lượng, diễn tập cô lập phải dùng cùng giao diện và đường quyền đó. Script riêng trên máy tính xách tay của một kỹ sư không phải biện pháp kiểm soát vận hành. Bằng chứng phải cho thấy vai trò vận hành được chỉ định có thể hoàn thành khôi phục mà không cần có quyền quản trị vĩnh viễn.

Koder.ai hỗ trợ xuất mã nguồn, triển khai và lưu trữ, ảnh chụp nhanh cùng hoàn tác, vì các ứng dụng xây ở đó có thể dùng các hiện vật cụ thể này trong cổng thay vì coi khôi phục là một đoạn văn trong pull request. Quy tắc tương tự áp dụng trên mọi nền tảng: chạy cơ chế khôi phục và kiểm tra ứng dụng đã phục hồi.

Một kiểm tra bắt buộc nên tóm tắt cả bảy

Quyết định hợp nhất cuối cùng nên yêu cầu một kiểm tra chính sách ổn định xác minh bảy kết quả bên dưới cho đúng commit đầu. Tên công việc riêng lẻ thay đổi, công việc ma trận tăng lên và đường dẫn tùy chọn bỏ qua công việc. Một trình tổng hợp nhỏ giúp bảo vệ nhánh không lệch khỏi chính sách.

Mỗi cổng nên phát ra kết quả được ký hoặc được nền tảng chứng thực, gồm commit, phiên bản chính sách, kết quả và vị trí bằng chứng. Trình tổng hợp từ chối kết quả thiếu, cũ, trung tính hoặc bị hủy. Nó không bao giờ suy ra thành công từ một công việc không báo cáo.

{
  "commit": "abc123",
  "policy": "merge-gates-v3",
  "results": {
    "tests": "pass",
    "codeql": "pass",
    "dependency_review": "pass",
    "secret_scan": "pass",
    "authorization": "pass",
    "migration_rehearsal": "not_applicable",
    "rollback_verification": "pass"
  },
  "decision": "allow"
}

Xác định đường bỏ qua hẹp vì tình huống khẩn cấp vẫn xảy ra. Yêu cầu một người bảo trì được chỉ định, người phê duyệt thứ hai, lý do bằng văn bản, thời hạn và issue theo dõi. Đừng để tác nhân yêu cầu hoặc phê duyệt ngoại lệ của chính nó. Báo cáo việc bỏ qua ở cùng nơi với kết quả cổng thông thường để chúng vẫn hiện rõ sau khi sự cố qua đi.

Những kiểm tra này sẽ thêm vài phút cho một số pull request và lâu hơn nhiều cho thay đổi di chuyển dữ liệu. Điều đó chấp nhận được khi thời gian đổi lấy bằng chứng cụ thể. Chạy cổng rẻ sớm, hủy commit đã bị thay thế, lưu đệm đầu vào xây dựng đáng tin và chỉ dành diễn tập môi trường đầy đủ cho đường dẫn liên quan. Đừng làm yếu cổng chỉ để bảng điều khiển xanh nhanh hơn.

Hãy bắt đầu bằng cách làm cho hành vi hiện tại có thể quan sát. Đặt cả bảy tên trong một tệp chính sách, liên kết mỗi tên với một kết quả bắt buộc và buộc công việc bị bỏ qua phải tự giải thích. Pull request đầu tiên do tác nhân tạo không thể cung cấp bản ghi đó đã tìm ra lỗ hổng trong hệ thống phân phối trước khi nó tìm ra lỗ hổng ở môi trường sản xuất.

Câu hỏi thường gặp

Pull request do tác nhân tạo có nên tuân theo quy tắc nghiêm ngặt hơn pull request do con người tạo không?

Hãy dùng cùng một loại bằng chứng chặn cho cả hai. Tác nhân có thể cần nhiều kiểm tra tự động hơn vì tạo thay đổi nhanh hơn, nhưng bản thay đổi do con người viết cũng có thể làm lộ bí mật, tạo lỗi phân quyền hoặc gây ra một đợt di chuyển dữ liệu không an toàn.

Người duyệt có thể bỏ qua cổng hợp nhất bị lỗi không?

Có, nhưng chỉ qua một ngoại lệ hẹp được ghi nhận, có hai người chịu trách nhiệm, lý do và thời hạn hết hiệu lực. Tác nhân tạo ra thay đổi không bao giờ được tự phê duyệt việc bỏ qua cổng kiểm tra.

CodeQL đạt có nghĩa pull request an toàn không?

Không. Điều đó chỉ có nghĩa các truy vấn đã chọn không tìm thấy kết quả cần chặn trong phần mã mà CodeQL phân tích thành công. Phụ thuộc, phân quyền khi chạy, bí mật, cấu hình và khả năng khôi phục vận hành vẫn cần bằng chứng riêng.

Điều gì xảy ra khi một trình quét bắt buộc không khả dụng?

Bước kiểm tra nên đóng theo hướng an toàn hoặc vẫn bị chặn. Nếu thay đổi là tình huống khẩn cấp, hãy dùng quy trình ngoại lệ đã ghi nhận thay vì biến một kết quả chưa rõ thành đạt.

Quét bí mật có nên kiểm tra các commit đã bị xóa không?

Nó nên kiểm tra toàn bộ dải commit của pull request. Một bí mật được thêm rồi xóa vẫn tồn tại trong lịch sử và cần được luân chuyển trước khi chấp nhận thay đổi đã làm sạch.

Kiểm thử phân quyền trong pull request như thế nào?

Gọi các trình xử lý dịch vụ thật với ma trận danh tính, vai trò, đối tượng thuê, đối tượng và hành động. Hãy đưa vào các trường hợp bị từ chối và thay đổi quyền sở hữu đối tượng, vì đăng nhập thành công hay ẩn điều khiển giao diện không chứng minh được phân quyền ở máy chủ.

Mọi đợt di chuyển cơ sở dữ liệu có cần tệp down không?

Không. Một số thay đổi phá hủy không thể đảo ngược một cách trung thực. Thay vào đó, hãy yêu cầu quy trình khôi phục theo hướng tiếp tục triển khai hoặc khôi phục từ bản sao lưu đã được kiểm thử, và gắn nhãn thay đổi là không thể đảo ngược.

Khác biệt giữa lập kế hoạch hoàn tác và xác minh hoàn tác là gì?

Lập kế hoạch mô tả các bước khôi phục dự kiến. Xác minh sẽ chạy các bước đó với bản dựng ứng viên và trạng thái đại diện, sau đó ghi nhận phiên bản trước có còn đọc và ghi chính xác hay không.

Làm sao để bảy cổng kiểm tra không làm chậm mọi pull request?

Chạy các kiểm tra rẻ trước, hủy các lần chạy cho commit đã bị thay thế, lưu đệm đầu vào đáng tin cậy và chỉ kích hoạt diễn tập di chuyển dữ liệu cho thay đổi liên quan. Mỗi cổng phải trả về kết quả đạt hoặc không áp dụng rõ ràng.

Bảo vệ nhánh nên yêu cầu kết quả nào?

Yêu cầu một kết quả chính sách ổn định tổng hợp cả bảy cổng cho đúng commit đầu hiện tại. Kết quả phải từ chối các trạng thái thiếu, cũ, bị bỏ qua, bị hủy hoặc trung tính thay vì đoán rằng chúng đã đạt.

Related posts