flowsec 0.5.2__tar.gz → 0.5.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. {flowsec-0.5.2 → flowsec-0.5.4}/AGENTS.md +71 -0
  2. {flowsec-0.5.2 → flowsec-0.5.4}/PKG-INFO +82 -168
  3. flowsec-0.5.4/PYPI_README.md +161 -0
  4. {flowsec-0.5.2 → flowsec-0.5.4}/README.md +18 -2
  5. {flowsec-0.5.2 → flowsec-0.5.4}/SECURITY.md +1 -1
  6. {flowsec-0.5.2 → flowsec-0.5.4}/docs/FULL_README.md +154 -82
  7. flowsec-0.5.4/homebrew-tap/Formula/flowsec.rb +207 -0
  8. {flowsec-0.5.2 → flowsec-0.5.4}/pyproject.toml +2 -2
  9. {flowsec-0.5.2 → flowsec-0.5.4}/.devcontainer/devcontainer.json +0 -0
  10. {flowsec-0.5.2 → flowsec-0.5.4}/.github/workflows/publish.yml +0 -0
  11. {flowsec-0.5.2 → flowsec-0.5.4}/.github/workflows/security.yml +0 -0
  12. {flowsec-0.5.2 → flowsec-0.5.4}/.gitignore +0 -0
  13. {flowsec-0.5.2 → flowsec-0.5.4}/LICENSE +0 -0
  14. {flowsec-0.5.2 → flowsec-0.5.4}/Makefile +0 -0
  15. {flowsec-0.5.2 → flowsec-0.5.4}/docs/screenshots/flowsec-logo.png +0 -0
  16. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/__init__.py +0 -0
  17. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/ai_narrative.py +0 -0
  18. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/cli.py +0 -0
  19. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/config.py +0 -0
  20. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/parser.py +0 -0
  21. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/report.py +0 -0
  22. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/__init__.py +0 -0
  23. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/artifact_signing.py +0 -0
  24. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/base.py +0 -0
  25. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/broad_artifact_upload.py +0 -0
  26. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/container_runs_as_root.py +0 -0
  27. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/continue_on_error_security.py +0 -0
  28. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/dependency_pinning.py +0 -0
  29. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/deploy_all_branches.py +0 -0
  30. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/env_vars_in_logs.py +0 -0
  31. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/excessive_permissions.py +0 -0
  32. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/github_context_injection.py +0 -0
  33. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/hardcoded_secrets.py +0 -0
  34. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/insecure_curl.py +0 -0
  35. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/missing_env_protection.py +0 -0
  36. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/missing_oidc.py +0 -0
  37. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/missing_timeout.py +0 -0
  38. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/mutable_container_image.py +0 -0
  39. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/persist_credentials.py +0 -0
  40. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/privileged_docker.py +0 -0
  41. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/pull_request_target.py +0 -0
  42. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/secret_as_cli_arg.py +0 -0
  43. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/secrets_in_build_args.py +0 -0
  44. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/secrets_in_run.py +0 -0
  45. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/self_hosted_runner.py +0 -0
  46. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/unpinned_actions.py +0 -0
  47. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/unverified_install_script.py +0 -0
  48. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/workflow_dispatch_injection.py +0 -0
  49. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/rules/workflow_run_trigger.py +0 -0
  50. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/scanner.py +0 -0
  51. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/scoring.py +0 -0
  52. {flowsec-0.5.2 → flowsec-0.5.4}/src/pipelineguard/templates/report.html +0 -0
  53. {flowsec-0.5.2 → flowsec-0.5.4}/tests/__init__.py +0 -0
  54. {flowsec-0.5.2 → flowsec-0.5.4}/tests/fixtures/azure_all_vulns.yml +0 -0
  55. {flowsec-0.5.2 → flowsec-0.5.4}/tests/fixtures/github_all_vulns.yml +0 -0
  56. {flowsec-0.5.2 → flowsec-0.5.4}/tests/fixtures/gitlab_all_vulns.yml +0 -0
  57. {flowsec-0.5.2 → flowsec-0.5.4}/tests/fixtures/sample_azure_vulnerable.yml +0 -0
  58. {flowsec-0.5.2 → flowsec-0.5.4}/tests/fixtures/sample_gitlab_vulnerable.yml +0 -0
  59. {flowsec-0.5.2 → flowsec-0.5.4}/tests/fixtures/sample_workflow_clean.yml +0 -0
  60. {flowsec-0.5.2 → flowsec-0.5.4}/tests/fixtures/sample_workflow_vulnerable.yml +0 -0
  61. {flowsec-0.5.2 → flowsec-0.5.4}/tests/test_azure_rules.py +0 -0
  62. {flowsec-0.5.2 → flowsec-0.5.4}/tests/test_github_rules.py +0 -0
  63. {flowsec-0.5.2 → flowsec-0.5.4}/tests/test_gitlab_rules.py +0 -0
