Delivery kit

Security baseline runbook

Last changed 2026-09-03 · all documents · security & deployment

This is the security posture I apply to every engagement, whatever the size. It is the floor, not the ceiling. Each project gets a copy of templates/project-checklist.md, and anything I do differently on that project gets written down there as a delta with a reason.

Scope of the word "aligned": the headings below loosely follow the ISO/IEC 27001:2022 Annex A control themes so a client's IT reviewer can map my answers onto their own framework. This is a self-assessed alignment of a one-person consultancy. I am not ISO 27001 certified and I do not claim to be. If a client needs certification, I say so and we talk about what that changes.

Delivery tiers referenced throughout (see the launch checklist for detail):

Organizational controls

1. Least-privilege access

I ask for the narrowest access that does the job: read-only where reading is enough, one folder or one dataset rather than a tenant, time-boxed where the platform supports it. If someone offers me admin because it is easier, I decline and ask for the scoped version.

How I verify: before the first data pull I write the exact scopes and the resources they cover into the project's access register, and I re-read them with the client on the kickoff call. If a scope in the register is wider than a line in the data-flow diagram needs, it gets cut before work starts.

2. Access register kept current

Every credential, app registration, shared folder, repo invite and hosting account has a row: who granted it, when, what it covers, when it was revoked.

How I verify: I review the register at three fixed points — kickoff, delivery, handover — and any row without a revoked date at handover is a blocker on calling the project finished.

3. Data minimization

I take the columns I need and leave the rest. If a file has names, emails, salaries or free-text notes the dashboard never shows, I drop them at the first processing step rather than carrying them around. Where an identifier is needed only to join or count, I hash or replace it.

How I verify: I diff the column list of the source extract against the column list the deliverable actually uses. Anything in the first list and not the second has to be justified in the project checklist or removed.

4. Data classification and residency (EU)

I treat everything a client gives me as confidential by default, and personal data as a step above that. Processing and storage stay in the EU/EEA: EU regions for any cloud service, EU-hosted repos and vaults, no "wherever it lands" defaults.

