API authentication

Control who calls your APIs and how your services authenticate to external systems.

Authentication controls who can access your APIs and how your services authenticate to external systems. You configure security definitions once in the Dashboard and attach them to channels or outgoing connections. One definition serves several purposes at once - it authenticates callers, selects their quota tier, signs them in to the OpenAPI console and identifies them in the per-consumer traffic analytics.

For systems that require custom authentication schemes, such as SAP or ServiceNow HMAC signatures or session-based flows, you can implement your own validation logic in service code.

Available security types

The table below shows which security types can be used with channels and outgoing connections.

TypeChannelsOutgoingUse when
Basic AuthYesYesUsername/password authentication
API keyYesYesAPI keys in headers
Bearer token---YesOAuth 2.0 client credentials flow with automatic token refresh
GroupsYes---Multiple clients need access to the same channel
NTLM---YesCalling Windows/Active Directory-protected APIs
mTLSYesYesClient certificates - presenting one to remote APIs and authenticating API clients by theirs
Kerberos (SPNEGO)---YesCalling SPNEGO-protected APIs with keytab-based Kerberos credentials
Note: The same security definitions and groups also protect MCP gateways, where the clients are AI agents - how a credential maps to an agent's identity is described under MCP gateway security.

Secure REST channels

A channel with a security definition rejects requests without valid credentials before your service code runs. Create the definition first, then select it on the channel.

Basic Auth

To create a Basic Auth definition, go to Security > Basic Auth in the Dashboard, click Create a new definition and fill in the form:

  1. Name: API Credentials
  2. Username: api.client
  3. Password: the password the client authenticates with
  4. Click OK

New Basic Auth definition

API keys

Each client application receives its own API key. Each definition also has its own HTTP header name, X-API-Key by default, and the client sends the key's value directly in that header.

To create an API key definition, go to Security > API Keys, click Create a new definition and fill in the form:

  1. Name: Mobile Clients
  2. Header: the HTTP header the key arrives in, X-API-Key by default
  3. API key: the key the client sends
  4. Click OK

New API key definition

With the default header, a client call looks like this:

curl -H "X-API-Key: your-api-key" http://localhost:11223/api/v1/services/my-service

And with a custom header configured for the definition:

curl -H "X-Custom-Token: your-api-key" http://localhost:11223/api/v1/services/my-service

When API key definitions are members of groups, all API key definitions used by one channel's groups share one header name - different channels can use different headers.

Assign security to a channel

Create or edit a REST channel and select the security definition in its Security field. Once attached, Zato rejects requests without valid credentials before your service code runs.

Channel with Basic Auth

If your service implements a custom authentication scheme itself, or the channel genuinely needs no security, select No security definition explicitly.

API client groups

When multiple clients need access to the same channel, organize their definitions into groups - each client keeps its own credentials and you revoke access for one client without changing the channel. To learn how groups work and how to create them, see security groups.

Access security information in code

When a request arrives through a secured channel, self.channel.security carries the authenticated identity:

# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class SecuredService(Service):
    """ Logs the authenticated caller of a secured channel.
    """
    name = 'demo.rest.secured-service'

    def handle(self) -> 'None':

        # The username of the caller the channel authenticated
        username = self.channel.security.username

        self.logger.info('Request from %s', username)

Calls with valid credentials reach the service and everything else is rejected:

# With Basic Auth credentials
curl -u api.client:api-password http://localhost:11223/api/secure/data

# With an API key in the header
curl -H "X-API-Key: your-api-key" http://localhost:11223/api/secure/data

# Without credentials - the channel returns 401
curl http://localhost:11223/api/secure/data

Authenticate outgoing calls

Create a Basic Auth, API key or Bearer token definition and select it in the outgoing connection's Security field. Zato adds the required headers to every request the connection makes, and with Bearer tokens it obtains and refreshes the OAuth tokens too.

Basic Auth

Create a Basic Auth definition under Security > Basic Auth, entering the username and password the external API expects, and select the definition in your outgoing REST connection.

API key

For APIs that require an API key in an HTTP header, create an API key definition under Security > API Keys and select it in the connection. The header name is configurable per definition, X-API-Key by default.

Bearer token

For APIs that use the OAuth 2.0 client credentials flow, create a Bearer token definition. Go to Security > OAuth > Outgoing > Client Credentials, click Create a new definition and fill in the form:

  1. Name: Customer Identity
  2. Username: your OAuth client ID
  3. Secret: the client secret
  4. Auth server URL: the token endpoint, e.g. https://auth.example.com/oauth2/token
  5. Click OK

New Bearer token definition

The remaining fields:

FieldPurpose
ScopesNewline-separated list of OAuth scopes to request
Client ID fieldField name for the client ID in the token request (default: client_id)
Client secret fieldField name for the secret in the token request (default: client_secret)
Grant typeOAuth grant type (default: client_credentials)
Extra fieldsAdditional key=value pairs to include in token requests
Data formatRequest format: JSON or Form data (most auth servers expect Form data)

When your service makes an outgoing call through a connection with a Bearer token definition attached:

  1. Zato checks its internal cache for a valid token
  2. If no cached token exists, or it expired, Zato requests a new one from the auth server
  3. The token is cached for half its validity period, so refreshes happen well before expiry
  4. The Authorization: Bearer <token> header is added to your request

For example, if the auth server returns a token valid for 3600 seconds, Zato caches it for 1800 seconds - after 30 minutes, the next API call triggers a fresh token request.

You can also override the scopes for a single request through the auth_scopes parameter - without it, the scopes from the security definition are used:

conn = self.rest['My API']
response = conn.get(self.cid, auth_scopes='read:users write:users')

Custom authentication

For custom authentication schemes such as SAP HMAC signatures or session-based login/logout flows, pass custom headers directly to the connection.

OpenAPI console access

Every security definition attached to REST channels doubles as a sign-in to the OpenAPI console - no separate console accounts exist:

Definition typeConsole usernameConsole password
Basic AuthThe usernameThe password
API keyThe definition's nameThe key
Bearer tokenThe client IDThe client secret

The console is deny by default. A signed-in caller receives an OpenAPI document containing only the channels their definition is assigned to, directly or through group membership, and the try-it client enforces the same rules. Credentials matching no channel yield an empty document - nothing leaks about endpoints the caller cannot invoke.

See also

PageWhat it covers
Security groupsMany credentials on one channel and the 403 rule
Custom authenticationHMAC signatures, proprietary tokens and session-based flows
Error catalogThe 401 versus 403 rule and every other status a channel returns
OpenAPI consoleThe console your security definitions sign callers in to

Learn more