# PyPI {#pypi}

Takumi Guard setup varies depending on your environment and the features you need. This page covers setup for both local development and GitHub Actions.

## Setup {#setup}

### Anonymous Usage {#setup-anonymous}

You can use Takumi Guard's package blocking without authentication. Simply set the index URL to enable malicious package blocking. Download tracking and [breach notifications](/docs/t/guard/features/breach-notifications.md) are not available, but this is the easiest way to get started.

For **pip**, run the following command to permanently set the index URL:

```bash
pip config set global.index-url https://pypi.flatt.tech/simple/
```

That's it. All `pip install` commands now route through Takumi Guard.

Alternatively, you can set the index URL via an environment variable in your shell profile (`.bashrc`, `.zshrc`, etc.):

```bash
# Add to your shell profile (.bashrc, .zshrc, etc.):
export PIP_INDEX_URL=https://pypi.flatt.tech/simple/
```

Or configure in `pip.conf` (`~/.config/pip/pip.conf` on Linux/macOS, `%APPDATA%\pip\pip.ini` on Windows):

```ini
[global]
index-url = https://pypi.flatt.tech/simple/
```

For a single one-time install without changing your environment, you can also pass `--index-url` directly:

```bash
pip install --index-url https://pypi.flatt.tech/simple/ <package>
```

:::tip Package Manager Compatibility
Takumi Guard works with **pip**, **uv**, and **poetry**. No lockfile migration is needed — existing lockfiles continue to work because package managers verify packages by integrity hash, not by index URL.

**uv** does not read `PIP_INDEX_URL` or `pip.conf`. Use one of the following:

Environment variable:

```bash
export UV_INDEX_URL=https://pypi.flatt.tech/simple/
```

Or configure permanently in `~/.config/uv/uv.toml` (user-level):

```toml
# ~/.config/uv/uv.toml
[[index]]
url = "https://pypi.flatt.tech/simple/"
default = true
```

Or in `pyproject.toml` (per-project):

```toml
# pyproject.toml
[[tool.uv.index]]
url = "https://pypi.flatt.tech/simple/"
default = true
```

To cover both pip and uv via environment variables, add both lines to your shell profile:

```bash
export PIP_INDEX_URL=https://pypi.flatt.tech/simple/
export UV_INDEX_URL=https://pypi.flatt.tech/simple/
```

**poetry** requires adding Takumi Guard as a primary source:

```bash
poetry source add --priority=primary takumi-guard https://pypi.flatt.tech/simple/
```

:::

### Email-Verified Access {#setup-email-verified}

Registering your email address enables download tracking and [breach notifications](/docs/t/guard/features/breach-notifications.md) in addition to package blocking. If a security advisory is published for a package you previously downloaded, a notification is sent to your registered email address. No Shisho Cloud account is required, and this is free of charge.

**Step 1: Register your email**

```bash
curl -X POST https://pypi.flatt.tech/api/v1/tokens \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "language": "en"}'
```

The `language` field is optional and defaults to `"en"`. Set it to `"ja"` to receive emails in Japanese. This preference is stored with your token and applies to all future emails, including breach notifications.

You'll receive a welcome email within a few seconds.

**Step 2: Get your API key from the email**

Your API key is included directly in the welcome email. The key is ready to use immediately — no link to click.

:::warning
Save this key somewhere secure. If you need a new one, you can regenerate it anytime: `curl -X POST -H 'Authorization: Bearer tg_anon_xxxxxx' https://pypi.flatt.tech/api/v1/tokens/regenerate`
:::

**Step 3: Configure pip**

The simplest way is a single command that persists to disk:

```bash
pip config set global.index-url https://token:tg_anon_xxxxxx@pypi.flatt.tech/simple/
```

If you use **uv**, also add the following to your shell profile (`.bashrc`, `.zshrc`, etc.) — uv does not read pip config:

```bash
export UV_INDEX_URL=https://token:tg_anon_xxxxxx@pypi.flatt.tech/simple/
```

Alternatively, you can set both via environment variables in your shell profile:

```bash
export PIP_INDEX_URL=https://token:tg_anon_xxxxxx@pypi.flatt.tech/simple/
export UV_INDEX_URL=https://token:tg_anon_xxxxxx@pypi.flatt.tech/simple/
```

Your `pip install` commands now authenticate with your token, enabling download tracking and breach notifications.

### GitHub Actions {#setup-ci}

To integrate Takumi Guard into your GitHub Actions workflow, use the `flatt-security/setup-takumi-guard-pypi` GitHub Action. You can use it anonymously or linked to an organization.

#### Anonymous Mode {#setup-ci-anonymous}

If you don't have a Shisho Cloud account yet, you can still use Takumi Guard in CI for package blocking. Omit the `bot-id` input:

```yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: flatt-security/setup-takumi-guard-pypi@v1
        # No bot-id — anonymous mode, blocking only

      - run: pip install -r requirements.txt
      - run: pytest
```

In anonymous mode, the action only configures the index URL. Blocked packages are still rejected with a 403 error, but download tracking and [breach notifications](/docs/t/guard/features/breach-notifications.md) are not available.

#### With Shisho Cloud Organization {#setup-ci-org}