@@ -328,6 +328,76 @@ FS003 (Excessive Permissions) fires when a GitHub workflow has `permissions: wri
328
328
 
329
329
  ---
330
330
 
331
+ ## Homebrew Tap
332
+
333
+ FlowSec is distributed via a dedicated Homebrew tap in addition to PyPI.
334
+
335
+ ### Repositories
336
+
337
+ | Repo | URL | Purpose |
338
+ |---|---|---|
339
+ | Main codebase | `github.com/VanshBhardwaj1945/FlowSec` | Source code, PyPI publishing |
340
+ | Homebrew tap | `github.com/VanshBhardwaj1945/homebrew-flowsec` | Homebrew formula only |
341
+
342
+ The tap repo holds a single file: `Formula/flowsec.rb`. Homebrew requires the repo to be named `homebrew-<tapname>` — this is mandatory, not a convention.
343
+
344
+ ### Install commands (for users)
345
+
346
+ ```bash
347
+ # One-liner (taps and installs in one step)
348
+ brew install VanshBhardwaj1945/flowsec/flowsec
349
+
350
+ # Or tap first, then install
351
+ brew tap VanshBhardwaj1945/flowsec
352
+ brew install flowsec
353
+ ```
354
+
355
+ ### Local tap path (for development)
356
+
357
+ When the tap is registered locally, brew stores it at:
358
+ ```
359
+ /usr/local/Homebrew/Library/Taps/vanshbhardwaj1945/homebrew-flowsec/Formula/flowsec.rb
360
+ ```
361
+
362
+ A canonical copy is also kept in this repo at `homebrew-tap/Formula/flowsec.rb`. When updating the formula, edit the canonical copy here first, then push it to the tap repo.
363
+
364
+ ### Formula structure
365
+
366
+ The formula (`flowsec.rb`) uses `Language::Python::Virtualenv` — Homebrew's standard approach for Python CLI tools. It installs flowsec and all 36 transitive runtime dependencies into an isolated virtualenv in the Cellar. The binary at `$(brew --prefix)/bin/flowsec` is a shim into that virtualenv.
367
+
368
+ Build-time dependencies: `rust` (required for `pydantic-core` and `jiter`, which are Rust extensions).
369
+ Runtime dependencies: `libsodium` (for PyNaCl), `libyaml` (for PyYAML), `python@3.11`.
370
+
371
+ ### Updating the formula for a new FlowSec release
372
+
373
+ When a new version is published to PyPI, the formula must be updated:
374
+
375
+ 1. Get the new tarball URL and SHA256 from `https://pypi.org/pypi/flowsec/X.Y.Z/json` (look in `urls` for `packagetype == "sdist"`)
376
+ 2. Update `url` and `sha256` at the top of `homebrew-tap/Formula/flowsec.rb`
377
+ 3. Check if any dependencies changed versions — re-run a pip dry-run to confirm:
378
+ ```bash
379
+ /usr/local/opt/python@3.11/libexec/bin/python -m pip install --dry-run --ignore-installed --report=/tmp/report.json flowsec==X.Y.Z
380
+ python3 -c "import json; [print(p['metadata']['name'], p['metadata']['version']) for p in json.load(open('/tmp/report.json'))['install']]"
381
+ ```
382
+ 4. If dependency versions changed, update the corresponding `resource` blocks (url + sha256). For pure-Python packages use the `-py3-none-any.whl` wheel URL. For compiled packages (cffi, cryptography, jiter, markupsafe, pydantic-core, pynacl, pyyaml, charset-normalizer) use the `.tar.gz` sdist URL.
383
+ 5. Commit the updated formula to both `homebrew-tap/Formula/flowsec.rb` in this repo **and** push it to `github.com/VanshBhardwaj1945/homebrew-flowsec`
384
+ 6. Test locally: `brew upgrade VanshBhardwaj1945/flowsec/flowsec`
385
+
386
+ ### Auditing and testing the formula
387
+
388
+ ```bash
389
+ # Check for style/correctness issues
390
+ brew audit --new VanshBhardwaj1945/flowsec/flowsec
391
+
392
+ # Run the formula's test block
393
+ brew test VanshBhardwaj1945/flowsec/flowsec
394
+
395
+ # Full install from source
396
+ brew install --build-from-source VanshBhardwaj1945/flowsec/flowsec
397
+ ```
398
+
399
+ ---
400
+
331
401
  ## Publishing to PyPI
