Skip to content

security: design simple secure remote access and stronger web authentication #181

Description

@eXPerience83

Context

Remote Dev is primarily a single-user / homelab development appliance, not a multi-tenant enterprise platform. Its most important security property is the outer-container boundary: Codex, Antigravity and future agents may be powerful/root inside their own role container, but must not gain access to the TrueNAS host, host container engine, broad host filesystem, sibling-agent state or the user's whole PC.

The current browser terminals use ttyd Basic authentication and the deployment is intended for a trusted LAN and/or private mesh such as Tailscale. Issue #69 now owns the simplified immediate password contract: one configuration-backed WEB_PASSWORD mechanism, with WEB_PASSWORD_FILE removed project-wide.

This issue is the single design/research tracker for stronger browser/remote-access security beyond that baseline. Do not scatter Tailscale/HTTPS/MFA/passkey/auth-gateway decisions across unrelated issues.

Product/security priorities

In order of importance:

  1. preserve outer-container isolation and narrow role-private mounts/credentials;
  2. keep Remote Dev ports off the public Internet;
  3. make network reachability private and explicit;
  4. keep a simple independent password per agent endpoint while it remains the supported ttyd authentication mechanism;
  5. evaluate stronger identity/authentication only where it materially improves security without making the appliance difficult to operate.

A host administrator/root is inside the trust boundary. Remote Dev does not attempt to hide App configuration or host files from a sufficiently privileged TrueNAS administrator.

Current baseline to preserve

  • launcher, Codex and optional Antigravity are separate containers using the same reviewed image reference;
  • launcher has no agent workspace/state/credentials and no Docker/Podman socket;
  • agent roles receive only their narrow role-private mounts;
  • no privileged mode, SYS_ADMIN, host PID/network namespace, host-root mount or host Docker socket;
  • agent browser endpoints require authentication unless an explicit insecure override is deliberately selected;
  • normal deployment is LAN/Tailscale/private-network only, never direct public-Internet exposure;
  • security/test: standardize agent-terminal authentication on WEB_PASSWORD #69 removes WEB_PASSWORD_FILE; current browser passwords are configuration-backed WEB_PASSWORD values.

Track A — simplest secure default

Define and document the easiest safe default for TrueNAS and generic Docker:

  • bind/publish only on an explicitly selected LAN or private-mesh address where practical;
  • never recommend 0.0.0.0 as a user-facing default merely for convenience;
  • preserve independent passwords for Codex and Antigravity while direct ttyd endpoints remain exposed;
  • define password-quality guidance appropriate to a single-factor local web terminal (long random/passphrase, no forced periodic rotation or arbitrary composition rules);
  • validate password values without logging value, length, hash or derived credential;
  • keep password changes simple through deployment configuration rather than granting the agent or launcher host-administration privileges;
  • document that an agent/root process in its own container is not a supported secrecy boundary for that role's own ttyd credential.

Track B — Tailscale / private-mesh access

Evaluate Tailscale as the preferred optional remote-access layer before inventing project-specific VPN/auth infrastructure.

Compare at least:

  1. Tailscale already running on the TrueNAS host;
  2. Tailscale Serve in front of Remote Dev;
  3. a narrowly scoped sidecar/in-stack Tailscale client only if it adds a concrete benefit for hosts that do not already provide Tailscale;
  4. other private-mesh/VPN equivalents only where needed for a vendor-neutral contract.

Requirements:

  • prefer private tailnet access over any public listener;
  • evaluate automatic HTTPS via Tailscale Serve;
  • evaluate binding backend ttyd/launcher endpoints to loopback or a private interface when a fronting service is used;
  • preserve role isolation and avoid giving agent containers Tailscale administrative credentials/control unless proven necessary;
  • do not require a container-engine socket;
  • do not treat Tailscale identity + ttyd password as formal MFA unless the actual authentication factors/session semantics justify that claim;
  • document account/device revocation and recovery behavior;
  • keep direct LAN access available where desired.

Funnel boundary

Tailscale Funnel intentionally makes a service reachable from the public Internet. It is not the default security improvement sought here.

  • keep Funnel disabled/out of the normal supported path;
  • any future Funnel/public exposure requires a separate explicit threat model and stronger front-door authentication/rate limiting before implementation.

Track C — single authenticated front door / auth gateway

