fieldwitness/docs/training/admin-operations-guide.md
Aaron D. Lee 6325e86873
Some checks failed
CI / lint (push) Failing after 1m1s
CI / typecheck (push) Failing after 31s
Comprehensive documentation for v0.2.0 release
README.md (700 lines):
- Three-tier deployment model with ASCII diagram
- Federation blueprint in web UI routes
- deploy/ directory in architecture tree
- Documentation index linking all guides

CLAUDE.md (256 lines):
- Updated architecture tree with all new docs and deploy files

New guides:
- docs/federation.md (317 lines) — gossip protocol mechanics, peer
  setup, trust filtering, offline bundles, relay deployment, jurisdiction
- docs/evidence-guide.md (283 lines) — evidence packages, cold archives,
  selective disclosure, chain anchoring, legal discovery workflow
- docs/source-dropbox.md (220 lines) — token management, client-side
  hashing, extract-then-strip pipeline, receipt mechanics, opsec
- docs/index.md — documentation hub linking all guides

Training materials:
- docs/training/reporter-quickstart.md (105 lines) — printable one-page
  card: boot USB, attest photo, encode message, check-in, emergency
- docs/training/emergency-card.md (79 lines) — wallet-sized laminated
  card: three destruction methods, 10-step order, key contacts
- docs/training/admin-reference.md (219 lines) — deployment tiers,
  CLI tables, backup checklist, hardening checklist, troubleshooting

Also includes existing architecture docs from the original repos.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 23:31:47 -04:00

15 KiB

SooSeF Admin Operations Guide

Audience: IT administrators, system operators, and technically competent journalists responsible for deploying, configuring, and maintaining SooSeF instances for their organization.

Prerequisites: Familiarity with Linux command line, Docker basics, and SSH. For Tier 1 USB builds, familiarity with Debian live-build.


Overview

This guide covers the operational tasks an admin performs after initial deployment. For installation and deployment, see deployment.md. For architecture details, see docs/architecture/.

Your responsibilities as a SooSeF admin:

  1. Deploy and maintain SooSeF instances (Tier 1 USB, Tier 2 server, Tier 3 relay)
  2. Manage user accounts and access
  3. Configure threat level presets for your environment
  4. Manage the source drop box
  5. Set up and maintain federation between organizations
  6. Monitor system health and perform backups
  7. Respond to security incidents

1. User Management

Creating User Accounts

On first start, the web UI prompts for the first admin account. Additional users are created through the Admin panel at /admin/.

Each user has:

  • A username and password (stored as Argon2id hashes in SQLite)
  • An admin flag (admin users can manage other accounts and the drop box)

Password Resets

From the admin panel, issue a temporary password for a locked-out user. The user should change it on next login. All password resets are recorded in the audit log (~/.soosef/audit.jsonl).

Account Lockout

After login_lockout_attempts (default: 5) failed logins, the account is locked for login_lockout_minutes (default: 15). Lockout state is in-memory and clears on server restart.

For persistent lockout (e.g., a compromised account), delete the user from the admin panel.

Audit Trail

All admin actions are logged to ~/.soosef/audit.jsonl in JSON-lines format:

{"timestamp": "2026-04-01T12:00:00+00:00", "actor": "admin", "action": "user.create", "target": "user:reporter1", "outcome": "success", "source": "web"}

Actions logged: user.create, user.delete, user.password_reset, key.channel.generate, key.identity.generate, killswitch.fire

Warning

: The audit log is destroyed by the killswitch. This is intentional -- in a field compromise, data destruction takes precedence over audit preservation.


2. Threat Level Configuration

SooSeF ships four presets at deploy/config-presets/. Select based on your operational environment.

Applying a Preset

$ cp deploy/config-presets/high-threat.json ~/.soosef/config.json

Restart the server to apply.

Preset Summary

Preset Session Timeout Killswitch Dead Man's Switch USB Monitor Cover Name
Low (press freedom) 30 min Off Off Off None
Medium (restricted press) 15 min On 48h / 4h grace On "Office Document Manager"
High (conflict zone) 5 min On 12h / 1h grace On "Local Inventory Tracker"
Critical (targeted surveillance) 3 min On 6h / 1h grace On "System Statistics"

Custom Configuration

Edit ~/.soosef/config.json directly. All fields have defaults. Key fields for security:

Field What It Controls
host Bind address. 127.0.0.1 = local only; 0.0.0.0 = LAN access
session_timeout_minutes How long before idle sessions expire
killswitch_enabled Whether the software killswitch is available
deadman_enabled Whether the dead man's switch is active
deadman_interval_hours Hours between required check-ins
deadman_grace_hours Grace period after missed check-in before auto-purge
deadman_warning_webhook URL to POST a JSON warning during grace period
cover_name CN for the self-signed TLS certificate (cover/duress mode)
backup_reminder_days Days before soosef status warns about overdue backups

Warning

: Setting auth_enabled: false disables all login requirements. Never do this on a network-accessible instance.


3. Source Drop Box Operations

The drop box provides SecureDrop-style anonymous file intake.