332
402
 
333
403
  The project uses PyPI trusted publishing (OIDC) — no API token needed. The workflow in `.github/workflows/publish.yml` handles everything automatically when a `v*` tag is pushed. PyPI generates Sigstore attestations automatically for OIDC-published packages.
@@ -359,3 +429,4 @@ The README.md is used as the PyPI long description. Hatchling detects `text/mark
359
429
  | `tests/fixtures/` | The ground truth for what each platform's YAML looks like and what should be detected. |
360
430
  | `.github/workflows/publish.yml` | PyPI release pipeline. Triggered by `v*` tags. |
361
431
  | `.github/workflows/security.yml` | Security checks on every push/PR to main. |
432
+ | `homebrew-tap/Formula/flowsec.rb` | Canonical copy of the Homebrew formula. Push changes here and to `github.com/VanshBhardwaj1945/homebrew-flowsec`. |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flowsec
3
- Version: 0.5.2
3
+ Version: 0.5.4
4
4
  Summary: CI/CD pipeline security analyzer — scans GitHub Actions, GitLab CI, and Azure DevOps configs for attack vectors
5
5
  Author-email: Vansh Bhardwaj <Scorpio.vansh@gmail.com>
6
6
  License: MIT
@@ -33,24 +33,74 @@ Requires-Dist: responses>=0.25.3; extra == 'dev'
33
33
  Requires-Dist: ruff>=0.4.4; extra == 'dev'
34
34
  Description-Content-Type: text/markdown
35
35
 
36
- <p align="center">
37
- <img src="docs/screenshots/flowsec-logo.png" alt="FlowSec" width="520" />
38
- </p>
36
+ # FlowSec
39
37
 
40
- <p align="center">
41
- <a href="https://codespaces.new/VanshBhardwaj1945/FlowSec"><img src="https://github.com/codespaces/badge.svg" alt="Open in GitHub Codespaces" /></a>
42
- <a href="https://badge.fury.io/py/flowsec"><img src="https://badge.fury.io/py/flowsec.svg" alt="PyPI version" /></a>
43
- </p>
38
+ A Python command-line security tool that scans CI/CD pipeline configurations for attack vectors across **GitHub Actions**, **GitLab CI**, and **Azure DevOps**. Every finding maps to a MITRE ATT&CK technique and an OWASP CICD Top 10 category.
44
39
 
45
- > A Python security tool that scans CI/CD pipeline configurations for attack vectors across GitHub Actions, GitLab CI, and Azure DevOps. Every finding maps to a MITRE ATT&CK technique and OWASP CICD Top 10 category.
46
- >
47
- > The pipeline is the attack surface. FlowSec treats it that way.
40
+ The pipeline is the attack surface. FlowSec treats it that way.
48
41
 
49
- **[Full documentation](docs/FULL_README.md)**
42
+ ---
43
+
44
+ ## Install
45
+
46
+ **Homebrew (macOS):**
47
+
48
+ ```bash
49
+ brew install VanshBhardwaj1945/flowsec/flowsec
50
+ ```
51
+
52
+ **PyPI:**
53
+
54
+ ```bash
55
+ pip install flowsec
56
+ ```
50
57
 
51
58
  ---
52
59
 
53
- ## What it catches
60
+ ## Quick Start
61
+
62
+ ```bash
63
+ # Scan a GitHub Actions repo
64
+ export GITHUB_TOKEN=your_token
65
+ flowsec scan --github --repo owner/repo
66
+
67
+ # Scan a local GitHub Actions workflow file
68
+ flowsec scan --github --file .github/workflows/ci.yml
69
+
70
+ # Scan a GitLab CI file
71
+ flowsec scan --gitlab --file .gitlab-ci.yml
72
+
73
+ # Scan an Azure DevOps pipeline file
74
+ flowsec scan --azure --file azure-pipelines.yml
75
+
76
+ # Generate an HTML report
77
+ flowsec scan --github --repo owner/repo --output report.html
78
+
79
+ # Generate AI attack narratives (requires ANTHROPIC_API_KEY)
80
+ flowsec scan --github --repo owner/repo --ai
81
+
82
+ # Fail pipeline if findings at or above threshold
83
+ flowsec scan --github --repo owner/repo --fail-on critical
84
+
85
+ # Ignore specific rules
86
+ flowsec scan --github --repo owner/repo --ignore FS006 --ignore FS011
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Platforms and Tokens
92
+
93
+ | Platform | File scan | Remote scan | Token required |
94
+ |---|---|---|---|
95
+ | GitHub Actions | `--github --file` | `--github --repo owner/repo` | `GITHUB_TOKEN` (remote only) |
96
+ | GitLab CI | `--gitlab --file` | `--gitlab --repo namespace/project` | `GITLAB_TOKEN` (remote only) |
97
+ | Azure DevOps | `--azure --file` | `--azure --repo org/project` | `AZURE_DEVOPS_TOKEN` (always — Azure requires auth even for public projects) |
98
+
99
+ Set tokens in a `.env` file in your working directory or as environment variables. FlowSec loads `.env` automatically.
100
+
101
+ ---
102
+
103
+ ## 26 Security Rules
54
104
 
