Air-Gapped CI Pipelines for Regulated Industries
Building air-gapped pipelines requires self-contained infrastructure and stateful API mocks.

Air-gapped CI pipelines for regulated industries must do more than move familiar tools behind a firewall. Every dependency must resolve locally, and every integration test must preserve the stateful behavior of the service it replaces. A compliant pipeline therefore needs a self-contained architecture, automated policy enforcement, and locally hosted API simulators maintained through a controlled verification and update process.
Why regulated industries cannot retrofit a standard CI/CD pipeline for air-gapped operation
Standard CI/CD pipelines assume they can reach external services at every step of delivery. Package managers pull from public registries, container runtimes pull from public image hubs, security scanners request rule updates, and notification webhooks call external SaaS endpoints. In an air-gapped environment, each call crosses a boundary that must stay closed. The pipeline still needs those dependencies when network access is removed. It exposes how much of the pipeline’s operation takes place outside its own infrastructure.
For air-gapped environments in defense, finance, healthcare, and critical infrastructure, isolation is a compliance requirement. A financial institution that handles sensitive transaction data must keep its build servers from querying external package repositories. Its entire dependency chain must be vetted and hosted internally. The constraint applies to the tools supporting a build as much as to the application being built. A locally hosted runner is therefore not, by itself, an air-gapped pipeline.
Munugoti’s framework identifies a related weakness in conventional regulated delivery, namely missing auditability and traceability compounded by manual bottlenecks. Network isolation makes those weaknesses harder to manage. Meanwhile, NIS2 mandates documented and traceable software supply chains, and industrial and government customers increasingly require SLSA-compliant build attestations. The pipeline must establish both where its inputs came from and how they became a release. That combination makes air-gapped CI a distinct engineering problem.
The self-contained architecture — what every layer of the perimeter must provide internally
The first layer is source control and execution. GitLab Community Edition on-premises provides git repository hosting, merge request workflows, CI/CD execution through GitLab Runners, and package and container registries without cloud connectivity. Builds run on CI servers that are self-hosted inside the isolated network. This places the source, review workflow, and execution environment within the same perimeter. The other layers must give those runners everything they need without external resolution.
Dependency management requires curated internal repositories for language-specific package managers, including PyPI, Maven, npm, and NuGet. Nexus Repository or Artifactory can serve the required libraries, with initial population through approved one-way data transfer. Runners must point to these internal mirrors. Once a build completes, its compiled binaries, libraries, and deployment packages belong in a local artifact repository. Secure validation checks keep artifacts that have been tampered with from reaching the next stage.
Container images need their own local supply path through Harbor, Nexus, or a private Docker registry. Approved images are manually imported and periodically updated, with image signing and verification enforced. Security tooling must be equally self-contained. Static analysis, SAST, and dependency vulnerability scanning need locally hosted engines and rule sets because cloud-connected scanning APIs are unavailable. Hosting the scanner locally is insufficient if its rules still depend on an outbound request.
Deployment and configuration management complete the map. Ansible, Puppet, Chef, and Terraform must operate only within the air-gapped network, using pre-approved local module libraries and infrastructure as code held in internal repositories. Munugoti’s architectural framework adds GitOps, with Git repositories serving as authoritative sources for declarative infrastructure state. With pull-based deployment, the pipeline no longer has direct access to production clusters. Zero-trust security principles then require access requests to be checked continuously, wherever they come from on the network, so requests from inside the perimeter must earn trust too.
Embedding compliance checks in the pipeline so they run automatically at every stage
With the infrastructure internalized, compliance must become part of its execution path. Compliance-as-Code converts regulatory requirements into executable policies evaluated during build and deployment. Open Policy Agent (OPA) and Sentinel support those evaluations, while Conftest provides a CLI testing utility built on OPA. The policies cover data handling, encryption standards, logging, access controls, and audit readiness. Their purpose is to make compliance a condition of progression.
Moving these checks earlier changes when a violation becomes visible. Developers receive feedback at build time, when a failure can be addressed and documented without waiting for a governance review cycle. At deployment, admission controllers enforce governance rules in a Kubernetes-native way that fits the GitOps model. Pull request approval workflows provide separation of duties within the same delivery process. Together, these controls replace a detached manual checkpoint with enforcement at the stages where decisions take effect.
The resulting evidence matters as much as the decision to pass or fail. GitOps provides traceability, rollback capability, and historical compliance visibility, while signed build artifacts and provenance establish the chain needed for regulatory examination. Singh’s paper describes how Compliance-as-Code reduces the need for separate governance teams to perform runtime reviews and helps DevSecOps teams share regulatory accountability.
Where the self-contained architecture breaks down — third-party API calls that punch through the perimeter
An internal registry can supply a package, but it cannot supply the behavior of an external API. This distinction leaves an unresolved dependency even after source control, images, scanners, and deployment tools have moved inside. Integration stages may still call Stripe or PayPal for payments, Slack for webhook notifications, GitHub for status checks, or Resend for transactional email. Those calls must be replaced with internal equivalents or disabled. Disabling them preserves isolation at the cost of leaving the integration behavior untested.
A live sandbox does not solve that conflict because reaching it still requires an outbound call. Recorded cassettes avoid the call by replaying captured HTTP responses, but they represent one execution path rather than the state transitions produced by a workflow. They also grow stale as the real API evolves. A replay can show how the application handles a saved response. It cannot, by that fact alone, establish that a sequence of operations remains valid.
Stateless mocks have a more specific limitation. A mock of POST /v1/payment_intents can return a hardcoded response, allowing an assertion of 200 to permit a merge even though the handler never stored the PaymentIntent ID. In that failure pattern, the first real checkout in staging fails because the next step of the webhook path reads undefined. More generally, it cannot establish that a customer created in step 1 exists in step 3, because the apparent consistency of its responses comes from stateless configuration.
What a stateful, locally hosted API simulator actually does that a mock cannot
A stateful simulator retains the effects of earlier API calls across a session. A record created in one step can be retrieved in a later step because the simulator’s internal state has changed. Responses therefore depend on both what happened before and which request pattern matched. That distinction is necessary when a payment step requires the exact transaction ID generated by an earlier order-creation call.
State fidelity is the compliance-relevant property of this behavior. The pipeline needs evidence that the tested integration behaves as the real API would within the workflows being exercised. A hardcoded success response cannot supply that evidence. With locally hosted simulation, stateful testing can run without making an outbound HTTPS call, using a live credential, or using up the provider’s rate limit. The build server reaches an internal service rather than treating a remote sandbox as an exception to isolation.
For CI simulation to be useful, it also needs to start with realistic pre-seeded data. An empty simulator forces every test to construct all of its fixtures, working against fast, repeatable runs. A known baseline gives the workflow a controlled starting point while allowing later calls to alter state. Fault injection must then test more than successful transactions by adding latency, 429 rate-limit responses, and 503 service unavailable responses.
The same requirement extends to semantically corrupt-but-valid response bodies. Infrastructure chaos tools that work at the HTTP or OS level cannot reach the individual response body fields where those faults occur. Simulation must therefore address API behavior as well as network availability. Its fidelity must also be supported by verification against the real API before every simulator release. Local hosting establishes isolation, but maintained behavioral accuracy establishes the value of the test.
How the simulator fits into each stage of the air-gapped pipeline in practice
The operational sequence begins when a commit triggers a build on the internal CI infrastructure. A .gitlab-ci.yml or Jenkinsfile declares the simulator as a sidecar or pre-step before integration testing. Its image comes from Harbor or Nexus inside the perimeter, following the same approved container workflow as other build tools. The simulator starts on an internal address with a known pre-seeded baseline. If startup fails, the pipeline fails immediately.
The integration suite then runs its sequential workflow against that address. An order-creation call establishes state and returns the transaction ID required by a later payment step. Subsequent requests test whether the integration carries that exact value through the workflow. Because the job has its own state, another team’s test cannot change the conditions it runs under. The simulator is torn down at job end, and the next run begins from the same baseline.
Separate resilience stages test the fault scenarios set out in the pipeline configuration, including rate limits, latency, and 503s. Integration results feed the compliance gate, where OPA policy checks and deployment admission controls can verify that testing used the internal simulator address. This makes endpoint selection part of auditable perimeter enforcement. After the required checks pass, the build artifact is signed and retained with its provenance in the local artifact repository. The simulator therefore participates in the same controlled delivery sequence as the compiler, scanner, and policy engine.
The pattern also applies to AI agent pipelines that call external APIs. A Slack notification agent, Stripe payment agent, or GitHub PR agent can be evaluated against stateful simulation that tracks tool calls, checks parameter passing, and injects failures. These workflows add multi-turn tool use, but retain the same needs for local resolution, repeatability, and state fidelity.
Keeping the perimeter intact over time — drift, updates, and the ongoing verification problem
A self-contained pipeline is accurate only while its internal components remain current. Dependencies, APIs, and compliance requirements evolve even when the isolated environment does not. Silent drift is hard to catch because a pipeline can keep reporting green while using outdated inputs or behavior. Maintenance must therefore keep the pipeline both isolated and accurate. Treating either as a one-time setup task leaves the other without a reliable foundation.
Package mirrors and container registries need updates through the same controlled, one-way import process used for initial population. Security patches cannot justify a shortcut outbound connection from the CI environment. Compliance policies also need to be kept in version control and deployed through the GitOps pull model. Singh’s paper recommends modular policy design and a version-controlled compliance library as the sustainable pattern. These practices keep the rules themselves within the governed delivery process.
API simulators need a corresponding release discipline because provider changes can invalidate previously accurate behavior. Before every simulator release, it is checked against the live API outside the isolated CI environment. Published fidelity scores make that verification auditable. A verified release is pulled on an internet-connected staging machine, validated, signed, transferred through the approved one-way path, and promoted to the internal container registry.
To be ready for an audit, teams must keep a documented provenance chain for every component, including the integration testing layer. Signed simulator artifacts and published fidelity scores support that chain just as SLSA attestations support build provenance. The ongoing commitment is to verify what runs inside while blocking what lies outside. The perimeter is only as strong as its least-verified component.


