מפרסמים חבילת npm בלי token קבוע: OIDC יוצר גם הוכחת מקור

|כותב: מערכת QUASA|5 דק׳ קריאה| 1
מפרסמים חבילת npm בלי token קבוע: OIDC יוצר גם הוכחת מקור

כדי לפרסם חבילת npm בלי token קבוע, מגדירים לה Trusted Publisher ומריצים את הפרסום מתהליך CI מורשה עם הרשאת OIDC. לפי תיעוד Trusted Publishing של npm, הזהות הזמנית מחליפה את סוד הכתיבה בצעד הפרסום; בפרסום מתאים מ־GitHub Actions או מ־GitLab CI/CD נוצרת גם הצהרת provenance אוטומטית.

סדר המעבר הוא להגדיר את הקשר בין החבילה לתהליך, לפרסם גרסה חדשה בלי להעביר לצעד הפרסום את ה־token הישן, ולבדוק גם את הגרסה וגם את הוכחת המקור. רק לאחר מכן מגבילים פרסום באמצעות tokens ומבטלים את סוד האוטומציה שאינו נחוץ עוד. כך שגיאת התאמה בהגדרות תתגלה בזמן שהמסלול הישן עדיין זמין.

מכינים את החבילה ואת זהות תהליך הפרסום

Trusted Publishing דורש Node בגרסה 22.14.0 ומעלה ו־npm CLI בגרסה 11.5.1 ומעלה. בדקו את שתי הגרסאות בסביבת ה־CI עצמה: בחירת גרסת Node אינה מבטיחה שגרסת npm המותקנת עומדת בדרישה. הכינו גם גרסת חבילה חדשה להפצה, וודאו שתהליך הבנייה הקיים מייצר את הקבצים שאתם מתכוונים לכלול בה.

בהגדרות החבילה ב־npmjs.com פתחו את Trusted publishing, בחרו GitHub Actions והזינו את שם המשתמש או הארגון, שם המאגר ושם קובץ ה־workflow. מזינים שם קובץ בלבד, כגון publish.yml, אף שהקובץ עצמו נמצא תחת .github/workflows/. אם התהליך שלכם מפעיל npm publish, אפשרו במפורש פרסום ישיר בהגדרת ה־publisher; הרשאה לפרסום בשלבים אינה נותנת מעצמה הרשאה לפקודה הזאת. npm אינו מאמת את פרטי הקשר בעת השמירה, ולכן טעות בשם או ברישיות עשויה להתגלות רק בהרצת הפרסום.

בדקו את repository.url ב־package.json לפני ההרצה. הנחיות npm ליצירת provenance דורשות מאגר ציבורי שתואם, כולל רישיות, למאגר שממנו מתבצע הפרסום. בפרויקט שפורסם מתוך fork, ערך שמצביע עדיין למאגר המקורי עלול לסכל את ההתאמה. הוכחת המקור קושרת את החבילה למקור ולתהליך הבנייה; היא אינה קביעה שהתוכן של החבילה בטוח.

מגדירים workflow מינימלי ב־GitHub Actions

תהליך פרסום ב־GitHub Actions מפיק גרסת חבילת npm באמצעות הרשאת OIDC שהוגדרה ל־workflow.

הדוגמה מיועדת לחבילה ציבורית קיימת שמפורסמת ממאגר GitHub ציבורי באמצעות runner של GitHub. שמרו את השורות הבאות בקובץ .github/workflows/publish.yml. טריגר על תגית הוא בחירה לדוגמה; בפרויקט שבו ההפצה מתחילה בדרך אחרת, התאימו רק את הטריגר ושמרו על הרשאות ה־OIDC ועל צעד פרסום ללא token.

name: Publish Package

on: {push: {tags: ['v*']}}

permissions: {id-token: write, contents: read}

jobs:

  publish:

    runs-on: ubuntu-latest

    steps:

      - uses: actions/checkout@v6

      - uses: actions/setup-node@v6

        with: {node-version: '24', registry-url: 'https://registry.npmjs.org', package-manager-cache: false}

      - run: npm install -g npm@latest

      - run: npm ci

      - run: npm publish

ההרשאה id-token: write מאפשרת לתהליך לקבל זהות OIDC; ההרשאה contents: read מאפשרת למשוך את קוד המאגר. השורה שמעדכנת את npm מוודאת שצעד הפרסום משתמש ב־CLI מתאים, גם אם גרסת npm שהגיעה עם Node ישנה מדי. אם ההפצה מחייבת בנייה או בדיקות, מקומן אחרי npm ci ולפני npm publish. בפרסום באמצעות Trusted Publishing אין צורך להוסיף לפקודה ‎--provenance, משום שההצהרה מופקת אוטומטית כאשר תנאי הזכאות מתקיימים.

השאירו את NODE_AUTH_TOKEN מחוץ לצעד npm publish. ה־CLI יכול לחזור לאימות באמצעות token מסורתי אם הוא מוצא אותו, ולכן פרסום מוצלח כשהסוד עדיין מוזרק לצעד אינו מוכיח שהמעבר ל־OIDC הצליח. אם npm ci מתקין תלויות פרטיות, תנו token לקריאה בלבד לצעד ההתקנה לבדו; ההרשאה הזו פותרת את צורכי ההתקנה בלי להחזיר סוד כתיבה לפרסום.

