Why utilities run GitLab inside their own networks
Utilities and energy operators run self-managed GitLab because the source code, pipeline definitions and change records for engineering and control-system work must stay inside networks they control, and often must keep working when those networks have no internet path at all. Compared with a standard build, three things change: the instance has to run offline, the change history has to serve as evidence for a NERC CIP style program, and the code that touches operational technology has to be kept apart from corporate systems. GitLab documents running self-managed instances in offline, air-gapped environments, including separate guidance for its security scanners, so offline operation is a supported pattern rather than a workaround. The open core split does not alter this. Content under the ee/ directory is covered by the Enterprise Edition license and the rest is MIT Expat licensed, but the deployment scope is the same either way, so the license question is about which features you need, not where the software may run.
The first decision is what the offline instance must be able to do without outside access. Confirm with GitLab which package sources, container images, security advisory data and scanner content you will mirror in, and who approves each import across the boundary. The same question applies to runners and to any integration that calls an external service. Second, decide which code belongs in the OT boundary at all. Many utilities keep configuration and logic for field devices in a separate instance or group with its own runners, users and approval rules, so that corporate projects and OT repositories never share an administrator. Third, map each change to the control evidence your auditor will ask for. CIP-013-2 expects vendor software and patches to be verified for integrity and authenticity, and CIP-005-7 covers remote access paths, so plan how packages are checked before they enter the boundary and who can reach the instance remotely. Your compliance team should confirm which CIP standards and asset categories apply to your registration before the design is fixed.
Set these decisions in writing before installation, because they shape the install method, backup location and runner placement that follow. Ask any implementation partner to show how the offline instance will receive upgrades, given that GitLab requires stops at versions such as 19.5 and 19.8 and that security fixes follow the maintenance policy. Ask how the separated OT environment will be monitored and who reviews its audit logs. Good answers name the network paths, the mirror process and the owner of each approval. Vague answers about air-gapping usually hide gaps in package verification and remote access, and those are the gaps a CIP audit tends to find.
Which energy requirements change the GitLab build
This table maps each supplied NERC CIP and NIS2 requirement to what it asks for and what it means for a self-managed GitLab design. Read it as a checklist for where GitLab, its runners and its backups sit relative to impact classification and perimeters. Confirm each applicability question with your compliance team and Regional Entity before building.
| Requirement | What it asks for | What it means for the GitLab design |
|---|---|---|
| CIP-002 impact classification | Sorts BES Cyber Systems into high, medium and low impact using bright-line criteria in Attachment 1 | Decide which systems GitLab runners and pipelines touch before placing them. Pipelines that deploy to or build firmware for medium or high impact systems pull those systems into scope |
| CIP-002 Applicable Systems scoping | Scopes most requirements by Applicable Systems, such as medium impact BES Cyber Systems with External Routable Connectivity and associated EACMS and PCA | Map each GitLab component (web, Gitaly, runners, backup storage) to an Applicable System category. Components that administer or authenticate to in-scope systems may fall under EACMS or PCA scoping |
| CIP-005-7 Electronic Security Perimeter | Requires routable-connected high and medium impact BES Cyber Systems to sit inside an ESP | Place the GitLab instance and runners on the correct side of the perimeter. Replication to a Geo secondary or to a runner fleet must cross the ESP through controlled paths |
| CIP-005-7 Interactive Remote Access | Routes all Interactive Remote Access through an Intermediate System with encryption and multi-factor authentication, plus detection and disabling of active vendor sessions | Do not expose GitLab web or SSH access to vendors directly. Route vendor access through the Intermediate System and enforce multi-factor authentication in GitLab's identity configuration |
| CIP-013-2 software integrity and vendor patches | Requires supply chain procurement processes to verify software integrity and authenticity of vendor software and patches | Plan how GitLab packages, runner binaries, container images and vendor patches are verified before they cross an isolated boundary. Document the verification step as a repeatable pipeline stage |
| CIP-013-2 vendor remote access coordination | Requires supply chain risk management plans that cover vendor incident notification, vulnerability disclosure and coordination of vendor-initiated remote access, reviewed at least every 15 calendar months | Record the vendor access pathways that touch GitLab, such as support sessions or upgrade work, and keep them in the plan that is reviewed on the 15-month cycle |
| CIP-011-3 information protection | Requires entities to protect BES Cyber System Information under a documented information protection program | Treat repositories, pipeline logs, artifacts and backups that contain BCSI as controlled data. Restrict project visibility, job log access and backup copies to the people and locations the program allows |
| The 13 CIP standards enforceable as of 17 October 2026 | Lists CIP-002-5.1a, CIP-003-9, CIP-004-7, CIP-005-7, CIP-006-6, CIP-007-6, CIP-008-6, CIP-009-6, CIP-010-4, CIP-011-3, CIP-012-2, CIP-013-2 and CIP-014-3 as mandatory in the US (NERC CIP standards page) | Build the GitLab evidence map against these versions, not older ones. Note that CIP-003-9 and CIP-012-2 became enforceable in 2026, and that CIP-015-1 and the virtualization revisions take effect later (1 October 2028 and 1 July 2028) |
| NIS2 Annex I energy coverage | Lists energy as a high-criticality sector with electricity, district heating and cooling, oil, gas and hydrogen subsectors (Directive (EU) 2022/2555) | EU operators in these subsectors should confirm their NIS2 transposition and obligations with national authorities. The same network separation and supplier controls described above apply to the GitLab design |
Modules and settings that matter for utility GitLab
A utility GitLab instance is judged on what it can prove, how it behaves when disconnected, and how cleanly OT code stays apart from corporate systems. The cards below cover the settings and components that shape those answers, and each one is a decision to make before the build starts rather than after the first audit request.
Offline install with the Linux package
The Linux package bundles PostgreSQL, Redis and Sidekiq, and it is the install method GitLab describes as the most mature and scalable. For an isolated control network, the offline environment guidance covers installing without internet access, and it also covers the separate offline options for security scanners. Ask the vendor and your own environment which scanner and AI features you actually need offline, because each has its own setup path. Plan how packages and container images will be transferred across the boundary and who verifies them.
Premium or Ultimate tier decision
Free, Premium and Ultimate are all available for self-managed installations, so the tier choice is a compliance and security decision, not only a licensing one. Premium lists advanced CI/CD and priority support, while Ultimate lists application security testing, software supply chain security, vulnerability management and compliance features. Map each change-control or software integrity evidence need to a named tier feature, and confirm the current feature list on the pricing page before you commit budget.
Corporate identity with enforced MFA
GitLab Self-Managed supports LDAP, SAML, generic OAuth 2.0, Kerberos, JWT, smart card authentication and SCIM provisioning. For utilities, tie access to the corporate directory so that joiners, movers and leavers flow through one process, and confirm that multi-factor authentication is enforced for every account that can change pipelines or approve merges. Access to OT-adjacent repositories should follow the same rules as access to the rest of the control environment.
Runner placement across OT and corporate zones
GitLab Runner executes CI/CD jobs and supports shell, Docker and autoscaling executors. Decide which zone each runner lives in: runners that build or test OT code should sit inside the zone that holds those assets, while corporate builds should not reach into it. Keep the Runner major and minor versions aligned with the GitLab version, and record the aligned versions in your change records so that the pipeline itself can be shown to be consistent.
Hardening through gitlab.rb
Much of the hardening sits in configuration files such as gitlab.rb, along with application settings, CI/CD settings and the operating system. GitLab's hardening guidance references NIST SP 800-53 and states that it is a work in progress to be rolled out gradually. Treat it as a baseline to adopt in stages, record each change as a version-controlled configuration item, and test each stage in a non-production instance before it reaches the control network.
Backup and Geo for a second site
Backups protect repositories, but restoring a utility instance also depends on secrets, configuration and the data behind CI artifacts, so the restore procedure needs its own test. For a second site, GitLab Geo in the Premium and Ultimate tiers provides a warm-standby secondary that is continuously synchronized. Confirm with your architect whether the second site sits in an approved location and whether it can run inside the same isolation rules as the primary.
Separate groups or instances for OT code
Decide whether OT code lives in a separate GitLab instance or in a restricted group within the corporate instance. A separate instance gives harder isolation and its own upgrade and backup cycle, while a restricted group is cheaper to run but depends on correct permissions and runner placement. Either way, document which repositories are in scope for the CIP program, who can administer them, and how their change history is exported as evidence.
How a utility GitLab rollout is sequenced
The sequence classifies what GitLab will hold before any server is built, so the perimeter, offline supply chain, identity, runners and change evidence are designed for the systems they touch. Each phase ends with a check that the next phase can rely on.
Classify code and systems by CIP impact
Start by mapping every repository, pipeline and deployment target to its impact rating under CIP-002-5.1a and to the Applicable Systems in the relevant requirement tables. Compliance, OT engineering and the asset owners decide which projects touch BES Cyber Systems, which touch only corporate IT, and which sit in a grey zone that needs a ruling. Projects that are out of scope for CIP still need a documented reason. The output is a signed classification register that names each repository group, its owner and its intended hosting zone. Confirm the final categorization with your Compliance Enforcement Authority contacts or internal compliance counsel, since the register is only as good as the rulings behind it.
Define the perimeter and data flows
Document where the GitLab instance, its runners and its backups will sit relative to any Electronic Security Perimeter, and list every permitted data flow in and out. Include developer access, Interactive Remote Access for vendors, package and image transfers, and replication to any secondary site. Vendor remote access paths must route through the Intermediate System and multi-factor authentication required by CIP-005-7. The output is a data flow diagram and a firewall rule set reviewed by the network, OT security and compliance teams, with each rule tied to a stated business purpose.
Build the offline bundle and verify integrity
Assemble the installation packages, container images, runner binaries and dependencies on an external staging network, then move them across the boundary on approved media. GitLab documents offline and air-gapped operation, so confirm the exact artifacts and any separate guidance for the security scanners you intend to run. Verify the integrity and authenticity of every item against vendor-published checksums and signatures before import, and record the hashes in the change package. This directly supports the software integrity and authenticity verification expected under CIP-013-2. The output is a manifest of artifacts, hashes and the person who verified each one.
Install and harden the instance
Install GitLab using the method your platform team has approved, and record the chosen method, version and topology in configuration as code. Size the deployment against the reference architecture that matches your user count and CI load, and confirm whether high availability is needed. Apply the hardening guidance in stages, starting with application settings, outbound request controls and the operating system, and log each deviation with its reason. The output is a built instance, a configuration baseline in version control and a hardening exception register reviewed by the security team.
Connect identity and runners
Integrate GitLab with the utility's identity provider using SAML, LDAP or another supported method, and map groups to roles so that developers, OT engineers and approvers hold only the access their projects need. Enforce multi-factor authentication for all accounts that can change protected branches or deployment settings. Register runners only inside the zone that matches each project's classification, and isolate runners that build OT code from those serving corporate projects. The output is a tested access matrix, a list of registered runners with their zones and tags, and evidence that an out-of-zone user cannot reach restricted projects.
Set backups and upgrade stops
Configure backups for the database, repositories, uploads and the secrets file, and store copies in the zone your recovery plan requires. Test a restore into an isolated environment and record the time and the gaps you found, because an untested backup is not evidence. Build an upgrade calendar that follows GitLab's maintenance policy and required upgrade stops, and stage each upgrade through the offline bundle process. Decide who approves an upgrade and how it is recorded as a change. The output is a restore test report and an upgrade plan that the change board has accepted.
Run change evidence through a pilot team
Choose one team with a bounded OT or corporate project and move its work into GitLab first. Use merge request approvals, protected branches, pipeline results and the audit trail as the change record, and check with compliance that each captured item matches what the change control procedure requires. Review gaps with the pilot team and with the auditors or internal assessors who will later review the program. The output is a set of sample change records that compliance has signed off, a list of procedure fixes, and a go or no-go decision for wider rollout.
How to separate OT code from corporate systems
The first decision is where OT code lives, and it should follow the impact classification of the systems it controls under CIP-002-5.1a, together with the Electronic Security Perimeter that CIP-005-7 requires around high and medium impact BES Cyber Systems with routable connectivity. There are three common options: a separate self-managed GitLab instance for OT, a separate group with restricted runners on the corporate instance, or placement inside the perimeter itself. A separate instance gives the strongest boundary but doubles upgrades, backups and access reviews. A group with dedicated runners is cheaper to run but depends on the corporate instance staying healthy. Confirm with your compliance team which option keeps each repository's evidence within the scope you have documented, and ask your auditor how they expect that boundary to be drawn before you build it.
Once placement is set, isolate the execution path. Register runners for OT projects only in the OT group, use protected runners that cannot be reached by corporate projects, and avoid shared Docker or shell executors that run jobs from both zones on the same host. Restrict outbound requests from the instance and from runners to an approved list of endpoints, and review the settings described in the GitLab hardening documentation for application-level controls. Enforce a rule that OT pipelines pull only from internal mirrors, with the Runner and GitLab versions kept aligned. For change approval, require protected branches and environments with approvers who are not the authors, and make sure the approval step matches the separation of duties your change process records. CIP-013-2 expects you to verify software integrity and authenticity for anything crossing into the boundary, so plan a signed artifact or checksum check at that point.
Use NIST SP 800-82 Rev. 3 and the ISA/IEC 62443 series as the frameworks to consult when you define zones, conduits and the security level target for each OT area, and map their terms to your impact categories rather than adopting them wholesale. Ask your engineers which build tools must run on Windows or on the plant floor, since those runners will need a separate host plan. Before any production change, test the boundary by attempting an unapproved cross-zone pipeline and an outbound call to an unlisted address, then record the results as evidence.
What do utilities ask before hiring a GitLab partner?
What drives the cost of a self-managed GitLab project for a utility?
The biggest driver is scope, not the software. GitLab Free costs 0 dollars, Premium costs 29 US dollars per user per month billed annually, and Ultimate is custom priced, according to the GitLab pricing page. Choosing a tier decides which security, compliance and advanced CI/CD features you pay for each year. Engagement cost then depends on the number of environments, whether the instance runs in an air-gapped network, how many runners and integrations are needed, how much change evidence must be produced, and whether high availability or Geo is in scope. Ask for a quote that separates one-time build work from recurring support, upgrades and license fees, and that names who pays for each line.
How long does a GitLab deployment in an isolated utility network take?
Duration depends on the environment and the evidence required, and no fixed figure applies to every utility. The main variables are how many network zones are involved, whether packages must cross a controlled transfer process, how identity is integrated, how many projects and pipelines are migrated, and how many approvals the change owners need before anything goes live. Ask the partner to show the build sequence and the points where your staff must review or sign off, and agree the timeline in writing before work starts, since most engagements are fixed-scope.
What must the utility provide before the engagement starts?
The partner needs accurate inputs or the design will be wrong. Prepare network diagrams that show zones, routing and any boundary between corporate and OT networks, plus an inventory of systems that touch BES Cyber Systems so impact classification can be checked against CIP-002. Provide identity sources and the groups that will map to GitLab roles, the named change owners and approvers, existing runner hosts, and the storage and backup targets you already run. Also confirm who in your organization can accept the offline package transfer process and who holds the license terms.
Can our internal team run GitLab after the project ends?
Often yes, if the handover is planned from the start. Running GitLab involves routine tasks such as backups, health checks, monitoring, runner maintenance and upgrades, all documented in GitLab's own guidance. The question is whether your staff have the time, skills and on-call coverage to do them in a controlled network. Ask the partner what runbooks, configuration records and test restores will be delivered, which tasks you would own, and which would stay under a support retainer. Retainers for ongoing support and upgrades are available from DeployOpen, and you should compare that cost against training and hiring for your own team.
How are GitLab upgrade stops planned in a network you cannot change quickly?
Upgrades must follow the required upgrade stops, which since GitLab 17.5 fall at versions x.2, x.5, x.8 and x.11, such as 18.2, 18.5, 18.8, 18.11 and 19.2, 19.5, 19.8 and 19.11, according to GitLab's upgrade paths documentation. GitLab ships a minor release on the third Thursday of each month and patch releases twice a month, and it maintains 19.5, 19.4 and 19.3 at present. Security fixes are backported to the previous two monthly releases, while bug fixes go only to the current stable release. For a utility, this means each upgrade must be scheduled through change control, tested in a non-production copy, and approved, with the path to the next stop documented in advance.
How are packages and licenses moved into an air-gapped network?
Offline installation is documented by GitLab for self-managed instances in air-gapped environments, including separate guidance for security scanners and GitLab Duo Self-Hosted offline, according to GitLab's offline environments page. Plan a controlled transfer process in which every package, container image and update is copied through an approved media or diode path, recorded, and checked for integrity and authenticity before import. This supports the software verification expected under CIP-013-2. Confirm with GitLab which features your tier includes for offline use, since some scanners and AI features have their own offline requirements, and get the license terms in writing for the tier you select.
Does GitLab alone make a utility CIP-compliant?
No. There is no CIP certificate, and compliance is judged by the Compliance Enforcement Authority through audits, spot checks and self-reports, according to NERC Rules of Procedure Appendix 4C. GitLab can serve as a system of record for change approvals, code review and pipeline evidence, but it does not decide which systems are in scope or which controls apply. Ask the partner which evidence it prepares for your compliance team and which decisions stay with your staff and your independent auditor. DeployOpen prepares systems, controls and evidence for compliance assessments but does not issue audit reports or certifications.
Compliance evidence GitLab can support, and what it cannot
GitLab can hold much of the change and access record a CIP program asks for, but the record is only useful if it is tied to the controls it supports. DeployOpen prepares systems, controls and evidence; it does not issue audit reports. There is no CIP certificate, and the Compliance Enforcement Authority, a Regional Entity or NERC, judges compliance through audits, spot checks and self-reports.
Change records and approvals
Merge requests, approval rules and pipeline results can show who proposed a change to a BES Cyber System's configuration, who approved it and what tests ran before it was applied. This supports the change management controls under CIP-010. The gap to check is scope: GitLab only records changes made through it, so manual changes on field devices need a separate, linked process.
Vendor software integrity checks
CIP-013-2 expects procurement processes to verify the integrity and authenticity of vendor software and patches before they enter the environment. Packages mirrored into GitLab's package and container registries can be checked against vendor hashes and signatures before promotion. Confirm which signature formats your vendors use and whether your verification steps are recorded as pipeline jobs.
Access control evidence
SAML or OIDC single sign-on, LDAP group sync and SCIM provisioning let access to repositories and pipelines follow the identity source your utility already reviews. Removals made in the directory can then flow through to GitLab. Auditors will ask for the mapping, the review cadence and proof that deprovisioning happened, so keep exports of group membership and provisioning logs.
Backup and restore records
GitLab backup tasks produce archives and logs that show when the system and repositories were protected and whether a restore was tested. These records support recovery planning under the CIP business continuity and recovery controls. Confirm that backups cover secrets files and object storage, and that restore tests are written up with dates, scope and results, because a backup file alone shows little about recoverability.
What GitLab cannot evidence
GitLab does not decide whether a system is in scope, whether a BES Cyber System is high, medium or low impact under CIP-002, or whether an Electronic Security Perimeter is correctly drawn. Those classifications, the risk assessments and the judgments about vendor remote access sit in your compliance program. Treat GitLab as one source of evidence inside that program, not as the program itself.
Running GitLab offline without weakening updates
An air-gapped utility keeps GitLab patched by planning every release as a transfer, not a download. GitLab ships a minor release on the third Thursday of each month and patch releases twice a month, and the maintenance policy currently covers 19.5, 19.4 and 19.3. Bug fixes go only to the current stable release, but security fixes are also backported to the previous two monthly releases. That means a site running 19.3 still receives security fixes, yet it falls behind on everything else. Before the change window opens, confirm with GitLab which release line your instance is on, and set a standing rule that the isolated instance stays on a version that is still maintained, with a named owner for tracking each release.
Upgrades cannot simply jump to the newest release. GitLab requires upgrades to pass through required upgrade stops, which since GitLab 17.5 fall at versions x.2, x.5, x.8 and x.11, for example 19.2, 19.5, 19.8 and 19.11. Build the offline upgrade calendar from the GitLab upgrade paths documentation and treat each stop as a planned outage with its own backup, restore test and rollback point. Runner versions must also move in step with GitLab, so the Runner packages in each transfer need to match the instance version in the same change record.
Every package that crosses the boundary is a supply chain event, and CIP-013-2 expects you to verify software integrity and authenticity for vendor software and patches before it is installed. Ask your transfer procedure to record the package name, version, checksum and the signature or provenance check performed on the outside network, then repeat the check on the inside before installation. Keep the offline installation guidance from the GitLab offline environments page in the change package, because it defines what must be mirrored for an air-gapped instance. Where a patch arrives late, document the exposure window and the compensating controls, so an auditor sees a managed decision rather than a silent gap.
How DeployOpen scopes and delivers utility GitLab work
DeployOpen is a Chainscore Labs company that plans, implements, hardens, backs up, documents and supports self-hosted open-source platforms inside the client's own infrastructure. For GitLab in energy and utility networks, we start from the network zones and compliance evidence your program needs, then build and hand over a GitLab estate that stays under your control.
How we scope
- Map which repositories and pipelines touch OT, BES Cyber Systems or corporate networks before any build starts
- Agree in writing the offline or air-gapped install method, update channel and package transfer process
- Define the change control evidence fields, approvers and retention your CIP program will need from GitLab
How we build
- Install GitLab and its runners inside your data centers or air-gapped enclaves, following the offline environment guidance
- Configure separate instances or runner pools so OT code never shares a runner or project tree with corporate systems
- Test restore procedures and upgrade stops in a non-production copy before the first production change
How we hand over
- Deliver written runbooks for installation, backups, upgrade stops, runner registration and offline package intake
- Document the access model, approval workflow and audit log locations that compliance staff will review
- Walk your operations and compliance teams through the evidence trail and the procedures they must maintain
How we support
- Offer ongoing support, upgrades and continuous testing as a retainer after handover
- Plan each GitLab release against the maintenance policy and required upgrade stops with your change board
- Confirm with your compliance advisors how any NERC CIP evidence requirement maps to the controls we deliver

