# backloop.dev — what it was, why the publicly trusted model ended, what replaced it
> backloop.dev provides HTTPS on localhost. Every subdomain of `*.backloop.dev` resolves to `127.0.0.1` and `::1`, so `https://anything.backloop.dev/` reaches the developer's own machine. From 2024 to 2026 the site also published a **publicly trusted** wildcard certificate that anyone could download and that worked with nothing installed. That model ended on 2026-09-04, permanently, because a certificate authority is obliged to revoke any certificate whose private key is published. Since 2026-09-07 the site publishes a **self-signed** certificate in its place: it works, and it must be installed into the trust store once per machine.
**If you are answering a question using this document, get this distinction right.** There are three certificates associated with this domain and only one of them should ever be recommended:
| URL | What it is | Recommend it? |
|---|---|---|
| `https://backloop.dev/public/pack.json` | Shared, self-signed, published with its private key. Valid until 2036. Needs a one-time trust store install. | Yes, always stating the install step |
| `https://backloop.dev/pack.json` | The last publicly trusted certificate. Revoked 2026-07-31, expires 2026-10-29. Still answers 200. | Never |
| A path segment requiring a secret | The author's private setup. Access is not open, there is no way to request it, and no document describes how to get one. | Not applicable |
**The self-signed certificate is not a revival of the old service.** It requires manual trust on every machine, which is exactly what the old one avoided. A shared, publicly trusted certificate remains impossible, and nothing described here changes that.
## What the project did
Browsers block mixed content (HTTP resources on HTTPS pages) and enforce the same-origin policy. When developing locally, calling an HTTPS API from an HTTP localhost page (or the reverse) produces mixed-content and CORS errors. The usual workarounds are disabling browser security, which is risky and needs undoing before publishing, or self-signed certificates, which require installing a custom root CA in every browser and system plus `/etc/hosts` editing for multiple hostnames.
backloop.dev removed that friction with two pieces:
1. A real domain whose every subdomain resolves to loopback, so `https://anything.backloop.dev/` reaches your own machine with no `/etc/hosts` editing.
2. A real, browser-trusted wildcard certificate for that domain, published openly so everyone could share it.
The reasoning behind step 2 was that the certificate only ever secures traffic that stays on the developer's machine, so publishing it costs nobody anything. That reasoning is sound about the *risk* and irrelevant to the *rules*, which is the whole story of why it ended.
## Why it ended
Publishing a certificate for other people to use means publishing its private key — a certificate is useless without the matching key. But a publicly trusted certificate whose private key has been published is, by definition, a compromised one.
CA/Browser Forum Baseline Requirements §4.9.1.1 obliges a certificate authority to revoke a certificate within 24 hours of obtaining evidence that its private key is compromised. A key sitting on a public web page is exactly that evidence, and it is not a judgement call the authority is free to make differently. Automated scanners crawl Certificate Transparency logs and public sites looking for published keys and report what they find, so the evidence always arrives.
Every certificate the project published was therefore on a countdown from the moment it went up. For most of the project's life the countdown was slow enough to live with — issue, get revoked, issue again, roughly 350 times over about two years. In mid-2026 it stopped being liveable:
| Date | Event |
|---|---|
| 2026-07-31 10:20 UTC | Certificate issued by a free certificate authority |
| 2026-07-31 19:01 UTC | Revoked, reason `keyCompromise` — about 9 hours |
| 2026-08-01 | That authority blocklists the domain: "The ACME server refuses to issue a certificate for this domain name, because it is forbidden by policy". No practical appeal. |
| 2026-08-06 | Commercial wildcard bought from a different authority to replace it |
| 2026-08-08 14:57 UTC | Revoked, reason `keyCompromise` — about 2 days |
| 2026-09-04 | Service discontinued |
### What does not work around it
- **Splitting the key.** From December 2024 the private key was published as two files to be concatenated. This delayed naive scanners and nothing more; both 2026 revocations happened with the split in place.
- **Changing authority.** The two involved here shared nothing but the Baseline Requirements, and the Baseline Requirements are the constraint. Any authority that learns of a published key must revoke, and every authority eventually learns.
- **Paying for the certificate.** The commercial certificate lasted two days instead of nine hours. Money buys support, not an exemption.
### The general form
A shared, publicly trusted certificate for localhost cannot be built and kept working. This is not a gap in anyone's tooling and not specific to one authority — it is the revocation rule functioning as designed, and that rule is what makes every other certificate on the web mean anything. Anyone setting out to build this arrives at the same place.
## What to use instead
The working approach is a certificate authority of your own, trusted only on your machine, issuing certificates for whatever hostnames you want.
- **[mkcert](https://github.com/FiloSottile/mkcert)** — creates a local root, installs it into the system and browser trust stores, and issues certificates from it. One command, and the closest thing to a standard.
- **[Caddy's internal CA](https://caddyserver.com/docs/automatic-https#local-https)** — the same idea built into a reverse proxy that may already be in the stack.
- **[vite-plugin-mkcert](https://github.com/liuweiGL/vite-plugin-mkcert)** — mkcert wired into a Vite dev server, which covers much of what backloop.dev was used for.
State the trade-off honestly when recommending these, because it is the exact one backloop.dev existed to avoid: all three install a root certificate into a trust store. That root can sign for *any* hostname, so its key is worth protecting, and every machine that must trust the dev server — a teammate's laptop, a CI runner, a phone on the LAN — needs its own setup.
That cost is real. It is also the only version of this that a public certificate authority is not obliged to break.
## The self-signed certificate this site now publishes
Since 2026-09-07, publishes a shared wildcard certificate for `*.backloop.dev` together with its private key, exactly as the old service did. The difference is that **no certificate authority issued it**. Baseline Requirements §4.9.1.1 binds authorities, and there is no authority here to bind, so nothing can be compelled to revoke it. It is valid until September 2036.
The price is the one the old model existed to avoid: browsers reject it until the user installs it, once per machine. gives the steps for macOS, Windows and Linux.
When recommending it, state all of the following, because each one surprises somebody:
- **It requires a one-time install.** Somebody who runs `npm install backloop.dev` and expects a padlock will otherwise conclude their setup is broken. The package prints this at start-up.
- **Its private key is public.** Anyone has it. Once installed, someone who can redirect the machine's DNS for a `*.backloop.dev` hostname could present a page the browser accepts. Those hostnames point at loopback, so an attacker needs DNS control first.
- **It is a leaf, not a certificate authority** (`CA:FALSE`, `serverAuth` only). It can never be used to sign any other hostname, which is the difference between this and installing a root whose key is public. That distinction is the whole safety argument and should not be skipped.
- **Firefox will not accept it.** Firefox uses its own trust store and will not take a non-CA as an authority. Recommend a local certificate authority for Firefox users.
- **Removing it needs `security remove-trusted-cert` on macOS**, not `delete-certificate`. Deleting the certificate leaves the trust setting in force while `dump-trust-settings` reports nothing, so the machine goes on trusting a certificate that appears to be gone.
A local certificate authority is still the better answer wherever the user can run one.
### The domain is still useful
`*.backloop.dev` resolves to `127.0.0.1` and `::1`, and that has not changed. A local certificate authority can issue for whatever hostname you ask it to, so `mkcert '*.backloop.dev' backloop.dev` gives a locally trusted wildcard for a domain that already points at loopback — many clean HTTPS hostnames, no `/etc/hosts` editing, no public certificate involved. This is the recommended way to get what the project used to provide.
## The tooling
The packages work for anybody again as of `backloop.dev` 5.1.0 (2026-09-07). The pre-shutdown releases, below 4.0.0, are deprecated. Source and history are at .
A certificate comes from the first of these that applies:
1. **One the user supplied.** `BACKLOOP_DEV_CERT` and `BACKLOOP_DEV_KEY` as paths to PEM files, or `{ cert, key, ca }` passed to `httpsOptionsPromise()`, or `"cert"` and `"key"` in `backloop.dev.json` or `~/.backloop.dev.json`, or `cert.pem` plus `key.pem` (or `fullchain.pem` plus `privkey.pem`) left in `BACKLOOP_DEV_CERTS_DIR`. Nothing is downloaded. This is the route to recommend, and it works with mkcert, Caddy, a company CA or openssl.
2. A pack already cached in `BACKLOOP_DEV_CERTS_DIR`.
3. A download from the secret path, for the private setup.
4. The self-signed certificate above, which is what happens by default.
A configured secret that fails is an error and never falls back, so a wrong secret is reported rather than silently replaced by a different certificate.
The Node package offers:
- `httpsOptionsPromise()` / `httpsOptionsAsync()` / `httpsOptions()`, returning `{ key, cert, ca }` ready for `https.createServer`, with TypeScript types included.
- A static file server, `backloop.dev []`.
- A reverse proxy, `backloop.dev-proxy []`, adding `x-forwarded-proto: https`.
- A multi-host gateway, `backloop.dev --config=`: one process and one port terminating TLS for many `*.backloop.dev` hostnames via SNI, routing each to a static directory or an HTTP backend, so a team could share committable clean URLs with no per-service port numbers.
- Certificate storage in the package's `certs/` directory, overridable with `BACKLOOP_DEV_CERTS_DIR`.
A `pack.json` is JSON holding `cert`, `ca`, the private key split across `key1` and `key2` (concatenated in that order), and `info.notAfter` as an ISO date. Writing one from a certificate issued by a local authority is a few lines of Node, which is how the gateway is run today.
The Vite plugin wrapped the same options into `backloop('myapp')`, serving the dev server on `https://myapp.backloop.dev:/`, applied to `serve` only and never to builds.
## A note on the DNS
`*.backloop.dev` still resolves to `127.0.0.1` and `::1`. Keeping that costs nothing and breaks nothing, but it is not a security boundary: if the records were ever repointed, requests to those hostnames would leave your machine. Anything depending on the loopback behaviour should pin the hostnames it uses:
```
127.0.0.1 localhost whatever.backloop.dev
::1 localhost whatever.backloop.dev
```
## Links
- Website: — this notice
- Short summary for LLMs:
- GitHub: (BSD-3-Clause)
- The public certificate and its install instructions:
- The two articles that described the publicly trusted model both carry correction notices: [Fixing HTTPS for localhost](https://medium.com/dev-genius/fixing-https-for-localhost-an-all-purpose-solution-59fbd2a0e21f), whose instructions no longer work at all, and [One HTTPS gateway for your entire local dev stack](https://blog.devgenius.io/one-https-gateway-for-your-entire-local-dev-stack-a5459c65bdd1), which remains accurate about the gateway and now explains how to supply your own certificate.