Runbook Engineering

Runbook as Code vs Runbook as Document: A Practical Difference

Marcus Webb 6 min read
Abstract split composition contrasting a document structure with an automated workflow

Every security team I have worked with has runbooks. Most of those teams would also admit, if you asked them honestly, that the runbooks are not what their on-call actually uses when an alert fires at 2am. They are what gets written after a serious incident, when someone senior decides that a documented process would prevent this from happening again.

That impulse is correct. The implementation is usually the problem.

What a document-based runbook actually is

A document-based runbook is a set of instructions written for a human reader operating under normal cognitive conditions. It says things like "Navigate to the AWS console and check the security group rules for the affected instance." It assumes the reader knows which instance is affected, has the correct permissions to navigate to it, and has time to read and parse each step before acting.

None of those assumptions hold during an active incident. The affected instance is usually not immediately obvious from the alert title. The on-call may or may not have remembered to check that their AWS session is still active. And reading carefully is the last thing that happens when you have woken up to a P1 notification at 3am.

The document-based runbook survives in most teams because it is easy to create. You open Confluence, you write down the steps, and you feel like you have done the work. Writing the document is within the normal skills and tools of any security engineer. What is harder to admit is that the document answers the question "what should someone do?" but does nothing about the question "will they be able to do it, in that condition, under that pressure?"

What a code-based runbook actually is

A code-based runbook is a machine-executable specification of the same steps. The fundamental difference is not the format: it is that the machine does not need to be awake, oriented, or calm to execute it.

In Parachute's runbook model, a runbook is a YAML file that specifies trigger conditions, action steps, conditional branches, and escalation paths. A step like "isolate the affected EC2 instance" becomes an explicit action with a typed parameter: the instance identifier, which Parachute derives from the alert metadata automatically. The runbook does not need someone to read it and decide what "affected instance" means. That resolution happens at execution time, before the on-call has opened their laptop.

This is the practical difference. A document-based runbook transfers knowledge to a human who must then act. A code-based runbook transfers the action itself to a system that executes without human mediation.

The intention gap

The reason most teams have document-based runbooks even when they want automation is not a tooling gap. It is an intention gap. Writing a document-based runbook can be done by one person in an afternoon. Writing a code-based runbook requires answers to questions that documentation-writing lets you avoid.

What exactly triggers this runbook? Not "a compromised host" but the specific alert condition that should trigger execution. What does the isolation step require as input? Not "the affected host" but the specific identifier format that the isolation API accepts. What happens if the isolation fails? The document can say "escalate to the on-call manager." The code needs an explicit branch.

These questions are hard not because the answers are unknown, but because forcing yourself to answer them precisely reveals how much ambiguity lives inside phrases like "investigate the alert" and "assess the scope of the incident." Documentation lets you leave those phrases in place. Code does not.

Where document runbooks still belong

We are not arguing that every runbook should be automated. There are incident types where the decision logic is too context-dependent for reliable automation: incidents that require legal review before containment, incidents involving potential insider threat where the scope of isolation is unclear, incidents where the evidence suggests a problem that is outside the security team's authority to act on unilaterally.

Document runbooks serve these cases. They are the right format for processes that require human judgment at every step, where the decision tree cannot be specified in advance because the branches depend on information that will only exist during the incident.

The mistake is treating these high-judgment cases as the template for all runbooks. The majority of security incidents, particularly at the detection-and-containment phase, follow a predictable enough pattern that the first ten to twenty minutes can be automated reliably. The on-call's judgment is needed at the point where the automated steps have completed and the evidence is in front of them, not at the point where they are still trying to figure out which host was affected.

Versioning as a quality signal

One of the underappreciated advantages of code-based runbooks is that they are naturally version-controlled. When a document-based runbook is updated, there is usually no record of what changed, when, or why. When a code-based runbook is updated and the change is committed to version control, there is an audit trail: who changed the isolation step to add a pre-isolation evidence pull, when they did it, and in response to which incident.

That audit trail is a quality signal. If a runbook has not been updated in eight months, it is probably out of date. If the last change was a revert, something went wrong with the previous version. If no one on the team has modified it in a year, no one on the team has been thinking critically about whether it still matches the threat environment.

Document-based runbooks rot silently. Code-based runbooks rot visibly, which means you can act on it.

Getting from document to code without a rewrite project

The transition does not need to be a large project. The practical approach is to pick one high-frequency incident type, the one that generates the most repetitive on-call load, and encode only the first four or five steps as executable actions. Not the full runbook. Just the context-gathering and initial containment phase.

For most teams that means: pull the relevant logs for the affected asset, identify the asset's network neighbors, optionally isolate the asset if the severity threshold is met. Those three to five steps cover the part of the incident where human time is most wasted. Everything after that, the investigation, the impact assessment, the remediation, can remain document-based until the team has learned what automation actually looks like in their environment.

The goal is not to replace the on-call. It is to make sure the on-call arrives at the point where their judgment is needed with the context already assembled, not still trying to find it.