SECURITY.md
Rama main · réplica de lectura del repositorio original.
# Security Policy
## What any-console is, security-wise
any-console gives a browser **full shell access to the host it runs on**.
Terminals, job execution, Git operations, and file read/write all run as the
OS user that owns the service. Treat access to any-console exactly like SSH
access to that machine: **anyone who holds the auth token (or a signed-in
device) can run arbitrary commands on your host.** There is no sandbox
between the web UI and your shell — that is the product working as designed,
which is why the deployment guidance below matters.
## Intended deployment
any-console is designed to be reachable **only from a private network you
trust** — a Tailscale tailnet, a LAN behind a firewall, or localhost.
- **Never expose it directly to the public internet** — no router port
forwarding, no Tailscale Funnel, no cloudflared / ngrok tunnels, no public
reverse proxy. The single-token auth model is not designed to withstand
internet-wide credential stuffing or token brute force.
- The recommended setup is [Tailscale Serve](https://tailscale.com/kb/1312/serve)
for HTTPS inside your tailnet, or plain HTTP on a trusted LAN.
- The server itself listens over plain HTTP (`0.0.0.0` by default) and does
not infer trust from where a connection appears to come from — anything
that can reach the port can attempt authentication. If the app is reached
exclusively through Tailscale Serve (which proxies to `127.0.0.1`), bind
the server to loopback (`__global__.host: "127.0.0.1"` in `config.json`)
so the plain-HTTP port is not also reachable over the LAN.
- Be careful with *any* other tunnel or proxy on the same host (`ssh -L`,
nginx, cloudflared): they can make external requests appear to come from
loopback. any-console always requires token / device-cookie authentication
regardless of transport — there is no header-based auto-auth to worry
about here.
## Authentication model
The model is intentionally simple (see `docs/DECISIONS.md` #3: single token,
no user separation):
- A random 32-character token is generated by `./any-console setup` (if
`data/auth.json` does not exist yet) and printed once in the setup output.
- Signing in exchanges the token for a per-device cookie. Devices can be
reviewed and revoked individually from **Settings → Auth**, and the
token itself can be rotated there.
- A signed-in device can add another device via a QR code (**Settings →
Auth → Trusted Devices → Add new device**) instead of retyping the token.
The QR link is short-lived (90s) and single-use; it never widens access
beyond the existing single-user model — it is device provisioning, not
user invites. See `docs/DECISIONS.md` #28.
- There are no user accounts or roles. One token means full access. The one
exception is scoped **API tokens** (Settings → Auth → API Tokens): they
can only queue dispatch requests (`POST /dispatch`), but an approved
dispatch still runs commands — treat them as secrets too.
- Request rate limiting and security headers are enabled by default.
- Authentication can be disabled — from the UI by turning off "Require
token authentication" in **Settings → Auth** (this empties the token, so
anyone with network access can use the console), or with
`ANY_CONSOLE_DISABLE_AUTH=1` in the server process environment (in
practice only `./any-console run` inherits your shell environment — a
managed systemd/launchd service does not). Both are intended for
disposable local development, never for a reachable deployment.
## If the token leaks
Assume full compromise of the OS user running any-console. Rotate the token
from **Settings → Auth** — note that rotating it does **not** invalidate
existing device cookies or API tokens, so also revoke all devices and API
tokens there. Do not just delete `data/auth.json` and restart: a server
without it runs with authentication disabled. Then audit the host: shell
history, tmux sessions, Git remotes/credentials, and `~/.ssh` reachable by
that user.
## Reporting a vulnerability
Please report vulnerabilities privately via
[GitHub private vulnerability reporting](https://github.com/kt0319/any-console/security/advisories/new)
rather than opening a public issue. Reports are handled on a best-effort
basis — this is a single-maintainer project — but authentication bypasses
and remote code execution reachable *without* a valid token are treated as
top priority.