|
| 1 | +<p align="center"> |
| 2 | + <img src="branding.png" alt="Takumi Guard — a panda security guard scanning npm packages" width="300" /> |
| 3 | +</p> |
| 4 | + |
| 5 | +<h1 align="center">Takumi Guard for npm</h1> |
| 6 | + |
| 7 | +<p align="center"> |
| 8 | + <strong>Stop malicious npm packages before they reach your CI.</strong><br /> |
| 9 | + A GitHub Action that routes installs through a security proxy — no secrets, no config files, two lines of YAML. |
| 10 | +</p> |
| 11 | + |
| 12 | +<p align="center"> |
| 13 | + <a href="https://github.com/flatt-security/setup-takumi-guard-npm/actions/workflows/test.yml"><img src="https://github.com/flatt-security/setup-takumi-guard-npm/actions/workflows/test.yml/badge.svg" alt="CI" /></a> |
| 14 | + <a href="LICENSE"><img src="https://img.shields.io/github/license/flatt-security/setup-takumi-guard-npm" alt="License" /></a> |
| 15 | +</p> |
| 16 | + |
| 17 | +--- |
| 18 | + |
| 19 | +## Contents |
| 20 | + |
| 21 | +- [What is Takumi Guard?](#what-is-takumi-guard) |
| 22 | +- [Quickstart (3 steps)](#quickstart) |
| 23 | +- [Verify it works](#verify-it-works) |
| 24 | +- [Setup modes](#setup-modes) |
| 25 | +- [Migrating existing projects (3 steps)](#migrating-existing-projects) |
| 26 | +- [Inputs](#inputs) |
| 27 | +- [Outputs](#outputs) |
| 28 | +- [Troubleshooting](#troubleshooting) |
| 29 | +- [Security](#security) |
| 30 | +- [Appendix: Email registration & token management](#appendix-email-registration--token-management) |
| 31 | + |
| 32 | +--- |
| 33 | + |
| 34 | +## What is Takumi Guard? |
| 35 | + |
| 36 | +Every `npm install` in your CI is a trust decision. Takumi Guard sits between your workflow and the npm registry, **blocking known-malicious packages before they execute**. |
| 37 | + |
| 38 | +- **How it works** -- Routes installs through a security proxy (`npm.flatt.tech`) that checks packages against a threat database in real time. |
| 39 | +- **What you change** -- One step in your workflow YAML. No config files, no secrets to manage. |
| 40 | +- **What it supports** -- **npm**, **pnpm**, and **yarn**. |
| 41 | + |
| 42 | +--- |
| 43 | + |
| 44 | +## Quickstart |
| 45 | + |
| 46 | +**Goal:** Add Takumi Guard to any GitHub Actions workflow. No account required. |
| 47 | + |
| 48 | +**Step 1.** Add the action to your workflow file (e.g. `.github/workflows/ci.yml`): |
| 49 | + |
| 50 | +```yaml |
| 51 | +steps: |
| 52 | + - uses: actions/checkout@v4 |
| 53 | + |
| 54 | + - uses: flatt-security/setup-takumi-guard-npm@v1 # <-- add this line |
| 55 | + |
| 56 | + - run: npm install |
| 57 | + - run: npm test |
| 58 | +``` |
| 59 | +
|
| 60 | +**Step 2.** Push the change. Every `npm install` in this job now runs through the Takumi Guard proxy. Malicious packages are blocked automatically. |
| 61 | + |
| 62 | +**Step 3.** *(Optional)* **Want audit logging and a dashboard?** Add a Bot ID for full visibility into package activity: |
| 63 | + |
| 64 | +```yaml |
| 65 | +jobs: |
| 66 | + build: |
| 67 | + runs-on: ubuntu-latest |
| 68 | + permissions: |
| 69 | + id-token: write # Required for authentication |
| 70 | + contents: read |
| 71 | + steps: |
| 72 | + - uses: actions/checkout@v4 |
| 73 | +
|
| 74 | + - uses: flatt-security/setup-takumi-guard-npm@v1 |
| 75 | + with: |
| 76 | + bot-id: "YOUR_BOT_ID" |
| 77 | +
|
| 78 | + - run: npm install |
| 79 | +``` |
| 80 | + |
| 81 | +> **Where do I get a Bot ID?** Create one at [Shisho Cloud byGMO](https://cloud.shisho.dev) -- or skip this entirely. Blocking works without it. The Bot ID is a public reference key, not a secret. |
| 82 | + |
| 83 | +--- |
| 84 | + |
| 85 | +## Verify it works |
| 86 | + |
| 87 | +Confirm blocking is active by trying to install a known-blocked test package. |
| 88 | + |
| 89 | +**From your terminal** (no account or setup needed): |
| 90 | + |
| 91 | +```bash |
| 92 | +npm install --registry https://npm.flatt.tech @panda-guard/test-malicious |
| 93 | +``` |
| 94 | + |
| 95 | +**Or as a CI step** in your workflow: |
| 96 | + |
| 97 | +```yaml |
| 98 | + - name: Verify Takumi Guard is active |
| 99 | + run: | |
| 100 | + npm install @panda-guard/test-malicious && exit 1 || echo "Blocked as expected" |
| 101 | +``` |
| 102 | + |
| 103 | +> **Expected result:** The install fails with a block message. If it does, the guard is working. |
| 104 | + |
| 105 | +--- |
| 106 | + |
| 107 | +## Setup modes |
| 108 | + |
| 109 | +Pick the mode that fits your situation. Here is how they compare at a glance: |
| 110 | + |
| 111 | +| Mode | Blocks malware | Audit logging | Account needed | Best for | |
| 112 | +|---|:---:|:---:|:---:|---| |
| 113 | +| **[Blocking only](#blocking-only)** | Yes | No | No | OSS projects, quick evaluation | |
| 114 | +| **[Full protection](#full-protection)** | Yes | Yes | Yes | Production workloads | |
| 115 | +| **[Auth-only](#auth-only-advanced)** | You manage | Yes | Yes | Monorepos, custom `.npmrc` | |
| 116 | + |
| 117 | +--- |
| 118 | + |
| 119 | +### Blocking only |
| 120 | + |
| 121 | +> **No account needed.** Add one line and you are protected. |
| 122 | + |
| 123 | +Blocks known-malicious packages. No signup, no authentication. |
| 124 | + |
| 125 | +```yaml |
| 126 | +- uses: flatt-security/setup-takumi-guard-npm@v1 |
| 127 | +``` |
| 128 | + |
| 129 | +Good for open-source projects or quick evaluation. |
| 130 | + |
| 131 | +--- |
| 132 | + |
| 133 | +### Full protection |
| 134 | + |
| 135 | +> **Recommended for production.** Blocks threats _and_ logs all package activity to your dashboard. |
| 136 | + |
| 137 | +```yaml |
| 138 | +permissions: |
| 139 | + id-token: write |
| 140 | +
|
| 141 | +steps: |
| 142 | + - uses: flatt-security/setup-takumi-guard-npm@v1 |
| 143 | + with: |
| 144 | + bot-id: "YOUR_BOT_ID" |
| 145 | +``` |
| 146 | + |
| 147 | +**Key details:** |
| 148 | +- Auth is handled via **GitHub's built-in OIDC** -- no PATs or secrets to rotate. |
| 149 | +- If authentication fails, **blocking remains active** but logging is degraded. The build continues with a warning. |
| 150 | +- Get a Bot ID from [Shisho Cloud byGMO](https://cloud.shisho.dev). |
| 151 | + |
| 152 | +--- |
| 153 | + |
| 154 | +### Auth-only (advanced) |
| 155 | + |
| 156 | +> **For custom setups.** You manage the registry URL in your own `.npmrc`. The action only handles authentication. |
| 157 | + |
| 158 | +```yaml |
| 159 | +- uses: flatt-security/setup-takumi-guard-npm@v1 |
| 160 | + with: |
| 161 | + bot-id: "YOUR_BOT_ID" |
| 162 | + set-registry: false |
| 163 | +``` |
| 164 | + |
| 165 | +**Key details:** |
| 166 | +- Useful for monorepos or projects that need full control over `.npmrc`. |
| 167 | +- Requires `registry=https://npm.flatt.tech/` in your committed `.npmrc`. |
| 168 | +- If authentication fails, **the action exits with an error** -- there is no fallback. |
| 169 | + |
| 170 | +--- |
| 171 | + |
| 172 | +## Migrating existing projects |
| 173 | + |
| 174 | +> **Why is this needed?** If your project already has a lockfile, it references `registry.npmjs.org`. You need a one-time regeneration so the lockfile points to the proxy registry instead. This works locally because the proxy serves package metadata without authentication. |
| 175 | + |
| 176 | +**Step 1.** Set the registry to the Takumi Guard proxy: |
| 177 | + |
| 178 | +```bash |
| 179 | +npm config set registry "https://npm.flatt.tech/" --location=project |
| 180 | +``` |
| 181 | + |
| 182 | +**Step 2.** Regenerate the lockfile for your package manager: |
| 183 | + |
| 184 | +<details> |
| 185 | +<summary><strong>pnpm</strong></summary> |
| 186 | + |
| 187 | +```bash |
| 188 | +rm pnpm-lock.yaml && pnpm install |
| 189 | +``` |
| 190 | +</details> |
| 191 | + |
| 192 | +<details> |
| 193 | +<summary><strong>npm</strong></summary> |
| 194 | + |
| 195 | +```bash |
| 196 | +rm package-lock.json && npm install |
| 197 | +``` |
| 198 | +</details> |
| 199 | + |
| 200 | +<details> |
| 201 | +<summary><strong>yarn</strong></summary> |
| 202 | + |
| 203 | +```bash |
| 204 | +yarn install |
| 205 | +``` |
| 206 | +</details> |
| 207 | + |
| 208 | +**Step 3.** Commit the updated `.npmrc` and lockfile: |
| 209 | + |
| 210 | +```bash |
| 211 | +git add .npmrc pnpm-lock.yaml # or package-lock.json / yarn.lock |
| 212 | +git commit -m "Route installs through Takumi Guard" |
| 213 | +``` |
| 214 | + |
| 215 | +> **Done.** Your CI will now install packages through Takumi Guard on the next push. |
| 216 | + |
| 217 | +--- |
| 218 | + |
| 219 | +## Inputs |
| 220 | + |
| 221 | +| Input | Required | Default | Description | |
| 222 | +|---|---|---|---| |
| 223 | +| `bot-id` | No | -- | Bot ID from Shisho Cloud byGMO. Omit for blocking-only mode. | |
| 224 | +| `set-registry` | No | `true` | Set the registry URL in `.npmrc`. Set to `false` if you manage it yourself. | |
| 225 | +| `registry-url` | No | `https://npm.flatt.tech` | Registry endpoint. | |
| 226 | +| `sts-url` | No | `https://sts.shisho.dev` | STS endpoint for token exchange. | |
| 227 | +| `expires-in` | No | `1800` | Token lifetime in seconds (max 86400). | |
| 228 | + |
| 229 | +--- |
| 230 | + |
| 231 | +## Outputs |
| 232 | + |
| 233 | +| Output | Description | |
| 234 | +|---|---| |
| 235 | +| `token-expires-at` | ISO 8601 timestamp of token expiration. Only set when authenticated. | |
| 236 | + |
| 237 | +--- |
| 238 | + |
| 239 | +## Troubleshooting |
| 240 | + |
| 241 | +**Find your error message below**, then follow the fix. |
| 242 | + |
| 243 | +| Error | Cause | Fix | |
| 244 | +|---|---|---| |
| 245 | +| `OIDC not available` | Missing permission on the job | Add `permissions: { id-token: write }` to your job | |
| 246 | +| `invalid ID token` | Trust condition mismatch | Check the bot's trust settings in Shisho Cloud byGMO | |
| 247 | +| `invalid request` | Malformed bot-id | Double-check the bot-id value from your console | |
| 248 | +| `Authentication failed ... Falling back` | STS token exchange failed | Verify bot-id and trust settings. Blocking is still active. | |
| 249 | +| Lockfile conflicts after setup | Lockfile still references `registry.npmjs.org` | Follow the [migration steps](#migrating-existing-projects) to regenerate it | |
| 250 | + |
| 251 | +> **Still stuck?** Open an issue on this repository with your error output and workflow file (redact any IDs). |
| 252 | + |
| 253 | +--- |
| 254 | + |
| 255 | +## Security |
| 256 | + |
| 257 | +- **Short-lived tokens** -- 30 minutes by default, 24 hours max. |
| 258 | +- **Auto-masked** -- Tokens are automatically masked in workflow logs. |
| 259 | +- **Project-scoped** -- The action writes to project-level `.npmrc` only. Your global npm config is untouched. |
| 260 | +- **Preserves scoped registries** -- Existing entries (e.g. `@myorg:registry=...`) are not overwritten. |
| 261 | + |
| 262 | +--- |
| 263 | + |
| 264 | +## Appendix: Email registration & token management |
| 265 | + |
| 266 | +> **Optional.** Register your email to receive breach notifications if a package you installed is later flagged as malicious. This works for local development -- CI workflows should use [Full protection](#full-protection) instead. |
| 267 | + |
| 268 | +### Register |
| 269 | + |
| 270 | +```bash |
| 271 | +curl -X POST https://npm.flatt.tech/api/v1/tokens \ |
| 272 | + -H "Content-Type: application/json" \ |
| 273 | + -d '{"email": "you@example.com"}' |
| 274 | +``` |
| 275 | + |
| 276 | +Check your inbox and click the verification link. You will receive a token like `tg_anon_xxx...`. |
| 277 | + |
| 278 | +**Language preference:** Add `"language": "ja"` to receive emails in Japanese. Defaults to English (`"en"`) if omitted. |
| 279 | + |
| 280 | +```bash |
| 281 | +curl -X POST https://npm.flatt.tech/api/v1/tokens \ |
| 282 | + -H "Content-Type: application/json" \ |
| 283 | + -d '{"email": "you@example.com", "language": "ja"}' |
| 284 | +``` |
| 285 | + |
| 286 | +### Configure npm |
| 287 | + |
| 288 | +```bash |
| 289 | +npm config set registry "https://npm.flatt.tech/" |
| 290 | +npm config set //npm.flatt.tech/:_authToken "tg_anon_xxx..." |
| 291 | +``` |
| 292 | + |
| 293 | +After this, `npm install` routes through Takumi Guard with your identity attached. If a package you downloaded is later found to be malicious, you will receive a breach notification email. |
| 294 | + |
| 295 | +### Check token status |
| 296 | + |
| 297 | +```bash |
| 298 | +curl -H "Authorization: Bearer tg_anon_xxx..." \ |
| 299 | + https://npm.flatt.tech/api/v1/tokens/status |
| 300 | +``` |
| 301 | + |
| 302 | +### Rotate your key |
| 303 | + |
| 304 | +If your key is compromised, regenerate it instantly: |
| 305 | + |
| 306 | +```bash |
| 307 | +curl -X POST -H "Authorization: Bearer tg_anon_xxx..." \ |
| 308 | + https://npm.flatt.tech/api/v1/tokens/regenerate |
| 309 | +``` |
| 310 | + |
| 311 | +Returns a new API key. The old one is invalidated immediately. Update your `.npmrc` with the new key. |
| 312 | + |
| 313 | +Alternatively, call `POST /api/v1/tokens` again with the same email to receive a rotation link via email. |
| 314 | + |
| 315 | +### Revoke a token |
| 316 | + |
| 317 | +```bash |
| 318 | +curl -X DELETE -H "Authorization: Bearer tg_anon_xxx..." \ |
| 319 | + https://npm.flatt.tech/api/v1/tokens |
| 320 | +``` |
| 321 | + |
| 322 | +Revoking a token stops future breach notifications and removes the email association. You can register again at any time. |
| 323 | + |
| 324 | +--- |
| 325 | + |
| 326 | +<p align="center"> |
| 327 | + Built by <a href="https://flatt.tech">GMO Flatt Security Inc.</a><br /> |
| 328 | + <a href="LICENSE">MIT License</a> |
| 329 | +</p> |
0 commit comments