Cates Works
All capabilities
Create

Accounts, Login & Security

When your app has accounts, security isn’t optional. I implement modern authentication (email/password, magic links, SMS codes, passkeys, and SSO), role-based permissions, and strict data isolation so one customer can never see another’s data — the same patterns I use across multi-tenant platforms.

“I need real user accounts, but I’m nervous about doing security wrong.”

What's included

  • Email, magic-link, SMS-OTP & passkey login
  • SSO / OIDC for teams
  • Role-based access control (RBAC)
  • Strict per-tenant / per-user data isolation
  • Session management & audit trails

Where I've shipped it

Real client work that put this capability to use.

Related reading

The API said 200 OK. Three times, nothing had happened.

A value I could write but never read back, a PATCH that returned success and quietly persisted nothing, and a login test that could only pass by defeating the security control I had just installed. Three ways a success response lied during one production deploy.

The security emails had never sent once, and nothing anywhere complained

A shared internal service sends the “we noticed a new sign-in” emails for several apps, and it verifies a signature on every request — against a list of secrets that turned out to be empty. Every send had been failing since the day the feature shipped, and because that call is fire-and-forget by design, nothing ever said so.

I turned on a captcha for one login screen. Two apps I never touched stopped letting anyone in.

Adding bot protection to a customer portal looked like a one-app change: a widget, a token, a switch. Minutes later staff couldn’t reach the admin console and the mobile app’s login was dead too. The switch wasn’t per-app — and that’s the part worth understanding before you flip one.

The bug report cited a fix. The fix was for a different bug.

A detailed security report landed on one of my own systems, complete with a specific commit as proof this exact class of bug had already been caught once before. The commit was real. It fixed something else entirely. Here’s what checking the citation — instead of just the argument — turned up.

I stopped trusting my own review, so I made two AI agents argue about it

The agent that writes a fix is the worst-positioned reviewer of that fix — it already believes the design is right, or it wouldn’t have built it that way. Here’s what changed when I stopped asking one agent to check its own work, and started asking a second one to try to break it instead.

What your software is allowed to know about you

Most tools “collect usage data.” Almost none of them tell you where the line is. Here’s the written contract I hold my own software to — the exact list of what may be sent, and what must be rejected.

Permission bugs don’t throw errors. They just leak.

A crash tells you something broke. A broken permission check quietly returns someone else’s data with a 200 OK. Here’s what a hard audit of my own platform turned up, and the rule that closed all of it.

One login for every app you own

Five products meant five sets of credentials, five password resets, and five places to forget to revoke access. Consolidating them behind one branded sign-in changed the support load more than any feature did.

Why your confirmation emails land in spam

The booking confirmation your customer never got is not a mail setting — it’s missing infrastructure. Here’s what has to be in place before a mailbox provider will trust mail from your domain.

Let’s talk

Have a project, or a product that could work harder?

Most projects begin with a short, no-pressure discovery call.