בודקים את הגרסה ואת הוכחת המקור

גרסת חבילת npm מקושרת בהצהרת provenance להרצת הבנייה ול־commit המקור שלה.

לאחר הרצה מוצלחת, פתחו ב־npm את דף הגרסה שפורסמה. הוראות הצפייה ב־provenance של npm מתארות סימון ירוק ליד הגרסה וגישה לפרטי סביבת הבנייה, הרצת ה־workflow, קובץ הבנייה, commit המקור והרשומה ביומן השקיפות. השוו את המאגר, ה־commit וההרצה להפצה שביצעתם, במיוחד אם כמה תהליכים מסוגלים לפרסם את אותה חבילה.

בדקו גם את מה שצרכן החבילה מתקין. בפרויקט בדיקה שתלוי בגרסה החדשה, הריצו npm install או npm ci, ואז npm audit signatures. הפקודה בודקת חתימות של הרישום והצהרות provenance עבור החבילות שהותקנו, ומחזירה שגיאה כשחתימה או הצהרה נדרשת חסרה או אינה תקפה. מאחר שהפלט עשוי לסכם תלויות רבות, פרטי הגרסה באתר נחוצים כדי לזהות את הקשר של החבילה המסוימת שלכם למאגר ולהרצת הבנייה.

פרסום שהסתיים בהצלחה והופעת provenance הם שתי בדיקות שונות. אם הגרסה קיימת אך הסימון אינו מופיע, בדקו את נראות המאגר והחבילה, את ספק ה־CI ואת הגדרות ה־provenance לפני שמסיקים שהפרסום באמצעות OIDC נכשל.

מזהים מגבלות לפני שמבטלים את הסוד

הפקה אוטומטית של provenance ב־Trusted Publishing דורשת חבילה ציבורית, מאגר ציבורי ופרסום מתאים מ־GitHub Actions או מ־GitLab CI/CD. גם כאשר החבילה ציבורית, פרסום ממאגר פרטי אינו מפיק את ההוכחה. CircleCI cloud תומך בפרסום באמצעות OIDC, אך הפרסום דרכו אינו מפיק כיום provenance אוטומטית. לכן אפשר להצליח בהחלפת ה־token ובכל זאת לא לקבל את הוכחת המקור המצופה.

סוג ה־runner חשוב אף הוא: ב־GitHub נדרש runner שמארחת GitHub, וב־GitLab נדרש shared runner של GitLab.com; runners בהפעלה עצמית אינם נתמכים ב־Trusted Publishing. אם מתקבלת שגיאת אימות, בדקו התאמה מדויקת של שם המאגר ושל שם קובץ ה־workflow, לרבות הסיומת והרישיות, ואת ההרשאה id-token: write. הפקודה npm whoami אינה מבחן להרשאת הפרסום באמצעות OIDC; המבחן הוא פעולת הפרסום שהוגדרה.

ב־workflow חוזר שמופעל באמצעות workflow_call, בדיקת הזהות עשויה להתייחס לשם התהליך הקורא במקום לקובץ שמכיל את npm publish. נדרשת הרשאת id-token: write גם בתהליך הקורא וגם בתהליך הנקרא; התאימו את פרטי ה־publisher לזהות שנבדקת. אותה בדיקת התאמה חשובה גם בהפעלה ידנית באמצעות workflow_dispatch. אם נדרש תיקון בחיבור Trusted Publisher קיים, מוחקים אותו ויוצרים חיבור חדש, משום שאי אפשר לערוך את שדותיו הקבועים.

מבטלים את token הכתיבה אחרי אימות ההפצה

לאחר שהגרסה הופיעה ברישום, פרטי ה־provenance תואמים להרצה ובדיקת החתימות הסתיימה כצפוי, בדקו אם ה־token הישן משמש חבילות או תהליכים נוספים. העבירו תחילה שימושים כאלה למסלול מתאים. הסירו את סוד הכתיבה מהגדרות ה־CI ומצעד הפרסום, כדי שההרצה הבאה לא תוכל לחזור אליו במקרה של כשל ב־OIDC.

בהגדרות החבילה, תחת Publishing access, אפשר לבחור Require two-factor authentication and disallow tokens. ההגבלה חוסמת פרסום באמצעות tokens רגילים, אך אינה חוסמת Trusted Publishers שמשתמשים ב־OIDC. אחרי שכל שימוש נחוץ בסוד טופל, בטלו גם את ה־automation token הישן בחשבון npm. כך ההפצה הבאה תלויה בזהות ה־workflow שהוגדרה לחבילה, ולא בהרשאת כתיבה קבועה שנותרה פעילה.

קראו גם:

שיתוף:

הירשמו לניוזלטר שלנו

קבלו את החדשות האחרונות על Web3, ‏AI וקריפטו ישירות לתיבת הדואר.

0