Runbook library and runbook rules

The step runbooks shipped with the platform, where each one comes from, and the rules every runbook keeps — one use case, never one resource.

Reference · Updated 2026-10-28 · Describes release 0.1.164

What this page covers

Runbooks and automatic fixes explains how a step runbook is written, certified and released. This page lists the runbooks the platform ships and the rules that keep a runbook general.

One use case, never one resource

A runbook describes how to fix one kind of problem, for example "IMDSv1 allowed on an instance". It never describes how to fix one particular resource. The quality check enforces this, so a runbook that breaks either rule below cannot be certified:

Why: a runbook certified on one instance, with that instance written into it, used to produce that instance's change for another instance's incident. A runbook certified with a pinned target before this rule existed now never expands into a change and never matches a fix; the incident records it under Pre-approved route matched — not run with the reason pinned_target on Needs you, and the route list shows the finding. The analysis's own steps on the incident's resource then make a normal change that a person releases.

The check cannot see a service selector whose value happens to be one resource's name, for example a service label equal to a VM's name. Write the selector for the use case.

AWS-published runbooks

AWS publishes remediation documents for Security Hub controls in its open-source project Automated Security Response on AWS (ASR). The platform does not run those documents. Running one installs ASR's own stacks in your account: Step Functions, Lambda functions and one IAM role with write access per remediation. Instead, the platform captures each document's steps as a step runbook made of its own typed operations, so the same write connection, approval, pre-state capture and rollback apply as for every other fix. Five runbooks are captured from ASR v4.1.0, all of them documents whose every write is already a typed operation:

Route Controls AWS document What it changes Target from
remediate-ec2.8-require-imdsv2 EC2.8 ASR-EnableIMDSV2OnInstance HttpTokens=required on the instance (aws.ec2.require_imdsv2) the finding's annotation:resource_arn
remediate-ec2.13-14-admin-ports EC2.13, EC2.14 AWS-DisablePublicAccessForSecurityGroup (an AWS-owned document ASR calls) revokes the one rule that opens TCP 22 or 3389 to 0.0.0.0/0 or ::/0 (aws.security_group.revoke_ingress) group: the finding; rule: the analysis (plan)
remediate-ec2.19-high-risk-ports EC2.19 ASR-DisableUnrestrictedAccessToHighRiskPorts revokes the one world-open rule on a high-risk port group: the finding; rule: the analysis (plan)
remediate-s3.1-account-public-access-block S3.1 ASR-ConfigureS3PublicAccessBlock all four account-level public access block flags on (aws.s3control.put_public_access_block) the analysis (plan): an account-wide setting
remediate-iam.7-password-policy IAM.7 (the document also serves IAM.11–17) ASR-SetIAMPasswordPolicy the account password policy baseline (aws.iam.update_account_password_policy) the analysis (plan): an account-wide setting

They are added once to every workspace that has an enabled AWS write connection (role write or read/write), bound to the oldest such connection, within one scheduler tick of the connection being enabled — disabled and not certified: the runbook catalog lists them as Not certified · disabled until a person points one at the connection they want and an approver certifies it, and both the catalog row and the route row name where each came from — Published by AWS · ASR-EnableIMDSV2OnInstance · Automated Security Response on AWS v4.1.0 (params.source: publisher, document, project and version); nothing enables them on its own. A workspace with no AWS write connection gets none, and a connection disabled later leaves the routes as they are. Once added they are yours: a runbook you delete or rename is not added again (the audit row route.asr_seeded records the version of the AWS set the workspace received; a later version adds only its new names and never touches an existing route).

Each runbook has the same shape. A check reads the current state before the write, and that recorded state is the backup: these are configuration changes that touch no data, so no image is taken. Then comes the change, then a validate step (the platform's typed read, then the control reading PASSED on Security Hub's next evaluation), and a compiled_inverse rollback that puts the recorded state back. The route's params.source records the AWS document, document_owner, the ASR version (v4.1.0), the controls and any difference from the document. The check step's reason names the document too, so the steps a certifier reads say where they came from.

Differences from the documents:

A runbook that takes a target from the analysis (plan) can make a fix a standard change once certified, but it never runs on its own. The EC2.8 runbook binds its instance from the finding. A finding is never fixed without a person, whatever runbook matches, so a person releases all five.

Where they are. The platform seeds them in the demo workspace, disabled and uncertified, on the placeholder write connection example-aws-writer (no credentials). To use one, point it at your AWS write connection, enable it, and have an approver Certify it. Each one passes the quality check. The route editor's permission check lists the actions each step needs:

Route Actions on the write role
remediate-ec2.8-require-imdsv2 ec2:DescribeInstances, ec2:ModifyInstanceMetadataOptions
remediate-ec2.13-14-admin-ports, remediate-ec2.19-high-risk-ports ec2:DescribeSecurityGroupRules, ec2:RevokeSecurityGroupIngress, and ec2:AuthorizeSecurityGroupIngress for the rollback
remediate-s3.1-account-public-access-block s3:GetAccountPublicAccessBlock, s3:PutAccountPublicAccessBlock
remediate-iam.7-password-policy iam:GetAccountPasswordPolicy, iam:UpdateAccountPasswordPolicy, and iam:DeleteAccountPasswordPolicy for a rollback to no policy

