Skip to content

[SECURITY] MUT-012: Compose/Railway run as root, install deps at boot, bind-mount repo #63

Closed

Description

@CodewithJha

Problem

Compose runs python:3.12-slim / node:22-bookworm as root, bind-mounts the entire repo .:/app, installs uv/npm at container start, and publishes 8000 and 3000. Railway startCommand is uv sync && … python -m mutiny_api --host 0.0.0.0. There is no Dockerfile; images are generic language bases.

Why it matters

Runtime supply-chain (whatever PyPI/npm serve at boot), root + bind-mount (container escape = host write), and an exposed operator UI (see MUT-001). This is a dev-shaped deploy artifact, not a confirmed RCE by itself.

Evidence

  • Audit ID: MUT-012 (MEDIUM, confirmed as written in manifests).
  • docker-compose.yml — no user:, volumes: [.:/app], pip install uv && uv sync / npm install in command, ports 8000 and 3000.
  • railway.toml — uv sync && mkdir -p data && uv run python scripts/ensure_sample_mutiny.py && uv run python -m mutiny_api --host 0.0.0.0.

Attack surface / Preconditions / Impact / Current mitigation / Recommended fix direction

  • Attack surface: Compose/Railway Hosted processes, host bind-mount, boot-time package install.
  • Preconditions: Operator uses default compose or Railway start as committed; typically combined with MUT-001’s published UI port.
  • Impact: Compromised PyPI/npm at start, or container breakout writing the host tree; not a Mutiny application RCE proof.
  • Current mitigation: MUTINY_API_TOKEN required for non-loopback API bind; Hosted does not exec customer adapters.
  • Recommended fix direction: Image-build deps, non-root user, mount only data/, publish UI only on loopback (with MUT-001).

Reproduction

Manifests as written. No live Docker escape was attempted.

Expected behavior

Default compose is safe for local demo: non-root if feasible, deps baked or locked at build, host mount limited to data, UI not published to all interfaces by default.

Suggested implementation direction

Add a real Dockerfile (or nixpacks build phase) that uv sync/npm ci at build. Run as non-root. Volume-mount ./data only. Align Railway start to use the built image without uv sync at every boot if possible.

Acceptance criteria

  • Default compose does not bind-mount the full git worktree into a root container as the documented happy path (data-only mount or documented “dev bind-mount” override).
  • Runtime pip install/npm install/uv sync is not required on every container start for the documented path (build-time install).
  • Process is not root or SECURITY.md explicitly says compose is local-dev-only and unsafe for exposed hosts.
  • python -m mutiny_api fail-closed bind/token behavior unchanged.
  • Document the threat model change in SECURITY.md / COLD_START.

Scope

docker-compose.yml, railway.toml, optional Dockerfile, SECURITY.md. Out of scope: MUT-001 auth BFF (related but separate issue), MUT-066 Railway sample ensure (deferred).

Related audit findings

MUT-012. Related: MUT-001 (UI bind), MUT-057 (raw uvicorn — documented, skip), MUT-066 (deferred).

Contributor notes

Generated from the Mutiny deep audit.

help wanted. Not a good-first-issue (deploy architecture).

Activity

  1. BasilZafar11 commented on Oct 24, 2026

    @BasilZafar11
    Contributor

    Opened PR #135 to fix #63. Dependencies now install during image builds, both services run as non-root, Compose uses data-only storage, and ports bind to loopback. Railway startup uses the built environment. All seven CI checks pass.

    #135

  2. added a commit that references this issue on Oct 27, 2026
  3. added a commit that references this issue on Oct 29, 2026
    09c25b1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is neededpriority:P1Important reliability/adoptionsecuritySecurity-related

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions