Secure by Default
Secure by Default
Secure by default means the user can do the obvious thing without reading the manual and still stay inside the safe path. It is a product property, not just a code property.
The default path should be safe even when the user is tired, copying commands from docs, running in a public repo, or debugging under time pressure.
The pattern
- Secrets are hidden until the user explicitly asks to reveal them.
- Local listeners bind to loopback unless the operator opts into a broader surface.
- Downloads have type checks, timeouts, and size caps before expensive parsing.
- Mutating commands preview or confirm when the blast radius is broad.
- Config files that may hold secrets are private by default.
- CI checks the dependency and site surfaces continuously, not once during release panic.
The important word is default. A power user can still opt into sharper tools, but the normal path should not leak a bearer token, bind a callback server to the LAN, or publish an unsigned artifact without any verification story.
Defaults follow operational reality
A default can be conceptually elegant and still be the wrong default.
The Spotuify auth reversal is the useful example. First-party/keymaster auth removed the Spotify Developer app setup step and avoided Development Mode write limits. On paper, that looked more secure and more user-friendly. In practice, sustained Web API polling through keymaster was policed harder than per-user dev-app traffic, so the default returned to dev-app PKCE and first-party became opt-in.
The rule: pick defaults from observed operating behavior, not from architectural neatness. If the elegant path fails more often, rate-limits harder, surprises users, or is harder to recover, it is not the safe default yet.
Easydeck added the public-SaaS version of this. Production checkout URLs must be public HTTPS, presentations default to private, public gallery/share views strip speaker notes, and internal user-sync calls require CONVEX_INTERNAL_SECRET. The safe path is the boring path: private until shared, public URL only in production, secret required for trusted mutation.
Sharp tools need friction
Security friction is bad when it blocks the main job. It is good when it forces intent at the moment of danger.
Examples:
config get client_secretreturning<redacted>by default is good friction.auth bearer --reveal-secretis good friction because the command exists for advanced debugging and token piping.- "Run this quarantine-removal command" without checksums or provenance is weak friction because it trains users to bypass the platform with no compensating evidence.
The rule: make safe behavior effortless and risky behavior explicit.