Back to updates
New releaseJul 21, 2026

honeyprompt v0.1.8

LLM-first deception framework: "The honeypot that talks back!™"

Share

honeyprompt

banner

Introducing honeyprompt, an LLM-first deception framework made by/for web developers. The personal passion project of @alectrocute.

Supports all major cloud and local LLM providers. SSH, HTTP, TLS, TCP, telnet and more. It ships as a small container (and a single static binary) and keeps every knob in one honeyprompt.yaml.

No plugins to compile, no database to run, easily extendable and can be deployed on low-end hardware.

Demo instance

A demo instance is available at 172.233.151.216, with the unauthenticated web panel here: http://172.233.151.216:9090. It is a public instance of honeyprompt running on a cheap Linode VPS, with openrouter/free as the sole LLM provider/model.

Quick start

For easiest setup in 2026, we recommend Docker and OpenRouter/openrouter/free as the LLM provider. All major cloud and local LLM providers are supported. Three files and one command stand up the full default deployment: seven LLM-backed decoys, durable event storage and the operator panel.

1. Grab the default config, compose file, and env template:

# if you don't have Docker:
# curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh

mkdir honeypot && cd honeypot
wget https://raw.githubusercontent.com/alectrocute/honeyprompt/main/honeyprompt.yaml
wget https://raw.githubusercontent.com/alectrocute/honeyprompt/main/compose.yaml
wget -O .env https://raw.githubusercontent.com/alectrocute/honeyprompt/main/.env.example

(Or clone the repo and cd into it — same three files.)

2. Fill in .env. Two values are required:

OPENROUTER_API_KEY=sk-or-...            # use a dedicated key with a spend limit
HONEYPROMPT_PANEL_PASSWORD=changeme     # basic-auth password for the panel

3. Start it:

docker compose up -d

4. Poke it:

ssh -p 2222 root@localhost            # password: root — then type anything
curl http://localhost:2375/v1.54/containers/json   # "exposed" Docker API

5. Watch it happen in the read-only panel at http://127.0.0.1:9090 (sign in as admin with your panel password). Every connection, credential, and command streams in live. If you are deployed to a remote host, you'll need to expose the :9090 port in compose.yaml. This is not recommended for production deployments.

Pin a numbered release instead of latest for production deployments — set HONEYPROMPT_IMAGE in .env.

The honeyprompt.yaml you just downloaded is a fully annotated showcase. It ships profiles for:

  • A generic corporate web server — port 80, the widest net; / serves the stock nginx welcome page instantly, and deeper paths fall through to the LLM for full HTML/CSS intranet pages, login forms, and admin panels built to keep the attacker clicking.
  • MCP / agent gateways — Streamable HTTP discovery, OAuth metadata, JSON-RPC tool calls, and tempting production tools.
  • Docker Engine API 29.5 — the unauthenticated port 2375 surface used by real cloud worms.
  • Kubernetes API v1.36 — namespace, workload, Secret, ConfigMap, and RBAC discovery.
  • Ubuntu 26.04 AI build infrastructure — SSH, GPU workloads, Docker, kubeconfigs, CI state, and provider credentials.
  • Redis 8.8 — common RESP probes used for credential theft, persistence, and lateral movement.
  • Industrial edge / OT — an intentionally legacy Telnet management plane, because modern defense still has to catch attacks against old infrastructure.

Running without an LLM

[!IMPORTANT] Even if you're using LLMs, determine the most frequently used paths and add static rules for them. This will save you massive amounts of LLM tokens and speed up responses to requests that are not worth the cost of an LLM call. Random examples: whoami, health checks, favicon, version probes, etc.

This minimal honeyprompt.yaml fakes an SSH box with two static rules and no LLM:

panel:
  enabled: true
  address: "0.0.0.0:8080"

events:
  buffer: 2000
  file: /data/events.jsonl # durable attacker activity

services:
  - protocol: ssh
    address: "0.0.0.0:2222"
    description: "Ubuntu 26.04 LTS build runner"
    serverName: "gpu-runner-07"
    passwordRegex: "^(root|admin|123456)$" # which passwords "work"
    commands:
      - regex: "^whoami$"
        handler: "root"
      - regex: "^(.+)$"
        handler: "bash: command not found"
docker run --rm \
  -p 2222:2222 -p 8080:8080 \
  -v "$(pwd)/honeyprompt.yaml:/etc/honeyprompt/honeyprompt.yaml:ro" \
  -v honeyprompt-data:/data \
  alectrocute/honeyprompt:latest

Deployment

For a persistent deployment, use the included compose.yaml. The deployment guide covers Docker Hub releases, required GitHub secrets, port and firewall setup, panel access over SSH, upgrades, rollback, event storage, and isolation.

Why LLM-first deception, briefly

A honeypot only has to do one thing well: stay convincing long enough that the attacker keeps typing. Every command they run is intelligence — the tools they reach for, the credentials they reuse, the CVEs they assume you haven't patched. Static honeypots break character the moment someone runs a command the author didn't anticipate. honeyprompt hands that moment to an LLM, so the shell answers dmesg | tail or cat /etc/shadow the way a real one would, and the session keeps going.

Check out Adel Karimi's excellent DEF CON 32 presentation on Galah, (the first?) LLM honeypot, which inspired this project: https://www.youtube.com/watch?v=XGsm4Qcc_Ag

What gets logged: two separate streams

This is the part worth understanding up front, because the two are deliberately kept apart:

  • Deception events: Every attacker interaction: connections, auth attempts, each command or request, the response honeyprompt sent back, which provider and model answered, and how long it took. This is your threat intel. It's held in a bounded in-memory buffer for the live panel and you can persist all of it to disk.
  • Operational logs: Startup, which ports it bound, provider failures, shutdown, internal errors. This is what you read when the runtime misbehaves. It has nothing to do with attacker activity.

You configure them separately:

# The honey: attacker activity.
events:
  buffer: 2000 # recent events kept in memory for the panel
  file: /data/events.jsonl # persist every event as JSON Lines

# The runtime's own diagnostics.
logging:
  level: info # debug | info | warn | error
  format: text # how it looks on the console: text (human) or json
  file: /data/honeyprompt.log # optional; on disk it's always JSON

events.jsonl is one self-contained JSON object per line — ready to tail -f, ship to a SIEM, or replay with jq. The Docker commands above mount the named volume honeyprompt-data at /data, so events survive container replacement. Both files are appended to and flushed on a clean shutdown.

format only affects how operational logs are rendered to the console; the operational log file, when enabled, is always structured JSON so it's easy to parse.

The web panel

screenshot

An optional, read-only dashboard streams deception events as they happen, breaks them down by protocol, and exports everything to JSON with one click:

Categories