Security thinking

Start with assets and harm

Identify what a product must protect and describe the concrete harm that follows if confidentiality, integrity, or availability fails.

Security starts with what matters. A generic instruction like “make the app secure” gives us nothing we can test.

Before you think about attackers or tools, list the assets: the data, actions, services, money, and reputation the product depends on. Then describe what happens if someone reads, changes, destroys, or blocks each one. This turns security from fear into a set of product requirements.

The three kinds of harm

Every asset can fail in three distinct ways:

  • Confidentiality fails when someone reads data they should not see.
  • Integrity fails when someone changes or deletes data without permission.
  • Availability fails when legitimate users cannot reach the data or the operation.

Imagine a shared notes app that stores private drafts and recovery email addresses. A leaked draft harms confidentiality. An overwritten draft harms integrity. An author locked out of the editor before a deadline is an availability failure, and it hurts even though nothing leaked.

Build the asset table

Write the assets down. A short table forces you to be concrete:

asset             owner         location            worst believable harm
private drafts    note author   postgres "notes"    competitor reads unreleased work
recovery emails   account team  postgres "users"    attacker resets accounts at scale
publish action    note author   POST /api/publish   defaced public page under our brand
nightly backup    ops           S3 bucket           silent corruption blocks every restore

Each row names an owner and a location. That matters later, because “who can rotate this credential” and “where does this data live” are the first questions in an incident.

The mistake to avoid

A list that only says “user data” hides these differences. It can lead us to protect database secrecy while missing deletion, account lockout, or a broken restore.

Check each row by asking for one observable failure per kind of harm:

asset: private drafts
read    -> another account downloads the draft      (confidentiality)
change  -> draft overwritten with defaced content   (integrity)
block   -> author cannot open the editor            (availability)

If you cannot describe what the failure would look like in a log, a screenshot, or a support ticket, the asset is still too vague to protect.

My advice: keep this table in the repository, next to the code. When a feature adds a new asset, add a row. This table is the input for every lesson that follows.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →