fieldwitness/src/soosef/paths.py
Aaron D. Lee b8d4eb5933 Add core modules, web frontend, CLI, keystore, and fieldkit
Core:
- paths.py: centralized ~/.soosef/ path constants
- config.py: JSON config loader with dataclass defaults
- exceptions.py: SoosefError hierarchy
- cli.py: unified Click CLI wrapping stegasoo + verisoo + native commands

Keystore:
- manager.py: unified key management (Ed25519 identity + channel keys)
- models.py: IdentityInfo, KeystoreStatus dataclasses
- export.py: encrypted key bundle export/import for USB transfer

Fieldkit:
- killswitch.py: ordered emergency data destruction (keys first)
- deadman.py: dead man's switch with check-in timer
- tamper.py: SHA-256 file integrity baseline + checking
- usb_monitor.py: pyudev USB whitelist enforcement
- geofence.py: haversine-based GPS boundary checking

Web frontend (Flask app factory + blueprints):
- app.py: create_app() factory with context processor
- blueprints: stego, attest, fieldkit, keys, admin
- templates: base.html (dark theme, unified nav), dashboard, all section pages
- static: CSS, favicon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 14:30:13 -04:00

82 lines
2.2 KiB
Python

"""
Centralized path constants for SooSeF.
All ~/.soosef/* paths are defined here. Every module that needs a path
imports from this module — no hardcoded paths anywhere else.
The base directory can be overridden via SOOSEF_DATA_DIR environment variable
for multi-instance deployments or testing.
"""
import os
from pathlib import Path
# Allow override for testing or multi-instance deployments
BASE_DIR = Path(os.environ.get("SOOSEF_DATA_DIR", Path.home() / ".soosef"))
# Ed25519 identity keypair (verisoo signing)
IDENTITY_DIR = BASE_DIR / "identity"
IDENTITY_PRIVATE_KEY = IDENTITY_DIR / "private.pem"
IDENTITY_PUBLIC_KEY = IDENTITY_DIR / "public.pem"
# Stegasoo state
STEGASOO_DIR = BASE_DIR / "stegasoo"
CHANNEL_KEY_FILE = STEGASOO_DIR / "channel.key"
# Verisoo attestation storage
ATTESTATIONS_DIR = BASE_DIR / "attestations"
ATTESTATION_LOG = ATTESTATIONS_DIR / "log.bin"
ATTESTATION_INDEX = ATTESTATIONS_DIR / "index"
PEERS_FILE = ATTESTATIONS_DIR / "peers.json"
# Web UI auth database
AUTH_DIR = BASE_DIR / "auth"
AUTH_DB = AUTH_DIR / "soosef.db"
# SSL certificates
CERTS_DIR = BASE_DIR / "certs"
SSL_CERT = CERTS_DIR / "cert.pem"
SSL_KEY = CERTS_DIR / "key.pem"
# Fieldkit state
FIELDKIT_DIR = BASE_DIR / "fieldkit"
FIELDKIT_CONFIG = FIELDKIT_DIR / "config.json"
DEADMAN_STATE = FIELDKIT_DIR / "deadman.json"
TAMPER_DIR = FIELDKIT_DIR / "tamper"
TAMPER_BASELINE = TAMPER_DIR / "baseline.json"
USB_DIR = FIELDKIT_DIR / "usb"
USB_WHITELIST = USB_DIR / "whitelist.json"
# Ephemeral
TEMP_DIR = BASE_DIR / "temp"
# Flask instance path (sessions, secret key)
INSTANCE_DIR = BASE_DIR / "instance"
SECRET_KEY_FILE = INSTANCE_DIR / ".secret_key"
# Unified config
CONFIG_FILE = BASE_DIR / "config.json"
def ensure_dirs() -> None:
"""Create all required directories with appropriate permissions."""
dirs = [
BASE_DIR,
IDENTITY_DIR,
STEGASOO_DIR,
ATTESTATIONS_DIR,
AUTH_DIR,
CERTS_DIR,
FIELDKIT_DIR,
TAMPER_DIR,
USB_DIR,
TEMP_DIR,
INSTANCE_DIR,
]
for d in dirs:
d.mkdir(parents=True, exist_ok=True)
# Restrict permissions on sensitive directories
for d in [BASE_DIR, IDENTITY_DIR, AUTH_DIR, CERTS_DIR]:
d.chmod(0o700)