Skip to main content
BlogDevOps

npm Trusted Publishing: Expiry 48 Jam dan Larangan issue_comment

npm kini mengedarluarsakan konfigurasi trusted publishing yang belum tervalidasi setelah 48 jam dan menolak token issue_comment. Ini perubahannya dan cara migrasinya.

Matthews Wong

Software Engineer

Oktober 202611 menit baca
npm Trusted Publishing: Expiry 48 Jam dan Larangan issue_comment

Ringkasan Utama

Pada 2 Oktober 2026 npm mulai mengedarluarsakan konfigurasi trusted publishing yang belum berhasil publish pertama kali dalam 48 jam, dan menolak token trusted publishing dari event issue_comment selain pull_request_target. Lakukan release dari push, release atau workflow_dispatch, jalankan npm trust list, dan buat ulang binding ke repository yang tidak lagi Anda kendalikan.

Minggu ini saya menyiapkan trusted publisher baru untuk sebuah package kecil, dan halaman docs npm menyebut sesuatu yang belum pernah saya baca: kalau publish pertama tidak terjadi dalam dua hari, konfigurasi kedaluwarsa dan bahkan tidak bisa diedit. Hapus, buat lagi, lalu publish dalam dua hari. Kalimat itu hanyalah ujung yang terlihat dari cerita yang jauh lebih besar.

Post ini membaca changelog GitHub tanggal 2 Oktober 2026, dokumentasi npm trusted publishers, referensi perintah npm trust dan panduan keamanan GitHub Actions, lalu riset Bloom Security yang menjelaskan mengapa perubahan ini perlu. Angka hanya saya kutip kalau saya membacanya di salah satu halaman itu. Bagian yang merupakan penalaran saya, saya tandai.

Dua perubahan dirilis pada 2 Oktober

Entri changelog GitHub memuat dua perubahan terpisah. Pertama, umur untuk trust yang belum terbukti: konfigurasi trusted publishing yang belum tervalidasi kini kedaluwarsa 48 jam setelah dibuat dan tidak lagi bisa mengotorisasi publish. Kedua, daftar event workflow yang lebih sempit: npm sekarang menolak token trusted publishing dari event issue_comment di GitHub Actions, menambah pembatasan yang sebelumnya sudah berlaku untuk pull_request_target.

Keduanya tidak mengganggu release yang sudah berjalan lewat konfigurasi tervalidasi dengan trigger tag push. Dampaknya ada di tiga tempat: konfigurasi baru yang dibiarkan menganggur dua hari, konfigurasi yang identitas repository atau project-nya Anda ubah, dan workflow apa pun yang publish dari perintah komentar. Tabel di bawah adalah seluruh aturannya sebagaimana dinyatakan changelog.

AreaAturan sejak 2 Oktober 2026Yang perlu Anda lakukan
Konfigurasi belum tervalidasiKedaluwarsa 48 jam setelah dibuat dan tidak lagi bisa mengotorisasi publishJalankan publish nyata pertama di dalam jendela itu
Konfigurasi tervalidasiBebas dari expiry setelah publish pertama yang berhasilTidak ada, tetapi tetap audit
Perubahan identitas repository atau projectPerlu trust relationship baru dengan jendela 48 jam baru; edit biasa tidak mengulang tenggatRencanakan rename atau transfer bersama binding baru
Token issue_commentDitolak, di samping pembatasan pull_request_target yang sudah adaPindahkan publish ke push, release atau workflow_dispatch
Konfigurasi kedaluwarsaTetap terlihat di settings, tidak dihitung ke batas per package, konfigurasi lain tidak terpengaruhBuat ulang untuk memulai jendela 48 jam baru

Cacat di balik jam ini: slug bukan identitas

Aturan 48 jam adalah tambalan untuk kelemahan desain yang oleh Bloom Security dinamai SlugFest. Menurut tulisan CSO Online dan Help Net Security, npm mencatat repository GitHub yang terhubung lewat owner dan namanya, bukan ID numerik permanen yang disertakan GitHub di token identitas OIDC, dan npm tidak memeriksanya. Saat repository di-rename, ditransfer atau dihapus, nama lamanya bisa diklaim orang lain, yang lalu membuat repository di alamat itu dengan workflow berfilename sama.

Orang itu tidak butuh kredensial GitHub atau npm milik maintainer. Bloom mendemonstrasikan serangan pada package dan repository yang mereka kendalikan, dan Help Net Security melaporkan rilis berbahaya membawa provenance attestation valid yang menyebut repository penyerang. Bloom menghitung lebih dari 1.500 package yang berpotensi terdampak dengan lebih dari 10 juta total unduhan, dan menyatakan belum melihat eksploitasi di dunia nyata.

