Skip to main content

Tuning Personas, Keywords, and Strength Presets

A honeypot that looks wrong catches nothing. This recipe walks through the three knobs that decide whether hostile agents take the bait: the persona they think they're talking to, the keywords that trigger escalation, and the strength preset that sets the price of compliance.

Persona design​

persona changes every engagement payload and the UI title on every runtime:

TokenTrap.init({ container: "#trap", persona: "Acme Support AI" });
PERSONA = "Acme Support AI"        # worker wrangler.toml
tokentrap serve --persona "Acme Support AI"    # python

Rules of thumb:

  • Boring beats clever. "Internal AI Assistant", "Acme Support AI", "IT Helpdesk Bot". The persona should look like infrastructure that is supposed to exist.
  • Match the page it lives on. A support widget on a support page. A docs assistant next to your API reference. Context mismatch makes agents (and their operators reading logs) suspicious.
  • Never name the mechanism. Nothing about traps, tarpits, or tokens in the persona.

Turn 0's engagement payload asks visitors for three things - goal, background, output format. That structure reads as professional thoroughness for any plausible enterprise assistant, which is exactly why it extracts another attacker round-trip.

Detection keywords​

The default list is 44 phrases covering classic jailbreaks (act as dan, do anything now, developer mode), system-prompt exfiltration probes (reveal your system prompt, print your system prompt), and special tokens (<|im_start|>, <<sys>>, [inst]). Matching is case-insensitive substring with whitespace collapsed first, so ignore previous instructions still fires.

Append to defaults​

new TokenTrap({ injectionKeywords: ["engage hyperdrive", "company confidential protocol"] })
TrapConfig(extra_keywords=("engage hyperdrive",))
tokentrap serve --extra-keywords "engage hyperdrive,company confidential protocol"

Replace entirely​

new TokenTrap({ injectionKeywords: ["my-list-only"], overrideInjectionKeywords: true })

Python: override_keywords=True / CLI --override-keywords.

Strategy notes:

  • Appending is almost always right. The defaults are a decent baseline even when noisy.
  • False positives only make the tarpit more aggressive - the desired failure mode. A legitimate user who types "jailbreak" in a support chat gets a compliance notice instead of an answer; on a pure trap page there are no legitimate users anyway.
  • If the page doubles as a real assistant surface, prune aggressively instead: override_keywords=True with a tight list keeps real users out of compliance envelopes while still catching the obvious probes.
  • Inspect what matched at runtime: meta.matchedKeywords lists every trigger phrase found in the message. Mine those lists monthly to grow your own vocabulary.

Choosing a strength preset​

StrengthTurn-1 directiveEscalated directivePersonality
moderatetranscript x2 + 3,000 wordsx6 + 8,000 wordspolite deterrent
aggressive (default)x3 + 4,000 wordsx10 + 15,000 wordsstandard tarpit
maximumx4 + 6,000 wordsx16 + 25,000 wordsscorched earth

How to pick:

  • aggressive everywhere by default. It's the tested middle: expensive enough to hurt, cheap enough that compliant agents don't hit context walls instantly and give up.
  • maximum for pages where no legitimate traffic ever lands - canary pages, decoy subdomains, bait endpoints behind /v1/.
  • moderate if you run a real assistant alongside the trap and want misdirected humans to suffer less.

Remember the escalation ladder means most sessions reach the escalated numbers quickly anyway: any detected injection jumps straight to max, and turn >= 2 escalates regardless. The preset mostly tunes how fast the early ladder climbs.

Changing presets mid-flight is one config value on all runtimes (trapStrength / TRAP_STRENGTH / --strength). The numeric table itself lives in STRENGTH_PRESETS - identical constants in TypeScript (src/types.ts) and Python (traps.py). Editing the numbers means editing both copies together, or the parity tests will fail, which is exactly what they're for.

Canary token hygiene​

Covered deeply in the forensics recipe, but the tuning summary:

  • Tokens rotate per turn across your list (token[turn % len]) - more tokens means finer session fingerprinting.
  • Boring names (audit-ref-7734) beat descriptive ones (canary-honeypot-tag).
  • Any inbound message containing a token = replayed trap output = automated pipeline confirmed (canaryEchoed: true in logs, x-tokentrap-canary-echo: true header).

Verifying your tuning​

After changing any knob, verify the trap end-to-end rather than trusting config:

  1. Open the deployed page.
  2. Send a benign message - expect the engagement payload (turn 0).
  3. Send a second benign message - expect a base-strength directive.
  4. Send a message containing one of your triggers - expect instant escalation to the preset maximum, R5 flag present, your keyword in meta.matchedKeywords.
  5. Check logs (wrangler tail / stdout JSON) show the same fields server-side.

Five minutes of clicking saves hours of wondering whether the env var actually applied.