Authentication is usually the first real backend a product grows, and it is the one where a mistake is least forgivable. Everything downstream — every permission, every private record, every account — inherits whatever assumptions you baked into it. So we treat auth as foundational engineering, not a checkbox, and we build it on a small set of principles that have held up across every product we ship.
Principle 1: Safe by default
The secure path has to be the easy path, or people will route around it under deadline pressure. So a new route is private until someone deliberately makes it public, a new record is owned until someone deliberately shares it, and the framework's safe primitives are the ones closest to hand. When the default is safe, forgetting to think about security still lands you somewhere defensible.
Principle 2: One identity seam
Who the current user is — and whether they are allowed to do a thing — is answered in exactly one place. The rest of the app asks that seam; it never re-derives identity from a cookie or a token on its own. This is the same seam discipline from our full-stack architecture, applied to the most sensitive question in the system.
// Every protected surface asks the same question the same way.
// The rule lives here; no route reimplements it or guesses.
export async function requireUser(): Promise<Session> {
const session = await getSession();
if (!session) throw new UnauthorizedError();
return session;
}Principle 3: Least privilege, expressed as data
Permissions are decided by asking whether a role may perform an action on a resource — not by scattering role checks through the UI. That decision lives in a pure function that takes the actor, the action, and the resource and returns an answer. Because it is data and logic rather than a tangle of conditionals, it can be tested exhaustively and reasoned about in one sitting.
- Deny by default. Access is something you grant explicitly, never something you forget to take away.
- One decision point. Authorization is answered in a single place, so a policy change applies everywhere at once.
- Auditable by design. Because the decision is pure, you can prove why any request was allowed or denied.
Principle 4: Trust is earned and verified, not assumed
This principle stretches beyond auth into the heart of Pulse. Trust should rest on something verifiable, not on a claim. In authentication that means never trusting client-supplied state you have not validated on the server. In a reputation system it means building the record from events that actually happened. Same instinct, different scale: prefer proof to assertion, everywhere it matters.
Security is not a feature you add. It is a set of defaults you refuse to compromise, especially when you are in a hurry.
- #Security
- #Authentication
- #Architecture
- #Product Engineering