---
title: 'TestingBot Tunnel Authentication: Basic Auth, Kerberos and Proxy Credentials'
description: 'Let TestingBot Tunnel authenticate for your tests: HTTP Basic auth for
  protected sites, Kerberos/SPNEGO for intranet sites and corporate proxies, keytabs
  for unattended use, and how proxy credentials are scoped.'
source_url:
  html: https://testingbot.com/support/tunnel/authentication
  md: https://testingbot.com/support/tunnel/authentication.md
---

# Credentials the tunnel presents for you

Some of what a test needs to reach sits behind a login prompt, and on corporate networks the route out does too. The tunnel can authenticate on your test's behalf, to **sites** and to **upstream proxies** , with HTTP Basic or Kerberos.

- Basic 
- Kerberos / SPNEGO 

| | Basic | Kerberos (Negotiate) |
| --- | --- | --- |
| **Sites** your test opens | `--auth` | `--krb5-hosts` |
| **Upstream proxy** for test traffic | `--proxy-userpwd` | `--proxy-auth-scheme negotiate` |
| **Proxy to TestingBot** | `--proxy-testingbot-userpwd` | `--proxy-auth-scheme negotiate` |

## Basic auth for protected sites

Staging sites often sit behind HTTP Basic authentication. Rather than putting credentials in every test URL, let the tunnel answer the prompt.

```bash
java -jar testingbot-tunnel.jar -a staging.example.com:80:myuser:mypassword
```

- The format is `host:port:user:password`. Pass several entries for several sites.
- To keep the password out of `ps`, use `TESTINGBOT_AUTH` instead, with entries comma-separated.
- This works on plain HTTP. HTTPS reaches the site as an encrypted `CONNECT` tunnel that the local tunnel cannot add headers to.

```bash
export TESTINGBOT_AUTH=staging.example.com:80:myuser:mypassword,admin.example.com:80:ops:secret
java -jar testingbot-tunnel.jar
```

## Basic auth for upstream proxies

```bash
export TESTINGBOT_PROXY_USERPWD=alice:hunter2
java -jar testingbot-tunnel.jar --proxy proxy.corp:8080
```

The same credentials are used for SOCKS5 proxies (`--proxy socks5://host:port`). If TestingBot's own traffic leaves through a different proxy, give that one its own credentials with `--proxy-testingbot-userpwd`; see [where credentials go](https://testingbot.com#scoping).

## Kerberos proxies (SPNEGO / Negotiate)

Many corporate proxies require Kerberos rather than a username and password. The tunnel speaks Negotiate on every path out: browser traffic, HTTPS CONNECT and its own connection to TestingBot.

```bash
kinit alice@CORP.EXAMPLE
java -jar testingbot-tunnel.jar --proxy proxy.corp:8080 --proxy-auth-scheme negotiate
```

| Option | Purpose |
| --- | --- |
| --proxy-auth-scheme \<basic\|negotiate\> | How to authenticate to the upstream proxy. Default `basic`. |
| --proxy-spn \<SPN\> | Service principal of the proxy. Defaults to `HTTP/<proxy-host>`. Accepts `HTTP/host` or `HTTP@host`. |
| --krb5-keytab \<FILE\> | Keytab to log in from, for machines where nobody runs `kinit`. Requires `--krb5-principal`. |
| --krb5-principal \<PRINCIPAL\> | Principal to log in as with the keytab, for example `svc-tunnel@CORP.EXAMPLE`. |

Without a keytab, credentials come from your existing Kerberos ticket cache.

## Unattended Kerberos with a keytab

On a build agent or in a container, nobody is there to run `kinit`. Give the tunnel a keytab for a service account instead.

```bash
java -jar testingbot-tunnel.jar \
  --proxy proxy.corp:8080 \
  --proxy-auth-scheme negotiate \
  --krb5-keytab /etc/tunnel/svc-tunnel.keytab \
  --krb5-principal svc-tunnel@CORP.EXAMPLE
```

Treat the keytab like a password: it can obtain tickets as that principal.

## Kerberos for intranet sites

`--krb5-hosts` sends the same Kerberos credentials to _sites_, for intranet applications that log users in with Kerberos.

```bash
java -jar testingbot-tunnel.jar --krb5-hosts intranet.corp.example,wiki.corp.example
```

- It is an explicit list and never a wildcard. A service ticket names the user, so every host that may receive one has to be written down.
- Empty by default, so no site receives Kerberos credentials unless you name it.
- Plain HTTP only. HTTPS reaches the target as an opaque `CONNECT` tunnel.

## Where credentials go

Proxy credentials are only ever sent to the proxy they were issued for, matched on protocol, host and port.

- `--proxy-userpwd` goes to `--proxy` and nowhere else.
- `--proxy-testingbot` does **not** inherit `--proxy-userpwd`. The two proxies usually belong to different operators, so give it its own `--proxy-testingbot-userpwd`.
- A proxy chosen by a [PAC file](https://testingbot.com/support/tunnel/upstream-proxy#pac-local) receives no credentials. The tunnel logs that it withheld them, so the resulting `407` explains itself.

```bash
java -jar testingbot-tunnel.jar \
  --proxy 10.0.0.9:8080 --proxy-userpwd testuser:testpass \
  --proxy-testingbot corp-egress:3128 --proxy-testingbot-userpwd egress:secret
```

## Checking a setup

Every Negotiate misconfiguration looks like the same `407` from the proxy. `--doctor` walks the whole chain and reports exactly which step fails.

```bash
java -jar testingbot-tunnel.jar --proxy proxy.corp:8080 --proxy-auth-scheme negotiate --doctor
```

Run it with the same options you start the tunnel with. It checks the configuration it is actually given.

## Looking for more help?

Have questions or need more information? Reach out via email or Slack.

[Email us](https://testingbot.com/contact/new) [Join our Slack](https://join.slack.com/t/testingb0t/shared_invite/zt-3bcw9xch-jk19~6XPs_xBrsAgAedkCw)
