Authenticated proxies are common on corporate gateways, outbound filtering stacks, and shared egress hosts where cURL must prove proxy identity before the destination site ever sees the request. This guide shows the direct cURL flow for confirming the proxy challenge, sending credentials, and verifying that the request reaches the upstream site through the authenticated tunnel.
For HTTP proxies, cURL sends credentials with --proxy-user (or -U) and uses HTTP Basic by default when the proxy asks for Basic authentication. The examples below use a masked service account and redacted proxy secret placeholder to show the pattern without exposing a live credential. When the proxy can offer more than one auth scheme, --proxy-anyauth lets cURL wait for the Proxy-Authenticate challenge and then retry with a supported method, which adds one extra request-response round trip.
Treat proxy credentials as short-lived secrets. Inline usernames and passwords are acceptable for quick local tests, but they still end up in shell history, copied snippets, and sometimes process inspection. For repeated work, move them into a temporary config file with tight permissions and delete it as soon as the proxy task is complete.
Steps to authenticate to an HTTP proxy with cURL:
- Check the proxy challenge without credentials so you know the request is failing at the proxy layer, not at the target site.
$ curl --proxy http://egress-proxy.ops.example.test:8080 --verbose --max-time 20 --output /dev/null https://ops-api.example.com/v1/health * Connected to egress-proxy.ops.example.test (203.0.113.20) port 8080 * Establish HTTP proxy tunnel to ops-api.example.com:443 > CONNECT ops-api.example.com:443 HTTP/1.1 > Host: ops-api.example.com:443 < HTTP/1.1 407 Proxy Authentication Required < Proxy-Authenticate: Basic realm="Egress Proxy" * CONNECT tunnel failed, response 407 curl: (56) CONNECT tunnel failed, response 407
A 407 Proxy Authentication Required response confirms that the proxy is reachable and that the authentication challenge is coming from the proxy hop rather than from the destination site.
- Retry with --proxy-user to send proxy credentials and confirm that the request now reaches the upstream site.
$ curl --proxy http://egress-proxy.ops.example.test:8080 \ --proxy-user 'svc-egress-reader:REDACTED_EGRESS_PROXY_PASSWORD' \ --silent --show-error --output /dev/null \ --write-out 'HTTP %{http_code}\n' \ https://ops-api.example.com/v1/health HTTP 200Inline credentials are useful for short local tests, but they can leak through shell history, copied snippets, and process inspection on shared systems.
- Add --proxy-anyauth when the proxy may advertise multiple auth schemes and let cURL retry with one it supports.
$ curl --proxy http://egress-proxy.ops.example.test:8080 \ --proxy-user 'svc-egress-reader:REDACTED_EGRESS_PROXY_PASSWORD' \ --proxy-anyauth --verbose --output /dev/null \ https://ops-api.example.com/v1/health < HTTP/1.1 407 Proxy Authentication Required < Proxy-Authenticate: Basic realm="Egress Proxy" * Proxy auth using Basic with user 'svc-egress-reader' > Proxy-Authorization: Basic c3ZjLWVncmVzcy1yZWFkZXI6UkVEQUNURURfRUdSRVNTX1BST1hZX1BBU1NXT1JE < HTTP/1.1 200 Connection established
--proxy-anyauth waits for the proxy challenge before choosing a method, so it adds one extra request-response round trip. If the proxy is fixed to NTLM, Negotiate, or Digest, prefer the matching auth flag instead of auto-detection.
Related: Authenticate with NTLM
- Inspect the verbose tunnel handshake when you need proof that the proxy accepted the credentials before the upstream request was sent.
$ curl --proxy http://egress-proxy.ops.example.test:8080 \ --proxy-user 'svc-egress-reader:REDACTED_EGRESS_PROXY_PASSWORD' \ --verbose --output /dev/null \ https://ops-api.example.com/v1/health * Proxy auth using Basic with user 'svc-egress-reader' > CONNECT ops-api.example.com:443 HTTP/1.1 > Proxy-Authorization: Basic c3ZjLWVncmVzcy1yZWFkZXI6UkVEQUNURURfRUdSRVNTX1BST1hZX1BBU1NXT1JE < HTTP/1.1 200 Connection established * CONNECT tunnel established, response 200 < HTTP/2 200
A successful proxy-authenticated HTTPS request shows both the proxy-side 200 Connection established response and the final upstream status, proving that the tunnel was built before the site response was received.
Verbose traces expose the encoded Proxy-Authorization header, so keep them local or redact them before sharing logs and tickets.
- Place repeated proxy settings in a temporary cURL config file instead of pasting credentials into every command.
$ cat <<'EOF' > curl-proxy.conf proxy = "http://egress-proxy.ops.example.test:8080" proxy-user = "svc-egress-reader:REDACTED_EGRESS_PROXY_PASSWORD" EOF $ chmod 600 curl-proxy.conf
The config file is still plain text, so keep it short-lived, limit it to the current task, and restrict access to the account that owns it.
- Run the request through the config file to reuse the same authenticated proxy settings across repeated commands.
$ curl --config curl-proxy.conf \ --silent --show-error --output /dev/null \ --write-out 'HTTP %{http_code}\n' \ https://ops-api.example.com/v1/health HTTP 200This keeps the command line focused on the actual request while reusing a single proxy definition for one script or one terminal session.
- Delete the temporary config file after the proxy task finishes so the credential copy does not linger on disk.
$ rm -f curl-proxy.conf
For longer-lived proxy credentials, use a dedicated secret-management workflow rather than leaving reusable passwords in temporary files.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