55
105
  | ID | Rule | Severity | MITRE | OWASP |
56
106
  |---|---|---|---|---|
@@ -83,127 +133,20 @@ Description-Content-Type: text/markdown
83
133
 
84
134
  ---
85
135
 
86
- ## Platforms supported
87
-
88
- | Platform | File scan | Remote repo scan |
89
- |---|---|---|
90
- | GitHub Actions | `flowsec scan --github --file workflow.yml` | `flowsec scan --github --repo owner/repo` |
91
- | GitLab CI | `flowsec scan --gitlab --file .gitlab-ci.yml` | `flowsec scan --gitlab --repo namespace/project` |
92
- | Azure DevOps | `flowsec scan --azure --file azure-pipelines.yml` | `flowsec scan --azure --repo org/project` |
93
-
94
- ---
95
-
96
- ## Real findings on a real repo
97
-
98
- Scanned `VanshBhardwaj1945/cloud-resume-challenge-azure` — 13 findings across 2 workflow files:
99
-
100
- ```
101
- [CRITICAL] FS002 - Unpinned Action — Supply Chain Attack Vector
102
- File: .github/workflows/backend.main.yaml
103
- Action 'actions/checkout@v4' is not pinned to a commit hash
104
-
105
- [HIGH] FS003 - Excessive Permissions — Overprivileged Workflow Token
106
- File: .github/workflows/backend.main.yaml
107
- Pipeline permissions set to 'None' — GitHub defaults apply
108
-
109
- [HIGH] FS004 - Missing OIDC — Long-Lived Cloud Credential in Use
110
- File: .github/workflows/backend.main.yaml
111
- Cloud provider action present but no id-token: write permission
112
-
113
- [LOW] FS006 - Missing Timeout — Job Runs Up to 6 Hours Unchecked
114
- File: .github/workflows/backend.main.yaml
115
- Job 'build-and-deploy' has no timeout — GitHub default is 6 hours
116
- ```
117
-
118
- ---
119
-
120
- ## Stack
121
-
122
- | Layer | Tools |
123
- |---|---|
124
- | Language | Python 3.11 |
125
- | GitHub Connection | PyGithub |
126
- | YAML Parsing | PyYAML with custom line-tracking loader |
127
- | Terminal Output | rich |
128
- | HTML Reports | Jinja2 — interactive filtering, expandable findings, PDF export |
129
- | AI Narratives | Anthropic Claude API with local caching |
130
- | Linting | ruff, mypy, bandit |
131
- | Packaging | hatch, pyproject.toml |
132
-
133
- ---
134
-
135
- ## Quick Start
136
-
137
- Click the Codespaces button above to run FlowSec in your browser with zero setup. Or install from PyPI:
136
+ ## Risk Score
138
137
 
