Stop malicious PyPI packages before they reach your CI.
A GitHub Action that routes installs through a security proxy — no secrets, no config files, two lines of YAML.
Not using CI? For local setup on your laptop, see the email registration & token management appendix below.
- What is Takumi Guard?
- Quickstart (3 steps)
- Setup modes
- Migrating existing projects
- Inputs
- Outputs
- Troubleshooting
- Security
- Appendix: Email registration & token management
Every pip install in your CI is a trust decision. Takumi Guard sits between your workflow and PyPI, blocking known-malicious packages before they execute.
- How it works -- Routes installs through a security proxy (
pypi.flatt.tech) that checks packages against a threat database in real time. - What you change -- One step in your workflow YAML. No config files, no secrets to manage.
- What it supports -- pip, uv, and poetry.
Goal: Add Takumi Guard to any GitHub Actions workflow. No account required.
Step 1. Add the action to your workflow file (e.g. .github/workflows/ci.yml):
steps:
- uses: actions/checkout@v4
- uses: flatt-security/setup-takumi-guard-pypi@v1 # <-- add this line
- run: pip install -r requirements.txt
- run: pytestStep 2. Push the change. Every pip install in this job now runs through the Takumi Guard proxy. Malicious packages are blocked automatically.
Step 3. (Optional) Want audit logging and a dashboard? Add a Bot ID for full visibility into package activity:
jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write # Required for authentication
contents: read
steps:
- uses: actions/checkout@v4
- uses: flatt-security/setup-takumi-guard-pypi@v1
with:
bot-id: "YOUR_BOT_ID"
- run: pip install -r requirements.txtWhere do I get a Bot ID? Create one at Shisho Cloud byGMO -- or skip this entirely. Blocking works without it. The Bot ID is a public reference key, not a secret.
| Mode | Blocks malware | Audit logging | Account needed | Best for |
|---|---|---|---|---|
| Blocking only | Yes | No | No | OSS projects, quick evaluation |
| Full protection | Yes | Yes | Yes | Production workloads |
| Auth-only | You manage | Yes | Yes | Custom pip.conf setups |
No account needed. Add one line and you are protected.
Blocks known-malicious packages. No signup, no authentication.
- uses: flatt-security/setup-takumi-guard-pypi@v1Good for open-source projects or quick evaluation.
Recommended for production. Blocks threats and logs all package activity to your dashboard.
permissions:
id-token: write
steps:
- uses: flatt-security/setup-takumi-guard-pypi@v1
with:
bot-id: "YOUR_BOT_ID"Key details:
- Auth is handled via GitHub's built-in OIDC -- no PATs or secrets to rotate.
- If authentication fails, blocking remains active but logging is degraded. The build continues with a warning.
- Get a Bot ID from Shisho Cloud byGMO.
For custom setups. You manage
PIP_INDEX_URL/UV_INDEX_URLyourself. The action only handles authentication.
- uses: flatt-security/setup-takumi-guard-pypi@v1
with:
bot-id: "YOUR_BOT_ID"
set-index-url: falseKey details:
- Useful for projects that need full control over pip/uv configuration.
- Requires
PIP_INDEX_URL=https://pypi.flatt.tech/simple/(andUV_INDEX_URLfor uv) set in your environment or config files. - If authentication fails, the action exits with an error -- there is no fallback.
Unlike npm, pip does not use lockfiles that reference a specific registry URL by default. Most projects can adopt Takumi Guard without any lockfile changes.
For pip / uv: No migration needed. The action sets PIP_INDEX_URL (for pip) and UV_INDEX_URL (for uv) so all installs automatically route through the proxy.
For poetry (with poetry.lock):
# Add the Takumi Guard source
poetry source add --priority=primary takumi-guard https://pypi.flatt.tech/simple/
# Regenerate lockfile
poetry lock --no-update
# Commit
git add pyproject.toml poetry.lock
git commit -m "Route installs through Takumi Guard"| Input | Required | Default | Description |
|---|---|---|---|
bot-id |
No | -- | Bot ID from Shisho Cloud byGMO. Omit for blocking-only mode. |
set-index-url |
No | true |
Set PIP_INDEX_URL and UV_INDEX_URL environment variables. Set to false if you manage them yourself. |
registry-url |
No | https://pypi.flatt.tech |
Registry endpoint. |
sts-url |
No | https://sts.cloud.shisho.dev |
STS endpoint for token exchange. |
expires-in |
No | 1800 |
Token lifetime in seconds (max 86400). |
| Output | Description |
|---|---|
token-expires-at |
ISO 8601 timestamp of token expiration. Only set when authenticated. |
| Error | Cause | Fix |
|---|---|---|
OIDC not available |
Missing permission on the job | Add permissions: { id-token: write } to your job |
invalid ID token |
Trust condition mismatch | Check the bot's trust settings in Shisho Cloud byGMO |
invalid request |
Malformed bot-id | Double-check the bot-id value from your console |
Authentication failed ... Falling back |
STS token exchange failed | Verify bot-id and trust settings. Blocking is still active. |
Still stuck? Open an issue on this repository with your error output and workflow file (redact any IDs).
- Short-lived tokens -- 30 minutes by default, 24 hours max.
- Auto-masked -- Tokens and authenticated URLs are automatically masked in workflow logs.
- Environment-scoped -- The action sets
PIP_INDEX_URLandUV_INDEX_URLfor the current job only. Your global pip/uv config is untouched. - Basic auth in URL -- pip uses
https://token:ACCESS_TOKEN@host/simple/format. The full URL is masked in logs.
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 instead.
curl -X POST https://pypi.flatt.tech/api/v1/tokens \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com"}'Check your inbox and click the verification link. You will receive a token like tg_anon_xxx....
Language preference: Add "language": "ja" to receive emails in Japanese. Defaults to English ("en") if omitted.
curl -X POST https://pypi.flatt.tech/api/v1/tokens \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "language": "ja"}'Set the index URL with your token:
# For pip (and uv pip commands)
export PIP_INDEX_URL=https://token:tg_anon_xxx...@pypi.flatt.tech/simple/
# For uv project commands (add/sync/lock)
export UV_INDEX_URL=https://token:tg_anon_xxx...@pypi.flatt.tech/simple/To make this permanent, add the lines to your shell profile or configure pip in ~/.config/pip/pip.conf (Linux/macOS) or %APPDATA%\pip\pip.ini (Windows):
[global]
index-url = https://token:tg_anon_xxx...@pypi.flatt.tech/simple/After this, pip install and uv commands route 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.
curl -H "Authorization: Bearer tg_anon_xxx..." \
https://pypi.flatt.tech/api/v1/tokens/statuscurl -X POST -H "Authorization: Bearer tg_anon_xxx..." \
https://pypi.flatt.tech/api/v1/tokens/regenerateReturns a new API key. The old one is invalidated immediately. Update your pip configuration with the new key.
curl -X DELETE -H "Authorization: Bearer tg_anon_xxx..." \
https://pypi.flatt.tech/api/v1/tokens
Built by GMO Flatt Security Inc.
MIT License
