Xuất bản npm bằng OIDC: bỏ token dài hạn nhưng repo riêng mất provenance

|Tác giả: Ban biên tập QUASA|7 phút đọc| 1
Xuất bản npm bằng OIDC: bỏ token dài hạn nhưng repo riêng mất provenance

Để phát hành gói npm từ GitHub Actions mà không giữ token ghi dài hạn, hãy đăng ký workflow làm trusted publisher cho gói, cấp id-token: write cho job phát hành và chạy npm publish trên runner do GitHub lưu trữ. Chỉ sau khi phát hành thành công một phiên bản bằng OIDC mới chặn xuất bản bằng token truyền thống và thu hồi token ghi cũ. Cách này thay thông tin xác thực lưu sẵn bằng danh tính ngắn hạn của lần chạy workflow.

OIDC giải quyết quyền xuất bản, còn provenance phụ thuộc vào mức hiển thị của mã nguồn và gói. Thông báo của GitHub về trusted publishing nêu rằng kho mã riêng vẫn phát hành được qua OIDC nhưng không có provenance, kể cả khi gói được công khai. Vì vậy, phát hành thành công không tự nó chứng minh người cài gói có thể kiểm tra nguồn và quy trình tạo bản phát hành.

Kiểm tra môi trường trước khi chuyển

Theo hướng dẫn trusted publishing của npm, job cần npm CLI từ 11.5.1 và Node.js từ 22.14.0; cấu hình publisher mới phải được xác thực bằng lần phát hành đầu tiên trong vòng 2 ngày. Với GitHub Actions, job xuất bản phải chạy trên runner do GitHub lưu trữ; runner tự quản chưa được hỗ trợ. Nếu các bước build và kiểm thử đang chạy trên runner tự quản, có thể giữ chúng ở đó, nhưng cần chuyển phần xuất bản sang job đáp ứng điều kiện này và đưa tệp cần phát hành đến đúng job.

Trước khi sửa workflow, xác định đúng kho GitHub, tệp workflow khởi chạy phát hành và environment nếu có. Trường repository.url trong package.json phải khớp chính xác với kho dùng để xuất bản; thông tin còn trỏ về kho cũ hoặc kho gốc khi chạy từ fork có thể khiến xác thực thất bại. Với workflow tái sử dụng qua workflow_call hoặc phát hành thủ công qua workflow_dispatch, npm kiểm tra tên workflow gọi thay vì chỉ nhìn tệp chứa lệnh npm publish. Vì thế, cần đối chiếu cấu hình publisher với toàn bộ chuỗi gọi.

Hãy tách token theo mục đích ngay từ đầu. Nếu npm ci cần tải dependency riêng từ npm, bước cài đặt vẫn cần token có quyền đọc, chẳng hạn qua NODE_AUTH_TOKEN. Danh tính OIDC dùng để xuất bản không cấp quyền đọc các gói riêng này. Token đọc có thể được giữ cho bước cài đặt, còn bước phát hành không cần nhận token ghi.

Đăng ký publisher đúng workflow và quyền phát hành

Tên tệp workflow GitHub Actions phải khớp với cấu hình trusted publisher của gói npm.

Trên npmjs.com, mở Settings của chính gói cần phát hành, tìm Trusted Publisher và chọn GitHub Actions. Điền tên tổ chức hoặc tài khoản, tên repository và tên tệp workflow trong .github/workflows, ví dụ publish.yml; chỉ nhập tên tệp kèm phần mở rộng, không nhập toàn bộ đường dẫn. Nếu job gắn với GitHub environment, điền đúng tên environment đó. npm không đối chiếu các trường ngay khi lưu, nên một lỗi chính tả có thể chỉ xuất hiện khi chạy phát hành.

Mỗi cấu hình trusted publisher có phạm vi riêng cho repository, workflow và environment. Cập nhật cấu hình của GitHub cho biết một gói có thể có nhiều cấu hình; npm stage publish được phép theo mặc định, còn npm publish trực tiếp phải được bật riêng cho từng cấu hình. Nếu workflow đang dùng npm publish, hãy cho phép xuất bản trực tiếp trong cấu hình tương ứng trước khi thử. Nếu muốn bản phát hành chờ người duy trì duyệt, dùng npm stage publish; gói chỉ trở nên khả dụng sau bước phê duyệt.

Quyền quản lý dist-tag được cấp riêng và không tự đi kèm quyền phát hành trực tiếp. Điều này quan trọng khi workflow vừa đưa phiên bản lên registry vừa gắn nhãn phát hành. Hãy chọn quyền khớp với các lệnh thực sự chạy. Nếu cấu hình mới hết hạn trước lần xuất bản đầu tiên, xóa nó và tạo lại để thực hiện lần phát hành xác thực.

