Goce Petrov’s personal lab: a three-stage ML pipeline (data, training, serving API). Bandit and Pylint run on every push, with findings committed back to the repo as artifacts. Not full AI threat coverage. A floor that most ML teams do not have yet.
ML Pipeline · Bandit · Pylint · SAST · GitHub Actions · Evidence Committed
The ML pipeline, the data flow, and where each scanner lives.
Three-stage ML pipeline on a single GitHub repo. The steps trace the commit-to-prediction path, 1 through 8. E is the evidence loop.
Git push: the ML engineer commits to main.
Trigger: every push runs security-scan.yml on the Actions runner.
SAST scan: Bandit checks all three Python stages, and Pylint checks train.py.
Raw data in: data_pipeline.py ingests and cleans the raw dataset.
Processed dataset: train.py fits the model on it.
Save pickle: the model is saved as model.pkl, which is not scanned.
load_model(): api.py loads the pickle for the serving endpoint.
Predict: a consumer calls the endpoint.
E: the scan reports are committed back to security-reports/, so the history can be diffed.
What is covered
Bandit SAST on all three Python stages → Pylint quality on train.py → both reports committed to security-reports/ on every push. Diffable, not ephemeral.
What is not covered yet
The pickle artefact is the largest blind spot. Model scanning, adversarial input tests on /predict and training-data poisoning checks come in the next iteration. The case study says so out loud.
A floor, not a ceiling. SAST on every stage is the baseline most ML teams still skip.
What is not here yet
Model-artifact scanning for pickle-based payloads. Training-data poisoning detection. Adversarial input testing against the serving API. Garak on the endpoint.
These belong in the next iteration. I am not claiming the current version replaces them. I am claiming it is the starting floor most ML teams have not built.
What this shows about me
I apply DevSecOps to ML, not just web apps.
The same pipeline discipline, different attack surface.
I commit the evidence.
security-reports/ gets the scan output on every push. Diffable history.
I know the difference between SAST and AI security.
I do not conflate them. The case study says so.
I ship baselines, not perfect systems.
A floor others can build on beats a ceiling nobody reaches.
Outcome
A working scan baseline on an ML pipeline, with evidence shipped as repo artifacts. The case study names exactly what the next layer of AI-specific controls needs to cover.
ML stages covered 3 (data, train, serve)
Scanners Bandit + Pylint
Evidence artifacts JSON + text committed
Next layer Model + adversarial testing
Honest framing Baseline, not ceiling
Coursework origin SecureAI hands-on lab