Not captured yet. These common controls have a document with at least one write that has no typed operation yet: EC2.7 (ASR-EnableEbsEncryptionByDefault), CloudTrail.1 (ASR-CreateCloudTrailMultiRegionTrail: a bucket, its policy and the trail) and SSM.1 (ASR-AttachSSMPermissionsToEC2: an instance profile and its role). A fix for them is a normal change with operator lines.

Package upgrade on an EC2 instance

aws.ssm.upgrade_packages upgrades named OS packages, such as a library a scanner flagged, in place on one EC2 instance. It runs through Systems Manager Run Command with the AWS-owned AWS-RunShellScript document. Like the patch, it is a runbook-only operation, so the analysis never proposes it. Rollback is not the same as backup: a package manager does not downgrade, so the quality check requires an image backup of the same instance before the upgrade and the restore of that image as its rollback.

{"version": 1,
 "parameters": {"instance": {"kind": "aws.ec2.instance", "from": "annotation:resource_arn", "required": true}},
 "steps": [
  {"id": "check", "phase": "check", "target": "${instance}"},
  {"id": "image", "phase": "backup", "operation": "aws.ec2.create_image", "target": "${instance}"},
  {"id": "upgrade", "phase": "change", "operation": "aws.ssm.upgrade_packages", "target": "${instance}",
   "args": {"packages": "openssl openssl-libs"}},
  {"id": "upgraded", "phase": "validate", "criteria": "openssl and openssl-libs each read a different installed version on ${instance}"},
  {"id": "undo", "phase": "rollback", "operation": "aws.ec2.restore_root_volume"}]}

Demotion

A certification is not permanent. Two workspace switches on Guardrails (in the product: /portal/guardrails) take it away, each audited and listed on Needs you → Demoted for a route editor to decide:

Switch (field) Default Takes the certification away when
Demote a pre-approved route after one rollback (demote_on_rollback) off the first released rollback of a run through a pre-approved route (an automatic direct API run is demoted by its rollback whatever the switch says)
Demote a certified runbook when its fix deviates (demote_on_deviation) on a run through a certified runbook route (remediate-…) fails its validation (still present), or its fix does not hold: the condition is back after it validated, or the same alert returns after the incident resolved

Both switches follow every route a change ran through: the route's own run, and each runbook a change request followed step for step. A change minted from a step runbook carries no route of its own, and before this release its rollback demoted nothing. A deviation found after an approver edited the runbook and certified the new revision does not demote it: the revision that deviated is already gone. The audit row names who declared the deviation (declared_by: the validation, or the person whose Verify found the condition still present).

A fix that did not hold is not the runbook's deviation when a recorded outside change explains it. Before demoting for a fix that did not hold, the platform reads the change ledger for a write on the same resource, made after the fix and no later than the recurrence, by a principal that is not the platform's own (a harvested cloud write recorded as outside or unknown; a write the cloud refused never counts). With one, the runbook keeps its certification: the audit row Runbook kept — an outside change explains the recurrence names the fix, the outside change and the recurrence incident, the route's certification line adds a fix it made (CHG-…) did not hold — an outside change (CHG-…) on the same resource explains it; certification kept, and the recurrence incident's Timeline carries the same row. The did-not-hold mark on the last-known-good record stands either way: the condition did come back.

The mark and the demotion are written when the recurrence opens, and a cloud audit log delivers the write minutes later (CloudTrail 5 to 15 minutes), so a runbook can be demoted before the write that explains it reaches the ledger. Since 0.1.164, after each audit harvest that records a cloud write, the platform reads the did-not-hold marks of the last 24 hours that name no outside change again. A mark the new write explains gets the audit row Recorded fix recurrence explained by an outside change and no longer counts against the fix. The runbook that this recurrence's mark demoted is certified again with the whole certification it held, audited Runbook certification restored — an outside change explains the recurrence (route.deviation_explained, restored: true) on the recurrence incident; the route's certification line reads as for a kept certification. The recurrence's change requests that nobody has requested yet, classed normal while the runbook was demoted, are classed again (Change class restored — the runbook was certified again). The runbook stays demoted, for an approver to certify, when the demotion came from another recurrence, when the runbook was demoted again since (a failed validation, another unexplained recurrence, a rollback), when a person disabled, edited, certified or withdrew it or chose Keep it manual, or when the demotion was written before 0.1.164.

Deviation is our proposal. Your change process described this rule as one that applies in some cases, not in all of them. The platform turns it on by default. A workspace that wants only rollbacks to demote turns it off (PATCH /guardrails with {"demote_on_deviation": false}; null goes back to the default). It applies only to certified runbook routes. A pre-approved route of another kind keeps the behaviour from before this release.

What you see after a demotion:

To restore it, an approver certifies the route again (Certify on the routes page). A route editor's tick of Pre-approved is a request that an approver decides (Ticking it again asks an approver to certify this revision.). Keep it manual takes it off Needs you. Separately, a fix that did not hold twice in 30 days blocks the route on that incident key, whatever the switches say (Automatic fix blocked).

Next steps