Table of Contents
Environment Variables
DECNET reads configuration from process environment. On import, decnet/env.py
loads .env.local first (preferred, git-ignored) then .env from the project
root. Any variable already present in the shell environment wins over both
files.
Only the variables listed below are recognised. Anything else is noise.
- Source of truth:
decnet/env.py - Starter template:
env.config.example
See also: DB drivers, Logging, Systemd, Tracing.
Validation rules
Two validators live in decnet/env.py:
_port(name, default)— integer in[1, 65535]. Applies toDECNET_API_PORT,DECNET_WEB_PORT,DECNET_DB_PORT._require_env(name)— variable must be set, and must not be a known-bad default. Under pytest (PYTEST*env var present) the bad-value check is skipped so test fixtures can use sentinel values.
Known-bad-values block list
_require_env rejects these case-insensitive literals:
adminsecretpasswordchangemefallback-secret-key-change-me
JWT secret length rule
When name == "DECNET_JWT_SECRET", the value must be at least 32 bytes.
This matches HS256's minimum key length (RFC 7518 §3.2 — "A key of the same
size as the hash output [...] or larger MUST be used"). The check is relaxed
when DECNET_DEVELOPER=true.
System logging
| Name | Type | Default | Required | Consequence |
|---|---|---|---|---|
DECNET_SYSTEM_LOGS |
path | decnet.system.log |
No | Destination for the RFC 5424 RotatingFileHandler installed by decnet/config.py. All microservice daemons (api, sniffer, profiler, collector) append here. Skipped under pytest. |
Embedded workers
These are escape hatches — leave them unset in normal deployments. decnet deploy always spawns standalone daemons, and embedding the same worker inside
the API duplicates DB writes and sniffer packets.
| Name | Type | Default | Required | Consequence |
|---|---|---|---|---|
DECNET_EMBED_PROFILER |
bool (true/other) |
false |
No | Embed profiler in API process. Do not combine with decnet profiler --daemon. |
DECNET_EMBED_SNIFFER |
bool | false |
No | Embed MACVLAN sniffer in API process. Do not combine with decnet sniffer --daemon. |
Request profiling (Pyinstrument)
| Name | Type | Default | Required | Consequence |
|---|---|---|---|---|
DECNET_PROFILE_REQUESTS |
bool | false |
No | Mount Pyinstrument ASGI middleware on the FastAPI app. Writes per-request HTML flamegraphs. |
DECNET_PROFILE_DIR |
path | profiles |
No | Output directory for flamegraphs. Relative paths are relative to $PWD. |
API server
| Name | Type | Default | Required | Consequence |
|---|---|---|---|---|
DECNET_API_HOST |
str | 127.0.0.1 |
No | Bind address for the FastAPI server. |
DECNET_API_PORT |
int (1–65535) | 8000 |
No | TCP port for the API. |
DECNET_JWT_SECRET |
str (≥32 chars) | — | Yes | HS256 signing secret. Missing, known-bad, or short values abort startup unless DECNET_DEVELOPER=true (and even then, known-bad is still rejected). |
DECNET_INGEST_LOG_FILE |
path | /var/log/decnet/decnet.log |
No | File the ingester tails for honeypot events. |
Ingester batching
| Name | Type | Default | Required | Consequence |
|---|---|---|---|---|
DECNET_BATCH_SIZE |
int | 100 |
No | Rows accumulated per DB commit. Larger batches reduce SQLite write-lock contention. |
DECNET_BATCH_MAX_WAIT_MS |
int | 250 |
No | Maximum milliseconds to wait before flushing a partial batch. Bounds latency during idle periods. |
Web dashboard
| Name | Type | Default | Required | Consequence |
|---|---|---|---|---|
DECNET_WEB_HOST |
str | 127.0.0.1 |
No | Bind address for the web dashboard. |
DECNET_WEB_PORT |
int (1–65535) | 8080 |
No | Web dashboard port. |
DECNET_ADMIN_USER |
str | admin |
No* | Admin login. admin is a known-bad default and is rejected at startup outside pytest. |
DECNET_ADMIN_PASSWORD |
str | admin |
No* | Admin password. Rejected if set to a known-bad value. Change both. |
DECNET_DEVELOPER |
bool | false |
No | true enables DEBUG logging and relaxes the JWT length check. Does not enable tracing. |
*The defaults exist so imports do not crash, but the web API refuses to start with them in non-pytest environments.
Tracing (OpenTelemetry)
Independent from DECNET_DEVELOPER so tracing can be toggled on its own.
| Name | Type | Default | Required | Consequence |
|---|---|---|---|---|
DECNET_DEVELOPER_TRACING |
bool | false |
No | Enable OpenTelemetry tracing for the API and workers. |
DECNET_OTEL_ENDPOINT |
URL | http://localhost:4317 |
No | OTLP gRPC collector endpoint. |
Database
See Database Drivers for the full driver matrix.
| Name | Type | Default | Required | Consequence |
|---|---|---|---|---|
DECNET_DB_TYPE |
sqlite | mysql |
sqlite |
No | Selects the repository subclass. Lower-cased automatically. |
DECNET_DB_URL |
SQLAlchemy URL | unset | No | Full URL, e.g. mysql+asyncmy://user:pass@host:3306/decnet. When set, all component vars below are ignored. |
DECNET_DB_HOST |
str | localhost |
No | MySQL host. |
DECNET_DB_PORT |
int (1–65535) | 3306 |
No | MySQL port. Validated only when explicitly set. |
DECNET_DB_NAME |
str | decnet |
No | Database name. |
DECNET_DB_USER |
str | decnet |
No | DB user. |
DECNET_DB_PASSWORD |
str | unset | No | DB password. None when unset. |
CORS
| Name | Type | Default | Required | Consequence |
|---|---|---|---|---|
DECNET_CORS_ORIGINS |
CSV of URLs | http://<web_host>:<web_port> |
No | Allowed origins for the dashboard API. Wildcard bind addresses (0.0.0.0, 127.0.0.1, ::) resolve to localhost in the default. |
Example override:
DECNET_CORS_ORIGINS=http://192.168.1.50:9090,https://dashboard.example.com
Realism content engine
The orchestrator's per-tick file plants and email drops are driven by
decnet/realism/. LLM enrichment for user-class file
bodies (notes, TODOs, drafts, scripts) is opt-in via these env vars;
when unset / empty / off, the orchestrator falls back to
deterministic templates and never calls an LLM.
| Name | Type | Default | Required | Consequence |
|---|---|---|---|---|
DECNET_REALISM_LLM |
string (ollama / fake / off / unset) |
unset | No | Picks the LLM backend in decnet/realism/llm/factory.py. Empty / off / none / 0 / false / disabled disables enrichment; any other value enables. The orchestrator process-local circuit breaker trips after 3 consecutive failures and falls back to templates for 60 s. |
DECNET_REALISM_MODEL |
string | llama3.1 |
No | Model name passed to ollama run. Override per-host in the orchestrator unit's EnvironmentFile. |
DECNET_REALISM_TIMEOUT |
float seconds | 60 |
No | Per-call wall-clock cap on ollama run. Hitting this raises LLMTimeout, which counts as one failure for the circuit breaker. |
DECNET_REALISM_PERSONAS |
path | /etc/decnet/email_personas.json |
No | Override path for the host-wide persona pool consumed by fleet (MACVLAN/IPVLAN) and SWARM-shard deckies. MazeNET-topology deckies use Topology.email_personas instead. Path is also resolved by decnet realism import-personas. |
DECNET_REALISM_FAKE_OUTPUT |
string | (canned email body) | No | Override the canned text the fake backend returns. Only useful in integration tests. |
The renamed predecessors DECNET_EMAILGEN_LLM / _MODEL / _TIMEOUT
/ _PERSONAS / _FAKE_OUTPUT are no longer read; pre-v1 clean break.
Canary worker
The canary worker (decnet canary) and the realism canary cultivator
both read these to know how to embed callbacks in planted artifacts.
When both are unset, the cultivator can still produce passive bait
(e.g. aws_creds) but raises for generators that require a callback
host (ssh_key DNS, mysql_dump).
| Name | Type | Default | Required | Consequence |
|---|---|---|---|---|
DECNET_CANARY_HTTP_BASE |
URL (no trailing slash) | unset | No | Public-facing base for HTTP callback URLs (e.g. https://canary.example.test). Generators embed <base>/c/<callback_token> into artifacts. |
DECNET_CANARY_DNS_ZONE |
DNS zone | unset | No | DNS zone for callback subdomains (e.g. canary.example.test). Generators embed <callback_token>.<zone> for DNS-trip artifacts (ssh_key comments, mysql_dump replica SOURCE_HOST). |
DECNET_CANARY_BLOB_DIR |
path | /var/lib/decnet/canary/blobs |
No | On-disk store for operator-uploaded canary blobs, deduplicated by sha256. |
Starter .env.local
Copy this to the project root as .env.local, change every placeholder, and
keep it out of git.
# System logging
DECNET_SYSTEM_LOGS=decnet.system.log
# Embedded workers (leave off unless you know why)
DECNET_EMBED_PROFILER=false
DECNET_EMBED_SNIFFER=false
# Request profiling
DECNET_PROFILE_REQUESTS=false
DECNET_PROFILE_DIR=profiles
# API
DECNET_API_HOST=127.0.0.1
DECNET_API_PORT=8000
# Generate with: python -c 'import secrets; print(secrets.token_urlsafe(48))'
DECNET_JWT_SECRET=REPLACE_WITH_A_64_BYTE_URLSAFE_TOKEN_NOT_IN_THE_BAD_LIST
DECNET_INGEST_LOG_FILE=/var/log/decnet/decnet.log
# Ingester batching
DECNET_BATCH_SIZE=100
DECNET_BATCH_MAX_WAIT_MS=250
# Web dashboard
DECNET_WEB_HOST=127.0.0.1
DECNET_WEB_PORT=8080
DECNET_ADMIN_USER=anti
DECNET_ADMIN_PASSWORD=REPLACE_ME_WITH_A_LONG_PASSPHRASE
DECNET_DEVELOPER=false
# Tracing
DECNET_DEVELOPER_TRACING=false
DECNET_OTEL_ENDPOINT=http://localhost:4317
# Database (sqlite is the default; uncomment the mysql block to switch)
DECNET_DB_TYPE=sqlite
# DECNET_DB_TYPE=mysql
# DECNET_DB_URL=mysql+asyncmy://decnet:REPLACE_ME@db.internal:3306/decnet
# DECNET_DB_HOST=db.internal
# DECNET_DB_PORT=3306
# DECNET_DB_NAME=decnet
# DECNET_DB_USER=decnet
# DECNET_DB_PASSWORD=REPLACE_ME
# CORS (only needed when the browser is not on the same host:port as the API)
# DECNET_CORS_ORIGINS=http://192.168.1.50:9090,https://dashboard.example.com
# Realism content engine (LLM enrichment is opt-in; templates are the fallback)
# DECNET_REALISM_LLM=ollama
# DECNET_REALISM_MODEL=llama3.1
# DECNET_REALISM_TIMEOUT=60
DECNET_REALISM_PERSONAS=/etc/decnet/email_personas.json
# Canary worker (set both to enable callback-bearing artifact generators)
# DECNET_CANARY_HTTP_BASE=https://canary.example.test
# DECNET_CANARY_DNS_ZONE=canary.example.test
Notes
decnet/config.py re-reads DECNET_DEVELOPER and DECNET_SYSTEM_LOGS during
logging setup. Those are the same variables documented above — there are no
others.
DECNET
User docs
- Quick-Start
- Installation
- Requirements-and-Python-Versions
- CLI-Reference
- INI-Config-Format
- Custom-Services
- Services-Catalog
- Service-Personas
- Archetypes
- Distro-Profiles
- OS-Fingerprint-Spoofing
- Networking-MACVLAN-IPVLAN
- Deployment-Modes
- SWARM-Mode
- Tailscale-Global-Deployment
- Resource-Footprint
- MazeNET
- Remote-Updates
- Environment-Variables
- Teardown-and-State
- Database-Drivers
- Systemd-Setup
- Logging-and-Syslog
- Fingerprinting
- Service-Bus
- Realism
- Web-Dashboard
- REST-API-Reference
- Mutation-and-Randomization
- Troubleshooting
Developer docs
DECNET — honeypot deception-network framework. Pre-1.0, active development — use with caution. See Sponsors to support the project. Contact: samuel@securejump.cl