GitLab : Synch Projects Between Air-gap Networks

Q:

What is the advised Group structure for GitLab self-hosted when software development projects on its private domain are those of same on another private domain, with recurring updates, and the two domains are air gapped?

A:

For your GitLab self-hosted setup with two air-gapped private domains that share the same software development projects with recurring updates, the GitLab Group structure should be designed to ensure:

Recommended Group Structure

1. Top-Level Groups per Domain

Create a top-level group for each air-gapped domain:

/DomainA
/DomainB

Each group represents one private domain's GitLab environment. This structure keeps administrative control separate between domains.

2. Mirrored Subgroups for Software Projects

Under each top-level group, create identically structured subgroups that mirror each other. For example:

/DomainA/SoftwareX
/DomainA/SoftwareY
/DomainB/SoftwareX
/DomainB/SoftwareY

Each subgroup represents a specific software that exists in both domains.

3. Repository-Level Project Syncing

Each software subgroup contains the actual repositories, such as:

/DomainA/SoftwareX/frontend
/DomainA/SoftwareX/backend
/DomainB/SoftwareX/frontend
/DomainB/SoftwareX/backend

This structure ensures that repositories stay identically structured between the two air-gapped environments, simplifying syncing and automation.

4. Special Synchronization Group (Optional)

If synchronization between the two domains is manual or handled via scripts, consider a dedicated synchronization group:

/SyncPipeline

This can contain: - Repositories for scripts that handle export/import of code updates. - Documentation related to the air-gapped transfer process. - Monitoring tools to track version consistency between environments.


Synchronization Between Domains

Since the domains are air-gapped, you need a manual or semi-automated process for transferring updates:

  1. Export from Domain A

    • Use git bundle or a GitLab repository export.
    • Export metadata such as merge requests (if needed).
  2. Transfer to Domain B

    • Physically transfer via USB, air-gapped transfer server, or secure file-sharing method.
    • Import into GitLab on Domain B.
  3. Validation

    • Check the integrity of the transferred repositories.
    • Run automated tests to ensure consistency.
  4. Merge and Deploy

    • Merge updates into Domain B's repositories.
    • Deploy as needed.

User & Access Management


Key Benefits of This Structure

Consistency between domains despite air-gapping.
Scalability for additional projects without restructuring.
Granular security via GitLab’s group and project-level permissions.
Easier synchronization using mirrored structures.

Would you like recommendations for automating the synchronization process between the air-gapped environments?

Q:

Some have argued that since Git is distributed, having dual repos per project is not justified; that it can and should be handled by git processes like merge.

A:

While Git’s distributed model works great in a connected world, an air-gapped environment introduces constraints that require a structured GitLab-based synchronization process.

Counterargument: Why Dual GitLab Repos Per Project are Justified in an Air-Gapped Environment

You're absolutely right that Git is inherently distributed, allowing developers to work with multiple remotes and branches rather than maintaining two separate GitLab repositories per project. However, in the case of air-gapped networks, the typical Git workflows—such as merging changes from a remote repository—face significant challenges due to the lack of direct network access.

Below are key reasons why keeping separate GitLab repositories (one per air-gapped domain) is justified:


1. Air-Gapped Constraints Prevent Direct Git Merge Workflows

How Git Normally Handles Multi-Environment Collaboration

In a standard Git setup, developers would: - Clone a shared remote repository. - Fetch and merge branches from the same upstream. - Push changes to a common repository.

Why This Doesn't Work in an Air-Gapped Setup

Because there is no common remote repository, keeping two GitLab repositories (one per domain) mimics the behavior of a single shared remote but allows synchronization via controlled transfers.


2. Security and Compliance Considerations

Many air-gapped environments exist for regulatory, security, or classified purposes (e.g., defense contractors, industrial control systems, financial institutions).

Keeping separate GitLab repositories ensures strict security and governance policies are followed when moving code across domains.


3. Avoiding Cross-Environment Merge Conflicts and Pollution

Git’s distributed nature assumes an open flow of commits, but in an air-gapped setup, repositories evolve independently, often in different timeframes.

By having separate GitLab repositories, each environment can stabilize updates before syncing, preventing environment-specific issues from leaking across domains.


4. Maintaining an Organized, Repeatable Sync Process

Git is flexible, but a structured GitLab-based approach ensures repeatability:

Workflow Pure Git Approach Dual GitLab Repos Approach
Synchronization Manual git format-patch & git am per repo Automated GitLab-based import/export using git bundle
Metadata Transfer Requires custom scripts to move issues & MRs GitLab API handles metadata syncing
Security Controls Requires strict ACLs per Git remote Each GitLab repo enforces separate policies
Air-Gap Compliance No inherent controls in git push GitLab project approval workflows ensure compliance

Having dual GitLab repositories helps maintain an automated, repeatable, and secure process without requiring direct network connectivity.


5. Practical Experience from Air-Gapped Environments

Many organizations already follow this structure in air-gapped setups:

  1. US DoD & Defense Contractors

    • Maintain separate repositories for classified and unclassified networks.
    • Code must be reviewed before being manually transferred between domains.
  2. Financial Institutions (e.g., Banks, Insurance Companies)

    • Keep internal GitLab repos separate from vendor-controlled repos.
    • Transfers happen through compliance-reviewed air-gap processes.
  3. Industrial Control Systems (ICS/SCADA)

    • IT (Internet-connected) and OT (Operational, air-gapped) environments do not share repositories directly.
    • All updates must be signed, reviewed, and manually imported.

