-
-
Notifications
You must be signed in to change notification settings - Fork 283
Security
Spoolman has no authentication. Anyone who can reach it over the network can read and change your entire inventory.
That is deliberate. Spoolman is built to sit on a trusted home network next to your printers, where requiring a login on every Moonraker or OctoPrint call would only get in the way. It does mean the thing that actually protects your data is your network, not Spoolman.
This page covers the two ways a web browser can be tricked into crossing that boundary for you, and the settings that close them.
Important
If Spoolman is reachable from outside your own network, put it behind a reverse proxy that handles authentication (Authelia, Authentik, or your proxy's own basic auth). Do not forward a port straight to it. No setting on this page is a substitute for that.
Out of the box, and with no configuration at all, Spoolman refuses:
- Writes from another website. A page on any site you happen to visit cannot make your browser create, edit or delete your spools, or change your settings.
- WebSocket connections from another website. These bypass the browser's usual same-origin protection entirely, so without this a malicious tab left open could quietly watch your inventory.
Requests with no Origin header — Moonraker, OctoPrint, Home Assistant, curl, anything that is not a browser — are unaffected and keep working exactly as before.
You only need the settings below if you have a browser-based client on a different address than Spoolman, or if you want protection against DNS rebinding.
Set this if a web UI served from a different address needs to talk to your Spoolman — a Fluidd or Mainsail instance on another host, or your own dashboard.
You do not need it for Spoolman's own web UI, and you do not need it for Moonraker, OctoPrint, Home Assistant or any other non-browser client.
It is a comma-separated list of origins. An origin is a scheme, a host and optionally a port:
environment:
- SPOOLMAN_CORS_ORIGIN=https://fluidd.local,http://mainsail.local:8080Important
Include the http:// or https://. A bare fluidd.local:8080 is not an origin and will never match, so it silently does nothing.
Spaces after the commas are fine, and a trailing slash is ignored. The port matters: http://mainsail.local and http://mainsail.local:8080 are different origins.
- SPOOLMAN_CORS_ORIGIN=*Warning
This turns the origin checks off completely. Any website you visit can then read and modify your Spoolman data in the background, without you noticing. Only do this on a network you trust completely, and prefer listing the origins you actually need. SPOOLMAN_DEBUG_MODE has the same effect and is not meant for normal use.
Spoolman logs a warning at startup when either is active, so check your logs if you are not sure.
This one is off by default and most people do not need it.
It protects against DNS rebinding: an attacker points a domain they own at your Spoolman's local IP address, so that a page on their site talks to your instance as if the two were the same site. The protections above cannot catch this, because as far as the browser is concerned the attacker's page really is talking to its own domain.
Turning it on tells Spoolman which hostnames it should answer to, so a name it has never heard of gets refused. Set it to your own hostname:
environment:
- SPOOLMAN_ALLOWED_HOSTS=spoolman.mydomain.comComma-separated for several, and *.mydomain.com covers the domain and all its subdomains. These are hostnames, not origins — no http://, no port.
You do not need to list the things an attacker cannot own in the first place; these keep working automatically once the setting is on:
- IP addresses, e.g.
192.168.1.50:7912 - Single-word names, e.g.
spoolman, or a Docker service name -
.local,.localhost,.lan,.home,.home.arpaand.internalnames - Any hostname already named in
SPOOLMAN_CORS_ORIGIN— you never have to write your domain in both settings
Important
If you reach Spoolman through a reverse proxy on a real domain name, that domain must be in this list once you enable the setting, or every request gets a 400. The error message names the setting, and the allowed hostnames are logged at startup.
So: if you reach Spoolman by IP or by a .local name — which is most people — you can turn this on and set it to your domain only if you have one. If you reach it by a real domain name, list that domain.
Make sure your proxy forwards the hostname the browser asked for. Any one of these is enough:
- nginx:
proxy_set_header Host $host; - Apache:
ProxyPreserveHost On - anything that sets the
X-Forwarded-Hostheader
Traefik, Caddy and HAProxy do this by default. Without it, Spoolman sees your proxy's internal address instead of your real hostname and may refuse requests that came from your own web UI.
SPOOLMAN_METRICS_ENABLED is off by default. When you turn it on, the /metrics endpoint serves your vendor and filament names, colors and per-spool prices to anyone who can reach it, with no authentication.
Keep it on your internal network, or put it behind your reverse proxy's authentication. Spoolman logs a reminder at startup when metrics are enabled.