Hati-hati memahami apa yang diperbaiki. Changelog menyebut GitHub membatasi risiko mempercayai nama repository atau project yang berpindah pemilik dengan mengedarluarsakan konfigurasi yang belum pernah divalidasi. Changelog tidak menyatakan binding tervalidasi yang sudah ada diikat ulang ke ID repository, dan Help Net Security mencatat hal itu sebagai pertanyaan terbuka. Bloom juga menyebut integrasi GitLab memiliki kelemahan yang sama. Jadi perbaikan ini mempersempit jendela, bukan menghapus kebutuhan Anda untuk memeriksa.

Cara kerja siklus 48 jam

Docs npm menggambarkan konfigurasi baru sebagai harus melakukan publish pertama yang berhasil dalam 2 hari; jika tidak tervalidasi di jendela itu, konfigurasi kedaluwarsa dan tidak bisa dipakai atau diedit, lalu Anda menghapus, membuat yang baru dan publish dalam 2 hari. Dua detail dari docs penting untuk perencanaan. npm tidak memverifikasi konfigurasi saat Anda menyimpan, jadi salah ketik filename workflow baru ketahuan saat publish, dan koneksi yang ada tidak bisa diubah sama sekali.

StatusBisa mengotorisasi publishCara keluar dari status
Belum tervalidasi, dalam 48 jamYa, untuk publish pertamaPublish pertama yang berhasil memvalidasinya
TervalidasiYaBebas expiry; perubahan identitas membuat relationship baru
Belum tervalidasi, lewat 48 jamTidakBuat ulang; entri kedaluwarsa tetap terlihat tetapi tidak dihitung ke batas
Identitas berubahHanya lewat relationship baruJendela 48 jam baru dimulai dari pembuatan relationship baru

Pembacaan praktisnya: membuat trusted publisher dan melakukan publish kini satu operasi di kalender Anda. Jangan menyiapkan binding hari Jumat untuk release yang direncanakan minggu depan. Buat saat versi sudah di-build, di-tag dan siap keluar.

Mengapa issue_comment tempat yang buruk untuk publish

Changelog tidak menjelaskan alasan menolak issue_comment, jadi yang berikut adalah pembacaan saya, berpijak pada docs GitHub. Workflow issue_comment hanya berjalan jika file workflow ada di default branch, dengan GITHUB_REF berupa default branch dan GITHUB_SHA commit terakhir di sana. Artinya event komentar menjalankan kode workflow default branch yang punya hak istimewa, tetapi event itu dipicu siapa pun yang bisa berkomentar, kelompok yang jauh lebih luas daripada yang bisa mendorong tag.

Panduan secure use dari GitHub sendiri sudah menyarankan menghindari pull_request_target bila tidak perlu dan memperingatkan bahwa trigger berhak istimewa ini tidak boleh secara eksplisit melakukan checkout kode yang tidak tepercaya. Aturan npm yang baru memperluas naluri yang sama: hak publish sebaiknya bergantung pada event yang dipicu maintainer, bukan event yang bisa dipicu orang asing dengan mengetik.

EventToken trusted publishing npmSiapa yang memicunya, menurut saya
push (tag), releaseDiizinkan menurut changelogSeseorang dengan akses write membuat tag atau release
workflow_dispatchDiizinkan menurut changelogMaintainer menekan tombol atau menjalankan gh workflow run
issue_commentDitolak sejak 2 Oktober 2026Siapa pun yang bisa berkomentar, menjalankan kode workflow default branch
pull_request_targetDitolak sebelum tanggal ituSiapa pun yang membuka pull request, dengan hak repository dasar

Jika proses release Anda adalah bot yang bereaksi pada komentar seperti /release, langkah npm publish-nya akan gagal setelah 2 Oktober. Jangan mencari cara mempertahankan trigger komentar. Biarkan komentar hanya membuka draft, lalu publish dari tag atau dispatch manual yang dikendalikan maintainer.

Migrasi workflow release

Bentuk yang bertahan setelah perubahan ini adalah yang ada di docs npm: workflow dengan trigger tag, izin id-token write, runner cloud-hosted, Node yang baru, dan tanpa cache. Berikut versi salah yang pernah saya lihat pada bot release berbasis komentar, lalu versi benar yang dibangun dari contoh di docs.

# Wrong: a comment-driven release bot. After 2 October 2026 npm rejects the
# trusted publishing token minted from an issue_comment event, so the
# publish step fails even though the workflow file is on the default branch.
name: release-on-comment
on:
  issue_comment:
    types: [created]
permissions:
  id-token: write
  contents: read
jobs:
  publish:
    if: contains(github.event.comment.body, '/release')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - run: npm ci && npm publish
# Right: .github/workflows/release.yml
# The filename here is what the trusted publisher on npm must name, with the
# .yml extension. npm does not check it when you save the binding.
name: release
on:
  push:
    tags:
      - 'v*'          # a tag only someone with write access can push
  workflow_dispatch:  # manual re-run by a maintainer

permissions:
  id-token: write     # the critical requirement: lets the job mint the OIDC token
  contents: read

jobs:
  publish:
    runs-on: ubuntu-latest   # cloud-hosted only; self-hosted is not supported yet
    environment: npm-publish # optional; must match the environment on npm if set
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: '24'                       # trusted publishing needs 22.14.0+
          registry-url: 'https://registry.npmjs.org'
          package-manager-cache: false             # never restore a cache in a release
      - run: npm ci
      - run: npm test
      - run: npm publish   # provenance is automatic for a public repo and package

Tiga detail di versi benar disengaja. Blok permissions hanya memberi id-token write dan contents read, contoh docs mengatur package-manager-cache ke false karena build release tidak boleh memulihkan cache, dan environment opsional memungkinkan Anda memasang deployment protection GitHub, yang juga harus Anda sebut di trusted publisher. Jika publish dipanggil dari reusable workflow, docs menyebut validasi memeriksa nama workflow pemanggil dan id-token write harus diatur di parent maupun child.

Persyaratan dari docs: npm CLI 11.5.1 atau lebih baru dan Node.js 22.14.0 ke atas untuk trusted publishing, dan hanya runner cloud-hosted yang didukung, sementara self-hosted runner tercantum sebagai rencana. Provenance dibuat otomatis untuk repository dan package publik, jadi Anda tidak perlu lagi memakai flag provenance.

Mengaudit binding yang sudah ada

Panduan maintainer dari Help Net Security singkat: daftar trust relationship Anda, pastikan tiap repository masih mengarah ke yang Anda kendalikan, hapus dan buat ulang binding yang menunjuk ke repository yang di-rename atau ditransfer, dan hapus binding sebelum menghapus repository. Perintah npm trust melakukan ini dari terminal. Menurut docs, perintah ini butuh npm 11.15.0 ke atas, izin write pada package dan 2FA tingkat akun, dan granular token dengan opsi bypass 2FA tidak didukung.

# Needs npm 11.15.0+, write access to the package and account-level 2FA.
npm install -g npm@^11.15.0

for pkg in @acme/widget @acme/widget-cli; do
  echo "== $pkg"
  # Prints each trust relationship: repository, workflow file, environment, id.
  npm trust list "$pkg"
done

# For every repository that list names, ask GitHub who it is NOW.
# Compare the full_name with what npm lists; a 404 or a different owner means
# the slug has moved or been freed, which is exactly the SlugFest precondition.
gh api repos/acme/widget --jq '{id, full_name}'

# Recreate a suspect binding: revoke the old id, then create the new one and
# publish within 48 hours so it validates.
npm trust revoke @acme/widget --id=<trust-id>
npm trust github @acme/widget --file release.yml --repo acme/widget \
  --env npm-publish --allow-publish -y

Jalankan loop di bawah untuk setiap package milik Anda. Panggilan GitHub API mengembalikan id numerik repository dan nama kanoniknya saat ini, yaitu identitas yang tidak pernah dikunci oleh pendekatan slug. Jika nama yang tercetak bukan yang tercantum di npm, atau panggilan mengembalikan 404, anggap binding mencurigakan dan buat ulang. Jika Anda konsumen package, panduan yang sama menyarankan memeriksa bahwa provenance attestation sebuah package menyebut repository asal proyek yang seharusnya.

Di mana ini bisa salah, dan apa yang belum diketahui

Mode gagal yang paling jelas adalah publish pertama yang dingin. Karena konfigurasi kedaluwarsa dalam 48 jam, binding yang dibuat jauh hari untuk release kuartalan mati sejak awal, dan npm tidak memberi tahu saat Anda menyimpan karena tidak memverifikasi konfigurasi sampai Anda publish. Jebakan kedua adalah rename: rename atau transfer repository kini adalah perubahan identitas, jadi Anda membuat relationship baru dan publish dalam jendela baru, artinya Anda tidak bisa rename pada pagi hari release.

