Flat vector illustration of a walled castle on an island beside a large ornate key

Castle walls vs. API keys: the moat doesn't matter if the spy gets invited in

Castle walls vs. API keys: the moat doesn't matter if the spy gets invited in

Perimeter defense fails the moment somebody knocks. Authentication doesn't care who knocks.

Somewhere out there is a Klipper user who set up port forwarding on a Tuesday, tested it from the office, and went back to printing. The setup works. Nothing bad happened that week, or that month, or that quarter. "Who's going to find my printer?" is a reasonable question with a bad answer: a machine that scans the entire internet in under an hour, every day, forever, and a search engine that indexes the results.

Here's the whole idea in one sentence: "You can have huge walls and turrets with a moat, but if the spy walks in with a family member or gets invited, that doesn't matter. The API key is in essence talking in a language the spy doesn't speak and can never learn — so it's probably the strongest defense you can get, and it's how your banks and stuff work."

The rest of this article is that sentence, with receipts.

The castle plan

The castle is the security model most of us inherited. Your firewall is the wall. NAT is the moat. The obscure port number is the drawbridge, moved slightly to the left so attackers trip over the side of the bridge instead of the middle. The castle makes one promise: strangers stay outside. And it rests on one assumption: you can tell a friend from an enemy by where they're standing. Outside the walls, suspect everything. Inside the walls, trust everyone.

For physical castles, that assumption held, because scouting a real castle took weeks and armies are expensive. The internet deleted the expensive part. Which brings us to the moat.

Discovery is free now

In 2013, researchers at the University of Michigan released ZMap, a scanner that can sweep every IPv4 address on the internet from a single machine in under 45 minutes. Not a cluster. One machine, one command, a coffee break. That was 2013; the tooling has only gotten better since.

Shodan turned that capability into a search engine. It scans constantly and indexes what it finds, including the HTTP banners and fingerprints your printer's interface leaks the moment anyone knocks on it. "There are search engines that constantly scan and index the entire internet for arbitrary IP addresses coming online, and those can be used to find your OctoPrint instance." That's not me talking; that's the OctoPrint maintainer, in 2022, explaining for the umpteenth time why exposing OctoPrint directly to the public internet is a bad idea.

The pattern shows up in the historical record, repeatedly:

  • September 2018: the SANS Internet Storm Center flags thousands of OctoPrint instances reachable from the internet with no authentication at all. A Shodan search at the time turned up over 3,700 exposed interfaces, nearly 1,600 of them in the US.
  • November 2018: a troll using Shodan finds more than 800,000 devices with printer ports open, picks the first 50,000, and prints pro-PewDiePie leaflets on them. Most owners just found out their printer talks to strangers.
  • January 2019: a second wave. This time the attackers ran Masscan themselves, sweeping the entire internet for port 9100 and finding 82,000 open printers in about 20 hours. They claimed messages printed on 100,000+ machines, and told the BBC that causing physical damage was "very much a possibility."
  • In 2017, for the earlier chapter: a self-described grey hat claimed over 150,000 printers pwned the same way.

Your Mainsail or Fluidd instance is findable the same way. Moonraker's HTTP headers, the frontend's favicon, the response on your forwarded port: all fingerprints, all indexed. "Nobody will find my port" isn't a plan. It's a wish, and the bots don't need luck.

The spy walks in with a family member

The castle's fatal flaw isn't that the walls are too low. It's that the walls answer the wrong question. They ask "where are you from?" when the useful question is "who are you?"

Three ways the wall gets walked around:

The invitation you sent. Every port forward is an open door, and you didn't invite one guest; you invited everyone. The door isn't "for you," it's for the entire internet. You just assumed nobody would walk through.

The family member. Anything already inside the network is trusted. Malware on your laptop, a phone app with bad manners, a sketchy plugin on the Pi: once something is inside the walls, the castle has no more questions. The printer trusts your LAN because it's your LAN. That's exactly the trust zero-trust architecture was invented to remove; NIST's definition is blunt: no implicit trust "based solely on their physical or network location."

The guest who doesn't know the rules. The webcam. OctoPrint's own docs admit the interface only embeds the camera stream and can't protect it: "If an anonymous user correctly guesses the webcam URL, they will thus be able to see it." People forward the camera port for the timelapse and never think of it as a door. It's a door. Same for every helper service you exposed along the way.

This is what "the spy walks in with a family member or gets invited" means technically. The perimeter can't tell you apart from the bot that knows the port, and it never even sees the devices that are already inside.

The language the spy can't learn

Flip the model. Think about your bank. The bank's front door is public on purpose. It has a street address, a website, a lobby. Anybody can walk up to it; everybody's browser does, dozens of times a day. What stops a stranger from reading your balance is not a wall around the building. It's that past the front door, the conversation itself demands proof of who you are, and every byte of it is encrypted.

