# Go Modules {#golang}

Takumi Guard speaks the [GOPROXY protocol](https://go.dev/ref/mod#goproxy-protocol), so you can route `go get`, `go mod download`, and `go build` through it the same way you'd point at any other corporate Go module proxy. This page covers setup for local development and CI.

## Setup {#setup}

Takumi Guard offers three ways to get started for Go:

- **[Anonymous](#setup-anonymous)** — No token required. Set `GOPROXY` to enable package blocking.
- **[Email-Verified](#setup-email-verified)** — Use an email-verified token (`tg_anon_…`) for download tracking and breach notifications.
- **[Org User Token](#setup-org-user-token)** — Use an org user token (`tg_org_…`) to track installations across your organization.

:::info Paid Feature
Org user tokens require an active base subscription with Guard enabled. See [Pricing & Billing](/docs/t/guard/billing/index.md) for details.
:::

### Anonymous Usage {#setup-anonymous}

You can use Takumi Guard's package blocking without authentication. Set the `GOPROXY` environment variable and all module fetches route through the proxy:

```bash
go env -w GOPROXY=https://golang.flatt.tech
```

That's it. All `go mod download`, `go get`, and `go build` calls now route through Takumi Guard for module metadata, and artifact (`.zip`) downloads are transparently redirected to `proxy.golang.org` to keep download speeds fast.

Set `GOPROXY` to the bare URL only — don't append a `,direct` or `|direct` fallback, or Takumi Guard can be silently bypassed. See [details](#goproxy-no-fallback).

:::tip Toolchain compatibility
Takumi Guard supports the Go toolchain at version 1.21 or later. Older versions use a less strict GOPROXY protocol and have not been validated.
:::

### 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 module you previously downloaded, a notification is sent to your registered email address. No Shisho Cloud account is required, and this is free of charge.

:::info
If you already have an org user token or email-verified token from using Takumi Guard with npm, PyPI, or RubyGems, you don't need to register again — the same token works for Go modules.
:::

**Step 1: Register your email**

```bash
curl -X POST https://golang.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://golang.flatt.tech/api/v1/tokens/regenerate`
:::

**Step 3: Configure the Go toolchain to send the token**

The Go toolchain authenticates to GOPROXY servers using `.netrc` HTTP Basic auth. The username is ignored; the token goes in the password field.

```bash
# 1. Add a line to ~/.netrc
echo "machine golang.flatt.tech login token password tg_anon_xxxxxx" >> ~/.netrc
chmod 600 ~/.netrc

# 2. Point GOPROXY at the registry (if not already done)
go env -w GOPROXY=https://golang.flatt.tech
```

The toolchain now authenticates with your `tg_anon_` token on every module fetch, enabling download tracking and breach notifications. Set `GOPROXY` to the bare URL only — no `,direct` or `|direct` fallback. See [details](#goproxy-no-fallback).

### Org User Tokens {#setup-org-user-token}

Org user tokens (`tg_org_…`) can be issued from the Takumi / Shisho Cloud console, or by a bot via the Guard API. See [Token Management](/docs/t/guard/features/token-management.md#user-tokens) for details on issuing tokens.

:::info
A single `tg_org_` token works across all Takumi Guard ecosystems (npm, PyPI, RubyGems, Go). If you have already issued a token for another ecosystem, the same token can be used here.
:::

Once you have a token, write it to `~/.netrc` and set `GOPROXY`:

```bash
echo "machine golang.flatt.tech login token password tg_org_xxxxxx" >> ~/.netrc
chmod 600 ~/.netrc
go env -w GOPROXY=https://golang.flatt.tech
```

Your `go mod download` commands now authenticate with the org user token, enabling [organization-wide install tracking](/docs/t/guard/features/installation-logs.md) and organization-level breach notifications (Slack, webhook, etc.). Set `GOPROXY` to the bare URL only — no `,direct` or `|direct` fallback. See [details](#goproxy-no-fallback).

### About configuring with `GOPROXY` {#goproxy-no-fallback}

Whichever tier you use, you set the same proxy URL with `go env -w GOPROXY=https://golang.flatt.tech`. Keep the following two points in mind for that setting.

#### Don't add a fallback

Set `GOPROXY` to `https://golang.flatt.tech` only. Don't append `,direct` or `|direct`.

Adding either fallback makes the Go toolchain **fetch modules directly from VCS** whenever the proxy returns an error. As a result, modules that are not yet indexed (which the proxy returns as `404`) — and, if you use `|direct`, even modules that are explicitly blocked (`403`) — can be fetched **without going through Takumi Guard**.

For the blocklist to apply in full, `GOPROXY` must be set to the proxy URL only.

Your organization's own private modules should not be routed through this proxy — exclude them with `GOPRIVATE`, as described in [Using with Private Modules](#private-modules).

#### Persisting the setting

The `GOPROXY` value you set with `go env -w` is saved to `$(go env GOENV)` (typically `~/.config/go/env`), so it persists across shells and reboots.

Use `export GOPROXY=…` if you only want it for the current shell session.

### GitHub Actions {#setup-ci}

To integrate Takumi Guard into your GitHub Actions workflow, use the `flatt-security/setup-takumi-guard-golang` 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: actions/setup-go@v5
        with:
          go-version: "1.23"

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

      - run: go build ./...
      - run: go test ./...
```

In anonymous mode, the action only configures `GOPROXY=https://golang.flatt.tech`. Blocked modules 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: actions/setup-go@v5
        with:
          go-version: "1.23"

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

      - run: go build ./...
      - run: go test ./...
```

The action handles the full OIDC exchange automatically:

1. Requests a GitHub OIDC token (with the registry host as audience)
2. Exchanges it for a short-lived Takumi Guard access token via the STS service
3. Writes the token to `~/.netrc` with mode `0600` and sets `GOPROXY=https://golang.flatt.tech`

:::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). If authentication fails (invalid `bot-id`, missing OIDC permission, STS unreachable, etc.), the step exits with a clear error message — there is no silent fallback to anonymous mode.

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

| Input          | Required | Default                        | Description                                                             |
| -------------- | -------- | ------------------------------ | ----------------------------------------------------------------------- |
| `bot-id`       | No       | —                              | Bot ID from Shisho Cloud. Omit for anonymous blocking-only mode.        |
| `set-goproxy`  | No       | `true`                         | Set to `false` if you manage `GOPROXY` yourself.                        |
| `registry-url` | No       | `https://golang.flatt.tech`    | Custom registry URL. Override only if directed by Shisho Cloud support. |
| `sts-url`      | No       | `https://sts.cloud.shisho.dev` | STS service URL used for the OIDC → access-token exchange.              |
| `expires-in`   | No       | `1800` (seconds)               | 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-golang).

## Using with Private Modules {#private-modules}

Takumi Guard is a read-only security proxy for public Go modules. If your project depends on private modules (e.g. modules under your company's GitHub organization), you need to configure the Go toolchain so that private modules bypass Takumi Guard and are fetched directly from VCS.

### `GOPRIVATE` {#private-modules-goprivate}

The Go toolchain has a built-in environment variable for this. `GOPRIVATE` is a comma-separated list of glob patterns; modules whose paths match are fetched directly from source (using your existing `git` credentials) and skip both the proxy and the checksum database (`sum.golang.org`).

```bash
go env -w GOPROXY=https://golang.flatt.tech
go env -w GOPRIVATE=github.com/your-org/*,*.internal.your-corp.com
```

With this configuration, the toolchain routes requests as follows:

- `github.com/spf13/cobra` (public) → fetched via Takumi Guard
- `github.com/your-org/private-repo` (matches `GOPRIVATE`) → fetched directly from VCS via `git`, bypasses Takumi Guard
- `internal.your-corp.com/team/lib` (matches `GOPRIVATE`) → same: direct VCS, bypasses Takumi Guard

:::tip
You don't need to put the Takumi Guard URL or API key in your `go.mod` or `go.sum`. The `.netrc` entry handles authentication, and `GOPRIVATE` keeps private module paths out of any proxy entirely.
:::

:::warning
Private modules routed directly via VCS bypass Takumi Guard's security scanning. This is acceptable for your organization's own modules, but be aware that those modules are not checked against the blocklist or verified against `sum.golang.org`.
:::

## Verify Your Setup {#verify-setup}

To confirm that Takumi Guard is working, try installing the harmless test module `github.com/flatt-security/hola-takumi-go` at the blocked version `v0.1.0`. `hola-takumi-go` is a harmless test module published by GMO Flatt Security for verifying Takumi Guard's behavior.

```bash
cd $(mktemp -d) && go mod init verify-takumi-guard && go get github.com/flatt-security/hola-takumi-go@v0.1.0
```

If Takumi Guard is configured correctly, the proxy filters out this version and `go get` fails with the following error:

```
go: github.com/flatt-security/hola-takumi-go@v0.1.0: reading https://golang.flatt.tech/github.com/flatt-security/hola-takumi-go/@v/v0.1.0.info: 403 Forbidden
	server response: Forbidden
```

:::note
If `hola-takumi-go v0.1.0` is already in your module cache, the toolchain uses the local copy instead of fetching. Clear the relevant module cache entry first:

```bash
go clean -modcache  # nuclear option: clears everything
# OR more targeted:
rm -rf "$(go env GOMODCACHE)/github.com/flatt-security/hola-takumi-go@v0.1.0"
```

:::

## Publishing {#publishing}

Takumi Guard is a read-only security proxy. Go modules are not "published" to a central registry the way npm packages are — `proxy.golang.org` indexes any tagged commit in any public VCS, so Takumi Guard does not affect how you release your modules. Tag and push to your VCS as usual.

## Uninstall {#uninstall}

To stop using Takumi Guard, unset the `GOPROXY` configuration.

### Local Environment {#uninstall-local}

```bash
# 1. Reset GOPROXY to the public default
go env -u GOPROXY                      # or: go env -w GOPROXY=https://proxy.golang.org,direct

# 2. Remove the Takumi Guard line from ~/.netrc
sed -i.bak '/^machine golang\.flatt\.tech /d' ~/.netrc
```

### GitHub Actions {#uninstall-ci}

Remove the `GOPROXY` env var and the `.netrc` configuration step from your workflow:

```yaml
# Remove the following:
# env:
#   GOPROXY: https://golang.flatt.tech
# - name: Configure Takumi Guard token
#   run: echo "machine golang.flatt.tech ..." > ~/.netrc
```

:::info
Once these are removed, `go build` will use the default `https://proxy.golang.org,direct`. No changes to `go.mod` or `go.sum` are required.
:::

### Revoking Org User Tokens {#uninstall-org-token}

If you are using org user tokens (`tg_org_…`), revoke them from **Guard** > **Tokens** in Shisho Cloud console in addition to updating your `.netrc`. Active tokens continue to be billed. See [Pricing](/docs/t/guard/billing/pricing.md) for details.

## Quick Reference {#quick-reference}

Minimum configuration for each usage tier. Replace `tg_anon_xxxxxx` / `tg_org_xxxxxx` with your actual token.

### Anonymous {#quick-reference-anonymous}

```bash
go env -w GOPROXY=https://golang.flatt.tech
```

### Anonymous (email-verified) {#quick-reference-email}

```bash
echo "machine golang.flatt.tech login token password tg_anon_xxxxxx" >> ~/.netrc
chmod 600 ~/.netrc
go env -w GOPROXY=https://golang.flatt.tech
```

### Organization {#quick-reference-org}

```bash
echo "machine golang.flatt.tech login token password tg_org_xxxxxx" >> ~/.netrc
chmod 600 ~/.netrc
go env -w GOPROXY=https://golang.flatt.tech
```

### With Private Modules {#quick-reference-private}

```bash
echo "machine golang.flatt.tech login token password tg_org_xxxxxx" >> ~/.netrc
chmod 600 ~/.netrc
go env -w GOPROXY=https://golang.flatt.tech
go env -w GOPRIVATE=github.com/your-org/*,*.internal.your-corp.com
```