Trade-off-nya nyata. Anda menukar binding tetap yang tenang dengan binding yang menuntut perhatian saat dibuat, dan tim dengan release train lambat akan merasakannya. Saya menerima trade ini, karena binding kedaluwarsa yang tidak pernah selesai divalidasi persis bentuk eksposur yang dijelaskan Bloom.

Yang tidak bisa saya konfirmasi dari sumber yang saya baca: apakah konfigurasi tervalidasi yang ada diikat ulang ke ID repository, apakah celah ini pernah dieksploitasi, dan mengapa persisnya issue_comment ditambahkan. Anggap itu terbuka, dan teruslah mengaudit alih-alih mengira platform sudah menutup celahnya untuk Anda.

Yang dikerjakan hari Senin

Kerjakan berurutan. Untuk akun kecil sekitar satu jam, untuk organisasi dengan banyak package bisa sehari.

  1. Jalankan npm trust list pada setiap package yang Anda publish dan catat tiap repository serta filename workflow yang terhubung.
  2. Resolve tiap repository lewat GitHub API; hapus dan buat ulang binding yang repository-nya di-rename, ditransfer atau dihapus.
  3. Cari issue_comment dan pull_request_target di dekat npm publish pada workflow Anda, lalu pindahkan publish ke push, release atau workflow_dispatch.
  4. Buat trusted publisher baru hanya saat release siap, lalu publish dalam 48 jam agar konfigurasi tervalidasi.
  5. Verifikasi provenance attestation pada release berikutnya menyebut repository Anda, dan jadikan itu satu baris di checklist release.

Untuk gambaran lebih luas tentang posisi jalur publish tanpa kunci di autentikasi pipeline, post saya tentang GitHub Actions OIDC dan tentang worm npm ala Shai-Hulud membahas area di sekitarnya.

Trust yang tidak pernah dipakai tidak boleh hidup selamanya. npm kini menegakkan itu untuk trusted publishing dengan mengedarluarsakan binding yang belum tervalidasi setelah 48 jam dan menolak token dari workflow berpemicu komentar, tetapi aturan yang saya bawa lebih sederhana: ikat ke repository yang bisa Anda buktikan Anda kendalikan, publish dari event yang hanya bisa dipicu maintainer, dan periksa ulang binding setiap kali repository berganti tangan.

FAQ

Pertanyaan Umum

Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.

Berapa lama konfigurasi npm trusted publishing berlaku sebelum kedaluwarsa?

Konfigurasi yang belum berhasil melakukan publish kedaluwarsa 48 jam setelah dibuat dan tidak lagi bisa mengotorisasi publish. Setelah publish pertamanya berhasil, konfigurasi tervalidasi dan bebas dari expiry. Entri yang kedaluwarsa tetap terlihat di settings, jadi Anda membuatnya ulang untuk memulai jendela 48 jam baru.

Mengapa npm menolak token issue_comment untuk trusted publishing?

Changelog GitHub menyebut aturannya tetapi tidak alasannya. Aturan ini memperluas pembatasan pull_request_target yang sudah ada, dan workflow issue_comment menjalankan kode default branch pada event yang bisa dipicu siapa pun yang dapat berkomentar. Pindahkan publish ke push, release atau workflow_dispatch.

Apa yang terjadi jika saya rename atau transfer repository yang publish ke npm?

Mengubah identitas repository atau project membutuhkan trust relationship baru dengan jendela validasi 48 jam yang baru. Edit biasa tidak mengulang tenggat. Buat binding baru, lalu publish dalam 48 jam agar tervalidasi.

Bagaimana cara memeriksa repository mana yang dipercaya package npm saya?

Jalankan npm trust list untuk setiap package; docs npm menyebut perintah ini butuh npm 11.15.0 ke atas, izin write dan 2FA tingkat akun. Lalu pastikan tiap repository yang tercantum masih mengarah ke yang Anda kendalikan. Hapus dan buat ulang binding yang menunjuk ke repository yang di-rename atau ditransfer.

Apa itu celah SlugFest pada npm trusted publishing?

Bloom Security melaporkan bahwa npm mencatat repository terhubung lewat owner dan nama, bukan memeriksa ID permanen di token OIDC. Nama yang diklaim ulang bisa mendapat kredensial publish yang valid. Bloom menghitung lebih dari 1.500 package berpotensi terdampak dan menyatakan belum melihat eksploitasi di dunia nyata.