Security basics every app founder should know (plain English)
A plain-English security primer covering the handful of mistakes app founders must never make.
Official guide · Jun 27
You do not need to be a security engineer to ship a safe app. You just need to never get a small handful of things wrong. Get these basics right and you have closed the doors that catch out almost every new founder.
Authentication vs authorization
These sound the same but are not. Authentication ("authn") is proving who you are — logging in with email and password, Google, or Apple. Authorization ("authz") is what you are allowed to do once you are in — can this user delete that post, see that invoice, edit someone else's profile?
The classic rookie mistake is checking authentication but forgetting authorization. A logged-in user is not automatically allowed to touch everyone's data. Always ask: "Could user A reach user B's stuff just by changing a number in the URL?" If yes, you have an authz hole.
API keys, and the secret you never paste
An API key is a password your app uses to talk to another service (your payment processor, your database, an email tool). Many services give you two kinds:
- A publishable / public key — safe to ship inside the app or website.
- A secret key — full power. Treat it like the master key to your house.
Never paste a full secret key anywhere it can leak — not in a chat message, a screenshot, a public code repository (like GitHub), or front-end code that runs on a user's phone. If a secret key ever gets exposed, rotate it (generate a new one and delete the old) immediately. Leaked keys are scraped by bots within minutes.
Environment variables vs hardcoding
Hardcoding means typing a secret directly into your code. Do not. That code gets committed and shared, and the secret rides along.
Instead use environment variables — secrets stored outside your code, loaded in when the app runs (a .env file locally, or your host's settings panel in production). Your code references a name, not the value. Add .env to your .gitignore so it never gets uploaded.
Encryption at rest and in transit
Encryption scrambles data so only the right party can read it.
- In transit = while data travels over the internet. This is HTTPS (the padlock in the browser). If your app talks to a server, it must use HTTPS, never plain HTTP.
- At rest = while data sits in your database or storage. Reputable providers (Supabase, Firebase, AWS) encrypt at rest for you automatically — just do not turn it off.
You rarely build encryption yourself. You just make sure it is switched on.
Row-level security (your real safety net)
Row-level security (RLS) is a database rule that says "a user can only see or change their own rows." A row is one record — one user, one order, one message. With RLS on, even if someone grabs your public key and pokes at your database directly, they still cannot read other people's data, because the database itself refuses.
If you use Supabase, turn RLS on for every table and write policies. An open table with no RLS is the single most common way vibe-coded apps leak their entire user list.
Least privilege and read-only keys
Least privilege means giving every key, person, and service the minimum access it needs — nothing more. If a tool only needs to read your metrics, give it a read-only key so it can never delete or change anything. Smaller blast radius if it leaks.
Your takeaway today
Open your project right now and check three things: (1) no secret keys are hardcoded or pushed to GitHub — move them to environment variables; (2) every database table has row-level security turned on; (3) any key you have shared with a tool is read-only or publishable, never your secret key. Fix those three and you are ahead of most founders shipping today.