139
- ```bash
140
- pip install flowsec
141
- export GITHUB_TOKEN=your_token_here
142
- flowsec scan --github --repo owner/repo
143
- ```
144
-
145
- Or run from source:
146
-
147
- ```bash
148
- git clone https://github.com/VanshBhardwaj1945/FlowSec.git
149
- cd FlowSec
150
- python3 -m venv .venv
151
- source .venv/bin/activate
152
- pip install -e ".[dev]"
153
- cp .env.example .env
154
- # Add your GITHUB_TOKEN to .env
155
- ```
156
-
157
- ---
158
-
159
- ## CLI
160
-
161
- ```bash
162
- # Scan a GitHub Actions repo (remote)
163
- flowsec scan --github --repo owner/repo
164
-
165
- # Scan a local GitHub Actions file
166
- flowsec scan --github --file .github/workflows/ci.yml
167
-
168
- # Scan a GitLab CI file (local)
169
- flowsec scan --gitlab --file .gitlab-ci.yml
170
-
171
- # Scan a GitLab CI repo (remote — requires GITLAB_TOKEN)
172
- flowsec scan --gitlab --repo namespace/project
173
-
174
- # Scan an Azure DevOps file (local)
175
- flowsec scan --azure --file azure-pipelines.yml
176
-
177
- # Scan an Azure DevOps repo (remote — requires AZURE_DEVOPS_TOKEN)
178
- flowsec scan --azure --repo org/project
179
-
180
- # Generate an HTML report
181
- flowsec scan --github --repo owner/repo --output report.html
182
-
183
- # Generate AI attack narratives (requires ANTHROPIC_API_KEY)
184
- flowsec scan --github --repo owner/repo --ai
185
-
186
- # Ignore specific rules
187
- flowsec scan --github --repo owner/repo --ignore FS006 --ignore FS011
188
-
189
- # Fail pipeline if findings at or above threshold
190
- flowsec scan --github --repo owner/repo --fail-on critical
191
-
192
- # Everything at once
193
- flowsec scan --github --repo owner/repo --ai --output report.html --fail-on high
194
- ```
138
+ Every scan produces a 0-100 risk score using severity-weighted diminishing returns and exponential normalization. A single critical finding scores ~28. A heavily vulnerable pipeline scores ~90-97. The score cannot exceed 100.
195
139
 
196
140
  ---
197
141
 
198
142
  ## Rule Suppression
199
143
 
200
- Suppress specific rules inline with `--ignore`:
201
-
202
144
  ```bash
145
+ # CLI flag
203
146
  flowsec scan --github --repo owner/repo --ignore FS006 --ignore FS011
204
- ```
205
147
 
206
- Or create a `.flowsec.yml` in your repo root for persistent suppression:
148
+ # .flowsec.yml in your repo root
149
+ ```
207
150
 
208
151
  ```yaml
209
152
  ignore:
@@ -217,8 +160,6 @@ ignore:
217
160
 
218
161
  ## Use as a Pipeline Gate
219
162
 
220
- Add FlowSec to your own GitHub Actions workflow to automatically block PRs that introduce security misconfigurations:
221
-
222
163
  ```yaml
223
164
  name: FlowSec Security Scan
224
165
  on: [push, pull_request]
@@ -227,56 +168,29 @@ jobs:
227
168
  runs-on: ubuntu-latest
228
169
  steps:
229
170
  - uses: actions/checkout@v4
230
- - name: Install FlowSec
231
- run: pip install flowsec
232
- - name: Run FlowSec
233
- run: flowsec scan --github --file .github/workflows/ci.yml --fail-on critical
171
+ - run: pip install flowsec
172
+ - run: flowsec scan --github --file .github/workflows/ci.yml --fail-on critical
234
173
  ```
235
174
 
236
- `--fail-on` supports `critical`, `high`, `medium`, and `low` thresholds.
237
-
238
175
  ---
239
176
 
