QuotaGuard and GitLab CI/CD Integration Guide
Two ways to use this guide: Setting up the integration yourself? Follow the setup steps below. Working with an AI coding agent? Share this page and use the instructions below to help it configure the integration, verify the connection and troubleshoot issues.
To let your agent set up and test the connection, provide the required proxy connection details through its secure credential mechanism rather than sharing your QuotaGuard account password. Review any changes it proposes.
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 for HTTP clients that honor them. Their proxied HTTP/HTTPS requests exit from one of your two static IPs, regardless of which shared runner picks up the job.
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 the full proxy connection URL assigned to your subscription under Setup > Outbound, as shown in the connection-details guide. Copy the complete URL, including its scheme, credentials, host, and port. Most build tooling, including curl, git, and the majority of HTTP clients, reads standard proxy variables; curl requires lowercase http_proxy for HTTP destinations but accepts HTTPS_PROXY for HTTPS.
Add these as masked variables so they do not appear in job logs:
| Key | Value | Flags |
|---|---|---|
HTTP_PROXY |
Assigned full proxy connection URL | Masked |
HTTPS_PROXY |
Same assigned full proxy connection URL | Masked |
NO_PROXY |
localhost,127.0.0.1,.internal |
NO_PROXY lists destinations that job HTTP clients should reach directly. Customize the example for your internal hosts. Add gitlab.com only if the job’s requests to GitLab should bypass QuotaGuard; leave it out when GitLab must see your QuotaGuard IPs. For GitLab Self-Managed, use your instance hostname instead. Matching varies by client: Go-based clients treat .gitlab.com as subdomains only, while gitlab.com matches both the host and its subdomains.
These job variables do not configure the runner manager’s connection to GitLab. Self-managed runner administrators configure its service environment separately; see GitLab’s runner proxy configuration.
Note on masking: Use single-line values with no spaces and at least 8 characters, and clear Expand variable reference on both proxy variables. With expansion enabled, GitLab restricts masking characters and rejects % in URL-encoded credentials. See GitLab’s masking requirements.
Step 2: Route Job Traffic Through the Proxy
With the variables set at the project or group level, jobs pick them up automatically. The examples below reuse those masked variables without putting credentials in .gitlab-ci.yml.
deploy:
stage: deploy
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. The explicit Python proxies mapping and Node ProxyAgent below route these requests through the proxy even if their destinations appear in NO_PROXY.
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:24-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 checks the proxy variable is present and prints the egress address. --noproxy "" forces this lookup through the proxy even if NO_PROXY excludes the verification host.
verify-ip:
stage: test
image: curlimages/curl:latest
script:
- 'test -n "$HTTPS_PROXY" || { echo "HTTPS_PROXY is not set"; exit 1; }'
- curl --noproxy "" -x "$HTTPS_PROXY" https://ip.quotaguard.com
Expected output:
{"ip":"<one of your two QuotaGuard static IPs>"}
The returned IP must match either of the two assigned IPs in your QuotaGuard dashboard. You can re-run the job, but observing both addresses is not required for success. Allowlist both assigned IPs at the destination.
Troubleshooting
407 Proxy Authentication Required
The credentials are wrong or the variable was not picked up. Use the presence check in the verify-ip job above, then compare the IP returned by ip.quotaguard.com with your assigned IPs. Check the stored credentials against Setup > Outbound in your QuotaGuard dashboard without printing the proxy URL or credentials in job logs.
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
Proxy-aware clients may be routing internal requests through QuotaGuard. Add hosts that should connect directly to NO_PROXY, following the client-specific matching rules above. Explicit proxy options such as the Python and Node examples above can override these exclusions.
Wrong IP returned
Check that the destination is not excluded by NO_PROXY; curl honors these exclusions even with -x. If the tool ignores 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