Skip to content

Commit 8f53b50

Browse files
committed
Setup Takumi Guard npm registry action
GitHub Action to route npm/pnpm/yarn installs through the Takumi Guard security proxy (npm.flatt.tech). Blocks known-malicious packages, supports anonymous and authenticated (OIDC) modes, and logs download activity to BigQuery for breach notifications.
0 parents  commit 8f53b50

File tree

6 files changed

+515
-0
lines changed

6 files changed

+515
-0
lines changed

.github/workflows/test.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Test
2+
on:
3+
push:
4+
branches: [main]
5+
pull_request:
6+
branches: [main]
7+
8+
jobs:
9+
lint:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Validate action.yml
15+
run: |
16+
python3 -c "import yaml; yaml.safe_load(open('action.yml'))"
17+
echo "action.yml is valid YAML"
18+
19+
- name: Check required fields
20+
run: |
21+
grep -q 'using:.*composite' action.yml
22+
grep -q "bot-id:" action.yml
23+
echo "Required fields present"

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
node_modules/
2+
.npmrc
3+
*.log
4+
.DS_Store
5+
*.pem
6+
*.pub

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 GMO Flatt Security Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
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

Comments
 (0)