240
- ## Status
241
-
242
- | Component | Status |
243
- |---|---|
244
- | Rule engine — BaseRule, Finding, Severity | Complete |
245
- | YAML parser with line number tracking | Complete |
246
- | 26 security rules FS001-FS026 | Complete |
247
- | MITRE ATT&CK + OWASP CICD Top 10 mapping | Complete |
248
- | Platform-aware rule engine (GitHub/GitLab/Azure) | Complete |
249
- | GitHub Actions scanner — remote repo and local file | Complete |
250
- | GitLab CI scanner — remote repo and local file | Complete |
251
- | Azure DevOps scanner — remote repo and local file | Complete |
252
- | CLI — `--github/--gitlab/--azure` + `--file/--repo` | Complete |
253
- | Rich terminal output with risk score (0-100) | Complete |
254
- | HTML report with filtering, PDF export | Complete |
255
- | AI attack narratives with local caching | Complete |
256
- | Line number tracking | Complete |
257
- | Pipeline gate `--fail-on` | Complete |
258
- | Rule suppression `--ignore` and `.flowsec.yml` | Complete |
259
- | GitHub Codespace config | Complete |
260
- | PyPI publish with OIDC trusted publishing | Complete |
261
- | CI security workflow (gitleaks, bandit, pip-audit, self-scan) | Complete |
262
-
263
- ---
264
-
265
- ## Roadmap
266
-
267
- **Phase 2 — Expansion**
268
- Jenkins support, AWS CodePipeline, 20+ rule library, Homebrew formula.
177
+ ## Security
269
178
 
270
- ---
179
+ FlowSec is built to the same standard it enforces:
271
180
 
272
- ## Security
181
+ - All GitHub Actions pinned to commit SHAs with least-privilege permissions
182
+ - PyPI publishing via OIDC trusted publishing — no long-lived tokens
183
+ - Own CI runs gitleaks, bandit, pip-audit, and FlowSec self-scan on every push
184
+ - Branch protection on main — force push blocked, 4 required status checks
185
+ - YAML parsed with a SafeLoader subclass — no code execution risk
186
+ - HTML reports use Jinja2 autoescape — XSS from finding content prevented
273
187
 
274
- See [SECURITY.md](SECURITY.md) for the responsible disclosure policy.
188
+ Report vulnerabilities via GitHub Security Advisories or email Scorpio.vansh@gmail.com.
275
189
 
276
190
  ---
277
191
 
278
- ## About this project
192
+ ## License
279
193
 
280
- Built as a security engineering portfolio project. The goal was to build an actual security tool — not run existing ones — and document every decision along the way.
194
+ MIT — see LICENSE on GitHub.
281
195
 
