BLOG
Don't Be Your Team's 2FA Proxy
A fortnight off, and back to a queue of Slack DMs asking for 2FA codes. Why 'shared 2FA' isn't really 2FA — and the day-one access setup that fixes it.
- #security
- #operations
- #shopify
- #cloudflare
I came back from a fortnight off to a queue of Slack DMs all asking the same thing: “can you send me the code?” My 2FA app is the gatekeeper for our hosting account, our Shopify Partner dashboard, the analytics tool, the mobile build consoles, and a handful of integration portals. The requests had come in from devs, project managers, and a couple of departments I rarely talk to. Reading the thread back is the cleanest org audit I’ve had in years.
How it always starts
Someone — usually me — sets up the account. The hosting control panel, the cloud console, the Shopify Partner dashboard, the analytics tool, the error tracker, the email platform, the domain registrar, the Apple Developer account. 2FA goes on a phone. “We’ll add proper users later.” Later never comes. The team grows, contractors rotate in for a sprint, a project manager wants to grab a metric, a designer needs to push an asset to the CDN — and the path of least resistance is: ping the person whose phone has the codes.
For the first month it feels efficient. By month six it’s normal. By the time you take a holiday, it is the system.
It isn’t really 2FA any more
Here’s the thing about TOTP codes that travel over Slack DMs: they stop being a second factor. They become a slower, weaker first factor — gated by whether the holder of the phone is awake, in the office, or on the same continent.
What you actually have, once the codes go in Slack:
- No audit trail. Cloudflare’s audit log says “Mathieu logged in and edited this DNS record.” It can’t tell you which of the four people who asked me for a code was the human in the chair. The log is technically truthful and practically useless.
- Offboarding theatre. A contractor finishes their sprint. You don’t rotate the shared password, because rotating it means re-sharing it with everyone who needs it. So the leaver still has the credential — they just no longer have the code on demand. The 2FA app is now the only thing standing between them and your CDN. That’s a hell of a load-bearing assumption.
- A single point of holiday. The team is blocked any time the 2FA holder is asleep, on a plane, or genuinely off-grid. Mine was blocked for two weeks. Estimates, access requests, and “quick” DNS changes don’t queue politely — they pile up and get vented at the same person on day one back.
There’s a compliance shape to this — auditors do notice — but I’m not making the audit argument. The practical one is sharper: passing TOTP codes through a human is one person being a slow, error-prone identity provider for the entire team.
What the day-one setup actually looks like
The fix is the boring fix everyone knew about and skipped: every human who touches the system gets their own login with their own second factor, on the smallest role that does the job. Audit-logged actions attributed to a person, not to “the account.” The trick is doing it on day one, before anyone’s earned a permanent credential by being there first.
The principle is the same everywhere; the menu is just labelled differently. One worked example, then a sweep of the usual suspects.
The Cloudflare flavour, as a worked example. Account Home → Members → Invite. Each invitee creates their own login, configures their own 2FA, and Cloudflare’s audit log starts attributing actions to actual humans instead of to “the account.” Pick the smallest role that fits — most people need Analytics or a scoped Zone Read, not Super Administrator. SSO is on the Enterprise plan; for small teams, individual logins with mandatory 2FA is genuinely fine. (CF is the example because it’s what this site runs on, but the rest of the list works the same way.)
The same idea, by platform:
- Shopify Partner — Settings → Manage team. Per-store and per-permission scoping. Partner team access is separate from store staff access; if you build for clients, both need provisioning. Get Partner right early — it’s what unblocks every client store handoff and every dev-store spin-up. (Whether Partner is part of your stack at all is upstream of this.)
- Google Workspace / Microsoft 365 — admin console, named users, force MFA
at the directory level. Don’t share the
admin@mailbox; create real users and grant admin permissions. The shared admin inbox is the original sin from which most of the others descend. - AWS / GCP / Azure — never share the root or owner account. Root gets a phone-bound 2FA and goes in a vault you never open. Everyone else gets a scoped IAM user, a workload identity, or SSO. The “everyone logs in as root because IAM was set up later” pattern is the cloud version of the Slack-codes problem, with much bigger blast radius.
- GitHub / GitLab orgs — named users, org-enforced 2FA, branch protection tied to people (and to machine identities for bots), not to a shared service account that half the team has the credentials for.
- Apple Developer & Google Play Console — the mobile pair is the worst offender and it’s not entirely your fault: Apple in particular ties certificates and 2FA to Apple IDs in awkward ways. Get the team set up as additional users before anyone has shipped a build, because untangling who owns the signing cert retroactively is its own bad afternoon.
- Analytics, observability, email platforms — Plausible, Sentry, Datadog, Klaviyo, Mailchimp, whatever your stack actually is. Look for “team members”, “invite user”, “organisation”. One per human, role-scoped.
- Domain registrars — the most-shared and least-thought-about credential in most companies. Some smaller registrars still only support a single login. If yours does, either move to one that supports proper team accounts (it’s a short migration) or treat the registrar as a known one-credential exception with a vault entry and a named owner.
Payment and integration consoles — Stripe, payment gateways, fulfilment, anywhere money moves or production gets pushed. Same pattern. If a tool truly only supports one login per account — and a few small SaaS still do — that’s a tool you should be replacing before it becomes load-bearing, not building team workflows around.
Password manager for the irreducible shared secrets that remain (1Password, Bitwarden — pick one). Not for casual day-to-day shared logins, which shouldn’t exist, but for the genuinely-one-login services where the platform forces your hand. Shared vault, named access, revocable on offboarding.
None of this is hard. The reason it doesn’t happen on day one is that on day one there’s only one person, and provisioning feels like overhead. Six months in, when there are eight people and three contractors, retrofitting it costs twenty times what it would have on day one — and that’s before you count the holiday weeks somebody else will eat trying to cover for you.
The pattern under the pattern
The 2FA story is one face of a broader thing in the holiday backlog. The other big strand was dev resource estimates — for third-party API integrations and a mobile build — sitting in my queue because I’m the one with the context to size them.
Both have the same shape: a piece of access or knowledge that lives in one head, that the rest of the team has learned to route around rather than fix. The 2FA case is the easy one to act on — the fix is mostly buttons in a dashboard. The estimation case is harder, because the answer isn’t “add more users”, it’s “spread context”, and that’s a longer story for another post.
The lesson still rhymes. The things that bite when you take a holiday are the things you should have addressed when nothing was biting at all. Day one is when the fix is free.