Cấp OIDC cho job và thử bản phát hành đầu tiên

Trong GitHub Actions, đặt permissions của job phát hành gồm id-token: write và contents: read, đồng thời chọn runner do GitHub lưu trữ như ubuntu-latest. Một luồng cơ bản là checkout mã, thiết lập Node.js và npm đạt yêu cầu, chạy npm ci, build hoặc kiểm thử theo dự án rồi gọi npm publish. Quyền id-token: write cho phép job yêu cầu danh tính OIDC; nó không phải token npm để đưa vào GitHub Secrets. Đừng truyền NODE_AUTH_TOKEN chứa quyền ghi cho bước publish, vì npm CLI có thể chuyển sang xác thực bằng token khi luồng OIDC không hoạt động.

Nếu workflow gọi một workflow dùng lại, cấp id-token: write ở cả workflow gọi và workflow được gọi. Thiếu quyền ở một mắt xích có thể khiến lệnh xuất bản không nhận được danh tính cần thiết. Đặt quyền này tại job phát hành thay vì mọi job nếu các bước kiểm thử cho pull request không cần OIDC; điều kiện kích hoạt phát hành, chẳng hạn một tag, cũng nên nằm ở luồng có quyền xuất bản. Cách sắp xếp đó giúp xác định lần chạy nào được phép đưa phiên bản lên npm.

Dùng một phiên bản chưa từng phát hành để chạy thử đúng luồng dự kiến. Kiểm tra log xác thực và trạng thái phiên bản trên npmjs.com, đồng thời bảo đảm bước publish không dựa vào secret chứa token ghi cũ. Việc lưu cấu hình publisher chưa kiểm tra được tên workflow, environment hay quyền job. Nếu xác thực thất bại, so lại các giá trị đã đăng ký, repository.url, loại runner, phiên bản công cụ và quyền npm publish của cấu hình trước khi khóa đường phát hành cũ.

Khóa đường token sau khi OIDC hoạt động

  1. Sau lần phát hành thành công qua OIDC, mở Settings → Publishing access của gói và chọn “Require two-factor authentication and disallow tokens”. Lựa chọn này chặn token truyền thống dùng để xuất bản nhưng vẫn cho trusted publisher hoạt động.
  2. Thu hồi token tự động hóa có quyền ghi không còn được dùng, sau đó xóa secret tương ứng khỏi GitHub Actions. Nếu nhiều workflow từng dùng cùng token, kiểm tra các luồng đó trước khi thu hồi để tránh làm gián đoạn bản phát hành khác.
  3. Giữ token chỉ đọc cho bước npm ci khi dự án còn dependency riêng; chỉ cấp nó cho bước cài đặt. Với dependency công khai hoàn toàn, bước này không cần token npm.

Thứ tự này giữ một đường phát hành đã được xác thực trong quá trình chuyển đổi. Bật “disallow tokens” trước khi thử OIDC có thể làm lần phát hành kế tiếp thất bại nếu cấu hình publisher hoặc job còn sai. Ngược lại, phát hành thử xong mà không thu hồi secret ghi cũ sẽ để lại thông tin xác thực không còn cần thiết trong CI.

Kho công khai, kho riêng và runner cho kết quả nào?

Gói npm phát hành từ kho GitHub công khai có thể có provenance; bản phát hành từ kho riêng thì không.
  • Kho GitHub công khai, gói npm công khai, runner GitHub-hosted: OIDC có thể xác thực lần phát hành và npm tự tạo provenance nếu tính năng không bị tắt trong cấu hình. Không cần thêm cờ --provenance chỉ để bật cơ chế mặc định.
  • Kho GitHub riêng, runner GitHub-hosted: có thể phát hành gói công khai hoặc riêng bằng OIDC, nhưng npm không tạo provenance từ kho nguồn riêng. Mức hiển thị của gói không thay đổi giới hạn này.
  • Kho công khai, gói npm riêng: OIDC vẫn dùng được cho xuất bản, còn provenance tự động không có vì gói không công khai. Kho nguồn công khai một mình chưa đủ.
  • Runner tự quản: luồng trusted publishing bằng OIDC của GitHub Actions chưa hỗ trợ, dù kho và gói công khai. Muốn bỏ token ghi theo quy trình này, job gọi npm publish phải chạy trên runner do GitHub lưu trữ.

Đọc thêm:

Chia sẻ:

Đăng ký bản tin

Nhận tin Web3, AI và tiền mã hóa mới nhất ngay trong hộp thư.

0