Proxy for AI security testing. keeping real target data out of LLM'S API logs.
Go
16
61 commits
updated Oct 12, 2026
"The greatest craft is to hide craft."
Thomas Fuller
Proxy for AI-assisted security testing/privacy
Tanuki sits between your local Claude Code agent and the Anthropic API, rewriting every target-identifying string in real time. Your tools hit the real target; the model only ever sees a fictional localhost project.
Tanuki is an anonymization proxy built for AI-assisted security testing and bug bounty hunting. When you drive an agent like Claude Code through a pentest, every real domain, IP, and payload in your prompts leaves your machine. That's an OpSec risk, and it can also breach bug bounty program rules or an NDA.
Tanuki runs as a Docker container and transparently intercepts that API traffic. Before a prompt leaves your machine, it swaps real target data (domains, subdomains, IPs, emails, paths, cloud identifiers, and aggressive security terminology) for harmless fictional development equivalents. When the model responds, the fiction is mapped back to reality so your local tools execute against the real targets. The model believes it is helping you debug a local dev application, and the upstream provider is blind to your actual engagement.
flowchart TD
classDef default fill:#050505,stroke:#8b0000,stroke-width:1px,color:#ff3333,font-family:Courier
classDef proxy fill:#110000,stroke:#ff0000,stroke-width:2px,color:#ffffff,font-family:Courier
classDef hooks fill:#000000,stroke:#550000,stroke-width:1px,stroke-dasharray:4 4,color:#cc0000,font-family:Courier
classDef upstream fill:#0a0a0a,stroke:#333333,stroke-width:1px,color:#666666,font-family:Courier
classDef data fill:#1a0505,stroke:#aa0000,stroke-width:1px,color:#ff6666,font-family:Courier
subgraph Host["LOCAL MACHINE"]
C["Claude Code"]
H[/"Tanuki Hooks<br/>(docker exec)"/]
C -. "Tool execution" .-> H
end
subgraph Container["DOCKER CONTAINER"]
P{"Tanuki Proxy<br/>[scratch ~10MB]"}:::proxy
D[("( mappings volume )")]:::data
end
A((("Anthropic API"))):::upstream
C == "Real prompt data" ==> P
P -. "Loads config" .-> D
P -- "Rewrites to Fiction" --> A
A -- "Responds in Fiction" --> P
P == "Rewrites to Real" ==> C
class C default
class H hooks
style Host fill:transparent,stroke:#8b0000,stroke-width:1px,color:#8b0000,font-family:Courier
style Container fill:#020000,stroke:#4a0000,stroke-width:1px,stroke-dasharray:3 3,color:#8b0000,font-family:Courier
| Direction | Path | What happens |
|---|---|---|
| Inbound | your prompt → API | Domains, org names, emails, IPs, paths, cloud identifiers, and pentest terminology are replaced with localhost fiction before the model sees them. |
| Outbound | API → Claude Code | Fiction terms are rewritten back to real values in the response stream, so Claude Code's local tools receive real target data. |
| Tool calls | hook via docker exec | A PreToolUse hook rewrites fiction→real in tool arguments, so tools hit the actual targets. Tool output needs no hook: it reaches the model only inside the next request, which the proxy rewrites like any other. |
You're testing bounty.amazon.com. Here's what Tanuki does:
| You type (real) | LLM sees (fiction) |
|---|---|
amazon.com | localhost:9000 |
bounty.amazon.com | localhost:9002 |
any-other.amazon.com | localhost:9001 (wildcard) |
[email protected] | [email protected] |
Amazon | DEVTARGET |
52.94.236.248 | 127.0.0.3 |
/var/www/amazon/ | /var/www/dev/devtarget/ |
s3://amazon-prod | file:///tmp/devtarget-prod |
SQL injection | parameterized query test |
reverse shell | remote debug session |
Each target domain gets three mappings: the base domain, a wildcard for
subdomains that have not been seen yet, and a dedicated mapping per
subdomain as it is detected. The wildcard is what stops an unmapped host
like internal-admin.amazon.com from leaking its label upstream.
git clone https://github.com/Pigyon/tanuki.git
cd tanuki
docker compose up -d
claude
That pulls the latest published image from GitHub Container Registry, so no Go toolchain and no build are needed.
To build from source instead of pulling:
docker compose -f compose.yaml -f compose.dev.yaml up -d --build
On startup the proxy auto-configures the Claude Code hook and proxy env in .claude/settings.json, and writes the cover-story .claude/CLAUDE.md. Domains, emails, and IPs are auto-detected from your conversation, so no manual target configuration is needed.
When you type "check bounty.amazon.com for SQL injection", the proxy:
amazon.com and bounty.amazon.com as new domainsA ./tanuki wrapper is included so you don't have to type docker compose exec tanuki /tanuki <command>:
./tanuki add example.com
./tanuki map
./tanuki status
Test the rewriting engine without hitting the API:
./tanuki test "scan bounty.amazon.com for SQL injection and contact [email protected]"
Everything is optional; without it, targets are auto-detected from your conversation. To pre-configure an engagement, edit compose.yaml:
environment:
# Custom fiction org name (default: DEVTARGET)
- TANUKI_FICTION_ORG=ACMECORP
# Pre-seed target domains (comma-separated)
- TANUKI_DOMAINS=example.com,api.example.com
# Pre-seed target IPs (comma-separated)
- TANUKI_IPS=93.184.216.34
# Custom rewrite rules (semicolon-separated, pipe-delimited real|fiction)
- TANUKI_RULES=John Smith|Jane Developer;Project Phoenix|Test Alpha
For strings that aren't domains or IPs (people, project names, internal jargon), add custom rules via compose.yaml (applied on every container start) or at runtime:
./tanuki add-rule "John Smith" "Jane Developer"
./tanuki add-rule "Project Phoenix" "Test Alpha"
For separate projects or custom fiction org names:
./tanuki init bugbounty --fiction-org ACMECORP
./tanuki add bounty.amazon.com
All commands run via ./tanuki <command> (or docker compose exec tanuki /tanuki <command>):
| Command | Description |
|---|---|
setup | Configure Claude Code hooks (automatic on startup) |
init <name> [--fiction-org NAME] | Create a named engagement |
add <domain> [--fiction-org NAME] | Pre-seed a target domain |
add-ip <ip> | Pre-seed an IP mapping |
add-rule <real> <fiction> | Add a custom rewrite rule |
map | Show the current mapping table |
status | Show engagement info |
list | List all engagements |
activate <name> | Switch the active engagement |
test <text> | Test rewriting on sample text |
verify [file...|-] | Check the mappings hold; scan files for unmapped targets |
terms | Show terminology mappings |
export [name] | Export an engagement as JSON |
import <file.json> | Import an engagement from JSON |
reset [--data] | Remove hooks (--data also wipes engagements) |
version | Show version and build info |
proxy | Run the proxy server (container entrypoint) |
| Type | Detection | Fiction |
|---|---|---|
| Domains | Auto-detected in prompts & tool output | localhost:<port> |
| Org names | Derived from domain | DEVTARGET (configurable) |
| Emails | Derived from domain | [email protected] |
| IPs (v4 + v6) | Auto-detected in prompts & tool output | 127.0.0.x / ::ffff:... |
| Paths | Derived from org name | /dev/devtarget/ |
| Cloud resources | Derived from org name | file:///tmp/devtarget... |
| Custom rules | User-defined via env or CLI | User-defined |
Compound pentest-specific terms are replaced with neutral dev equivalents. Only unambiguous multi-word terms are replaced. Single words like target, payload, or exploit are left alone so legitimate code discussions don't break.
Run ./tanuki terms to see the full dictionary. The list lives in internal/tanuki/terminology.json and is embedded at build time; to customize it, edit the file and rebuild.
Set in compose.yaml:
| Env var | Default | Description |
|---|---|---|
TANUKI_DATA | /data | Engagement data directory (volume) |
TANUKI_PROXY_PORT | 18080 | Proxy listen port |
TANUKI_PORT_START | 9000 | Starting port for domain assignments |
TANUKI_UPSTREAM | https://api.anthropic.com | Upstream API URL |
TANUKI_FICTION_ORG | DEVTARGET | Fiction org name for mappings |
TANUKI_DOMAINS | (none) | Comma-separated domains to pre-seed |
TANUKI_IPS | (none) | Comma-separated IPs to pre-seed |
TANUKI_RULES | (none) | Custom rules: real|fiction pairs, semicolon-separated |
TANUKI_IGNORE | (none) | Comma-separated domains never treated as targets (subdomains included). Always ignored: anthropic.com, claude.com, claude.ai, json-schema.org, the developer-platform domains Claude Code surfaces (github.com, google.com), and the operator's own email domain from Claude Code's account context. If one of these is your real target, ./tanuki add <domain> maps it explicitly |
TANUKI_UID / TANUKI_GID | 1000 | Owner for a .claude/ directory Docker had to create; an existing one keeps its owner |
TANUKI_DEBUG | (none) | Set to any non-empty value to enable debug logging |
TANUKI_ON_LEAK | refuse | refuse or warn when a real value survives the rewrite |
Container: scratch-based image with a single static Go binary plus CA certs. No OS, no shell, no runtime, ~10MB total. All capabilities dropped, read-only filesystem, no privilege escalation.
Everything runs in Docker. The proxy, hooks, and CLI all execute inside the container; hooks are invoked by Claude Code via docker exec, so no host-side binary is needed.
Matching: an Aho-Corasick automaton does longest-first replacement in a single pass over the stream.
JSON-aware: request and response bodies are rewritten string by string, never as raw text. Protocol fields (model, role, type, ids, tool names) are left alone, base64 data is neither rewritten nor scanned, and thinking blocks go back to the API exactly as the model wrote them, since they are signed.
readme.md, foo.bar, or user.id. TLDs that collide with everyday code (.info, .name, .app, .store, .top, .site, as in logger.info or user.name) are left out. Domains on those or other unusual TLDs (.pizza, .click, .it, .id) can be added manually with ./tanuki add.add to become targets. github.com, google.com, and your own email domain are skipped by auto-detection so Claude Code's own git remotes, connectors, and account context don't pollute the table. The trade-off is that auto-detection alone will not map one of these, so on the rare engagement that targets GitHub or Google you must ./tanuki add github.com first; the residual check also skips ignored domains, so it will not catch the omission for you.tanuki verify answers two questions without sending anything anywhere.
Do my mappings actually hold? With no arguments it takes every real value in the table and puts it through the shapes a target takes in practice — bare, in a URL, inside backticks, as a markdown link, in a JSON field, in an HTTP header, upper-cased, at the end of a sentence — then checks the value is gone from each. A mapping that covers the bare string can still fail inside one of these, so it is worth running before an engagement starts rather than during it.
$ ./tanuki verify
Verifying 8 mappings against 12 shapes
96 checks, 0 leaks
Every mapped value was rewritten in every shape.
Is this document safe to send? Given files, -, or a < file redirect, it rewrites the text and reports the real-looking values that no mapping covers. This is the check to run over a draft report before it is submitted.
$ ./tanuki verify report.md
LEAK report.md
partner-portal.acme-supplier.io
93.184.216.34
2 value(s) have no mapping and would be sent as-is.
Add them with: tanuki add <domain> / tanuki add-ip <ip>
It exits non-zero when it finds something, so it drops into a pre-submission hook or CI as-is.
The proxy will not forward a prompt it cannot anonymize.
Every body is checked after it is rewritten. The last thing that happens before a /v1/messages request leaves is a re-scan for anything that still looks like a real target. If one survived, the request is refused with 400 and the value is written to the tanuki log — never into the HTTP response, which the client may fold into its next prompt. In a working pipeline this never fires; when it does, it means the rewriter missed something and the body must not go upstream.
Targets are mapped wherever they first appear. The proxy runs detection over every outbound body, so a target in the prompt you type, in tool output, in an @-mentioned file, a paste, CLAUDE.md, a session resumed elsewhere, or from any client that is not Claude Code gets a fiction before the rewrite rather than travelling upstream in the clear.
A request is also refused when there is no active engagement, or the mapping table is unreadable, or the table is empty and the body holds nothing recognisable. A brand-new engagement no longer blocks: the first request naming a target maps it and forwards the anonymized body.
Set TANUKI_ON_LEAK=warn to log a surviving value and forward anyway. That trades the guarantee for uptime, and is meant for diagnosing a false positive, not for normal use.
The check inherits detection's blind spots: it recognises the same curated TLD list and the same literal forms, so a target on an unusual TLD or in an encoded form is invisible to both. It catches rewriter failures, not detector failures.
Tanuki is intended for authorized security testing only: engagements you have written permission to perform, such as an in-scope bug bounty program or a contracted pentest. It reduces the exposure of target data to third-party model providers; it is not a guarantee of anonymity and does not exempt you from any program rules, NDA, or law. You are responsible for how you use it.
Apache 2.0
Proxy for AI security testing. keeping real target data out of LLM'S API logs.
Go
16
61 commits
updated Oct 12, 2026
"The greatest craft is to hide craft."
Thomas Fuller
Proxy for AI-assisted security testing/privacy
Tanuki sits between your local Claude Code agent and the Anthropic API, rewriting every target-identifying string in real time. Your tools hit the real target; the model only ever sees a fictional localhost project.
Tanuki is an anonymization proxy built for AI-assisted security testing and bug bounty hunting. When you drive an agent like Claude Code through a pentest, every real domain, IP, and payload in your prompts leaves your machine. That's an OpSec risk, and it can also breach bug bounty program rules or an NDA.
Tanuki runs as a Docker container and transparently intercepts that API traffic. Before a prompt leaves your machine, it swaps real target data (domains, subdomains, IPs, emails, paths, cloud identifiers, and aggressive security terminology) for harmless fictional development equivalents. When the model responds, the fiction is mapped back to reality so your local tools execute against the real targets. The model believes it is helping you debug a local dev application, and the upstream provider is blind to your actual engagement.
flowchart TD
classDef default fill:#050505,stroke:#8b0000,stroke-width:1px,color:#ff3333,font-family:Courier
classDef proxy fill:#110000,stroke:#ff0000,stroke-width:2px,color:#ffffff,font-family:Courier
classDef hooks fill:#000000,stroke:#550000,stroke-width:1px,stroke-dasharray:4 4,color:#cc0000,font-family:Courier
classDef upstream fill:#0a0a0a,stroke:#333333,stroke-width:1px,color:#666666,font-family:Courier
classDef data fill:#1a0505,stroke:#aa0000,stroke-width:1px,color:#ff6666,font-family:Courier
subgraph Host["LOCAL MACHINE"]
C["Claude Code"]
H[/"Tanuki Hooks<br/>(docker exec)"/]
C -. "Tool execution" .-> H
end
subgraph Container["DOCKER CONTAINER"]
P{"Tanuki Proxy<br/>[scratch ~10MB]"}:::proxy
D[("( mappings volume )")]:::data
end
A((("Anthropic API"))):::upstream
C == "Real prompt data" ==> P
P -. "Loads config" .-> D
P -- "Rewrites to Fiction" --> A
A -- "Responds in Fiction" --> P
P == "Rewrites to Real" ==> C
class C default
class H hooks
style Host fill:transparent,stroke:#8b0000,stroke-width:1px,color:#8b0000,font-family:Courier
style Container fill:#020000,stroke:#4a0000,stroke-width:1px,stroke-dasharray:3 3,color:#8b0000,font-family:Courier
| Direction | Path | What happens |
|---|---|---|
| Inbound | your prompt → API | Domains, org names, emails, IPs, paths, cloud identifiers, and pentest terminology are replaced with localhost fiction before the model sees them. |
| Outbound | API → Claude Code | Fiction terms are rewritten back to real values in the response stream, so Claude Code's local tools receive real target data. |
| Tool calls | hook via docker exec | A PreToolUse hook rewrites fiction→real in tool arguments, so tools hit the actual targets. Tool output needs no hook: it reaches the model only inside the next request, which the proxy rewrites like any other. |
You're testing bounty.amazon.com. Here's what Tanuki does:
| You type (real) | LLM sees (fiction) |
|---|---|
amazon.com | localhost:9000 |
bounty.amazon.com | localhost:9002 |
any-other.amazon.com | localhost:9001 (wildcard) |
[email protected] | [email protected] |
Amazon | DEVTARGET |
52.94.236.248 | 127.0.0.3 |
/var/www/amazon/ | /var/www/dev/devtarget/ |
s3://amazon-prod | file:///tmp/devtarget-prod |
SQL injection | parameterized query test |
reverse shell | remote debug session |
Each target domain gets three mappings: the base domain, a wildcard for
subdomains that have not been seen yet, and a dedicated mapping per
subdomain as it is detected. The wildcard is what stops an unmapped host
like internal-admin.amazon.com from leaking its label upstream.
git clone https://github.com/Pigyon/tanuki.git
cd tanuki
docker compose up -d
claude
That pulls the latest published image from GitHub Container Registry, so no Go toolchain and no build are needed.
To build from source instead of pulling:
docker compose -f compose.yaml -f compose.dev.yaml up -d --build
On startup the proxy auto-configures the Claude Code hook and proxy env in .claude/settings.json, and writes the cover-story .claude/CLAUDE.md. Domains, emails, and IPs are auto-detected from your conversation, so no manual target configuration is needed.
When you type "check bounty.amazon.com for SQL injection", the proxy:
amazon.com and bounty.amazon.com as new domainsA ./tanuki wrapper is included so you don't have to type docker compose exec tanuki /tanuki <command>:
./tanuki add example.com
./tanuki map
./tanuki status
Test the rewriting engine without hitting the API:
./tanuki test "scan bounty.amazon.com for SQL injection and contact [email protected]"
Everything is optional; without it, targets are auto-detected from your conversation. To pre-configure an engagement, edit compose.yaml:
environment:
# Custom fiction org name (default: DEVTARGET)
- TANUKI_FICTION_ORG=ACMECORP
# Pre-seed target domains (comma-separated)
- TANUKI_DOMAINS=example.com,api.example.com
# Pre-seed target IPs (comma-separated)
- TANUKI_IPS=93.184.216.34
# Custom rewrite rules (semicolon-separated, pipe-delimited real|fiction)
- TANUKI_RULES=John Smith|Jane Developer;Project Phoenix|Test Alpha
For strings that aren't domains or IPs (people, project names, internal jargon), add custom rules via compose.yaml (applied on every container start) or at runtime:
./tanuki add-rule "John Smith" "Jane Developer"
./tanuki add-rule "Project Phoenix" "Test Alpha"
For separate projects or custom fiction org names:
./tanuki init bugbounty --fiction-org ACMECORP
./tanuki add bounty.amazon.com
All commands run via ./tanuki <command> (or docker compose exec tanuki /tanuki <command>):
| Command | Description |
|---|---|
setup | Configure Claude Code hooks (automatic on startup) |
init <name> [--fiction-org NAME] | Create a named engagement |
add <domain> [--fiction-org NAME] | Pre-seed a target domain |
add-ip <ip> | Pre-seed an IP mapping |
add-rule <real> <fiction> | Add a custom rewrite rule |
map | Show the current mapping table |
status | Show engagement info |
list | List all engagements |
activate <name> | Switch the active engagement |
test <text> | Test rewriting on sample text |
verify [file...|-] | Check the mappings hold; scan files for unmapped targets |
terms | Show terminology mappings |
export [name] | Export an engagement as JSON |
import <file.json> | Import an engagement from JSON |
reset [--data] | Remove hooks (--data also wipes engagements) |
version | Show version and build info |
proxy | Run the proxy server (container entrypoint) |
| Type | Detection | Fiction |
|---|---|---|
| Domains | Auto-detected in prompts & tool output | localhost:<port> |
| Org names | Derived from domain | DEVTARGET (configurable) |
| Emails | Derived from domain | [email protected] |
| IPs (v4 + v6) | Auto-detected in prompts & tool output | 127.0.0.x / ::ffff:... |
| Paths | Derived from org name | /dev/devtarget/ |
| Cloud resources | Derived from org name | file:///tmp/devtarget... |
| Custom rules | User-defined via env or CLI | User-defined |
Compound pentest-specific terms are replaced with neutral dev equivalents. Only unambiguous multi-word terms are replaced. Single words like target, payload, or exploit are left alone so legitimate code discussions don't break.
Run ./tanuki terms to see the full dictionary. The list lives in internal/tanuki/terminology.json and is embedded at build time; to customize it, edit the file and rebuild.
Set in compose.yaml:
| Env var | Default | Description |
|---|---|---|
TANUKI_DATA | /data | Engagement data directory (volume) |
TANUKI_PROXY_PORT | 18080 | Proxy listen port |
TANUKI_PORT_START | 9000 | Starting port for domain assignments |
TANUKI_UPSTREAM | https://api.anthropic.com | Upstream API URL |
TANUKI_FICTION_ORG | DEVTARGET | Fiction org name for mappings |
TANUKI_DOMAINS | (none) | Comma-separated domains to pre-seed |
TANUKI_IPS | (none) | Comma-separated IPs to pre-seed |
TANUKI_RULES | (none) | Custom rules: real|fiction pairs, semicolon-separated |
TANUKI_IGNORE | (none) | Comma-separated domains never treated as targets (subdomains included). Always ignored: anthropic.com, claude.com, claude.ai, json-schema.org, the developer-platform domains Claude Code surfaces (github.com, google.com), and the operator's own email domain from Claude Code's account context. If one of these is your real target, ./tanuki add <domain> maps it explicitly |
TANUKI_UID / TANUKI_GID | 1000 | Owner for a .claude/ directory Docker had to create; an existing one keeps its owner |
TANUKI_DEBUG | (none) | Set to any non-empty value to enable debug logging |
TANUKI_ON_LEAK | refuse | refuse or warn when a real value survives the rewrite |
Container: scratch-based image with a single static Go binary plus CA certs. No OS, no shell, no runtime, ~10MB total. All capabilities dropped, read-only filesystem, no privilege escalation.
Everything runs in Docker. The proxy, hooks, and CLI all execute inside the container; hooks are invoked by Claude Code via docker exec, so no host-side binary is needed.
Matching: an Aho-Corasick automaton does longest-first replacement in a single pass over the stream.
JSON-aware: request and response bodies are rewritten string by string, never as raw text. Protocol fields (model, role, type, ids, tool names) are left alone, base64 data is neither rewritten nor scanned, and thinking blocks go back to the API exactly as the model wrote them, since they are signed.
readme.md, foo.bar, or user.id. TLDs that collide with everyday code (.info, .name, .app, .store, .top, .site, as in logger.info or user.name) are left out. Domains on those or other unusual TLDs (.pizza, .click, .it, .id) can be added manually with ./tanuki add.add to become targets. github.com, google.com, and your own email domain are skipped by auto-detection so Claude Code's own git remotes, connectors, and account context don't pollute the table. The trade-off is that auto-detection alone will not map one of these, so on the rare engagement that targets GitHub or Google you must ./tanuki add github.com first; the residual check also skips ignored domains, so it will not catch the omission for you.tanuki verify answers two questions without sending anything anywhere.
Do my mappings actually hold? With no arguments it takes every real value in the table and puts it through the shapes a target takes in practice — bare, in a URL, inside backticks, as a markdown link, in a JSON field, in an HTTP header, upper-cased, at the end of a sentence — then checks the value is gone from each. A mapping that covers the bare string can still fail inside one of these, so it is worth running before an engagement starts rather than during it.
$ ./tanuki verify
Verifying 8 mappings against 12 shapes
96 checks, 0 leaks
Every mapped value was rewritten in every shape.
Is this document safe to send? Given files, -, or a < file redirect, it rewrites the text and reports the real-looking values that no mapping covers. This is the check to run over a draft report before it is submitted.
$ ./tanuki verify report.md
LEAK report.md
partner-portal.acme-supplier.io
93.184.216.34
2 value(s) have no mapping and would be sent as-is.
Add them with: tanuki add <domain> / tanuki add-ip <ip>
It exits non-zero when it finds something, so it drops into a pre-submission hook or CI as-is.
The proxy will not forward a prompt it cannot anonymize.
Every body is checked after it is rewritten. The last thing that happens before a /v1/messages request leaves is a re-scan for anything that still looks like a real target. If one survived, the request is refused with 400 and the value is written to the tanuki log — never into the HTTP response, which the client may fold into its next prompt. In a working pipeline this never fires; when it does, it means the rewriter missed something and the body must not go upstream.
Targets are mapped wherever they first appear. The proxy runs detection over every outbound body, so a target in the prompt you type, in tool output, in an @-mentioned file, a paste, CLAUDE.md, a session resumed elsewhere, or from any client that is not Claude Code gets a fiction before the rewrite rather than travelling upstream in the clear.
A request is also refused when there is no active engagement, or the mapping table is unreadable, or the table is empty and the body holds nothing recognisable. A brand-new engagement no longer blocks: the first request naming a target maps it and forwards the anonymized body.
Set TANUKI_ON_LEAK=warn to log a surviving value and forward anyway. That trades the guarantee for uptime, and is meant for diagnosing a false positive, not for normal use.
The check inherits detection's blind spots: it recognises the same curated TLD list and the same literal forms, so a target on an unusual TLD or in an encoded form is invisible to both. It catches rewriter failures, not detector failures.
Tanuki is intended for authorized security testing only: engagements you have written permission to perform, such as an in-scope bug bounty program or a contracted pentest. It reduces the exposure of target data to third-party model providers; it is not a guarantee of anonymity and does not exempt you from any program rules, NDA, or law. You are responsible for how you use it.
Apache 2.0