The Importance Of Product Sense And Design In Security

Every security control has an adoption rate. Most teams just never measure it.

We like to think our job in security is eliminating risk. But from the user's side of the glass, security is experienced as friction: the VPN that drops mid-deploy, the password policy that demands a hieroglyph, the approval workflow with a three-day SLA attached to a three-minute task. And when security becomes friction, something predictable happens: people route around it. Not because they're malicious, but because they have jobs to do.

The uncomfortable truth is that a control nobody uses isn't a control at all. It's a cost center with a console with pointless stats. Teams with genuine product sense build security that survives contact with real humans. The rest build roadblocks and then act surprised when shadow IT grows around them.

The Dancing Bunnies Law

Microsoft had an old thought experiment they had introduced known as the "dancing bunnies" problem: promise a user dancing bunnies on the other side of a security warning, and they will click through anything to get them. Any dialog, any certificate error, any permission prompt. The lesson isn't that users are stupid, it’s that users never weigh security against functionality, because functionality is the job. Security is invisible until it blocks something. A warning dialog standing between a person and their goal is not a security decision in their mind. It's an obstacle.

This gives us a kind of physical law for security design: any control that depends on the user choosing security over functionality is already broken. The only question is when the workaround appears.

So what does it look like when we design with that law instead of against it?

What Getting It Right Looks Like

Passkeys and biometrics: invisible security

For decades, authentication advice amounted to asking users to care more: longer passwords, weirder characters, rotation schedules. The result was predictable: reuse, sticky notes, and "Password1!" with an exclamation point of resentment.

FIDO2 and passkeys flipped the approach. Instead of demanding more effort from users, they demanded more design from us. The result is phishing-resistant authentication that is genuinely easier than the insecure thing it replaced. Face ID and Touch ID didn't succeed because users suddenly developed threat models. They succeeded because the secure path became the path of least resistance. A glance or a fingerprint, and the cryptography happens as a side effect.

That's the bar, security as a byproduct of a better experience, not a tax on it.

Chrome's HTTPS warnings: security that's understood

Detecting a threat is only half the job. You also have to communicate it to a tired human at 11 pm. Early browser certificate warnings were walls of jargon: ERR_CERT_AUTHORITY_INVALID, "the security certificate presented by this website was not issued by a trusted certificate authority." Users did what the dancing bunnies law predicts: they clicked through reflexively, and "click through the warning" became trained behavior.

Chrome's team treated this as a design problem. It iterated for years: plain-language explanations, opinionated visual design, the gradual "Not secure" labeling of HTTP pages in the address bar, and full-page interstitials reserved for cases where the risk is real. They measured click-through rates and kept redesigning until the numbers moved. The outcome was the web's shift to HTTPS by default, one of the largest security upgrades in internet history, and it was driven as much by UX work as by cryptography.

Both examples share a trait: someone with product sense asked, "What will a real human actually do here?" and then designed for the honest answer.

The Front Line: Authorization on the Front End

Nowhere does all of this entire issue converge more than in front-end authorization. The front end is where your security model meets the human, where abstract permissions become buttons, menus, dialogs, and dead ends. And it's where a lack of product sense does the most damage.

Hiding the button never hid the API

First, the foundational truth: client-side authorization is UX, not enforcement. Removing a button from the DOM does not close the endpoint behind it. Teams that forget this end up with IDOR and broken object-level authorization bugs. The UI looked locked down, so everyone assumed it was.

But the opposite failure is just as common, teams that treat the front end as only enforcement's dumb mirror and invest nothing in its design. The front end's real job is to shape behavior and mental models. The backend keeps people honest. The frontend keeps them oriented.

What do you show a user who can't do something?

This is a security decision that most teams make by accident:

  • Hide the action entirely. Clean, but the user never learns the feature exists, which is bad for discoverability and hides the shape of the permission model.

  • Show it disabled, with an explanation. "Requires admin role" teaches the permission model passively, every day, and turns a wall into a signpost.

  • Show it and fail on click. The worst option. A 403 after the fact feels like a bug, erodes trust, and teaches users that the UI lies.

There's no universal right answer, but there's a big difference between choosing deliberately per feature and letting it happen by default.

Design the request path, not just the deny path

Google Drive's "Request access" flow is a quiet masterpiece of security design. A user hits a document they can't open, a classic security block. Instead of a dead end, they get a workflow: ask the owner, who grants or denies in one click. The denied user becomes a petitioner, not an adversary hunting for a workaround.

Compare that to the average enterprise 403 page: a dead end with a ticket queue's email address on it. Every 403 is either a dead end or a workflow. You choose which. Dead ends breed workarounds, while workflows breed compliance.

The sharing dialog is the highest-stakes UI in security

One dropdown, "Anyone with the link," decides whether data walks out of your organization. A remarkable number of real-world exposures trace back not to elite attackers but to a sharing dialog where the dangerous option was one click away and visually identical to the safe one.

This is pure design work: external-recipient badges, "who can see this" summaries, warnings when sharing outside the organization, expiring links. Gmail's yellow "this recipient is outside your organization" banner has probably prevented more data loss than many DLP deployments.

Admin creep is a design failure

When requesting the right permission is harder than granting admin, everyone becomes admin. Over-permissioning in most organizations isn't laziness. It's a permission model too complex for the UI that exposes it.

Role design is product design. "Viewer / Editor / Owner" works because users can predict what each one allows. If your roles need a wiki page to decode, users will stop trying to decode them, and your least-privilege policy becomes a slide in a deck nobody follows.

Step-up auth: friction with a sniper scope

The dancing bunnies law doesn't say friction is bad. It says friction is spent. Spend it where the risk is.

GitHub's "sudo mode" is the pattern done right: browse and comment all day with a normal session, but change a security setting or add a deploy key, and you re-authenticate. The friction lands exactly on the dangerous action and nowhere else. Compare that to blanket ten-minute session timeouts, which punish everyone equally and mostly train people to build keep-alive scripts.

The UI is the documentation of the security model

Users don't read your authorization policy. They reverse-engineer it from what the UI shows them. If the UI displays actions that will fail, hides things that exist, or uses language nobody can parse, users build a wrong mental model and act on it. Misconfiguration isn't a user failure, it's the predictable output of a UI that misdocuments the system underneath it.

Building Product Sense as a Security Practitioner

Product sense isn't a personality trait. It's a set of habits:

  • Measure adoption and bypass rates, not just vulnerability counts. A control with 12% adoption is a finding, not a success metric.

  • Watch a real user hit your deny screen. Sit with support. Shadow a developer for a day. The gap between how you think your control works and how it's experienced is where the findings live.

  • Treat developers and employees as customers. Journey-map their interactions with your controls, from onboarding to the 2 am incident.

  • Befriend a designer. Sit in on user research and product design meetings as a fly on the wall. Steal their methods, usability testing works on security flows too.

  • Red-team your own UX. Ask: "If I had a deadline and no patience, how would I get around this?" Then go look at whether people already are.

Conclusion

FIDO2 made authentication invisible. Chrome made threat communication understandable. The dancing bunnies law explains why both were necessary. And front-end authorization is where all three lessons meet: the UI decides what users can do, what they think they can do, and what they actually end up doing.

The best security control is the one people actually use. Security that fights the user loses. Not sometimes. Every time, at scale, silently. The goal was never users who care about security. The goal is design so good that security is simply what happens while people do their jobs.

Next
Next

Is it time to get rid of NPM?