Some networks require outbound traffic to pass through an NTLM-authenticated proxy. Most command-line tools (curl, git, package managers, etc.) don’t support NTLM natively, which makes working behind these proxies painful. Alpaca solves this by running as a small local proxy: it listens on localhost, handles the NTLM handshake with your upstream proxy using cached credentials, and forwards traffic transparently. You point http_proxy/https_proxy at Alpaca instead of the real proxy, and it takes care of authentication for you.
This post covers setting up Alpaca on both macOS and Linux.
NTLM (NT LAN Manager) is a Microsoft challenge-response authentication protocol commonly used by network proxies. Instead of sending your password directly, the client and server exchange a random challenge that gets encrypted with a hash of your password, letting the server verify your identity without the password ever crossing the wire in plaintext. Because it’s a Windows/Active Directory technology, credentials are tied to a DOMAIN\username pair rather than just a username. Most non-Windows tools (curl, git, apt, etc.) don’t speak NTLM natively, which is exactly the gap Alpaca fills.
Install Alpaca with Homebrew and inspect the running service with brew services info alpaca. Alpaca listens on port 3128, so once installed, both http_proxy and https_proxy should point to http://localhost:3128.
Alpaca needs to know your NTLM credentials to authenticate against the upstream proxy on your behalf. Check the launch agent file to confirm it has the required environment variables and program arguments (/opt/homebrew/opt/alpaca/homebrew.mxcl.alpaca.plist):
<key>EnvironmentVariables</key>
<dict>
<key>NTLM_CREDENTIALS</key>
<string>USERNAME@DOMAIN:PASS_HASH</string>
</dict>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/opt/alpaca/bin/alpaca</string>
<string>-C</string>
<string>file:///Users/USERNAME/.config/proxy.pac</string>
</array>
If you don’t already have a PASS_HASH to put in the plist, generate one from Terminal the same way Linux users do:
alpaca -d DOMAIN -u USERNAME -H
# Password (for DOMAIN\USERNAME):
# NTLM_CREDENTIALS="USERNAME@DOMAIN:HASH"; export NTLM_CREDENTIALS
Copy the HASH portion of the printed value into PASS_HASH above, then restart the service with brew services restart alpaca for the change to take effect.
Make sure the proxy auto-config (PAC) file exists at the path referenced above (e.g. ~/.config/proxy.pac). If it doesn’t exist yet, find out the proxy host and port for your network and create a minimal PAC file yourself:
function FindProxyForURL(url, host) {
return "PROXY proxy.example.com:8080; DIRECT";
}
To force macOS to route traffic through Alpaca, set the HTTP and HTTPS proxies in System Settings → Network to localhost (no protocol prefix), disable automatic proxy configuration, and make sure there’s no http:// prefix in the server address fields.
Run Alpaca once to generate the NTLM credential export snippet (replace the domain and username with your own):
alpaca -d DOMAIN -u USERNAME -H
# Password (for DOMAIN\USERNAME):
# Add this to your ~/.profile (or equivalent) and restart your shell
# NTLM_CREDENTIALS="USERNAME@DOMAIN:HASH"; export NTLM_CREDENTIALS
Instead of relying on your shell profile, store the credentials in a root-owned file that only the Alpaca service can read:
sudo tee /etc/default/alpaca >/dev/null <<'EOF'
NTLM_CREDENTIALS="USERNAME@DOMAIN:HASH"
EOF
sudo chmod 600 /etc/default/alpaca
Restart your shell only if you also want the variable available in your interactive environment — the systemd service will read it from the defaults file regardless.
Create a systemd unit at /etc/systemd/system/alpaca.service so Alpaca starts automatically and points to your PAC file:
[Unit]
Description=Alpaca service
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=/etc/default/alpaca
ExecStart=/opt/alpaca/bin/alpaca -C file:///home/USERNAME/.config/proxy.pac
Restart=on-failure
RestartSec=5
User=USERNAME
StandardOutput=append:/var/log/alpaca.out.log
StandardError=append:/var/log/alpaca.err.log
[Install]
WantedBy=multi-user.target
Update User, ExecStart, and the PAC file path to match your home directory and Alpaca installation. If no PAC file exists yet at that path, find out the proxy host and port for your network and create a minimal one yourself:
function FindProxyForURL(url, host) {
return "PROXY proxy.example.com:8080; DIRECT";
}
Reload systemd and enable the service so it starts immediately and on every boot:
sudo systemctl daemon-reload
sudo systemctl enable --now alpaca
With the service running, any HTTP(S) traffic routed through your PAC file will use the NTLM_CREDENTIALS you configured, without prompting for a password.
If you’re on a Debian/Ubuntu system and need apt to go through the proxy as well, create a dedicated config file:
sudo nano /etc/apt/apt.conf.d/95proxy
Add the following lines:
Acquire::http::Proxy "http://USER:PASS@PROXY_HOST:PROXY_PORT/";
Acquire::https::Proxy "http://USER:PASS@PROXY_HOST:PROXY_PORT/";