MotorSignal-App/backend/motorsignal_api/docs/ops-actions/ARCHITECTURE.md

2.8 KiB
Raw Permalink Blame History

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: Fetch origin/master, verify clean state, build Next.js release in staging, atomically swap symlink, restart website, and verify health with automatic rollback.
  • restart_website: Restart motorsignal-website.service and verify loopback and public endpoints.
  • restart_api: Detached restart of motorsignal-api.service via systemd-run, with pre-committed action audit and startup reconciliation.
  • reboot_server: Detached system reboot via systemd-run, requiring explicit typed confirmation "REBOOT MOTORSIGNAL SERVER".

2. Security Boundaries & Threat Model

Principle of Least Privilege

  • The web and API processes (motorsignal service 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 owner role via require_ops_roles("owner").
  • operator role 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_api requires confirmation_text == "RESTART API".
  • reboot_server requires confirmation_text == "REBOOT MOTORSIGNAL SERVER".