282
- **[Read the full documentation](docs/FULL_README.md)**
196
+ **Source:** https://github.com/VanshBhardwaj1945/FlowSec
@@ -0,0 +1,161 @@
1
+ # FlowSec
2
+
3
+ A Python command-line security tool that scans CI/CD pipeline configurations for attack vectors across **GitHub Actions**, **GitLab CI**, and **Azure DevOps**. Every finding maps to a MITRE ATT&CK technique and an OWASP CICD Top 10 category.
4
+
5
+ The pipeline is the attack surface. FlowSec treats it that way.
6
+
7
+ ---
8
+
9
+ ## Install
10
+
11
+ **Homebrew (macOS):**
12
+
13
+ ```bash
14
+ brew install VanshBhardwaj1945/flowsec/flowsec
15
+ ```
16
+
17
+ **PyPI:**
18
+
19
+ ```bash
20
+ pip install flowsec
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Quick Start
26
+
27
+ ```bash
28
+ # Scan a GitHub Actions repo
29
+ export GITHUB_TOKEN=your_token
30
+ flowsec scan --github --repo owner/repo
31
+
32
+ # Scan a local GitHub Actions workflow file
33
+ flowsec scan --github --file .github/workflows/ci.yml
34
+
35
+ # Scan a GitLab CI file
36
+ flowsec scan --gitlab --file .gitlab-ci.yml
37
+
38
+ # Scan an Azure DevOps pipeline file
39
+ flowsec scan --azure --file azure-pipelines.yml
40
+
41
+ # Generate an HTML report
42
+ flowsec scan --github --repo owner/repo --output report.html
43
+
44
+ # Generate AI attack narratives (requires ANTHROPIC_API_KEY)
45
+ flowsec scan --github --repo owner/repo --ai
46
+
47
+ # Fail pipeline if findings at or above threshold
48
+ flowsec scan --github --repo owner/repo --fail-on critical
49
+
50
+ # Ignore specific rules
51
+ flowsec scan --github --repo owner/repo --ignore FS006 --ignore FS011
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Platforms and Tokens
57
+
58
+ | Platform | File scan | Remote scan | Token required |
59
+ |---|---|---|---|
60
+ | GitHub Actions | `--github --file` | `--github --repo owner/repo` | `GITHUB_TOKEN` (remote only) |
61
+ | GitLab CI | `--gitlab --file` | `--gitlab --repo namespace/project` | `GITLAB_TOKEN` (remote only) |
62
+ | Azure DevOps | `--azure --file` | `--azure --repo org/project` | `AZURE_DEVOPS_TOKEN` (always — Azure requires auth even for public projects) |
63
+
64
+ Set tokens in a `.env` file in your working directory or as environment variables. FlowSec loads `.env` automatically.
65
+
66
+ ---
67
+
68
+ ## 26 Security Rules
69
+
70
+ | ID | Rule | Severity | MITRE | OWASP |
71
+ |---|---|---|---|---|
72
+ | FS001 | Hardcoded Secret — Plaintext Credential in Workflow | CRITICAL | T1552.001 | CICD-SEC-6 |
73
+ | FS002 | Unpinned Action — Supply Chain Attack Vector | CRITICAL | T1195.001 | CICD-SEC-3 |
74
+ | FS003 | Excessive Permissions — Overprivileged Workflow Token | HIGH | T1078 | CICD-SEC-5 |
75
+ | FS004 | Missing OIDC — Long-Lived Cloud Credential in Use | HIGH | T1552.004 | CICD-SEC-6 |
76
+ | FS005 | Pull Request Target — Secrets Exposed to Fork Code | CRITICAL | T1611 | CICD-SEC-4 |
77
+ | FS006 | Missing Timeout — Job Runs Up to 6 Hours Unchecked | LOW | T1499 | CICD-SEC-10 |
78
+ | FS007 | Self-Hosted Runner — Persistent Environment Risk | HIGH | T1053 | CICD-SEC-7 |
79
+ | FS008 | Missing Artifact Signing — No Tamper Protection | MEDIUM | T1553 | CICD-SEC-8 |
80
+ | FS009 | Unpinned Dependency — Package Installed Without Version Lock | HIGH | T1195.002 | CICD-SEC-3 |
81
+ | FS010 | Secret in Run Command — Plaintext Credential in Shell Step | CRITICAL | T1552.001 | CICD-SEC-6 |
82
+ | FS011 | GitHub Context Injection — Untrusted Event Data in Run Step | CRITICAL | T1059.004 | CICD-SEC-4 |
83
+ | FS012 | Missing Environment Protection — Deploy Job Has No Approval Gate | HIGH | T1078 | CICD-SEC-5 |
84
+ | FS013 | Workflow Dispatch Injection — Unvalidated Input in Shell Command | CRITICAL | T1059 | CICD-SEC-9 |
85
+ | FS014 | Mutable Container Image — Unpinned Image Tag in Pipeline | MEDIUM | T1195.001 | CICD-SEC-3 |
86
+ | FS015 | Persist Credentials — GitHub Token Remains in Git Config After Checkout | MEDIUM | T1552.001 | CICD-SEC-6 |
87
+ | FS016 | workflow_run Trigger — Privileged Execution from Untrusted Workflow | HIGH | T1059 | CICD-SEC-1 |
88
+ | FS017 | Security Scan Silenced — Failures Suppressed with continue-on-error | MEDIUM | T1562.001 | CICD-SEC-7 |
89
+ | FS018 | Secret as CLI Argument — Credential Exposed in Process List | HIGH | T1552 | CICD-SEC-6 |
90
+ | FS019 | Unverified Install Script — Remote Code Fetched and Executed Directly | HIGH | T1195.002 | CICD-SEC-3 |
91
+ | FS020 | Container Running as Root — Elevated Privilege in Pipeline | HIGH | T1611 | CICD-SEC-7 |
92
+ | FS021 | Secret in Docker Build Argument — Credential Stored in Image History | HIGH | T1552.001 | CICD-SEC-6 |
93
+ | FS022 | Broad Artifact Upload — Entire Workspace Exposed as Artifact | MEDIUM | T1560 | CICD-SEC-9 |
94
+ | FS023 | Insecure curl — SSL Verification Disabled in Pipeline | HIGH | T1071 | CICD-SEC-3 |
95
+ | FS024 | Privileged Docker Container — Full Host Access Granted in Pipeline | CRITICAL | T1611 | CICD-SEC-7 |
96
+ | FS025 | Environment Variables Printed to Logs — Secrets Exposed in Pipeline Output | MEDIUM | T1552.001 | CICD-SEC-6 |
97
+ | FS026 | Unguarded Deploy — Deployment Job Runs on Untrusted Branches | HIGH | T1078 | CICD-SEC-1 |
98
+
99
+ ---
100
+
101
+ ## Risk Score
102
+
103
+ Every scan produces a 0-100 risk score using severity-weighted diminishing returns and exponential normalization. A single critical finding scores ~28. A heavily vulnerable pipeline scores ~90-97. The score cannot exceed 100.
104
+
105
+ ---
106
+
107
+ ## Rule Suppression
108
+
109
+ ```bash
110
+ # CLI flag
111
+ flowsec scan --github --repo owner/repo --ignore FS006 --ignore FS011
112
+
113
+ # .flowsec.yml in your repo root
114
+ ```
115
+
116
+ ```yaml
117
+ ignore:
118
+ - rule_id: FS006
119
+ reason: "We use external timeout management"
120
+ - rule_id: FS011
121
+ reason: "Branch protection managed at org level"
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Use as a Pipeline Gate
127
+
128
+ ```yaml
129
+ name: FlowSec Security Scan
130
+ on: [push, pull_request]
131
+ jobs:
132
+ security:
133
+ runs-on: ubuntu-latest
134
+ steps:
135
+ - uses: actions/checkout@v4
136
+ - run: pip install flowsec
137
+ - run: flowsec scan --github --file .github/workflows/ci.yml --fail-on critical
138
+ ```
139
+
140
+ ---
141
+
142
+ ## Security
143
+
144
+ FlowSec is built to the same standard it enforces:
145
+
146
+ - All GitHub Actions pinned to commit SHAs with least-privilege permissions
147
+ - PyPI publishing via OIDC trusted publishing — no long-lived tokens
148
+ - Own CI runs gitleaks, bandit, pip-audit, and FlowSec self-scan on every push
149
+ - Branch protection on main — force push blocked, 4 required status checks
150
+ - YAML parsed with a SafeLoader subclass — no code execution risk
151
+ - HTML reports use Jinja2 autoescape — XSS from finding content prevented
152
+
153
+ Report vulnerabilities via GitHub Security Advisories or email Scorpio.vansh@gmail.com.
154
+
155
+ ---
156
+
157
+ ## License
158
+
159
+ MIT — see LICENSE on GitHub.
160
+
161
+ **Source:** https://github.com/VanshBhardwaj1945/FlowSec
@@ -99,7 +99,22 @@ Scanned `VanshBhardwaj1945/cloud-resume-challenge-azure` — 13 findings across
99
99
 
100
100
  ## Quick Start
101
101
 
102
- Click the Codespaces button above to run FlowSec in your browser with zero setup. Or install from PyPI:
102
+ Click the Codespaces button above to run FlowSec in your browser with zero setup.
103
+
104
+ **Homebrew (macOS):**
105
+
106
+ ```bash
107
+ brew install VanshBhardwaj1945/flowsec/flowsec
108
+ ```
109
+
110
+ Or tap once then install:
111
+
112
+ ```bash
113
+ brew tap VanshBhardwaj1945/flowsec
114
+ brew install flowsec
115
+ ```
116
+
117
+ **PyPI:**
103
118
 
104
119
  ```bash
