Case Study · Compliance & Governance
NERC CIP-005 evidence pipeline as a weekly CI job
Audit prep becomes a query, not a project. Same evidence every week, signed, archived, and ready.
Sector: Electric Utility · Platform: GitLab CI + FortiGate + NCN share · Timeline: 4 weeks
The situation
NERC CIP-005 evidence collection was a quarterly fire drill: engineers manually pulled FortiGate policy backups, attached them to tickets, copied them to the NCN CIP share, and prepared a narrative. Different engineers produced subtly different evidence, and the archive grew inconsistent.
What we built
- A weekly GitLab CI pipeline triggered every Monday morning.
- A dedicated GitLab runner inside the OT enclave (the only environment with line-of-sight to the production FortiGate) configured as a shared
unix-tagged runner.
- The job pulls the running configuration from the production FortiGate, sanitizes ephemeral fields, and commits the file to a protected branch in self-hosted GitLab.
- A post-commit hook auto-archives the file to the NCN CIP-005 share with the week's date stamp.
- Drift report rendered as a CI artifact -- diff vs. prior week, highlighted by section (firewall policy, address objects, routes, admins).
Design decisions worth flagging
- Backups don't transit the corporate network. The runner lives inside the OT enclave; the only egress is to the GitLab API.
- Protected branch, MR-only changes. No human can push directly. Every change to the pipeline itself is reviewed.
- Auto-archive uses the runbook the auditors already know. Files land where existing CIP documentation said they would, just on a Monday-by-Monday cadence.
- Template is reusable. The same pattern now runs against multiple FortiGates with site-specific overrides.
Outcome
Evidence is collected without engineer time once the pipeline is built. Audit prep, which previously took a senior engineer one week per quarter, is now a saved-search export. Drift reports surface unexpected changes within a week of them landing in production -- a defensive control we didn't have before.
← Back to case studies