- README.md: full project overview with features, install extras, CLI reference, web UI routes, config table, architecture diagrams, security model, /health API, and development setup - CLAUDE.md: updated for monorepo — reflects inlined subpackages, new import patterns, pip extras, and added modules - docs/deployment.md: practical RPi deployment guide covering hardware, OS setup, security hardening (swap/coredumps/firewall), installation, systemd service, config reference, fieldkit setup, key management, operational security limitations, troubleshooting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
14 KiB
SooSeF -- Soo Security Fieldkit
Offline-first security toolkit for journalists, NGOs, and at-risk organizations.
What is SooSeF?
SooSeF combines steganography, provenance attestation, and field security tools into a single package designed for airgapped and resource-constrained environments. It lets you:
- Hide messages in images, audio, and video using multiple steganographic techniques
- Prove authenticity of photos and documents with Ed25519 signatures and Merkle trees
- Protect data in the field with a killswitch, dead man's switch, tamper detection, USB device whitelisting, and GPS geofencing
- Manage cryptographic keys with identity rotation, channel key generation, and encrypted key bundle export/import
Stegasoo (steganography, v4.3.0) and Verisoo (attestation, v0.1.0) are included as
subpackages (import soosef.stegasoo, import soosef.verisoo). Everything ships as one
install: pip install soosef.
Quick Start
pip install "soosef[web,cli]"
soosef init
soosef serve
This creates the ~/.soosef/ directory structure, generates an Ed25519 identity and
channel key, writes a default config, and starts an HTTPS web UI on
https://127.0.0.1:5000.
Features
Steganography (Stegasoo)
- LSB encoding -- bit-level message hiding in PNG images
- DCT encoding -- frequency-domain hiding in JPEG images (requires
stego-dctextra) - Audio steganography -- hide data in WAV/FLAC audio (requires
stego-audioextra) - Video steganography -- frame-level encoding
- AES-256-GCM encryption with Argon2id key derivation
- EXIF stripping on encode to prevent metadata leakage
- Compression support (zstandard, optional LZ4)
Attestation (Verisoo)
- Ed25519 digital signatures for images and files
- Perceptual hashing (ImageHash) for tamper-evident photo attestation
- LMDB-backed attestation storage
- Append-only hash chain (CBOR-encoded) with Merkle tree verification
- Batch attestation for directories
Fieldkit
- Killswitch -- emergency destruction of all data under
~/.soosef/ - Dead man's switch -- automated purge if check-in is missed
- Tamper detection -- file integrity monitoring with baseline snapshots
- USB whitelist -- block or alert on unauthorized USB devices (Linux/pyudev)
- Geofence -- GPS boundary enforcement with configurable radius
Key Management
- Two separate key domains: AES-256-GCM channel keys (stego) and Ed25519 identity keys (attestation)
- Key rotation for both identity and channel keys
- Encrypted key bundle export/import for secure backup and transfer
- QR code generation for key sharing
Installation
Basic install (core library only)
pip install soosef
With extras
pip install "soosef[web,cli]" # Web UI + CLI (most common)
pip install "soosef[all]" # Everything except dev tools
pip install "soosef[dev]" # All + pytest, black, ruff, mypy
Available extras
| Extra | What it adds |
|---|---|
stego-dct |
DCT steganography (numpy, scipy, jpeglib, reedsolo) |
stego-audio |
Audio steganography (pydub, soundfile, reedsolo) |
stego-compression |
LZ4 compression support |
attest |
Attestation features (imagehash, lmdb, exifread) |
cli |
Click CLI with rich output and QR code support |
web |
Flask web UI with Waitress/Gunicorn, includes attest + stego-dct |
api |
FastAPI REST API with uvicorn, includes stego-dct |
fieldkit |
Tamper monitoring (watchdog) and USB whitelist (pyudev) |
federation |
Peer-to-peer attestation federation (aiohttp) |
rpi |
Raspberry Pi deployment (web + cli + fieldkit + gpiozero) |
all |
All of the above |
dev |
All + pytest, pytest-cov, black, ruff, mypy |
Airgapped / Raspberry Pi install
Bundle wheels on a networked machine, then install offline:
# On networked machine
pip download "soosef[rpi]" -d ./wheels
# Transfer ./wheels to target via USB
# On airgapped machine
pip install --no-index --find-links=./wheels "soosef[rpi]"
soosef init
soosef serve --host 0.0.0.0
CLI Reference
All commands accept --data-dir PATH to override the default ~/.soosef directory,
and --json for machine-readable output.
soosef [--data-dir PATH] [--json] COMMAND
Core commands
| Command | Description |
|---|---|
soosef init |
Create directory structure, generate identity + channel key, write default config |
soosef serve |
Start the web UI (default: https://127.0.0.1:5000) |
soosef status |
Show instance status: identity, keys, chain, fieldkit, config |
soosef serve options
| Option | Default | Description |
|---|---|---|
--host |
127.0.0.1 |
Bind address |
--port |
5000 |
Bind port |
--no-https |
off | Disable HTTPS (use HTTP) |
--debug |
off | Use Flask dev server instead of Waitress |
--workers |
4 |
Number of Waitress/Gunicorn worker threads |
Steganography commands (soosef stego)
soosef stego encode -i cover.png -m "secret message" -o output.png
soosef stego decode -i output.png
Attestation commands (soosef attest)
soosef attest sign -i photo.jpg # Sign a file
soosef attest verify -i photo.jpg # Verify attestation
soosef attest batch ./photos/ --caption "Field report"
Fieldkit commands (soosef fieldkit)
soosef fieldkit status # Show fieldkit state
soosef fieldkit checkin # Reset dead man's switch timer
soosef fieldkit check-deadman # Check if deadman timer has expired
soosef fieldkit purge --confirm # Activate killswitch (destroys all data)
soosef fieldkit geofence set --lat 48.8566 --lon 2.3522 --radius 1000
soosef fieldkit geofence check --lat 48.8600 --lon 2.3500
soosef fieldkit geofence clear
soosef fieldkit usb snapshot # Snapshot current USB devices as whitelist
soosef fieldkit usb check # Check for unauthorized USB devices
Key management commands (soosef keys)
soosef keys show # Display current key info
soosef keys export -o backup.enc # Export encrypted key bundle
soosef keys import -b backup.enc # Import key bundle
soosef keys rotate-identity # Generate new Ed25519 identity
soosef keys rotate-channel # Generate new channel key
Chain commands (soosef chain)
soosef chain status # Show chain head, length, integrity
soosef chain verify # Verify entire chain integrity
soosef chain show INDEX # Show a specific chain record
soosef chain log --count 20 # Show recent chain entries
soosef chain backfill # Backfill existing attestations into chain
soosef chain export --start 0 --end 100 -o chain.cbor
Web UI
Start with soosef serve. The web UI provides authenticated access to all features
through Flask blueprints.
Routes
| Blueprint | Routes | Description |
|---|---|---|
| stego | /encode, /decode, /generate |
Steganography operations |
| attest | /attest, /verify |
Attestation signing and verification |
| fieldkit | /fieldkit/* |
Killswitch, dead man's switch, status dashboard |
| keys | /keys/* |
Key management, rotation, export/import |
| admin | /admin/* |
User management (multi-user auth via SQLite) |
| health | /health |
Capability reporting endpoint (see API section) |
Configuration
SooSeF loads configuration from ~/.soosef/config.json. All fields have sensible defaults.
soosef init writes the default config file.
Config fields
| Field | Type | Default | Description |
|---|---|---|---|
host |
string | 127.0.0.1 |
Web UI bind address |
port |
int | 5000 |
Web UI bind port |
https_enabled |
bool | true |
Enable HTTPS with self-signed cert |
auth_enabled |
bool | true |
Require login for web UI |
max_upload_mb |
int | 50 |
Maximum upload size in MB |
session_timeout_minutes |
int | 15 |
Session expiry |
login_lockout_attempts |
int | 5 |
Failed logins before lockout |
login_lockout_minutes |
int | 15 |
Lockout duration |
default_embed_mode |
string | auto |
Stegasoo encoding mode |
killswitch_enabled |
bool | false |
Enable killswitch functionality |
deadman_enabled |
bool | false |
Enable dead man's switch |
deadman_interval_hours |
int | 24 |
Check-in interval |
deadman_grace_hours |
int | 2 |
Grace period after missed check-in |
deadman_warning_webhook |
string | "" |
URL to POST warning before auto-purge |
usb_monitoring_enabled |
bool | false |
Enable USB device whitelist enforcement |
tamper_monitoring_enabled |
bool | false |
Enable file integrity monitoring |
chain_enabled |
bool | true |
Enable attestation hash chain |
chain_auto_wrap |
bool | true |
Auto-wrap attestations in chain records |
backup_reminder_days |
int | 7 |
Days before backup reminder |
gpio_killswitch_pin |
int | 17 |
Raspberry Pi GPIO pin for hardware killswitch |
gpio_killswitch_hold_seconds |
float | 5.0 |
Hold duration to trigger hardware killswitch |
Environment variables
| Variable | Description |
|---|---|
SOOSEF_DATA_DIR |
Override the data directory (default: ~/.soosef) |
Architecture
Source layout
src/soosef/
__init__.py Package init, __version__
cli.py Click CLI (entry point: soosef)
paths.py All path constants (single source of truth)
config.py Unified config loader (dataclass + JSON)
exceptions.py SoosefError base exception
stegasoo/ Steganography engine (subpackage)
verisoo/ Attestation engine (subpackage)
keystore/
manager.py Key material management (channel + identity)
models.py KeyBundle, IdentityBundle dataclasses
export.py Encrypted key bundle export/import
fieldkit/
killswitch.py Emergency data destruction
deadman.py Dead man's switch
tamper.py File integrity monitoring
usb_monitor.py USB device whitelist (Linux/pyudev)
geofence.py GPS boundary enforcement
frontends/web/
app.py Flask app factory (create_app())
auth.py SQLite3 multi-user auth
temp_storage.py File-based temp storage with expiry
subprocess_stego.py Crash-safe subprocess isolation
ssl_utils.py Self-signed HTTPS cert generation
blueprints/
stego.py /encode, /decode, /generate
attest.py /attest, /verify
fieldkit.py /fieldkit/*
keys.py /keys/*
admin.py /admin/*
Data directory (~/.soosef/)
~/.soosef/
config.json Unified configuration
audit.jsonl Append-only audit trail
identity/ Ed25519 keypair (private.pem, public.pem, identity.meta.json)
stegasoo/ Channel key (channel.key)
attestations/ Verisoo attestation store (log.bin, index/, peers.json)
chain/ Hash chain (chain.bin, state.cbor)
auth/ Web UI auth database (soosef.db)
certs/ Self-signed TLS certificates
fieldkit/ Fieldkit state (deadman.json, tamper/, usb/, geofence.json)
temp/ Ephemeral file storage
instance/ Flask instance (sessions, secret key)
Sensitive directories (identity/, auth/, certs/, and the root) are created with
0700 permissions.
Security Model
Two key domains, never merged. Stegasoo uses AES-256-GCM with keys derived via Argon2id from user-supplied factors. Verisoo uses Ed25519 for signing. These serve different security purposes and are kept strictly separate.
Killswitch priority. The killswitch destroys all data under ~/.soosef/, including
the audit log. This is intentional -- in a field compromise scenario, data destruction
takes precedence over audit trail preservation.
Offline-first. All static assets are vendored (no CDN calls). Pip wheels can be bundled for fully airgapped installation. No network access is required for any core functionality.
Web UI hardening:
- CSRF protection via Flask-WTF
- Session timeout (default: 15 minutes)
- Login rate limiting with lockout (5 attempts, 15-minute lockout)
- HTTPS by default with auto-generated self-signed certificates
- EXIF stripping on steganographic encode to prevent metadata leakage
Subprocess isolation. Steganographic operations run in a subprocess boundary
(subprocess_stego.py) to contain crashes and prevent memory corruption from affecting
the main web server process.
API
/health endpoint
The web UI exposes a /health endpoint that reports installed capabilities:
{
"status": "ok",
"version": "0.2.0",
"capabilities": ["stego-lsb", "stego-dct", "attest", "fieldkit", "chain"]
}
Useful for monitoring and for clients to discover which extras are installed.
FastAPI (optional)
Install the api extra for a standalone FastAPI REST interface:
pip install "soosef[api]"
This provides soosef.api with a FastAPI application served by uvicorn, suitable for
programmatic integration.
Development
Setup
git clone https://github.com/alee/soosef.git
cd soosef
pip install -e ".[dev]"
Commands
pytest # Run tests with coverage
black src/ tests/ frontends/ # Format (100-char line length)
ruff check src/ tests/ frontends/ --fix # Lint
mypy src/ # Type check
Code style
- Black with 100-character line length
- Ruff with E, F, I, N, W, UP rule sets
- mypy strict mode with missing imports ignored
- Imperative commit messages (e.g., "Add killswitch purge confirmation")
Python support
Python 3.11, 3.12, 3.13, and 3.14.
License
MIT License. See LICENSE for details.