The current launcher only navigates; it does not proxy ttyd HTTP/WebSocket traffic. Research whether a future authenticated gateway can safely become the only browser entry point without giving it agent state or container-control privileges.

Candidate shape:

browser
  -> HTTPS/private mesh/auth gateway
      -> launcher
      -> Codex ttyd
      -> Antigravity ttyd

Requirements:

  • backend agent ports need not be directly reachable from the user network when gateway mode is enabled;
  • preserve WebSocket, origin, base-path, reconnect and tmux behavior;
  • gateway must never receive/mount agent OAuth, GitHub, SSH, workspace or runtime state;
  • no Docker socket or TrueNAS API credentials merely to route traffic;
  • avoid duplicating full authentication/session code inside Remote Dev if a mature upstream component can own it more safely;
  • keep direct/simple mode available for users who do not want a gateway.

Track D — identity headers / passwordless private mode

Research whether a trusted fronting layer can authenticate the user and pass a bounded verified identity to ttyd/backend, for example through ttyd's supported auth-header mechanism or another reviewed proxy contract.

Potential outcome:

Tailscale/validated gateway identity
  -> trusted local backend path
  -> ttyd without a reusable app password

Before accepting this:

  • prove client-supplied identity headers cannot bypass the trusted gateway;
  • backend must not also be directly reachable on an interface where the header can be forged;
  • define exactly which header/value is trusted and how it is normalized;
  • test browser/WebSocket behavior and logout/revocation;
  • do not claim passwordless security merely because a header exists.

Track E — MFA / passkeys

Do not implement a home-grown TOTP/WebAuthn/session system inside the launcher.

If stronger interactive authentication is worthwhile, evaluate a mature auth gateway that can provide:

  • WebAuthn/passkeys as the preferred phishing-resistant UX;
  • optional TOTP only as fallback/recovery where appropriate;
  • secure session cookies, CSRF/origin handling and logout;
  • simple backup/recovery behavior suitable for a home deployment.

Candidates such as Authelia or another maintained reverse-auth gateway may be evaluated, but this issue does not preselect a product.

Decision criteria:

  • materially stronger than current WEB_PASSWORD + private network;
  • easy enough to install/update/recover on TrueNAS;
  • no agent access to gateway secrets/admin state;
  • no broad host privilege;
  • no per-agent duplicated MFA enrollment unless there is a compelling reason;
  • failure/recovery cannot silently expose ttyd without authentication.

Admin/menu boundary

Changing the web-access security configuration from inside an agent terminal is not a goal.

  • Codex/Antigravity must not gain TrueNAS/Docker administrative control merely to rotate their own web password;
  • launcher must not gain a Docker socket or TrueNAS admin token merely to provide a settings UI;
  • if a future menu/admin exists, define a separate least-privilege control plane and authentication boundary first;
  • simple deployment configuration remains preferable when changes are infrequent.

Relationship to SSH

#124 owns optional role-scoped inbound SSH / remote-client integration. Keep it separate:

TrueNAS Community App boundary

#170 is deferred future research. Current work stays on compose/truenas.yml.

If a Community App is revisited later, it must consume the security decisions established here/#69 rather than invent a third authentication model.

Deliverables

  • threat-model summary for local LAN, Tailscale/private mesh and accidental public exposure;
  • recommended simple default for current TrueNAS YAML users;
  • Tailscale Serve/HTTPS feasibility result;
  • decision on whether direct agent ports can/should become loopback-only behind an optional gateway;
  • auth-header/passwordless feasibility result;
  • passkey/MFA gateway recommendation or explicit defer decision;
  • clear separation of baseline, optional stronger mode and explicitly unsupported public-exposure modes;
  • focused implementation issue(s) only after a design is selected.

Non-goals

  • enterprise multi-tenant RBAC;
  • hiding secrets from TrueNAS root/administrators;
  • custom cryptographic authentication protocols;
  • writing our own TOTP/WebAuthn stack;
  • public Internet exposure by default;
  • Funnel/Tor/public relay as a shortcut around private networking;
  • giving agents or launcher host/container administration privileges;
  • replacing the completed outer-container hardening model.

Acceptance criteria

This research is complete when Remote Dev has one documented access-security ladder that is both realistic and simple:

  1. secure local/private baseline;
  2. recommended private remote-access/HTTPS option;
  3. optional stronger identity/passkey layer only if justified;
  4. no contradictory password/secret mechanisms or public-exposure recommendations across active issues/docs.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions