Why this site has no login form
The admin panel behind pontelon.com stores no passwords, no password hashes and no sessions of its own. Here is what that buys, and what it costs.
The most secure credential is the one you never stored.
Pontelon’s own admin panel is a small application: a contact inbox, a customer
list, a staff directory, some settings. The sort of thing that normally gets an
email-and-password form, a users table with a bcrypt column, a session cookie,
a password reset flow, and — eventually — an incident.
It has none of those. Identity is handled entirely by Cloudflare Access, which authenticates the visitor before a request ever reaches our Worker and forwards a signed JWT. The application verifies that token and reads the email out of it. That is the whole of it.
What disappears
Work through what a password-based version would have needed, and what each piece is worth defending:
- A credential store. There is no
password_hashcolumn, so there is nothing in the database worth stealing. A full dump of our D1 instance contains contact inquiries and a customer list. Unpleasant; not catastrophic. - A session mechanism. No session table, no signed cookie of our own, and therefore no session fixation, no session-not-invalidated-on-logout, no “sessions live for 30 days because someone complained”.
- A reset flow. Password reset is the most-attacked endpoint in most applications, because it is designed to give access to someone who cannot prove they have it. We do not have one to get wrong.
- Credential stuffing. There is no form to stuff.
- Rate limiting on login. Nothing to rate-limit.
Each of those is a class of bug, not a bug. Deleting a class is worth more than fixing ten instances of it.
What it costs
Honesty requires the other column.
You are dependent on an identity provider. If Cloudflare Access is down, the admin panel is unreachable. For a panel used by one person a few times a week, that is an easy trade. For a support team working a queue, it is a conversation about SLAs.
It only works for people you can enumerate. Access is excellent for staff and useless for customers. The moment you have ten thousand users who each expect an account, you are building authentication again.
The verification is yours to get right. The token arrives; nothing forces you to check it properly. Three things go wrong here more often than anything else:
-
Trusting
Cf-Access-Authenticated-User-Email. Access sets this header, and so can anybody who reaches your origin without transiting Access. If your origin is addressable — and unless you have mTLS or a tunnel, it is — that header is a plaintext assertion from an unauthenticated stranger. The email must come out of the verified JWT payload and nowhere else. -
Checking the signature but not the audience. Every Access application in an account is signed by the same team keys. A token minted for a different app in the same tenant will pass a signature check perfectly. The
audclaim is what pins a token to this application, and omitting it turns every other app in your account into a way in. -
Failing open. If the JWKS endpoint is unreachable, what does your code do? An unconfigured admin panel that lets everybody in is strictly worse than one that lets nobody in. Missing config, unreachable keys, malformed token and unknown email should all take the same path out: denied.
The rule we would apply to your system
Not “never build authentication”. Sometimes you must.
The rule is: be able to say what a database dump costs you. If the answer includes “every customer’s password hash, which some of them reused on their bank”, you have taken on a liability that has nothing to do with your product. Ask whether you need it.
When customer accounts genuinely are required, our default is passwordless
magic links — a signed, single-use, short-expiry token emailed to the address,
exchanged for an HttpOnly; Secure; SameSite=Lax session cookie. It stores an
email address and nothing else. There is no credential to steal, no reset flow
to get wrong, and credential stuffing does not apply.
It is not the most convenient thing you can build. It is the thing with the fewest ways to go badly wrong, and after enough incident reviews those stop being different considerations.