Security
The security basics AI-built apps skip — secrets, logins, row-level security, bot abuse — and the isolation that keeps untrusted code contained.
51 posts · page 2 of 2
Multi-Tenant SaaS on Postgres: Shared Schema + RLS vs Schema-per-Tenant vs Database-per-Tenant
The tenancy model is the hardest SaaS decision to reverse. Shared schema with RLS vs schema-per-tenant vs database-per-tenant — isolation, migrations, pooling, per-tenant restore — plus the owner-bypass, pooling, and foreign-key traps that silently break row-level security.
I Leaked an API Key. What Now? A Step-by-Step Response
You pushed a .env file to GitHub, pasted a key in a screenshot, or found your secret key in your app's frontend code. What to do in the next ten minutes, the next hour, and the next day — revoke, rotate, check for abuse, clean up — and how to stop it happening again.
Implementing Rate Limiting: Algorithms, Redis, and Response Headers
Fixed window, sliding window, token bucket, and GCRA — how each behaves at the edges, how to implement them atomically in Redis or Postgres, choosing keys behind proxies, fail-open vs fail-closed, headers clients can use, and layered limits for login, APIs, and AI endpoints.
How Automatic SSL Actually Works (and Why It Sometimes Doesn't)
The padlock in the browser comes from a certificate that has to be issued, installed, and renewed on a schedule that keeps getting shorter. How Let's Encrypt and ACME prove you own a domain, how tools like Traefik and Caddy automate it, and the five reasons a certificate fails to issue or renew.
How to Keep API Keys Out of an AI-Built App
AI-generated code hardcodes API keys all the time — and 'put it in an environment variable' isn't enough if the variable ends up in the browser. Which keys are safe to expose, which never are, and how to fix a key that's already leaked.
Handling Webhooks Reliably: Signatures, Idempotency, and Retries
Webhooks arrive late, twice, out of order, or from someone pretending to be Stripe. How to verify signatures against the raw body, acknowledge fast and process in the background, make handlers idempotent, cope with ordering, and test the whole thing locally.
What Is .gitignore? Keeping Secrets and Junk Out of Git
A .gitignore file tells Git which files never to save — your .env secrets, node_modules, build output, and OS clutter. How it works, the pattern syntax, a starter file for JavaScript projects, and what to do if you already committed something you shouldn't have.
GDPR Basics for App Builders: What a Small App Actually Needs
If anyone in the EU or UK uses your app, GDPR probably applies. What personal data is, the principles in plain English, lawful bases, the rights users have (access, deletion), what to do about third-party services and data breaches, and a practical checklist for a small app. Not legal advice.
Form Validation Explained: Client-Side, Server-Side, and Why You Need Both
Validation checks that what users type makes sense before you save it. The difference between browser-side and server-side validation, why only the server's counts for security, built-in HTML validation, sharing rules with a schema, and writing error messages people understand.
Firecracker vs gVisor vs Containers: Choosing Isolation for Untrusted Code
Containers share a kernel; gVisor intercepts it; Firecracker gives each workload its own. How the three isolation models actually work, what each costs in performance and compatibility, and how to match the boundary to the threat — for AI agents, multi-tenant platforms, and code execution.
What Is an Environment Variable? .env Files Explained
Environment variables are how an app gets its settings and secrets — database passwords, API keys, the site's URL — without writing them into the code. What they are, how .env files work, why they must never reach GitHub, and the prefix that quietly makes a 'secret' public.
CSRF Explained: Cross-Site Request Forgery and How Modern Apps Prevent It
CSRF tricks a logged-in user's browser into making a request they didn't intend. How the attack works, what SameSite cookies do and don't cover, CSRF tokens, Origin and Fetch Metadata checks, framework defaults, and why token-in-header APIs are different.
CORS Errors Explained: Why Your Frontend Can't Reach Your API
'Blocked by CORS policy: No Access-Control-Allow-Origin header' is one of the most common errors in AI-built apps. What CORS is, why the browser enforces it, how to fix it properly on the server, why the quick fixes are dangerous, and when you don't need CORS at all.
What Is a Cookie? How Websites Remember You
Cookies are how you stay logged in, keep items in a cart, and — yes — get tracked across the web. What a cookie is, how session cookies work, first- vs third-party cookies, the security settings every login cookie needs, and cookies vs local storage.
Content Security Policy: A Practical Guide to CSP Headers
A Content Security Policy tells the browser which scripts, styles, and connections your page may use, turning many XSS bugs into blocked requests. The directives that matter, nonce-based strict CSP, Report-Only rollout, Next.js specifics, and mistakes that make CSP useless.
Hardening Containers With Capabilities, seccomp, AppArmor, and User Namespaces
A default container shares the host kernel and starts with more privilege than most workloads need. A layer-by-layer guide: dropping capabilities, no-new-privileges, seccomp, AppArmor and SELinux, read-only filesystems, and user namespaces — and how to verify each.
Claude Code Permission Modes Explained: Manual, Accept Edits, Plan, and Auto
Claude Code can ask before every action, auto-approve edits, only plan, or run with a safety classifier reviewing each step. What each permission mode does, which one you start in, how to switch with Shift+Tab, allow and deny rules, and which mode to use when.
Connecting MCP Servers to Claude Code: Setup, Scopes, and the Security Question
MCP servers let Claude Code talk to your issue tracker, database, error monitoring, and docs. Adding one is a single command. Choosing which ones to trust is the harder part. How to connect them, where the configuration lives, and how to keep a useful integration from becoming a data leak.
Claude Code Hooks: Rules the Agent Can't Forget
CLAUDE.md tells Claude Code what you'd like. Hooks make it happen, every time — blocking edits to protected files, formatting after every change, refusing to stop while tests fail. Five practical hooks, how they work, and the honest limits of what a hook can enforce.
Claude Code --dangerously-skip-permissions: When It's Safe, and What to Use Instead
An agent that stops to ask permission can't work while you're away. An agent that never asks can delete things. How Claude Code's permission modes and allow/deny rules work, when skipping prompts is reasonable, and what has to be true of the environment first.
Backups for Beginners: How to Not Lose Your App's Data
Your code is in Git. Your users' data isn't. What actually needs backing up, the 3-2-1 rule, why a backup you've never restored doesn't count, how often to back up, and a simple backup plan for a small app — including what to do before letting an AI agent near your database.
Authentication vs Authorization: What's the Difference?
Authentication checks who you are. Authorization checks what you're allowed to do. Mixing them up is behind many of the worst security holes in AI-built apps. A plain-English explanation with the hotel analogy, the mistakes to look for, and a five-minute test.
AI Hallucinated a Package: Fake Libraries, Made-Up APIs, and Slopsquatting
AI coding tools sometimes invent packages, functions, and settings that don't exist — and attackers now register the fake package names. Why it happens, how to spot hallucinated imports and APIs, what 'slopsquatting' is, and the habits that keep invented code out of your app.
Egress Control for AI Agents: Designing an Allowlist Proxy
Restricting where an agent can send data is the most reliable defence against exfiltration, and easy to get subtly wrong. Network-layer enforcement, SNI vs TLS interception, DNS as a covert channel, allowlisted domains as leak paths, credential brokering, and testing.
How to Add Stripe Payments to an AI-Built App Without Getting Burned
AI tools will happily wire up Stripe in a way that looks finished and lets anyone pay $0.01 for your product. The four rules that make payments safe — server-side prices, verified webhooks, idempotent fulfilment, and a real live-mode test — explained without the jargon.
How to Add Login to an AI-Built App (Without Building It Yourself)
Authentication is the one feature you should never let an AI write from scratch. What 'login' actually involves, the three sensible ways to add it, and the checks that tell you whether the login your AI tool built is protecting anything at all.
Docker vs Linux Users for Multi-Tenant Workspace Isolation
Separate Linux users look like a cheap way to isolate tenants until you try to enforce a CPU limit. A walkthrough of why containers win for multi-tenant development workspaces — and how to verify the limits are real.