# Kerberos (SPNEGO)

Outgoing connections authenticating to SPNEGO-protected APIs with keytab-based credentials - no kinit, no caches.

[Video: New Kerberos definition](https://zatosource-production.b-cdn.net/docs/gfx/security/kerberos-create.webm?v=1790440846)

Dashboard menu: Security > Kerberos

## Overview {#overview}

A Kerberos security definition describes authentication with the HTTP Negotiate mechanism (SPNEGO) - the kind of authentication that Windows and Active Directory environments expose in front of their APIs, also used by systems such as Hadoop, IIS-hosted services and SAP gateways.

The definition is used with outgoing REST and SOAP connections - Zato is the client that authenticates to a remote, SPNEGO-protected API. The credentials come from a keytab file mounted into the container, so there is no `kinit`, no credential cache and no ticket renewal to manage - tickets are acquired from the keytab on demand and re-acquired automatically when they expire.

Definitions are managed in the dashboard under **Security** > **Kerberos**. There is no password and no change-password action - the keytab is the credential. Changes take effect immediately, without server restarts.

## Definition fields {#definition-fields}

| Field | Notes |
| --- | --- |
| Name | A unique name for the definition |
| Principal | The Kerberos principal to authenticate as, e.g. `zato@EXAMPLE.COM` |
| Keytab path | Path to the principal's keytab file, as mounted into the container |
| Target SPN | Optional - the remote service's principal name, e.g. `HTTP@api.example.com`. Leave empty to derive it from the target host name. |
| Delegate credentials | Optional - whether to delegate credentials to the remote service so it can act on behalf of the principal |

The definition is exported and imported with [enmasse](https://zato.io/docs/admin/enmasse.html) under the `security` key, with `type: spnego` - the fields are in the [enmasse reference](https://zato.io/docs/admin/enmasse-reference.html).

## Outgoing connections {#outgoing-connections}

Assign a definition to an [outgoing REST](https://zato.io/docs/dev/rest/outconns.html) or [SOAP](https://zato.io/docs/dev/soap/index.html) connection by selecting **Kerberos (SPNEGO)/\<name>** in the connection's security dropdown. From then on, every call through that connection performs the Negotiate handshake - the remote server replies with `401` and `WWW-Authenticate: Negotiate`, Zato obtains a service ticket with the keytab's credentials and retries with the token attached.

The keytab is a file that you mount into the container, along with a `krb5.conf` that points at your realm's KDC:

```bash
docker run \
    --mount type=bind,source=/path/to/zato.keytab,target=/opt/hot-deploy/krb5/zato.keytab \
    --mount type=bind,source=/path/to/krb5.conf,target=/etc/krb5.conf \
    zatosource/zato-4.1
```

The definition then points to the keytab path inside the container - `/opt/hot-deploy/krb5/zato.keytab` in the example above.

To export a keytab for a principal in an MIT KDC:

```bash
$ kadmin -q "ktadd -k zato.keytab zato@EXAMPLE.COM"
```

In Active Directory, use `ktpass` on a domain controller:

```bash
C:\> ktpass /princ zato@EXAMPLE.COM /mapuser zato /pass * /out zato.keytab \
    /crypto AES256-SHA1 /ptype KRB5_NT_PRINCIPAL
```

The target SPN is only needed when the remote service registered its principal under a name other than `HTTP/<hostname>` - the default derivation covers the typical setup.

## Troubleshooting {#troubleshooting}

Failures are reported as GSSAPI errors logged with the connection's name:

| Log message | Cause |
| --- | --- |
| `Cannot find KDC for realm` | The realm is not described in `/etc/krb5.conf` or the KDC is unreachable |
| `Keytab contains no suitable keys` | The keytab does not hold keys for the configured principal - re-export it, watching the principal name and the key version number (kvno) |
| `Server not found in Kerberos database` | The derived or configured target SPN does not exist in the realm - set the target SPN explicitly |
| `Ticket expired` or `Clock skew too great` | The container's clock differs from the KDC's by more than the allowed skew - synchronize time |

## Learn more {#learn-more}

- [Securing channels](https://zato.io/docs/admin/security/channel.html) - Which security types a channel accepts, and how to assign them
- [Securing outgoing connections](https://zato.io/docs/admin/security/outgoing.html) - Credentials Zato presents to the systems it calls
- [API keys](https://zato.io/docs/security/api-keys.html) - Per-client keys in a configurable HTTP header
- [Basic Auth](https://zato.io/docs/security/basic-auth.html) - Usernames and passwords for channels and outgoing connections
- [Bearer tokens](https://zato.io/docs/security/bearer-tokens/) - Static tokens and JWTs verified against a JWKS endpoint
- [Security groups](https://zato.io/docs/security/groups.html) - Many API client credentials on one channel or MCP gateway
- [mTLS](https://zato.io/docs/security/mtls/) - Client certificates in both directions, matched by fingerprint or DN
- [NTLM](https://zato.io/docs/security/ntlm.html) - Windows domain credentials for outgoing connections
- [WS-Security](https://zato.io/docs/security/ws-security.html) - UsernameToken, X.509 and SAML for SOAP traffic
- [Quota tiers](https://zato.io/docs/security/quota-tiers.html) - Named rate-limit plans assigned to any number of API clients
- [TLS certificates](https://zato.io/docs/admin/security/ssl/) - Your own certificates, the self-signed ones and how to rotate them
