June 11, 2026
Why Johnny Still Can’t Encrypt — and What It Means for Security vs Developer Velocity Today
More than two decades ago, researchers published a paper with a blunt conclusion: ordinary users could not reliably use email encryption…
Oluwakemi Oshunkeye
3 min read
More than two decades ago, researchers published a paper with a blunt conclusion: ordinary users could not reliably use email encryption tools, even when the tools were technically sound. Years later, a follow-up study — "Why Johnny Still Can't Encrypt" — found something uncomfortable but important: the problem never really went away.
Despite better interfaces, more mature tooling, and stronger cryptography, most users still struggle to correctly use encryption systems in practice.
That finding isn't just about email. It's about something much bigger: security systems fail most often not because the math is wrong, but because humans can't consistently use them correctly under real-world constraints.
And in modern software development, this tension shows up everywhere — especially in the tradeoff between security enforcement and developer velocity.
The real problem isn't encryption — it's usability under pressure
The follow-up study found that users still struggled with:
- Understanding key management and trust
- Knowing whether something was actually secure
- Completing multi-step security workflows correctly
- Interpreting vague or technical feedback from tools
Even when users finished the task, they often did so incorrectly without realizing it.
The takeaway wasn't "people are bad at security." It was more precise:
Security systems that depend on correct human execution will fail in unpredictable ways.
This is the core lesson that extends far beyond PGP email.
Why this still matters in modern engineering
Today's systems are far more complex than email encryption ever was:
- Cloud IAM policies
- Kubernetes RBAC
- Secret management systems
- API authentication flows
- Infrastructure-as-code deployments
- Zero-trust architectures
All of these systems assume something dangerous:
That humans will consistently make correct security decisions in high-pressure environments.
But in reality, developers are optimizing for:
- shipping features
- debugging production issues
- meeting deadlines
- minimizing cognitive overhead
Security is rarely the primary focus in the moment of action.
So when security is:
- confusing
- slow
- or difficult to verify
developers don't stop working.
They adapt.
And that adaptation usually looks like:
- over-permissioned roles
- disabled security checks in dev
- copied secrets in environment files
- long-lived credentials
- "temporary" exceptions that become permanent
Not because people don't care — but because the system makes the secure path harder than the insecure one.
The real tension: security vs developer velocity
Modern engineering teams constantly navigate a three-way tension:
- Security strength
- Usability
- Development speed
You rarely maximize all three at once.
If security is too strict:
- teams slow down
- frustration increases
- workarounds appear
If velocity is prioritized:
- risk accumulates silently
- misconfigurations spread
- security debt builds up
If usability is ignored:
- even strong controls get bypassed in practice
The result is that "security policy" often diverges from "security reality."
The key insight: security is a product, not a rule
The biggest shift in modern thinking is this:
Security is not something you enforce onto developers. It is something you design for them.
In high-performing engineering organizations, security is treated like a product with users (developers) and UX constraints.
That changes everything.
Instead of asking:
- "How do we make this more secure?"
Teams start asking:
- "How do we make the secure path the easiest path?"
What this looks like in practice
1. Secure defaults beat perfect policies
Most real-world security wins come from defaults, not enforcement.
- default-deny IAM with easy scoped exceptions
- secure infrastructure templates
- pre-approved deployment patterns
If the secure option is the default, fewer decisions are left to humans under pressure.
2. Automation replaces judgment calls
Humans are inconsistent under load. Systems shouldn't depend on them for critical decisions.
So mature teams invest in:
- CI/CD policy enforcement
- secret scanning
- infrastructure validation
- runtime security controls
The goal is simple: remove security decisions from runtime human context whenever possible.
3. Security must live inside the developer workflow
Security that happens "somewhere else" gets ignored.
Effective systems integrate into:
- IDEs
- pull requests
- build pipelines
- local development environments
The closer security is to the developer's actual flow, the less friction it creates.
4. Friction must be intentional, not accidental
Zero-friction security is usually just insecurity disguised as convenience.
But unnecessary friction is just as dangerous — it drives bypass behavior.
Good security design introduces:
- minimal friction
- at the right moment
- for the right level of risk
5. Systems must assume humans will make mistakes
This is the most important shift.
Instead of assuming perfect compliance, modern systems assume failure will happen and design for it:
- least privilege to reduce blast radius
- strong audit logs
- easy rollback mechanisms
- segmentation of critical systems
- safe defaults that prevent catastrophic misconfigurations
Security becomes resilient rather than dependent on perfection.
The real takeaway
The lesson from "Why Johnny Still Can't Encrypt" is not about encryption tools.
It's about a deeper truth:
If a security system requires users to consistently make correct decisions under pressure, it will eventually fail.
And in modern software engineering, that means security cannot be a layer on top of development velocity.
It has to be part of the development system itself.
The winning approach is not choosing between security and speed.
References:
https://people.eecs.berkeley.edu/~tygar/papers/Why_Johnny_Cant_Encrypt/OReilly.pdf