2.8 KiB
2.8 KiB
MotorSignal Operations Actions — Architecture & Security Model
1. Overview
The Operations Action subsystem provides authenticated, audited, and strictly bounded execution of administrative operations on the MotorSignal production infrastructure (api.motorsignal.app).
Supported Actions:
deploy_website: Fetchorigin/master, verify clean state, build Next.js release in staging, atomically swap symlink, restart website, and verify health with automatic rollback.restart_website: Restartmotorsignal-website.serviceand verify loopback and public endpoints.restart_api: Detached restart ofmotorsignal-api.serviceviasystemd-run, with pre-committed action audit and startup reconciliation.reboot_server: Detached system reboot viasystemd-run, requiring explicit typed confirmation"REBOOT MOTORSIGNAL SERVER".
2. Security Boundaries & Threat Model
Principle of Least Privilege
- The web and API processes (
motorsignalservice user) do NOT have unrestricted root access or arbitrary sudo permissions. - Sudo access is strictly constrained to a single canonical, root-owned, non-writable script:
/opt/motorsignal/current/backend/scripts/ops-action-helper.sh - Sudoers policy (
/etc/sudoers.d/motorsignal-ops-actions):motorsignal ALL=(root) NOPASSWD: /opt/motorsignal/current/backend/scripts/ops-action-helper.sh - The helper script rejects:
- Wildcard arguments
- Shell string interpolation
- Arbitrary paths, branches, git remotes, or environment flags
- Free-form user text
Non-Interactive Subprocess Execution
- In Python, all execution uses
subprocess.run(..., shell=False)with an explicit argv array[helper_path, action_type]. - Output is sanitized: raw exceptions, filesystem paths, passwords, and tokens are scrubbed before storage or display.
Role-Based Access Control
- All action invocations require the
ownerrole viarequire_ops_roles("owner"). operatorrole users have read-only access to/api/v1/ops/actions(history and status).- Unauthenticated requests receive HTTP 401; unauthorized requests receive HTTP 403.
Mutual Exclusion & Concurrency Control
- Only one infrastructure mutation may execute at a time.
- The service queries for active actions in
('queued', 'preflight', 'running', 'verifying', 'rollback_running'). - If an active action exists, subsequent requests are rejected immediately with HTTP 409 Conflict.
Idempotency
- Requests may supply an
idempotency_key(8–128 characters). - Enforced at the database level via a unique partial index on
(requested_by_id, action_type, idempotency_key). - Repeated requests return the existing action record without re-executing.
Typed Confirmations
restart_apirequiresconfirmation_text == "RESTART API".reboot_serverrequiresconfirmation_text == "REBOOT MOTORSIGNAL SERVER".