# API keys

Per-client keys in a configurable HTTP header - inbound matching on channels and outgoing headers from one definition.

[Video: New API key definition](https://zatosource-production.b-cdn.net/docs/gfx/security/api-key-create.webm?v=1792089442)

Dashboard menu: Security > API keys

## Overview {#overview}

An API key security definition describes a key sent in an HTTP header of the caller's choosing. One definition serves both directions of traffic:

- **Channels** - API clients present the key in the configured header and Zato matches it before any service code runs.
- **Outgoing** - Zato attaches the key in the configured header to every call an outgoing REST connection makes.

Definitions are managed in the dashboard under **Security** > **API keys**. Changes take effect immediately, without server restarts.

## Definition fields {#definition-fields}

| Field | Notes |
| --- | --- |
| Name | A unique name for the definition |
| Header | The HTTP header the key is sent in, `X-API-Key` by default. The default is server-wide and can be redefined with the `Zato_API_Key_Name` environment variable. |
| API key | The key itself - the exact value clients present and outgoing calls attach |

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

## Inbound REST channels {#inbound-rest-channels}

Assign a definition to a [REST channel](https://zato.io/docs/dev/rest/channels.html) by selecting **API key/\<name>** in the channel's security dropdown. From then on, every request to that channel must present the key in the definition's header:

```bash
$ curl -H "X-API-Key: mobile-api-key-value" http://localhost:11223/api/orders
```

Matching is an exact, constant-time comparison of the header's value against the definition's key. A request without the header, or with a key that does not match, receives a 401 response.

The header is per definition, so different channels can expect their keys in different headers - a partner integration can use `X-Partner-Token` while mobile clients stay on `X-API-Key`.

## Security groups and MCP gateways {#security-groups-and-mcp-gateways}

API key definitions can be members of [API client security groups](https://zato.io/docs/dev/rest/security-groups.html), next to Basic Auth and Bearer token members. A group assigned to a channel accepts a request when any of its members matches the presented credentials.

- Groups are managed under **Security** > **Groups** in the dashboard.
- All API key members of one channel's groups share one header name - the first member's header becomes channel-wide and a member with a different header is rejected when the configuration loads.
- Group membership changes are live - adding or removing a member is reflected in enforcement immediately, without restarts.
- Rejections at the group level return 403, unlike direct channel assignments which return 401.

The same definitions and groups also protect [MCP gateways](https://zato.io/docs/ai/mcp/security.html), where the clients are AI agents presenting the key on every request.

## Outgoing connections {#outgoing-connections}

The same definition drives outgoing calls. When an [outgoing REST connection](https://zato.io/docs/dev/rest/outconns.html) uses an API key definition, Zato attaches the key in the configured header to every request the connection makes - there is nothing to add in service code.

## Rate limiting {#rate-limiting}

The **Rate limiting** link next to a definition in its list assigns a [quota tier](https://zato.io/docs/security/quota-tiers.html) or custom [rate limiting](https://zato.io/docs/admin/guide/rate-limit.html) rules to the clients holding the key - counters are tracked per definition.

## OpenAPI console sign-in {#openapi-console-sign-in}

An API key definition also signs in to the [OpenAPI console](https://zato.io/docs/dev/rest/openapi-console.html) - the definition's name is the username and the key is the password. The signed-in caller receives an OpenAPI document containing only the channels the definition is assigned to, directly or through group membership.

## 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
- [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
- [Kerberos (SPNEGO)](https://zato.io/docs/security/kerberos/) - Negotiate authentication from a keytab, with no ticket management
- [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