Creating Upload Tokens

  1. Go to /dropbox/admin in the web UI (admin account required)
  2. Set a label (internal only -- the source never sees this)
  3. Set expiry in hours (default: 24)
  4. Set max files (default: 10)
  5. Click Create Token

You receive a URL like https://<host>:<port>/dropbox/upload/<token>.

Sharing URLs With Sources

Share the URL over an already-secure channel only:

  • Best: Hand-written on paper, in person
  • Good: Signal, Wire, or other end-to-end encrypted messenger
  • Acceptable: Encrypted email (PGP/GPG)
  • Never: Unencrypted email, SMS, or any channel you do not control

What Happens When a Source Uploads

  1. The source opens the URL in any browser (no account needed, no SooSeF branding)
  2. Their browser computes SHA-256 hashes client-side before upload (SubtleCrypto)
  3. Files are uploaded and processed:
    • EXIF metadata is extracted (evidentiary fields: GPS, timestamp)
    • All metadata is stripped from the stored copy (protects source device info)
    • The original bytes are attested (signed) before stripping
  4. The source receives a receipt code (HMAC of file hash + token)
  5. Files are stored in ~/.soosef/temp/dropbox/ with mode 0700

Revoking Tokens

From /dropbox/admin, click Revoke on any active token. The token is immediately deleted from the database. Any source with the URL can no longer upload.

Receipt Verification

Sources can verify their submission was received at /dropbox/verify-receipt by entering their receipt code. This returns the filename, SHA-256, and reception timestamp.

Operational Security

  • The upload page has no SooSeF branding -- it is a minimal HTML form
  • No external resources are loaded (no CDN, fonts, analytics) -- Tor Browser compatible
  • SooSeF does not log source IP addresses
  • If using a reverse proxy (nginx, Caddy), disable access logging for /dropbox/upload/
  • Tokens auto-expire and are cleaned up on every admin page load
  • For maximum source protection, run SooSeF as a Tor hidden service

Storage Management

Uploaded files accumulate in ~/.soosef/temp/dropbox/. Periodically review and process submissions, then remove them from the temp directory. The files are not automatically cleaned up (they persist until you act on them or the killswitch fires).


4. Key Management

Two Key Domains

SooSeF manages two independent key types:

Key Algorithm Location Purpose
Identity key Ed25519 ~/.soosef/identity/ Sign attestations, chain records
Channel key AES-256-GCM (Argon2id-derived) ~/.soosef/stegasoo/channel.key Steganographic encoding

These are never merged. Rotating one does not affect the other.

Key Rotation

Identity rotation archives the old keypair and generates a new one. If the chain is enabled, a soosef/key-rotation-v1 record is signed by the OLD key, creating a verifiable trust chain.

$ soosef keys rotate-identity

After rotating, immediately:

  1. Take a fresh backup (soosef keys export)
  2. Notify all collaborators of the new fingerprint
  3. Update trusted-key lists at partner organizations

Channel rotation archives the old key and generates a new one:

$ soosef keys rotate-channel

After rotating, share the new channel key with all stego correspondents.

Trust Store

Import collaborator public keys so you can verify their attestations and accept their federation bundles:

$ soosef keys trust --import /media/usb/partner-pubkey.pem

Always verify fingerprints out-of-band (in person or over a known-secure voice channel).

List trusted keys:

$ soosef keys show

Remove a trusted key:

$ soosef keys untrust <fingerprint>

Backup Schedule

SooSeF warns when backups are overdue (configurable via backup_reminder_days).

# Create encrypted backup
$ soosef keys export -o /media/usb/backup.enc

# Check backup status
$ soosef status

Store backups on separate physical media, in a different location from the device.


5. Federation Setup

Federation allows multiple SooSeF instances to exchange attestation records.

Adding Federation Peers

Through the web UI: Go to /federation/, click Add Peer, enter the peer's URL and Ed25519 fingerprint.

Through the CLI or peer_store:

# Peers are managed via the web UI or programmatically through PeerStore

Trust Key Exchange

Before two organizations can federate, exchange public keys:

  1. Export your public key: cp ~/.soosef/identity/public.pem /media/usb/our-pubkey.pem
  2. Give it to the partner organization (physical handoff or secure channel)
  3. Import their key: soosef keys trust --import /media/usb/their-pubkey.pem
  4. Verify fingerprints out-of-band

Exporting Attestation Bundles

# Export all records
$ soosef chain export --output /media/usb/bundle.zip

# Export a specific range
$ soosef chain export --start 100 --end 200 --output /media/usb/bundle.zip

# Export filtered by investigation
# (investigation tag is set during attestation)

Importing Attestation Bundles

On the receiving instance, imported records are:

  • Verified against the trust store (untrusted signers are rejected)
  • Deduplicated by SHA-256 (existing records are skipped)
  • Tagged with federated_from metadata
  • Acknowledged via a delivery-ack chain record (two-way handshake)

Gossip Sync (Tier 2 <-> Tier 3)

If the Tier 2 server and Tier 3 relay have network connectivity, gossip sync runs automatically at the configured interval (default: 60 seconds, set via VERISOO_GOSSIP_INTERVAL environment variable).

Gossip flow:

  1. Nodes exchange Merkle roots
  2. If roots differ, request consistency proof
  3. Fetch missing records
  4. Append to local log

Monitor sync status at /federation/ in the web UI.

Airgapped Federation

All federation is designed for sneakernet operation:

  1. Export bundle to USB on sending instance
  2. Physically carry USB to receiving instance
  3. Import bundle
  4. Optionally export delivery acknowledgment back on USB

No network connectivity is required at any point.


6. Chain and Anchoring

Chain Verification

Verify the full chain periodically:

$ soosef chain verify

This checks all hash linkage and Ed25519 signatures. It also verifies key rotation records and tracks authorized signers.

Timestamp Anchoring

Anchor the chain head to prove it existed before a given time:

# Automated (requires network)
$ soosef chain anchor --tsa https://freetsa.org/tsr

# Manual (prints hash for external submission)
$ soosef chain anchor

A single anchor implicitly timestamps every prior record (the chain is append-only).

When to anchor:

  • Before sharing evidence with third parties
  • At regular intervals (daily or weekly)
  • Before key rotation
  • Before and after major investigations

Selective Disclosure

For legal discovery or court orders, produce a proof showing specific records while keeping others redacted:

$ soosef chain disclose -i 42,43,44 -o disclosure.json

The output includes full records for selected indices and hash-only entries for everything else. A third party can verify the selected records are part of an unbroken chain.


7. Evidence Preservation

Evidence Packages

For handing evidence to lawyers, courts, or organizations without SooSeF:

Self-contained ZIP containing original images, attestation records, chain data, your public key, a standalone verify.py, and a README. The recipient verifies with:

$ pip install cryptography
$ python verify.py

Cold Archives

For long-term preservation (10+ year horizon), OAIS-aligned:

Full state export including chain binary, attestation log, LMDB index, anchors, public key, trusted keys, optional encrypted key bundle, ALGORITHMS.txt, and verify.py.

When to create cold archives:

  • Weekly or monthly as part of backup strategy
  • Before key rotation or travel
  • When archiving a completed investigation

Store on at least two separate physical media in different locations.


8. Monitoring and Health

Health Endpoint

# Web UI
$ curl -k https://127.0.0.1:5000/health

# Federation API
$ curl http://localhost:8000/health

Returns capabilities (stego-lsb, stego-dct, attest, fieldkit, chain).

System Status

$ soosef status --json

Checks: identity key, channel key, chain integrity, dead man's switch state, backup status, geofence, trusted keys.

Docker Monitoring

# Service status
$ docker compose ps

# Logs
$ docker compose logs -f server

# Resource usage
$ docker stats

The Docker images include HEALTHCHECK directives that poll /health every 30 seconds.


9. Incident Response

Device Seizure (Imminent)

  1. Trigger killswitch: soosef fieldkit purge --confirm CONFIRM-PURGE
  2. For Tier 1 USB: pull the USB stick and destroy it physically if possible
  3. Verify with a separate device that federation copies are intact

Device Seizure (After the Fact)

  1. Assume all local data is compromised
  2. Verify Tier 2/3 copies of attestation data
  3. Generate new keys on a fresh instance
  4. Record a key recovery event in the chain (if the old chain is still accessible)
  5. Notify all collaborators to update their trust stores

Federation Peer Compromise

  1. The compromised peer has attestation metadata (hashes, signatures, timestamps) but not decrypted content
  2. Remove the peer from your peer list (/federation/ > Remove Peer)
  3. Assess what metadata exposure means for your organization
  4. Consider whether attestation patterns reveal sensitive information

Dead Man's Switch Triggered Accidentally

Data is gone. Restore from the most recent backup:

$ soosef init
$ soosef keys import -b /media/usb/backup.enc

Federation copies of attestation data are unaffected. Local attestations created since the last federation sync or backup are lost.


10. Maintenance Tasks

Regular Schedule

Task Frequency Command
Check system status Daily soosef status
Check in (if deadman armed) Per interval soosef fieldkit checkin
Backup keys Per backup_reminder_days soosef keys export
Verify chain integrity Weekly soosef chain verify
Anchor chain Weekly soosef chain anchor
Review drop box submissions As needed /dropbox/admin
Clean temp files Monthly Remove processed files from ~/.soosef/temp/
Create cold archive Monthly Export via CLI or web
Update SooSeF As releases are available pip install --upgrade soosef

Docker Volume Backup

$ docker compose stop server
$ docker run --rm -v server-data:/data -v /backup:/backup \
    busybox tar czf /backup/soosef-$(date +%Y%m%d).tar.gz -C /data .
$ docker compose start server

Log Rotation

audit.jsonl grows indefinitely. On long-running Tier 2 servers, archive old entries periodically. The audit log is append-only; truncate by copying the tail:

$ tail -n 10000 ~/.soosef/audit.jsonl > ~/.soosef/audit.jsonl.tmp
$ mv ~/.soosef/audit.jsonl.tmp ~/.soosef/audit.jsonl

Warning

: Truncating the audit log removes historical records. Archive the full file before truncating if you need the history for compliance or legal purposes.