A runbook automation platform holds the keys to run privileged commands across your estate, so whoever controls it, or can edit a job in it, effectively controls every server and cloud account it reaches. Tools such as Rundeck (also sold as PagerDuty Runbook Automation), StackStorm, AWS Systems Manager Automation and Azure Automation exist to let operators and on-call engineers run approved procedures without holding standing administrator rights. Done well, that is a large security gain. Done badly, it becomes a single, poorly governed super-user with SSH keys, cloud roles and API tokens that never expire. This guide explains the trust model of these platforms, how to set up access control, credential storage and execution identity, and how to detect misuse. It is for platform, SRE and security teams who run or approve runbook automation.
Key takeaways
- The platform is a tier 0 system. Anyone who can edit a job, a node source or a stored credential can run code wherever the platform's identities reach; protect it like a domain controller or PAM vault.
- Separate who may edit from who may run. Operators should run reviewed jobs with fixed parameters; only a small group should create or change jobs, and changes should go through version control.
- Execution identity is the real privilege. Prefer managed identities and short-lived assumed roles over stored keys, and scope each runbook's role to the actions it performs.
- Secrets must not leak through parameters and logs. Use the platform's key storage or an external vault, mark secret parameters as secret, and check execution output.
- Audit every execution to a person. Record who ran what, with which parameters, as which identity, on which targets, and alert on ad hoc commands and job edits.
What runbook automation is and why it is attacked
Runbook automation turns operational procedures (restart a service, rotate a certificate, collect diagnostics, fail over a database) into jobs that run on demand, on a schedule or in response to an event or webhook. The platform holds the credentials needed to reach target systems and runs commands through node executors (SSH, WinRM), cloud APIs or agents.
From an attacker's point of view this is ideal: a single console that already has authenticated reach to many hosts. MITRE ATT&CK tracks this as T1072 Software Deployment Tools (execution and lateral movement through centrally managed tools) and, for cloud run-command services, T1651 Cloud Administration Command. The typical paths in are a stolen operator session or API token, an exposed web console, a compromised integration that can trigger jobs, or a malicious change to a job definition stored in a repository.
Platform trust models compared
| Platform | Access model | Credential storage | Execution identity |
|---|---|---|---|
| Rundeck / PagerDuty Runbook Automation | YAML *.aclpolicy files with application and project contexts; deny rules first, then allow; anything unmatched is denied | Key Storage (built-in db or file backend, optional Storage Converter encryption, or external providers such as HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, CyberArk) | SSH or WinRM keys and passwords referenced from Key Storage, for example via the ssh-key-storage-path node attribute |
| StackStorm | RBAC (open source since 3.4) with system roles system_admin, admin, observer and custom roles in /opt/stackstorm/rbac/roles/ | Datastore with AES-256 encrypted values (--encrypt or secret: true); key file at the path set by encryption_key_path | Rule-triggered executions run as the system user (default stanley) |
| AWS Systems Manager Automation | IAM policies on who can start executions and which documents | Parameter Store and Secrets Manager, read at runtime | The starting user's permissions, or a service role assumed by Automation |
| Azure Automation | Azure RBAC roles on the Automation account | Automation credential and variable assets, or Key Vault | System-assigned or user-assigned managed identity (the default and recommended method) |
Access control: separate editing from running
The single most important design decision is that people who run jobs cannot change what the jobs do. Otherwise "run approved job" quietly becomes "run anything".
Rundeck
- Two contexts: the application context (
context: application: 'rundeck') controls projects, ACLs, users, API tokens and key storage; the project context controls jobs, nodes, ad hoc commands and webhooks. Users normally need both. - Executor role: grant
jobactionsread,view,runandkill, plusnoderun, scoped to job group or name. Do not grantcreate,updateordelete. - Ad hoc commands:
adhocrunlets a user type arbitrary commands against nodes. Reserve it for a small, named group, ideally through just-in-time elevation. - runAs and killAs: these let an action be attributed to another user through certain API endpoints. Grant them only to integration accounts that genuinely act on behalf of users, because they weaken attribution.
- Block execution on the server itself: the documentation's example restricts
nodeaccess to nodes whererundeck_serveris'false', so jobs cannot run commands on the Rundeck host and read its configuration or keys. - Key storage permissions: the
storageresource supportscreate,read,update,deletefiltered bypath. Key Storage is project-scoped by default; keep it that way so one project's operators cannot use another project's keys. - Policy files are code: ACL files are cached (content for 2 minutes, file list for 30 minutes), so deploy them through version control and a pipeline, and expect a short delay before changes take effect.
StackStorm
- Enable RBAC: set
enable = Trueandbackend = defaultin the[rbac]section of/etc/st2/st2.conf, and apply definitions withst2-apply-rbac-definitionsafter every change. - Grant narrowly: use permission types such as
action_executeandaction_viewon specific packs or actions. Creating a rule also requiresaction_executeon the action it uses, and webhook-triggered rules needwebhook_create, so rule authors are effectively executors. - Know the gaps: permission isolation (users see only their own executions and rules) is off by default; with LDAP group sync, removed users keep access until their token expires.
Cloud runbooks
- Azure Automation: built-in roles separate duties. Automation Job Operator creates and manages jobs; Automation Runbook Operator views runbook properties and, combined with Job Operator, lets a user run a specific runbook; Automation Contributor manages everything except access. Microsoft warns that Automation Contributor can reach any resource the account's managed identity can reach, so treat that role as privileged.
- AWS Systems Manager Automation: without a service role, a runbook runs with the permissions of the person who started it; with a service role, users can run a runbook that needs more permission than they hold. Restrict which documents a user may start, and which roles they may pass. See the AWS Systems Manager Security Guide.
Execution identity and credential storage
Each runbook ultimately acts as some identity on the target. That identity, not the operator's, decides the blast radius.
| Option | Strength | Weakness | Use when |
|---|---|---|---|
| Managed identity or assumed cloud role | No stored secret; short-lived tokens; per-runbook scoping possible | Over-broad role assignments are easy to make | Cloud targets; first choice |
| Dynamic credential from a vault per execution | Expires on its own; issued per job | Needs vault integration and reliable revocation | Databases and hosts that support it |
| Static SSH key or password in platform key storage | Simple; widely supported | Long-lived; one key often reaches many hosts | Legacy hosts; rotate on a schedule and restrict by path |
| Credential embedded in job script or parameter default | None | Visible to editors, in exports and often in logs | Never |
- Azure: Run As accounts, including Classic Run As accounts, retired on 30 September 2023 and were replaced by managed identities. Migrated runbooks authenticate with
Connect-AzAccount -Identity. Assign each identity only the roles the runbook needs: a runbook that starts and stops one VM needs only that permission on that VM. Hybrid Runbook Workers outside Azure need their own credentials defined in Automation. See the Azure Managed Identities Security Guide. - AWS: a service role is required when a user must run an automation that needs more permission than they have, for State Manager associations, for runs longer than 12 hours, and for non-Amazon runbooks using
aws:executeScriptto call AWS APIs. Use one role per runbook or task family, and scope the starter'siam:PassRoleto that role. - StackStorm datastore: generate the key with
st2-generate-symmetric-crypto-key, restrict the key file to thest2user and root, and remember that admins can decrypt every secret. If a parameter default uses thedecrypt_kvfilter, mark that parametersecret: true, or anyone who can run the action can see the plaintext. - StackStorm API keys: they do not expire and are stored only as a hash. Give each integration its own key with
used_bymetadata, disable keys you are not sure about, and inventory them. User tokens expire after 24 hours by default (token_ttl). - Rundeck Key Storage: use an external provider where you have one, organise keys under
keys/project/<project>/, and keep public key download disabled unless needed. See the Secrets Management Guide.
Triggers, webhooks and integrations
Runbooks are increasingly triggered by alerts, chat commands, ticketing systems, SOAR playbooks and AI agents rather than by a person clicking "run". Each trigger is an identity that can start privileged work.
- Authenticate every webhook: use per-integration secrets or signed requests, never an unauthenticated URL, and restrict source addresses where the sender supports it.
- Treat event data as untrusted input: alert fields, ticket text and chat messages must not flow unvalidated into shell commands. Use typed parameters with allowed values (for example a fixed list of service names) instead of free text.
- Constrain automated callers: an integration account that triggers jobs should be able to run only the specific jobs it needs, never ad hoc commands or job editing.
- AI agents as callers: when an agent can invoke runbooks, the runbook catalogue becomes its tool list. Expose only reviewed, parameter-constrained jobs, require human approval for disruptive ones, and log the agent identity separately. See the Privileged Operations Runbooks.
Hardening the platform itself
- Single sign-on with MFA for the console, with local accounts limited to a break-glass account held in your PAM vault.
- No internet exposure of the web console or API; reach it through VPN, a zero trust access proxy or a bastion network.
- Job definitions in version control with pull request review, so a malicious edit needs a second person. Disable direct editing in production projects where the platform supports source control import.
- Patch promptly and track advisories; the platform's host holds every key it uses.
- Protect the host and database: restrict OS and database access, encrypt backups, and keep encryption key files (StackStorm's datastore key, Rundeck converter keys) off shared storage.
- Network segmentation: allow the platform to reach targets only on the management ports it uses (for example SSH 22 and WinRM 5985/5986), and block targets from initiating connections back.
Implementation and migration steps
- Inventory: list projects, jobs, triggers, stored credentials, API tokens and the identities each job runs as. Flag jobs that run ad hoc input, embed secrets or run as a domain or cloud administrator.
- Define roles: admin, job author, operator and integration. Write ACL or RBAC definitions in a repository and apply them through a pipeline.
- Pilot in audit mode: apply the new role definitions to one project, watch denied actions for two weeks, then adjust. Keep the previous policy files tagged so you can roll back in minutes.
- Move credentials: migrate cloud runbooks to managed identities or assumed roles, move host credentials into key storage or an external vault, and rotate every credential that was previously visible in job definitions.
- Constrain parameters: replace free-text options with allowed values, mark secret parameters, and remove default values that contain secrets.
- Turn on logging and forwarding to your SIEM before broadening access.
- Review quarterly: access, unused jobs, unused credentials and stale API keys.
Small and large organisations: a small team may run a single Rundeck or StackStorm instance with three roles and an external vault, and that is sufficient if editing is restricted. Large organisations should run separate instances or projects per environment (production apart from non-production), integrate approvals with change management, and give each business unit its own execution identities so one compromised project cannot reach the whole estate.
Detection and measurement
| Event | Why it matters |
|---|---|
| Job created, edited or deleted outside the source control pipeline | Possible malicious change to a trusted procedure |
| Ad hoc command execution, especially against many nodes | Direct use of the platform as a remote shell (T1072) |
| ACL, RBAC or role assignment changes | Privilege escalation inside the platform |
| Key storage or datastore secret read, created or decrypted | Credential access |
| New API token or API key created | Persistence through a non-expiring credential |
| Cloud run-command or automation execution started by an unexpected principal | Abuse of cloud administration commands (T1651) |
Useful metrics:
- Percentage of executions that ran a reviewed job rather than an ad hoc command.
- Number of people with job edit or admin rights, against an agreed ceiling.
- Percentage of execution identities that are managed, federated or short-lived.
- Count of stored static credentials older than the rotation policy.
- Non-expiring API keys without a named owner (target zero).
Framework mapping
| Framework | Reference | How it applies |
|---|---|---|
| NIST CSF 2.0 | PR.AA-05, PR.PS-01, PR.PS-04, DE.CM-09 | Least privilege for operators and execution identities; job definitions under configuration management; execution logs; monitoring of the platform |
| NIST SP 800-53 Rev. 5 | AC-2, AC-6, CM-3, CM-5, IA-5, AU-2, AU-12 | Account management for integration accounts; least privilege; change control for jobs; access restrictions for change; authenticator management; event logging and audit record generation |
| ISO/IEC 27001:2022 Annex A | 8.2, 8.9, 8.15, 8.32 | Privileged access rights, configuration management, logging, change management |
| CIS Controls v8.1 | Control 5, Control 6, Control 8 | Account management, access control management, audit log management |
| MITRE ATT&CK | T1072, T1651, T1552.004, T1098 | Abuse of deployment and automation tools, cloud administration commands, theft of stored private keys, account manipulation for persistence |
Common failure patterns
- Operators who can edit jobs: the "operator" role includes
updateon jobs, so any operator can change a reviewed procedure into an arbitrary command. - One root key for everything: a single SSH key or domain admin password in key storage used by every job on every host.
- Over-privileged cloud identities: Automation accounts given Contributor on a subscription, or SSM service roles with administrator access, because scoping per runbook felt like too much work.
- Secrets in output: jobs that echo tokens or connection strings into execution logs, which are then readable by everyone with
viewaccess and forwarded to log tools. - Forgotten integration keys: non-expiring API keys created for a monitoring or chat integration that was retired years ago.
- Console on the internet: a web UI exposed for on-call convenience, protected only by local passwords.
Practitioner checklist
- Classify the runbook platform as tier 0 and restrict network access to its console and API.
- Enforce SSO with MFA and keep a single vaulted break-glass account.
- Separate job authors from operators; deny ad hoc command execution to most users.
- Manage job definitions and ACL or RBAC files in version control with review.
- Use managed identities or assumed roles scoped per runbook; remove stored cloud keys.
- Store host credentials in key storage or an external vault, scoped by project, and rotate them.
- Mark secret parameters, remove secret defaults and check execution logs for leaked values.
- Authenticate every webhook and constrain integration accounts to named jobs.
- Forward job edits, ad hoc runs, ACL changes and credential access to the SIEM with alerts.
- Review access, jobs, credentials and API keys every quarter.
Standards and references
- Rundeck Docs: Access Control Policy
- Rundeck Docs: Key Storage
- StackStorm Docs: Role Based Access Control
- StackStorm Docs: Datastore
- StackStorm Docs: Authentication
- AWS: Setting up Systems Manager Automation
- Microsoft Learn: Manage role permissions and security in Azure Automation
- MITRE ATT&CK: Software Deployment Tools
Related NHI Mgmt Group resources: Ansible and AWX Security Guide · SOAR and Security Automation Guide · JIT Access Guide · Top 10 Workflow Automation Security Risks