The DNS Module as a **Rust component** compiled to WebAssembly and served by Fermyon Spin — our first real use of the Spin server on port 4245, and a genuinely good fit: a small, sandboxed, portable HTTP service that can reach exactly one host.
## Why Spin Fits DNS
A DNS agent should do one narrow thing and touch one endpoint. Spin's component model enforces exactly that. Outbound HTTP is allowed only to hosts named in the manifest — so this component reaches deSEC and nothing else, even if its code were compromised.
[component.dns] allowed_outbound_hosts = ["https://desec.io"] [variables] desec_token = { required = true, secret = true }
## Rust, Native to WebAssembly
Rust is Spin's first-class language and compiles to compact WebAssembly directly — no JavaScript-to-WASM step. The component is a small HTTP handler wrapping the deSEC REST calls (the same operations as the TypeScript core's deSEC adapter). `spin up` serves it. A TypeScript→WASM variant can be built later to compare the two toolchains on Spin, per the original plan to try both.
## Running It
`spin up --listen 127.0.0.1:4245`, fronted by Caddy as `dns.localhost` (the port policy: reach by name, never a hardcoded port). The token arrives as a Spin variable from an environment or Vault provider — never in the manifest. The same component deploys unchanged to a VPS or Fermyon Cloud, which is the portability the Embassy model wants.
## Links
## See - DNS Module — the core this wraps - Calling the Module — why Spin is canonical - The Guide — what consumes this service