That's the design that runs the modern internet: SSH, HTTPS, your bank, your email. All of them assume the attacker CAN reach the endpoint. They don't pretend the endpoint is hidden. They make discovery worthless: the attacker knocks all day and gets nowhere, because the conversation requires something they don't have.

Rob's metaphor, made precise: a spoken language can be learned by listening. That's how kids do it. A cryptographic key is not a vocabulary. Listen to a million encrypted handshakes and you'll hear noise; the key never crosses the wire, and the math behind the handshake is the same math that puts the padlock in your browser. That's the actual content behind "can never learn." It's not a vibe, it's number theory.

For Klipper users, this isn't abstract. Moonraker already speaks this language. Its docs: "Untrusted clients must use either a JSON Web Token or an API key to access Moonraker's HTTP APIs." The API key goes in the X-Api-Key header; browser sessions log in and get tokens; websockets get one-shot tokens. IP-based trust (trusted_clients) covers your LAN, but everything beyond it has to prove identity on every request. An exposed Moonraker with auth on is a wall of 401s to every bot on the internet. The bot doesn't need to break anything. It needs your key, which it doesn't have and can't derive.

Same story on any SSH box with password login disabled: bots hammer port 22 all day, every day, and fail. Nobody cares. Discovery was assumed. The defense moved into the conversation.

Where the key fails

Now the honest part. The API key is the strongest single layer, and it has four boring failure modes.

Leak the key, teach the spy the language. An API key is a bearer token: whoever holds it, is you. And keys leak in boring ways. Frontends often show the key in their settings pages, and settings screenshots end up on forums and in Discord servers. Config files get committed to public repos. Keys get pasted into chats "just for a second." The scale of this is documented: GitGuardian's 2024 report found 12.8 million new secrets leaked on public GitHub in 2023 alone, up 28% year over year, and 90% of valid exposed secrets were still working five days after the author was notified. People delete the commit instead of rotating the key; scanners have usually already copied it. The fix is unglamorous: never commit configs, blur screenshots, rotate keys you've shared. Moonraker makes rotation one request, and the change applies immediately.

No TLS, no privacy. Over plain HTTP, the key crosses the wire in the clear. Anyone on the path can read it: the coffee-shop Wi-Fi, a compromised router, the relay box in between. Authentication and encryption are a pair; an API key without HTTPS is a password shouted across a room. That's why the auth layer sits on HTTPS, or inside a VPN that encrypts for you.

Physical access defeats everything. Take the SD card out of the Pi and read it on any laptop: API key, Wi-Fi password, configs, all of it. Every defense in this article assumes the attacker is remote. A person in the room with the hardware is a different threat model, and no API key fixes it. The walls here are software.

Auth doesn't patch a bug. In May 2022, OctoPrint fixed three vulnerabilities (two XSS and an open redirect) that were specifically exploitable against instances exposed on the public internet, via malicious links sent to the admin. Auth on the API doesn't stop a crafted link. Software that is reachable is software that must be updated.

None of this makes the key pointless. It makes the key a layer.

Layers, not walls

Here's the setup that survives contact with the internet:

  1. Make it undiscoverable. A VPN like Tailscale puts your printer, your phone, and your laptop on one private network. No forwarded ports. Discovery returns silence: nothing to find, no banner to fingerprint, no version to check. This is the single biggest change you can make, and the guide in this series walks through it.
  2. Keep authentication on anyway. The API key is the second line, for the day something inside the tunnel misbehaves. Your laptop gets malware; the malware can reach the printer over the VPN; the key is what stands between it and G-code upload. (How-to in this series.)
  3. HTTPS for anything that must stay public.
  4. Update the stack. OS, Moonraker, frontend, printer firmware.
  5. Handle keys like passwords. No commits, no screenshots, rotate after sharing.

The castle is still worth building. It keeps out the low-effort noise, groups your devices, and gives you a place to hang rules. But it's a layer, never the plan. The plan is: nothing to discover, and a language the finder can't speak.

The short version

  • Delete the port forwards. Today.
  • Turn on Moonraker's API key / user auth (see the how-to).
  • Put the printer on Tailscale (see the guide).
  • Update regularly; put the webcam behind auth or don't expose it.
  • Never commit configs or post screenshots with keys visible; rotate anything you've shared.

Next in this series

  • Moonraker API keys: how to lock your Klipper web interface down properly (planned: /blog/remote-series/moonraker-api-keys-guide)
  • Remote access without port forwarding: Tailscale for 3D printers (planned: /blog/remote-series/tailscale-remote-access)

Sources

Quick poll: what's remote monitoring worth to you?

Three questions, one tap each. We read every answer — it shapes what we build and cover next.

Votes are anonymous and stored on your device only. No account, no tracking.
Back to blog

Leave a comment

Please note, comments need to be approved before they are published.