105
120
  pip install flowsec
@@ -223,6 +238,7 @@ jobs:
223
238
  | Rule suppression `--ignore` and `.flowsec.yml` | Complete |
224
239
  | GitHub Codespace config | Complete |
225
240
  | PyPI publish with OIDC trusted publishing | Complete |
241
+ | Homebrew tap (`brew install VanshBhardwaj1945/flowsec/flowsec`) | Complete |
226
242
  | CI security workflow (gitleaks, bandit, pip-audit, self-scan) | Complete |
227
243
 
228
244
  ---
@@ -230,7 +246,7 @@ jobs:
230
246
  ## Roadmap
231
247
 
232
248
  **Phase 2 — Expansion**
233
- Jenkins support, AWS CodePipeline, 20+ rule library, Homebrew formula.
249
+ Jenkins support, AWS CodePipeline, 20+ rule library.
234
250
 
235
251
  ---
236
252
 
@@ -18,7 +18,7 @@ Include:
18
18
  - Steps to reproduce or a proof-of-concept
19
19
  - Any suggested fix (optional)
20
20
 
21
- You will receive a response within **72 hours** and a fix or mitigation within **14 days** for confirmed issues.
21
+ You will receive a response within **144 hours** and a fix or mitigation within **14 days** for confirmed issues.
22
22
 
23
23
  ## Scope
24
24