Soteria is a misconfiguration detector for GitHub workflow files. It has been designed to be modular, so that custom detectors can be added by the user. This tool caters to both developers and researchers, offering outputs for developers and JSON files containing detailed results for researchers.
Developers can use Soteria to detect misconfigurations in workflows before pushing the code to GitHub. The output of the tool will help the developer identify where the misconfigurations are exactly, together with a table showing the summary of the findings. Below is an example of a check ran on the .github/workflows directory of a project.
Researchers can use the JSON files returned by Soteria to analyze large datasets of workflows and study the misconfigurations in them. For example, we used Soteria to perform an empirical study of misconfigurations in GitHub CI/CD workflows.
- CICD-SEC-3: Dependency Chain Abuse
- CICD-SEC-4: Poisoned Pipeline Execution
- CICD-SEC-5: Insufficient Pipeline-Based Access Controls (PBAC)
- CICD-SEC-7: Insecure System Configuration
- CICD-SEC-9: Improper Artifact Integrity Validation
Below is a table of the default misconfigurations grouped by category.
| Category | Misconfiguration | Severity | Rule |
|---|---|---|---|
| CICD-SEC-3 | no-hash-version-pin |
Low | here |
| CICD-SEC-4 | unconditional-injection |
High | here |
conditional-injection |
Medium | here | |
pwn-request |
High | here | |
| CICD-SEC-5 | coarse-permission |
Medium | here |
global-secret |
Medium | here | |
| CICD-SEC-7 | self-hosted-runner |
Medium | here |
| CICD-SEC-9 | caching-in-release |
Critical | here |
unsafe-artifact-download |
Critical | here |
Soteria has 3 commands: check, stats, and detectors. Each command has also a set of flags that can be used.
NAME:
soteria check - Perform a static analysis check on the given file(s) or directory
USAGE:
soteria check [command options]
OPTIONS:
--config value, -c value Path to the configuration file
--repo value, -r value Name of the repository (will be used to name the global results file)
--string, -s YAML being passed as string (default: false)
--verbose, -v Verbose mode (default: false)
--max-rows value, -m value Maximum number of rows to print for the statistics table (default: 10)
--global, -g Output only one global JSON file per repository with the aggregated results (default: false)
--out value, -o value Output directory for the workflows' statistics (one JSON file per workflow will be generated, plus a global one)
--help, -h show help
NAME:
soteria stats - Compute file structure statistics on the given file(s) or directory (only for GitHub workflow files)
USAGE:
soteria stats [command options]
OPTIONS:
--repo value, -r value Name of the repository (will be used to name the global results file)
--string, -s YAML being passed as string (default: false)
--max-rows value, -m value Maximum number of rows to print for the statistics table (default: 10)
--global, -g Output only one global JSON file per repository with the aggregated statistics (default: false)
--out value, -o value Output directory for the workflows' statistics (one JSON file per workflow will be generated, plus a global one)
--help, -h show help
NAME:
soteria detectors - Get the list of all the available detectors. If the 'config' flag is set, it returns the detectors enabled by that configuration file
USAGE:
soteria detectors [command options]
OPTIONS:
--config value, -c value Path to the configuration file
--help, -h show help
A YAML configuration file can be optionally passed to Soteria. This file defines some options that the tool will set based on the developer's preferences. For instance, a developer can indicate which detectors should be used in the static analysis. To tell Soteria which detectors to use, the following syntax can be used:
detectors:
method: "include"
names:
- "poisoned-pipeline-execution/pwn-request"
- "insufficient-pbac/*"In the case above, we are telling the tool to use the pwn-request detector together with all detectors present in the insufficient-pbac group (denoted by the /*). If, instead, we want to exclude specific detectors, the following syntax can be used:
detectors:
method: "exclude"
names:
- "poisoned-pipeline-execution/*"
- "dependency-chain-abuse/no-hash-version-pin"In the case above, all but the no-hash-version-pin misconfiguration and the misconfigurations present in the poisoned-pipeline-execution group will be used during the analysis of the workflow.
Soteria was presented and used in the following scientific research papers:
-
Riggio, E. and Pautasso C. (2025). Pipelines Under Pressure: An Empirical Study of Security Misconfigurations of GitHub Workflows. Proceedings of 26th International Conference on Product-Focused Software Process Improvement (PROFES), in press, Springer
-
Serbout S., Muñoz Hurtado D. C., Atwi H., Riggio E., and Pautasso C. (2025). Evolution Scatterplot: Exploring Software ChangeDynamics in Large-Scale Historical Datasets. Proceedings of 13th IEEE Working Conference on Software Visualization (VISSOFT), pp. 94-105, IEEE, doi: 10.1109/VISSOFT67405.2025.00021.
- Edoardo Riggio - https://edoriggio.com