Linking to a Shisho Cloud organization enables organization-level download tracking and [breach notifications](/docs/t/guard/features/breach-notifications.md) (via webhook). No long-lived secrets need to be stored in your CI environment. Authentication is performed securely by exchanging a GitHub OIDC token for a short-lived access token via the Shisho Cloud STS service.

**Prerequisites:**

1. A bot identity registered in Shisho Cloud. Copy the **Bot ID** from the registry settings page in the Shisho Cloud console.
2. The `id-token: write` and `contents: read` permissions in your workflow job.

**Step 1: Add the action to your workflow**

```yaml
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      id-token: write # Required for OIDC token exchange
      contents: read
    steps:
      - uses: actions/checkout@v4

      - uses: flatt-security/setup-takumi-guard-pypi@v1
        with:
          bot-id: "BT01EXAMPLE..." # Copy from Shisho Cloud console

      - run: pip install -r requirements.txt
      - run: pytest
```

The action handles the full OIDC exchange automatically:

1. Requests a GitHub OIDC token
2. Exchanges it for a short-lived Takumi Guard access token via the STS service
3. Configures pip to use the Takumi Guard index with that token

:::info
The Bot ID is not a secret — it is a public reference key used to look up the allowlist during token exchange. You can commit it directly in your workflow file. The Shisho Cloud console provides a ready-to-copy workflow snippet with the Bot ID pre-filled.
:::

The access token expires after 30 minutes by default (configurable up to 24 hours via the `expires-in` input).

#### Action Inputs Reference {#action-inputs}

| Input           | Required | Default                   | Description                                                                    |
| --------------- | -------- | ------------------------- | ------------------------------------------------------------------------------ |
| `bot-id`        | No       | —                         | Bot ID from Shisho Cloud. Omit for anonymous blocking-only mode.               |
| `set-index-url` | No       | `true`                    | Set to `false` if you manage `pip.conf` yourself and only need the auth token. |
| `registry-url`  | No       | `https://pypi.flatt.tech` | Custom registry URL. Override only if directed by Shisho Cloud support.        |
| `expires-in`    | No       | `1800`                    | Access token lifetime in seconds. Maximum `86400` (24 hours).                  |

For the full list of inputs and outputs, see the [action repository](https://github.com/flatt-security/setup-takumi-guard-pypi).

## Using with Private Packages {#private-packages}

Takumi Guard is a read-only security proxy for public PyPI packages. If your project depends on private packages, you can use `--extra-index-url` to fetch private packages from a separate index while routing public packages through Takumi Guard.

### Extra Index URL {#private-packages-extra-index}

Configure Takumi Guard as the primary index and your private index as an extra source. In `pip.conf`:

```ini
[global]
index-url = https://pypi.flatt.tech/simple/
extra-index-url = https://pypi.your-company.com/simple/
```

Or pass both on the command line:

```bash
pip install \
  --index-url https://pypi.flatt.tech/simple/ \
  --extra-index-url https://pypi.your-company.com/simple/ \
  <package>
```

With this configuration, pip searches both indexes and installs the best matching version.

:::warning
Private packages fetched from an extra index bypass Takumi Guard's security scanning. This is acceptable for your organization's own packages, but be aware that those packages will not be checked against the blocklist.
:::

### GitHub Actions with Private Packages {#private-packages-ci}

When using the `flatt-security/setup-takumi-guard-pypi` action with private packages, let the action configure the Takumi Guard index as usual and add your private index via `PIP_EXTRA_INDEX_URL`:

```yaml
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4

      - uses: flatt-security/setup-takumi-guard-pypi@v1
        with:
          bot-id: "BT01EXAMPLE..."

      # Add your private index as an extra source
      - run: echo "PIP_EXTRA_INDEX_URL=https://pypi.your-company.com/simple/" >> "$GITHUB_ENV"

      - run: pip install -r requirements.txt
      - run: pytest
```

## Publishing {#publishing}

Takumi Guard is a read-only security proxy for package installs. Publishing packages is not affected because `twine upload` and similar tools communicate directly with `https://upload.pypi.org/` (or your configured upload endpoint), not through the index URL.

```bash
twine upload dist/*
```

No changes to your publishing workflow are needed.

## Uninstall {#uninstall}

To stop using Takumi Guard, revert your index URL settings to the default PyPI index.

### Local Environment {#uninstall-local}

Remove the Takumi Guard lines from your `pip.conf`:

```ini
# Remove the following lines
[global]
index-url = https://token:tg_anon_xxxxxx@pypi.flatt.tech/simple/
```

If you set the index URL via an environment variable, unset it:

```bash
unset PIP_INDEX_URL
```

If you use uv, unset the corresponding variable:

```bash
unset UV_INDEX_URL
```

If you added a poetry source, remove it:

```bash
poetry source remove takumi-guard
```

### GitHub Actions {#uninstall-ci}

Remove the `flatt-security/setup-takumi-guard-pypi` step from your workflow file:

```yaml
# Remove the following step
- uses: flatt-security/setup-takumi-guard-pypi@v1
  with:
    bot-id: "BT01EXAMPLE..."
```

:::info
Once the index URL setting is removed, `pip install` will access the public PyPI index directly. No lockfile changes are required.
:::