How I verify: for each service in the data-flow diagram I record the actual configured region (not the vendor's marketing claim) and paste the region string from the console into the project checklist. Any transfer outside the EEA gets flagged in the Art. 30 register before it happens, not after.

5. Subprocessors named, not assumed

Any third party that touches client data — hosting, vault, error tracking, email — is listed by name and purpose. I do not add a new one mid-project without telling the client first.

How I verify: the subprocessor list lives in the Art. 30 register (templates/gdpr-art30-register.csv). Adding a service is a two-step change: register row first, integration second.

6. Written data-processing terms before data moves

Where I am processing personal data on a client's behalf, the paperwork is in place before the first extract, not retro-fitted.

How I verify: I do not accept a data file until the signed agreement is in hand. See templates/dpa-notes.md — I start from a standard model reviewed by a professional and never draft the clauses myself.

7. Incident plan that exists before I need it

Detect, contain, tell the client, assess the 72-hour GDPR question, write it up. One page, no ceremony.

How I verify: templates/incident-plan.md is filled in per project with the client's named contact and the agreed notification window. I walk the steps once at kickoff so I am not reading it for the first time during an incident.

People controls

8. Offboarding, rotation and end-of-engagement deletion

When an engagement ends — or when anyone's involvement ends — credentials get rotated, my access gets removed, and client data gets deleted from my machines and any service I stood up.

How I verify: templates/handover.md is completed and countersigned by the client contact. Deletion is only ticked when I have emptied the working folder, the backups that contain it, and the trash — and I say which backups those were.

9. My own working environment

Where that is, physically: the business is registered in Belgium and I work inside the EEA, so any processing that happens on my own machine happens inside the EEA too — there is no third-country transfer hiding in the phrase "my laptop", which is the question this section exists to answer for a DPO who has read the rest and wondered.

Full-disk encryption on, screen lock on, OS and browser patched, no client data on removable drives, no client data in a personal cloud sync folder. Client work lives in one known directory per client, not scattered.

How I verify: a monthly check that FileVault is on, the OS is on a supported version, and no client data has drifted outside the designated folders.

9a. My accounts

For a one-person consultancy, account takeover is the realistic breach path — not a clever attack on a dashboard, but someone getting into the GitHub or hosting account and replacing a file a client trusts. So:

How I verify: the MFA status of every account in that list is recorded in the access register at the start of an engagement, and re-checked at handover. If a provider shows a session or device list, stale sessions get revoked at the same time.

What I do not claim: I am one person. There is no separation of duties here, no second pair of eyes on my own account hygiene, and no SOC watching for a compromise of my laptop at three in the morning. What there is instead is a very small blast radius — I hold no client data at rest between engagements, and anything automated runs on your credentials, which you can revoke without me.

9b. AI and LLM tooling

I use AI coding assistants. Being specific about the boundary, because a vague answer here is worse than either a yes or a no:

How I verify: the same rule as every other data-handling control — client extracts live in one known directory per client, and that directory is not shared with any assistant tooling.

Technological controls

10. Secrets in a vault, never in code

API keys, connection strings and tokens live in a managed secret store in the client's own account, in an EU region, with access granted to the job's identity rather than to a person — Azure Key Vault on Microsoft, Secret Manager on Google, the platform's own equivalent elsewhere. Code reads them at runtime from the environment. Nothing sensitive goes in a repo, a notebook, a screenshot or a chat message.

How I verify: I run a secret scan over the full history before a repo is handed over, and where the client's platform offers push protection or secret scanning on their own repos, it gets turned on as part of handover. .env and data files are git-ignored — and because "git status is clean" is clean precisely when the ignore file works, that check cannot detect the failure it is meant to cover, so the real check is git ls-files against the list of things that must never be committed.

11. Encryption in transit and at rest

HTTPS/TLS for everything, no plain HTTP endpoints, no unencrypted database connections. At rest: disk encryption on my machines, platform encryption on managed storage, and encrypted archives for anything I have to send.

How I verify: I check the TLS certificate and confirm HTTP redirects to HTTPS before a URL goes to the client, and I record the at-rest encryption setting for each storage location in the project checklist.

12. Pinned dependencies and patching

Dependencies are pinned to exact versions with a lockfile committed. Front-end libraries are bundled into the deliverable rather than pulled from a CDN. Dependabot (or the platform equivalent) is on for every repo, and security updates get applied rather than accumulating.

How I verify: the lockfile is in the repo and the build is reproducible from a clean checkout, and I clear open dependency alerts before each delivery. Anything I choose not to patch gets a one-line reason in the project checklist.

Worth saying plainly: the tier-one deliverable has no dependencies and no build step at all — one HTML file, with the chart library and the fonts vendored into it rather than fetched. There is no lockfile because there is nothing to lock, and no supply chain to compromise between me and you. This control applies to the automated tier, where a scheduled job does have a runtime and does have packages.

13. Separate dev and prod

Development never points at production data or production credentials. Separate app registrations, separate secrets, separate storage. Test data is synthetic or a minimized sample.

How I verify: the two environments hold different credential values and I check the target from the running config, not from memory, before any job that writes. If a pipeline can write to prod, that path needs an explicit flag rather than being the default.

14. Logging and failure alerts

Jobs log what ran, when, how many rows, and what failed. Logs record events, not payloads — no personal data in log lines. Failures alert me the same day, and a silent job is treated as a failure.

How I verify: I trigger a deliberate failure during setup and confirm the alert actually arrives. I also confirm a missed run is detectable — a job that stops running should raise something rather than going quiet.

15. Backups with a documented restore test

Anything I would not want to rebuild by hand is backed up: code in Git, the pipeline configuration, the deliverable, and any state the client depends on. Backups are encrypted and stored in the EU. A backup nobody has restored is a guess, not a backup.

How I verify: I do a real restore into a scratch location at least once per project, before handover, and write down the date, what I restored, how long it took, and what broke. That note goes in the project checklist.

16. Secure coding for what I ship

Data values are rendered as text, never as markup. Inputs from a file are treated as untrusted. No eval of data, no string-built queries. Changes go through Git with a readable history, and the delivered version is tagged.

How I verify: a search for innerHTML in the deliverable returns only markup I wrote myself, never a data value — see annex-tier1.md for the tier-1 detail. Totals in the deliverable are reconciled against the source before it ships.

Loose ISO 27001:2022 Annex A mapping

For a client's IT reviewer. Indicative, self-assessed, not an audit.

AreaThis runbookAnnex A (2022)
Access control1, 25.15, 5.16, 5.18, 8.2, 8.3
Classification & privacy3, 4, 65.12, 5.34, 5.31
Supplier / cloud55.19–5.23
Incident management75.24–5.28
Offboarding & deletion86.5, 8.10
Endpoint97.9, 8.1
Cryptography & secrets10, 115.17, 8.24
Vulnerability & config128.8, 8.9, 8.19
Environment separation138.31
Logging & monitoring148.15, 8.16
Backup & continuity155.29, 5.30, 8.13
Secure development168.25, 8.28, 8.32