Xuất bản gói npm không cần Token với Trusted Publishing
Bài viết chia sẻ kinh nghiệm sử dụng tính năng Trusted Publishing (OIDC) của npm để thay thế các token truy cập dài hạn truyền thống trong GitHub Actions. Cách tiếp cận này giúp quy trình CI/CD an toàn hơn, loại bỏ rủi ro lộ token và giảm bớt gánh nặng quản lý secrets thủ công.

Tuần trước, tôi vừa xuất bản một gói npm mới có tên là markdown-repository — một công cụ xây dựng truy vấn theo phong cách Firestore dành cho các tệp markdown. Mã nguồn hoạt động tốt, các bài kiểm tra (test) đều vượt qua, nhưng việc thiết lập quy trình xuất bản (release pipeline) lại tốn nhiều công sức hơn cả việc viết chính gói phần mềm đó.
Cách làm cũ
Quy trình xuất bản npm tiêu thống thường sử dụng một token truy cập dài hạn (long-lived access token). Bạn tạo token này trên npmjs.com, lưu nó vào GitHub Actions secret và tham chiếu nó trong workflow:
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Cách này hoạt động tốt, nhưng token không bao giờ hết hạn, có quyền ghi vào các gói của bạn và tồn tại dưới dạng văn bản thuần trong các bí mật (secrets) của CI. Nếu nó bị rò rỉ — thông qua việc sao chép tệp workflow hoặc một nhật ký (log) bất cẩn — bất kỳ ai cũng có thể đăng ký gói dưới tên của bạn.
Mặc dù các token có độ chi tiết (granular tokens) của npm đã cải thiện điều này một chút (bạn có thể giới hạn chúng cho các gói cụ thể và đặt ngày hết hạn 90 ngày), nhưng bạn vẫn phải thay đổi (rotate) chúng thủ công.
Trusted Publishing
Hiện tại, npm đã hỗ trợ Trusted Publishing với OIDC. Thay vì lưu trữ một token tĩnh, workflow GitHub Actions của bạn sẽ chứng minh danh tính của mình với npm bằng cách sử dụng thông tin đăng ký ngắn hạn của OpenID Connect. npm sẽ xác thực thông tin đăng ký này dựa trên workflow mà bạn đã ủy quyền và chấp nhận yêu cầu xuất bản.
Không cần lưu token. Không cần thay đổi token. Không sợ lộ token.
Lần xuất bản đầu tiên phải thực hiện thủ công
Trước khi bạn có thể cấu hình trusted publishing, gói phần mềm phải đã tồn tại trên registry. npm không có tính năng "nhà xuất bản đang chờ xử lý" — bạn không thể thiết lập OIDC cho một gói chưa tồn tại.
Đối với phiên bản đầu tiên, hãy xuất bản từ máy của bạn:
npm login
npm publish --access public
Tôi đã mất khá nhiều thời gian để sửa lỗi workflow trước khi nhận ra rằng trusted publishing chỉ hoạt động từ lần phát hành thứ hai trở đi. Khi gói đã có trên npmjs.com, hãy vào phần cài đặt (settings) và thêm một nhà xuất bản tin cậy (trusted publisher). Từ đó trở đi, workflow sẽ tự động xử lý mọi thứ.
Thiết lập Workflow
Quá trình thiết lập bao gồm hai phần.
Trên npmjs.com: Vào cài đặt gói của bạn, thêm một trusted publisher. Chỉ định tổ chức (org) hoặc người dùng (user) trên GitHub, kho lưu trữ (repository), tên tệp workflow và tùy chọn tên môi trường (environment).
Trong workflow: Thêm quyền id-token: write và một environment khớp với những gì bạn đã cấu hình trên npm.
name: Release
on:
release:
types: [published]
permissions:
contents: read
id-token: write
jobs:
publish:
runs-on: ubuntu-latest
environment: release
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24.x
registry-url: https://registry.npmjs.org
cache: npm
- run: npm ci
- run: npm test
- run: npm run build
- run: npm publish --provenance --access public
Việc chứng minh nguồn gốc (provenance attestation) là tự động với trusted publishing. Cờ --provenance là dư thừa nhưng giúp làm rõ ý định.
Lỗi 404 dễ gây hiểu lầm
Ba lần phát hành đầu tiên của tôi đều thất bại với lỗi này:
npm error 404 Not Found - PUT https://registry.npmjs.org/markdown-repository
npm error 404 '[email protected]' is not in this registry.
Gói đã tồn tại. Phiên bản đúng. Việc trao đổi token OIDC đã thành công — tôi có thể thấy bản tuyên bố nguồn gốc đã ký trong nhật ký minh bạch (transparency log) của Rekor. Mọi thứ đều ổn trừ việc xuất bản thực tế.
Vấn đề nằm ở chỗ: Node 22 đi kèm với npm 10.x. Trusted Publishing yêu cầu npm 11.5.1 hoặc mới hơn.
Tài liệu của npm có đề cập đến yêu cầu này, nhưng thông báo lỗi thì không. Một lỗi 404 khi PUT trông giống như vấn đề về registry hoặc xung đột tên gói. Không có gì chỉ ra sự không khớp phiên bản npm.
Giải pháp
Sử dụng Node 24.x trong workflow của bạn. Trên GitHub Actions, node-version: 24.x sẽ giải quyết thành một bản vá gần đây bao gồm npm 11.5.1+:
- uses: actions/setup-node@v4
with:
node-version: 24.x
Nếu bạn đang bám chân vào phiên bản Node cũ hơn, hãy nâng cấp npm một cách rõ ràng:
- run: npm install -g npm@latest
Với npm 11.5.1+, cùng một workflow sẽ xuất bản thành công mà không cần bất kỳ token nào.
Sự không khớp về Môi trường (Environment)
Lỗi 404 tương tự cũng xuất hiện khi tên môi trường trên npmjs.com không khớp với trường environment trong công việc workflow của bạn. Nếu workflow của bạn ghi environment: release nhưng npm để trống trường môi trường (hoặc ngược lại), các yêu cầu (claims) OIDC sẽ không khớp và npm sẽ từ chối yêu cầu xuất bản — với thông báo lỗi 404 thay vì một thông báo lỗi có ý nghĩa.
Hình dung Pipeline hiện tại
Toàn bộ workflow cho markdown-repository chạy lint, test và build trên mọi lần commit. Khi có một bản phát hành (release) trên GitHub, nó sẽ xuất bản lên npm kèm theo nguồn gốc (provenance) — không cần cấu hình bí mật (secrets) nào trong kho lưu trữ.
Bài viết liên quan

Phần mềm
Anthropic ra mắt Claude Opus 4.7: Nâng cấp mạnh mẽ cho lập trình nhưng vẫn thua Mythos Preview
16 tháng 4, 2026

Công nghệ
Qwen3.6-35B-A3B: Quyền năng Lập trình Agentic, Nay Đã Mở Cửa Cho Tất Cả
16 tháng 4, 2026

Công nghệ
Spotify thắng kiện 322 triệu USD từ nhóm pirate Anna's Archive nhưng đối mặt với bài toán thu hồi
16 tháng 4, 2026
