QuotaGuard and GitLab CI/CD Integration Guide
QuotaGuard Static IPs give your GitLab CI/CD pipelines two fixed outbound IP addresses for firewalled deploys and IP-restricted APIs. Set HTTP_PROXY and HTTPS_PROXY as CI/CD variables, and every job exits from one of your two static IPs no matter which shared runner picks it up.
Why GitLab CI/CD Pipelines Need a Static IP
GitLab states in its own documentation that it does not provide static IP addresses for outgoing connections from CI/CD runners. GitLab.com instance runners run on shared Google Cloud infrastructure (us-east1, plus us-central1 for GPU and Arm64 runners), and macOS runners run on AWS us-east-1. The outbound IP a job uses is drawn from those shared cloud ranges and changes from job to job.
The only native workaround is to allowlist GitLab’s entire Google Cloud and AWS ranges on the destination, which is broad enough that most security teams reject it. When a partner API, a firewalled database, or a deploy target asks for the IP your pipeline connects from, you need one stable answer.
QuotaGuard Gives Your Pipelines Two Fixed IPs
QuotaGuard Static is an HTTP, HTTPS, and SOCKS5 proxy running on AWS. Every subscription is assigned two static IP addresses behind a load balancer, and those two IPs do not change. The IPs belong to your QuotaGuard account, not to a runner or a job, so every pipeline run connects through the same two addresses. You allowlist them once on the destination. Your two assigned IPs are shown in your QuotaGuard dashboard after sign-up.
Step 1: Add the Proxy as CI/CD Variables
In your project or group, open Settings > CI/CD > Variables and add your QuotaGuard connection string. Most build tooling, including curl, git, and the majority of HTTP clients, reads the standard HTTP_PROXY and HTTPS_PROXY variables automatically.
Add these as masked variables so they do not appear in job logs:
| Key | Value | Flags |
|---|---|---|
HTTP_PROXY |
http://username:password@<your-quotaguard-proxy-host>:9293 |
Masked |
HTTPS_PROXY |
http://username:password@<your-quotaguard-proxy-host>:9293 |
Masked |
NO_PROXY |
localhost,127.0.0.1,.internal |
Add .gitlab.com and any internal hosts to NO_PROXY so runner-to-GitLab traffic and internal services bypass the proxy.
Note on masking: GitLab will refuse to mask a value containing characters it cannot mask. A proxy URL with @ and : masks fine, but if your password contains unusual characters and masking is rejected, URL-encode the password in the connection string.
Step 2: Route Job Traffic Through the Proxy
With the variables set at the project or group level, jobs pick them up automatically. You can also scope them to a single job.
deploy:
stage: deploy
variables:
HTTP_PROXY: "http://username:password@<your-quotaguard-proxy-host>:9293"
HTTPS_PROXY: "http://username:password@<your-quotaguard-proxy-host>:9293"
NO_PROXY: "localhost,127.0.0.1,.internal"
script:
- curl -X POST https://api.partner-service.com/deploy
A language client in a job
If a job runs application code that makes the call, the standard proxy variables are read by most clients. To be explicit, pass the proxy directly.
Python:
test-api:
image: python:3.12-slim
script:
- pip install requests
- |
python - <<'PY'
import os, requests
p = os.environ["HTTPS_PROXY"]
r = requests.get("https://api.partner-service.com/data", proxies={"http": p, "https": p})
print(r.status_code)
PY
Node:
test-api:
image: node:20-slim
script:
- npm install undici
- |
node -e '
const { ProxyAgent, fetch } = require("undici");
const dispatcher = new ProxyAgent(process.env.HTTPS_PROXY);
fetch("https://api.partner-service.com/data", { dispatcher })
.then(r => console.log(r.status));
'
Tools that ignore the standard variables
Some CLIs do not read HTTP_PROXY. Pass the proxy explicitly. For curl:
script:
- curl -x "$HTTPS_PROXY" https://api.partner-service.com/data
For git over HTTPS, set it per command:
script:
- git -c http.proxy="$HTTPS_PROXY" clone https://internal.git.example.com/repo.git
Shared SaaS Runners Are the Primary Use Case
This setup is built for GitLab.com SaaS shared runners, where you cannot pin the egress IP. On private or self-hosted runners you control the host and can pin egress yourself, so you may not need a proxy. QuotaGuard still works on those runners if you would rather not build and maintain your own NAT, and it gives you the same two IPs across every runner type. The variables also apply to scheduled pipelines, since they run as normal jobs.
Testing Your Pipeline Is Using the Static IP
Add a verify job that prints the egress address.
verify-ip:
stage: test
image: curlimages/curl:latest
variables:
HTTPS_PROXY: "http://username:password@<your-quotaguard-proxy-host>:9293"
script:
- curl -x "$HTTPS_PROXY" https://ip.quotaguard.com
Expected output:
{"ip":"<one of your two QuotaGuard static IPs>"}
The returned IP should match one of the two static IPs in your QuotaGuard dashboard. Re-run the job to see both IPs in action (load-balanced).
Troubleshooting
407 Proxy Authentication Required
The credentials are wrong or the variable was not picked up. Echo a masked check in a scratch job and confirm the username and password match your QuotaGuard dashboard. Remember that masked variables are hidden in logs, so test against ip.quotaguard.com rather than printing the URL.
Variable not applied
If the job ignores the proxy, the variable may be scoped to a different environment or marked protected while the branch is not protected. Protected variables are only exposed to protected branches and tags. Either unprotect the variable or run on a protected branch.
Requests to internal services break after enabling the proxy
Everything is now routing through QuotaGuard, including internal hosts. Add those hosts to NO_PROXY so they bypass the proxy.
Wrong IP returned
The tool is not honoring the proxy variables. Pass the proxy explicitly with curl -x, git -c http.proxy, or the client’s proxy option as shown above.
Connection timeout
Confirm the runner has outbound network access and that nothing blocks port 9293. Self-managed runners behind a corporate firewall may need 9293 opened.
QuotaGuard Static vs QuotaGuard Shield
| Feature | QuotaGuard Static | QuotaGuard Shield |
|---|---|---|
| Protocol | HTTP / HTTPS / SOCKS5 | HTTPS / SOCKS5 over TLS |
| Customer-to-proxy hop | Plaintext | TLS-encrypted |
| HTTPS payload | Tunneled end-to-end, never decrypted at the proxy | Tunneled end-to-end, never decrypted at the proxy |
| Best for | Most apps | Regulated data or environments that require TLS on every hop |
| Starting price | $19/month | $29/month |
For most CI/CD pipelines, Static is the right product. Choose QuotaGuard Shield if your pipeline moves regulated data or your environment requires TLS between your app and the proxy itself.
Ready to Get Started?
Get in touch or create a free trial account.
View GitLab CI/CD Integration Features