Each of these industries could use a single Git repository in theory, but operational security requires dual repositories.


Conclusion: Git Alone is Not Enough in an Air-Gapped Setup

While Git’s distributed model works great in a connected world, an air-gapped environment introduces constraints that require a structured GitLab-based synchronization process.

Key Takeaways: ✅ Separate GitLab repositories ensure compliance with air-gap security policies.
GitLab-based sync workflows prevent accidental overwrite and maintain control over merges.
Environment-specific changes and delays in patching require controlled synchronization.
An air-gapped sync process using GitLab tools is easier to automate than raw Git workflows.

👉 For non-air-gapped setups, a single Git repository makes sense.
👉 For air-gapped domains, dual GitLab repositories are the best practice.

Q:

Mismatches of GroupX/.../ProjectY paths between Domains A and B are handled simply at git remote add origin ... ?

A:

Handling Mismatches in GitLab Group Paths Between Air-Gapped Domains

Yes, mismatches in repository paths between Domain A and Domain B can be handled at the git remote add origin ... level when syncing repositories across air-gapped environments.

However, you need to carefully map paths between the two domains to avoid breaking synchronization workflows.


1. Simple Path Mapping at git remote add origin

If Group paths differ but Project names remain the same, you can manually adjust the remote URL when syncing.

Example: Different GitLab Group Paths

Domain Path Structure
Domain A /SoftwareA/BackendProject.git
Domain B /Infrastructure/Backend.git

How to Handle This in Git

On Domain A:

git clone --mirror https://git.domainA.lan/SoftwareA/BackendProject.git
cd BackendProject.git
git bundle create backend.bundle --all

Move the backend.bundle file to Domain B via USB or a secure offline method.

On Domain B, restore the repository with a different path:

git clone --mirror backend.bundle Backend.git
cd Backend.git
git remote add origin https://git.domainB.lan/Infrastructure/Backend.git
git push --mirror origin

This effectively re-maps the project from /SoftwareA/BackendProject on Domain A to /Infrastructure/Backend on Domain B.


2. Handling Path Differences Across Multiple Repositories

For multiple repositories, you can automate the remapping using a script.

Mapping Config File (repo_mapping.txt)

# Format: SourceRepo,TargetRepo
SoftwareA/BackendProject,Infrastructure/Backend
SoftwareA/FrontendProject,Infrastructure/Frontend

Automated Transfer Script

#!/bin/bash

DOMAIN_A="git.domainA.lan"
DOMAIN_B="git.domainB.lan"
TRANSFER_DIR="/transfer"

mkdir -p $TRANSFER_DIR

while IFS=',' read -r SOURCE_REPO TARGET_REPO; do
    echo "Exporting $SOURCE_REPO..."
    git clone --mirror "https://$DOMAIN_A/$SOURCE_REPO.git" "$TRANSFER_DIR/$SOURCE_REPO.git"
    cd "$TRANSFER_DIR/$SOURCE_REPO.git"
    git bundle create "$TRANSFER_DIR/$TARGET_REPO.bundle" --all
    cd -
done < repo_mapping.txt

echo "Transfer the bundles manually, then run the import script on Domain B."

Import Script on Domain B

#!/bin/bash

DOMAIN_B="git.domainB.lan"
TRANSFER_DIR="/transfer"

while IFS=',' read -r SOURCE_REPO TARGET_REPO; do
    echo "Importing $TARGET_REPO..."
    git clone --mirror "$TRANSFER_DIR/$TARGET_REPO.bundle" "$TARGET_REPO.git"
    cd "$TARGET_REPO.git"
    git remote add origin "https://$DOMAIN_B/$TARGET_REPO.git"
    git push --mirror origin
    cd -
done < repo_mapping.txt

This script ensures: ✅ Repository paths are automatically remapped.
Human error is reduced in the transfer process.
Multiple repositories can be synced in bulk.


3. Handling Group and Namespace Renaming at GitLab Level

If renaming paths at git remote add origin isn't ideal, another approach is to modify GitLab namespaces on the receiving domain.

Method 1: Rename GitLab Groups on Domain B

Method 2: Use GitLab Repository Mirroring (If Allowed)


4. Special Case: If Only Project Names Differ

If Group paths are the same, but Project names differ, the process is still simple.

Domain Repository Path
Domain A /SoftwareX/Backend.git
Domain B /SoftwareX/BackendAPI.git

You can still handle this via:

git clone --mirror https://git.domainA.lan/SoftwareX/Backend.git
cd Backend.git
git remote add origin https://git.domainB.lan/SoftwareX/BackendAPI.git
git push --mirror origin

This maps Backend (Domain A) → BackendAPI (Domain B).


Final Thoughts

Yes, mismatches in repository paths between domains can be handled via git remote add origin ....
For multiple repositories, an automated mapping script ensures consistency.
If managing GitLab instances, renaming groups or using mirroring can be alternatives.

Q :

Ansible Playbook that: