Fintech Supply-Chain Pipeline

Reproducing a supply-chain attack inside a fintech CI/CD pipeline

A transaction processor with a poisoned dependency. Bandit misses it - the attack is not in the source. Trivy catches it in the built image. The only thing between that finding and production is one YAML flag.

Year
2025
Role
DevSecOps
Stack
Python, Docker, GitHub Actions
Target
Fintech CI/CD
Supply ChainTrivyBanditDockerGitHub ActionsCVE Scanning
github.com/gocko1004/fintech-secure-pipeline-demo ->
High-level design
The fintech pipeline, the supply-chain path,
and the exact point the gate closes.
Numbered steps trace a poisoned dependency from commit to merge-block, 1 through 8. B is the blocked push. Full step names in the legend.
Actor
Developer
commits to main
Source- github.com
GitHub repo
fintech pipeline demo
requirements.txt
poisoned pkg pinned
CVE-loaded dep
Actions runner
ci.yml
On every push
CI Pipeline- ubuntu-22.04
Bandit SAST
reads .py files only / 0 findings
blind to deps
Docker builder
python:3.11-slim
fintech-app-image
built in memory
CVE baked in
Trivy scan
HIGH + CRITICAL
CVE DBSBOM
CI gate
exit-code: 1 / merge blocked
Severity gate
Target env
Prod registry
push never happens
push rejected
Production runtime
untouched
1git push
2trigger
3source scan (0 findings)
4docker build
5pip install poisoned dep
6CVE baked into image
7Trivy image scan
8HIGH CVE reported
Bmerge blocked, push rejected
Before (insecure default)
Trivy runs with exit-code: 0 → HIGH CVE logged but ignored → image promoted to prod registry → attack ships.
After (one-line fix)
Trivy runs with exit-code: 1 on HIGH/CRITICAL → gate fails → merge blocked → registry never sees the poisoned image.
Source SAST is the wrong layer for this attack. The image scanner is. One YAML flag turns its finding into a gate.
Why fintech

Fintech pipelines move customer data and money. The threat model is not hypothetical - a poisoned dependency in a payment library is a full breach.

Source-level SAST is the default. It would not have caught this. The image scanner is the layer that actually matters.

What this shows about me
I reason about where controls belong.
Source vs image vs runtime - each scanner has a blind spot.
I read the config, not the marketing.
exit-code: 0 vs 1 is the whole game. I flipped it in this repo.
I write pipelines a fintech CISO would accept.
Severity gated at HIGH/CRITICAL, no bypass flag, no silent scans.
I can narrate the supply-chain path in plain English.
From dependency to CVE to merge block, step by step.
Outcome

A fintech pipeline that now fails loud on supply-chain CVEs. The exact line that turns a reported finding into a blocked merge is visible in the diff.

Pipeline stages6
ScannersBandit + Trivy
Target severityHIGH + CRITICAL
Gate fixexit-code: 1
AudienceFintech + banking
DemoPush triggers pipeline
home/work/fintech-pipeline
Home