Declare a connection
Declare each connection with environment variables that follow this pattern:<NAME> is a label you choose, and is how a resource references the connection. <PROPERTY> is one of the properties the connection’s type accepts.
Connection names have to start with a letter and can contain letters, numbers and underscores, so
DEFAULT_SR is a valid name. A name can’t contain _CONFIG_, because that’s the delimiter between the name and the property. Gateway rejects such a variable at startup rather than guessing where the name ends. Names are case-insensitive and Gateway stores them in upper case, so default_sr and DEFAULT_SR are the same connection. We recommend you declare them in upper case to match the variable.TYPE, which selects the system it connects to:
Every connection follows the same shape. This one is a Confluent-like schema registry named
DEFAULT_SR, which needs only a URL:
Reference a connection
A resource reaches a connection through a field in its own configuration:
Set the field to the connection’s
<NAME>. The schema registry connection declared above is named DEFAULT_SR, so an Interceptor or topic view reaches it with:
400 Bad Request. Remove a connection that a resource already names and the resource stays saved and visible through the API, but stops serving traffic.
An Interceptor can name a schema registry connection, or configure a registry inline in its own schemaRegistryConfig. Gateway rejects a configuration that sets both rather than silently picking one.
Connect to a schema registry
Gateway needs a schema registry to decode Avro, Protobuf and JSON-Schema records. Both Interceptors and topic views can reference a schema registry connection. Gateway contacts the registry at startup and fails to start if it can’t be reached — see what happens at startup for the timeout, the permissions the connection needs and what the log shows.Confluent-like schema registries
SetTYPE to CONFLUENT_SCHEMA_REGISTRY for Confluent Schema Registry and compatible registries, including Redpanda Schema Registry:
AWS Glue schema registries
SetTYPE to AWS_SCHEMA_REGISTRY for AWS Glue Schema Registry:
BASIC_CREDENTIALS_ property unset and Gateway falls back to the AWS SDK’s default credentials provider, which searches environment variables, Java system properties, the shared credentials and config files, and container or instance IAM roles. See how the AWS SDK resolves default credentials.
Pass additional client properties
A schema registry connection also accepts any property its registry’s own client understands. Gateway doesn’t interpret these properties. It collects them and hands the map to the client, so a key the client doesn’t recognize passes startup rather than failing it. Use indexed entries, where each value is akey=value pair split at the first =:
= and migration from existing JSON configuration:
- Indexed entries win. An indexed entry overrides the same key in the JSON object, so you can patch one value without rewriting the object.
- Two indexed entries can’t share a key. There’s no patch order between them, so Gateway rejects the pair and names the key.
_CONFIG_0=schema.registry.url=… beside _CONFIG_SCHEMA_REGISTRY_URL, for example. Gateway doesn’t check for the overlap, and which of the two it connects with is left to the registry’s client.
Which keys to use depends on the registry:
Connect to a KMS
Gateway encrypts data in Kafka records with keys held in a key management service. An external connection holds the provider’s address, credentials and account details, so an Interceptor’skeyId contains the provider-specific identifier described below rather than a full provider URI. When it validates the Interceptor configuration, Gateway rejects any keyId that starts with a supported KMS URI scheme, such as azure-kms://.
External connections support HashiCorp Vault, AWS KMS, Azure Key Vault, Google Cloud KMS and Fortanix DSM. You can also configure these providers inline in an Interceptor’s kmsConfig. In-memory KMS and Gateway KMS remain inline-only; see choose your KMS provider.
An Interceptor can also use a KMS connection for crypto shredding. The connection holds the master key, and Gateway stores a separate key for each record.
HashiCorp Vault
SetTYPE to HASHICORP_VAULT. This example authenticates with a token, one of the auth methods covered below:
NAMESPACE too.
For every property a Vault connection accepts, including mutual TLS and connection retry, see the environment variables reference.
Authenticate with a token
SetAUTH_TYPE to TOKEN and AUTH_TOKEN to the Vault token Gateway authenticates with:
Authenticate with AppRole
SetAUTH_TYPE to APP_ROLE and pass the role ID and secret ID. Vault exchanges them for a short-lived token, which Gateway renews in the background:
AUTH_MOUNT when you mounted it somewhere other than approle, see the environment variables reference.
Authenticate with a username and password
SetAUTH_TYPE to USERNAME_PASSWORD and pass the userpass login. Vault exchanges it for a short-lived token, which Gateway renews in the background:
AUTH_MOUNT when you mounted it somewhere other than userpass, see the environment variables reference.
Authenticate with JWT
SetAUTH_TYPE to JWT and pass the Vault role, a signed JWT and the JWT auth method’s mount path. Vault verifies the JWT and returns a short-lived token, which Gateway renews in the background:
AUTH_MOUNT is required here, unlike the other methods: Gateway builds the JWT login path from it, so there’s no default. For every property this method accepts, see the environment variables reference.
Authenticate with LDAP
SetAUTH_TYPE to LDAP and pass the LDAP login. Vault checks it against the directory and returns a short-lived token, which Gateway renews in the background:
AUTH_MOUNT when you mounted it somewhere other than ldap, see the environment variables reference.
Authenticate with GitHub
SetAUTH_TYPE to GITHUB and AUTH_TOKEN to a GitHub token. Vault exchanges it for a short-lived token, which Gateway renews in the background. Gateway can run anywhere, since the token is a static credential:
AUTH_MOUNT when you mounted it somewhere other than github, see the environment variables reference.
Authenticate with Kubernetes
SetAUTH_TYPE to KUBERNETES and AUTH_ROLE to the Vault role. Gateway reads the pod’s service account token and Vault exchanges it for a short-lived token, which Gateway renews in the background. Gateway has to run inside the target cluster, since it reads the token the cluster mounts into the pod:
/var/run/secrets/kubernetes.io/serviceaccount/token by default. For every property this method accepts, including AUTH_TOKEN_PATH when the token is elsewhere, see the environment variables reference.
Authenticate with GCP
SetAUTH_TYPE to GCP, AUTH_ROLE to the Vault role and AUTH_JWT to a signed Google-issued JWT. Vault verifies it and returns a short-lived token, which Gateway renews in the background. Gateway can run anywhere, since it forwards a JWT minted elsewhere. Mint the JWT close to startup, as Vault rejects one older than 15 minutes:
Authenticate with AWS IAM
SetAUTH_TYPE to AWS_IAM and pass a pre-signed sts:GetCallerIdentity request: its URL, body and headers. Vault replays the request to AWS to confirm the caller, then returns a short-lived token, which Gateway renews in the background. Gateway can run anywhere, since it forwards a request signed elsewhere:
AUTH_ROLE and AUTH_MOUNT, see the environment variables reference.
Authenticate with AWS EC2
SetAUTH_TYPE to AWS_EC2 and pass the EC2 instance identity document and its signature. Vault verifies them with AWS and returns a short-lived token, which Gateway renews in the background. Gateway has to run on an EC2 instance, since the identity document comes from the instance metadata service:
AUTH_ROLE, AUTH_NONCE and AUTH_MOUNT, see the environment variables reference.
Authenticate with AWS EC2 by PKCS7
SetAUTH_TYPE to AWS_EC2_PKCS7 and pass the PKCS7 signature of the EC2 instance identity document. Vault verifies it with AWS and returns a short-lived token, which Gateway renews in the background. Gateway has to run on an EC2 instance, since the signature comes from the instance metadata service:
AUTH_ROLE, AUTH_NONCE and AUTH_MOUNT, see the environment variables reference.
Gateway configures these six methods the same way as any Vault auth method, but each one logs in against an identity provider our automated tests don’t cover. Validate your connection in a non-production environment before you use it in production.
Tokenize with the Transform Secrets Engine
The Transform Secrets Engine needs Vault Enterprise and has to be mounted at its default path,transform. The connection’s Vault identity needs the Transform policy. To tokenize through a connection, set ENGINE_TYPE to TRANSFORM and leave ENGINE_MOUNT unset:
kmsConnectionName to PROD_TRANSFORM and each keyId to a bare Transform role name, such as email. See how to configure tokenization.
To cache tokens, see the environment variables reference.
AWS KMS
SetTYPE to AWS_KMS. A connection covers one AWS account in one region. This example authenticates with access keys, one of three credential types covered below:
REGION and ACCOUNT_ID are both required, because Gateway builds each key’s full ARN from them — so an Interceptor names a key as a bare key id or alias/<name>, never an ARN. See how the ARN is built and what’s rejected.
The connection needs kms:Encrypt and kms:Decrypt on every key it uses, allowed by the key policy and by the identity’s IAM policy.
Authenticate with access keys
SetCREDENTIALS_TYPE to BASIC and pass a long-lived access key pair:
Authenticate with temporary credentials
SetCREDENTIALS_TYPE to SESSION and pass the session token alongside the key pair. Gateway doesn’t refresh these, so they stop working when they expire:
Authenticate with the AWS default provider chain
SetCREDENTIALS_TYPE to DEFAULT and pass no credentials at all. Gateway uses the AWS SDK’s default provider chain, which searches the container or instance role, IAM Roles for Service Accounts, the shared credentials file and the AWS_ environment variables. This suits a Gateway that already runs with an AWS identity, and it’s the only type where the credentials rotate without a restart:
Azure Key Vault
SetTYPE to AZURE_KMS. A connection covers one Azure Key Vault. This example authenticates with a client secret, one of three credential types covered below:
VAULT_URL has to be an HTTPS URL with a host and no trailing slash. The connection owns this URL, so each Interceptor keyId is a bare key name rather than a path or name/version. Gateway resolves the latest version of the key.
The identity needs get, encrypt and decrypt access to each key. If a key doesn’t exist, Gateway creates an RSA key, so the identity also needs create access.
Authenticate with a client secret
SetCREDENTIALS_TYPE to TOKEN and pass the application and tenant identifiers with the client secret, as shown above.
Authenticate with a username and password
SetCREDENTIALS_TYPE to USERNAME_PASSWORD and pass the application and tenant identifiers with the username and password:
Username and password authentication uses the Resource Owner Password Credentials flow. It can’t complete multifactor authentication (MFA) or satisfy a Conditional Access policy that requires MFA, and Microsoft recommends against using it. For production, use
CREDENTIALS_TYPE=DEFAULT with a workload identity or managed identity instead. See Microsoft’s ROPC guidance .Authenticate with the Azure default credential chain
SetCREDENTIALS_TYPE to DEFAULT and pass no credentials on the connection:
DefaultAzureCredential resolves credentials .
Google Cloud KMS
SetTYPE to GCP_KMS. A connection covers one key ring in one Google Cloud project and location:
PROJECT, LOCATION and KEY_RING are required because Gateway builds the full Cloud KMS resource name from them. Each Interceptor keyId is the bare crypto key name, never a full projects/.../cryptoKeys/... resource path. The crypto key has to exist before Gateway uses it.
The identity needs permission to encrypt and decrypt with each key. The predefined roles/cloudkms.cryptoKeyEncrypterDecrypter role provides these permissions.
Authenticate with Application Default Credentials
LeaveSERVICE_ACCOUNT_CREDENTIALS_FILE_PATH unset. Gateway uses Application Default Credentials , including a GKE workload identity or the attached service account on Google Cloud infrastructure.
Authenticate with a service-account key file
SetSERVICE_ACCOUNT_CREDENTIALS_FILE_PATH to the path of a readable service-account JSON key file, as shown above.
You can also set ENDPOINT to the root URL of a private Cloud KMS endpoint. The URL has to end with /. Leave it unset to use https://cloudkms.googleapis.com/.
Fortanix DSM
SetTYPE to FORTANIX_KMS. This example authenticates to Fortanix Data Security Manager (DSM) with an API key, one of two credential types covered below:
The connection owns the DSM base URL, so each Interceptor
keyId is a bare security-object name. Gateway searches security objects by that name and uses the first match, so keep names unique. The existing object has to be an AES key. If no object matches, Gateway generates a 256-bit AES security object.
Gateway sends AES-CBC encrypt and decrypt requests. It doesn’t set permissions on a generated object, so the Fortanix application has to be allowed to search for and generate security objects, and to encrypt and decrypt with them.
Authenticate with an API key
SetCREDENTIALS_TYPE to API_KEY and pass the application API key, as shown above.
Authenticate with a username and password
SetCREDENTIALS_TYPE to USERNAME_PASSWORD and pass the Fortanix username and password:
What happens at startup
Connections are read once, when Gateway starts, and this is true of every connection type:- Configuration is validated. An unrecognized property, or a malformed value such as a JSON object of additional client properties, fails startup and names the variable.
- Connections load before persisted resources. Interceptors and topic views are activated from storage after the connections exist, so their names resolve.
- A missing connection doesn’t stop Gateway. If an Interceptor or topic view names a connection that’s no longer declared, that resource stays saved and visible through the API but doesn’t activate, while everything else starts normally. Gateway logs an error naming the missing connection — check the startup log.
- Secrets are masked in the startup log. Additional client property values are masked whichever format set them, and their keys stay visible.
Gateway checks schema registry connections in parallel and waits for all of them to finish, so one broken connection doesn’t hide another — you see every failure in one startup attempt. Each attempt is bounded by
GATEWAY_EXTERNAL_CONNECTIONS_INIT_TIMEOUT_SECONDS, which defaults to 30 seconds and caps at 300. See the variable reference.
The check, and the permission it needs, differ by registry:
- Confluent-like — Gateway lists the registry’s subjects, so the connection needs permission to list them even if your Interceptors only read schemas by ID.
- AWS Glue — Gateway requests a schema version that deliberately doesn’t exist, so the connection needs
glue:GetSchemaVersionand a not-found answer counts as success.
Verify the configuration
Gateway logs each schema registry connection’s startup check. Look for one line per connection:No schema registry connections configured and starts normally.
Gateway reports KMS connections separately, one line each:
No KMS connections configured. The summary names each credential method but never prints a secret value.
Current limitations
- Connections are read and checked once, at startup. Changing one takes a restart. Gateway doesn’t monitor a system that becomes unreachable afterwards, so that failure surfaces on traffic needing an uncached schema.
- A schema-backed topic view has to use
SELECT *. AWHEREclause is still allowed. See read schema-encoded topics. - Gateway doesn’t contact a KMS at startup. It validates the connection’s properties, so a wrong credential or an unreachable provider surfaces when an Interceptor that names it loads, not at boot.
- An Interceptor that names a removed connection stops applying, rather than failing. It stays saved and visible through the API, but after a restart the traffic it covered passes through unprocessed. An upcoming release will reject that traffic instead.
- There’s no API that lists configured connections. Use the startup log to confirm what Gateway loaded.