How to Enforce Data Residency in CI
Pinning runners and artifact storage to a region, then asserting the region at runtime, keeps regulated data from leaving its jurisdiction during CI.
Some data must stay in a region. In CI that means region-scoped runners and region-scoped artifact buckets, plus a runtime assertion so a misconfigured job fails loudly. This page shows the pattern; it is educational, verify residency needs with your own counsel.
Steps
- Target self-hosted runners labeled by region.
- Point artifact and cache storage at a bucket in the same region.
- Assert the runner region at runtime and fail if it is wrong.
Region-pinned job
.github/workflows/ci.yml
jobs:
build-eu:
runs-on: [self-hosted, region-eu-central-1]
env:
AWS_REGION: eu-central-1
ARTIFACT_BUCKET: acme-ci-artifacts-eu
steps:
- name: Assert region
run: |
R=$(curl -s http://169.254.169.254/latest/meta-data/placement/region)
[ "$R" = "eu-central-1" ] || { echo "Runner not in EU: $R"; exit 1; }
- run: ./build.sh && aws s3 cp dist/ "s3://$ARTIFACT_BUCKET/" --recursiveNotes
- GitHub-hosted runners do not guarantee a region; use self-hosted for hard residency needs.
- The runtime assertion catches label or infrastructure drift before data is written.
Related guides
How to Scan for PII and Secrets in CIScan a repository for secrets and PII in GitHub Actions with gitleaks and a custom pattern set, failing the b…
How to Retain CI Logs and Artifacts for AuditSet GitHub Actions log and artifact retention to match audit requirements and archive exports to long-term st…
How to Segregate Production Credentials in CIKeep production credentials out of build and test jobs in GitHub Actions by binding them to a protected envir…