Security considerations - aaronwmorris/indi-allsky GitHub Wiki
Security Architecture & Hardening
indi-allsky incorporates defense-in-depth principles across process isolation, credential cryptography, network restrictions, and web application security.
1. Process Isolation & Least Privilege
- Unprivileged Execution: All background services (
indi-allsky.service,gunicorn-indi-allsky.service,indiserver.service) execute under a dedicated non-root service account (indi-allsky). - Group-Based Hardware Access: Hardware access is delegated via standard Linux supplementary groups:
video: Camera access (V4L2, libcamera).dialout: Serial interfaces (GPS, RS-232 focusers, udev devices).gpio: Access to/dev/gpiochip*for dew heaters, fans, and focusers.i2c: Sensor buses (BME280, TSL2591, MLX90614, etc.).spi: SPI-driven display modules and sensors.
- Controlled Privileged Operations: System-level commands (rebooting, power management, time synchronization, and USB drive auto-mounting) are mediated via PolicyKit (
/etc/polkit-1/rules.d/90-indi-allsky.rules) rather thansudoor SUID binaries.
2. Cryptography & Credential Security
- Password Storage: User passwords are encrypted with the Argon2 password-hashing function via
passlib, resisting GPU/ASIC brute-force attempts. - Configuration Secrets Encryption: Sensitive configuration attributes stored in the database (API tokens, MQTT credentials, S3 secret keys, Wi-Fi passwords) are encrypted symmetrically using Fernet (AES-128-CBC with HMAC-SHA256).
- The encryption key is stored on the filesystem in
/etc/indi-allsky/flask.json(PASSWORD_KEY). - If
PASSWORD_KEYis lost or altered, stored third-party credentials must be re-entered.
- The encryption key is stored on the filesystem in
- SyncAPI HMAC Signatures: Synchronization between on-premises cameras and remote web portals utilizes pre-shared HMAC keys. Raw API keys are never transmitted over the network; each request payload is cryptographically signed and timestamped.
3. Web Application Security
The web layer (Flask, Flask-WTF, Flask-Login) includes standard defensive measures:
- CSRF Protection: All state-modifying POST/PUT operations require cryptographically signed CSRF tokens (
WTF_CSRF_TIME_LIMIT). - SQL Injection Prevention: Database interactions operate exclusively through SQLAlchemy ORM parameter binding; raw SQL concatenation is avoided.
- Session Security: Session cookies enforce
HttpOnly,SameSite=Lax, andSecureattributes by default. - Role-Based Access Control:
- Anonymous: Restricted to viewing live images, charts, and public archives (or fully blocked if
INDI_ALLSKY_AUTH_ALL_VIEWSis enabled). - Standard User: Authenticated access to media archives and astronomical status panels.
- Administrator: Exclusive authority to modify hardware configurations, trigger calibration routines, manage users, and issue system control tasks.
- Anonymous: Restricted to viewing live images, charts, and public archives (or fully blocked if
4. Network Boundary & Remote Access Hardening
Admin Network Restrictions (ADMIN_NETWORKS)
Administrative actions and Action API endpoints (/indi-allsky/action/*) require the requesting client IP address to reside within CIDR subnets defined in /etc/indi-allsky/flask.json:
"ADMIN_NETWORKS": [
"127.0.0.1/32",
"::1/128",
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16"
]
Exposing to the Internet
If the allsky camera must be accessible outside the local area network:
- Prefer Encrypted Overlays: Utilize Cloudflare Tunnels, Tailscale, or WireGuard rather than direct router port-forwarding.
- Require Authentication: Set
"INDI_ALLSKY_AUTH_ALL_VIEWS": truein/etc/indi-allsky/flask.jsonto prevent unauthenticated access to the live camera canvas. - Protect Media Directories: Set
"INDI_ALLSKY_AUTH_MEDIA_VIEWS": trueif image and timelapse archives should not be publicly indexable.