> ## Documentation Index
> Fetch the complete documentation index at: https://docs.conduktor.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure Gateway external connections (preview)

> Declare a connection to an external system once in Conduktor Gateway, then reference it by name from Interceptors and topic views instead of repeating it.

An external connection is a named, reusable declaration of one external system, made when Gateway starts. Interceptors and topic views then reference it by name, instead of each carrying its own copy of the address and credentials.

<Note>
  **Preview functionality**. This is a preview feature and is subject to change. Inline configuration remains fully supported.
</Note>

For topic views this is the only way to configure a schema registry.

For Interceptors, prefer an external connection when several resources use the same registry: the address and credentials live in one place instead of being repeated in every Interceptor, so rotating a credential or moving a registry is a single edit. Inline configuration keeps working and is not deprecated.

## Declare a connection

Declare each connection with environment variables that follow this pattern:

```
GATEWAY_EXTERNAL_CONNECTION_<NAME>_CONFIG_<PROPERTY>
```

`<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.

<Note>
  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.
</Note>

Every connection needs a `TYPE`, which selects the system it connects to:

| `TYPE`                      | System                                                                                  | Properties                                                            |
| --------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `CONFLUENT_SCHEMA_REGISTRY` | Confluent Schema Registry and compatible registries, including Redpanda Schema Registry | [Confluent-like schema registries](#confluent-like-schema-registries) |
| `AWS_SCHEMA_REGISTRY`       | AWS Glue Schema Registry                                                                | [AWS Glue schema registries](#aws-glue-schema-registries)             |
| `HASHICORP_VAULT`           | HashiCorp Vault, for encryption keys                                                    | [HashiCorp Vault](#hashicorp-vault)                                   |
| `AWS_KMS`                   | AWS Key Management Service, for encryption keys                                         | [AWS KMS](#aws-kms)                                                   |

Every connection follows the same shape. This one is a Confluent-like schema registry named `DEFAULT_SR`, which needs only a URL:

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_DEFAULT_SR_CONFIG_TYPE=CONFLUENT_SCHEMA_REGISTRY
GATEWAY_EXTERNAL_CONNECTION_DEFAULT_SR_CONFIG_SCHEMA_REGISTRY_URL=http://schema-registry:8081
```

Gateway rejects an unrecognized property at startup, naming the variable and listing the properties the connection's type accepts, so a typo never becomes a silently ignored setting.

## Reference a connection

A resource reaches a connection through a field in its own configuration:

| Resource                                                                                                                                                   | Field                               |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
| Interceptors that read schemas — [data security](/guide/reference/data-security) and [data quality](/guide/conduktor-in-production/admin/gateway-policies) | `schemaRegistryConnectionName`      |
| [Topic views](/guide/conduktor-concepts/logical-topics#read-schema-encoded-topics)                                                                         | `spec.schemaRegistryConnectionName` |
| [Encryption Interceptors](/guide/reference/data-security#name-a-kms-external-connection)                                                                   | `kmsConnectionName`                 |

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:

```json theme={null}
"schemaRegistryConnectionName": "DEFAULT_SR"
```

Gateway checks the name when you create or update the resource, and rejects an unknown one 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](#what-happens-at-startup) for the timeout, the permissions the connection needs and what the log shows.

### Confluent-like schema registries

Set `TYPE` to `CONFLUENT_SCHEMA_REGISTRY` for Confluent Schema Registry and compatible registries, including Redpanda Schema Registry:

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_DEFAULT_SR_CONFIG_TYPE=CONFLUENT_SCHEMA_REGISTRY
GATEWAY_EXTERNAL_CONNECTION_DEFAULT_SR_CONFIG_SCHEMA_REGISTRY_URL=http://schema-registry:8081
```

For every property this type accepts, see the [environment variables reference](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/environment-variables#external-connections-confluent-like-schema-registry).

To reach a registry that needs authentication, pass the registry client's own properties as [additional client properties](#pass-additional-client-properties).

<Warning>
  Don't put credentials in `SCHEMA_REGISTRY_URL`. Gateway rejects a URL carrying user information before an `@` and names the connection, so pass them as additional client properties instead.
</Warning>

### AWS Glue schema registries

Set `TYPE` to `AWS_SCHEMA_REGISTRY` for AWS Glue Schema Registry:

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_PROD_SR_CONFIG_TYPE=AWS_SCHEMA_REGISTRY
GATEWAY_EXTERNAL_CONNECTION_PROD_SR_CONFIG_REGION=us-east-1
GATEWAY_EXTERNAL_CONNECTION_PROD_SR_CONFIG_BASIC_CREDENTIALS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
GATEWAY_EXTERNAL_CONNECTION_PROD_SR_CONFIG_BASIC_CREDENTIALS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```

For every property this type accepts, see the [environment variables reference](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/environment-variables#external-connections-aws-glue-schema-registry).

Leave every `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](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials-chain.html).

### 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 a `key=value` pair split at the first `=`:

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_DEFAULT_SR_CONFIG_0=basic.auth.credentials.source=USER_INFO
GATEWAY_EXTERNAL_CONNECTION_DEFAULT_SR_CONFIG_1=basic.auth.user.info=user:password
```

Or pass a JSON object, which suits keys containing `=` and migration from existing JSON configuration:

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_DEFAULT_SR_CONFIG_JSON={"basic.auth.credentials.source":"USER_INFO","basic.auth.user.info":"user:password"}
```

Both formats work together, under two rules:

* **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.

A client property can address the same setting as a typed one — `_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:

| Connection type             | Keys are                                                                                                                                                                                                             | Reference                                                                                                                                       |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `CONFLUENT_SCHEMA_REGISTRY` | Confluent Schema Registry client configuration. This is also how the connection authenticates, since it has no typed credential properties: use `basic.auth.credentials.source` and `basic.auth.user.info`, as above | [Schema Registry security](https://docs.confluent.io/platform/current/schema-registry/security/index.html) <Icon icon="up-right-from-square" /> |
| `AWS_SCHEMA_REGISTRY`       | AWS Glue Schema Registry serde configuration, merged over the typed properties. Credentials come from the `BASIC_CREDENTIALS_` properties or the AWS SDK's default chain, so these keys cover other client settings  | [AWS Glue Schema Registry library](https://github.com/awslabs/aws-glue-schema-registry) <Icon icon="up-right-from-square" />                    |

## 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 names a key rather than a full key URI.

Not every provider is available as an external connection yet. Encryption Interceptors reach [more of them](/guide/reference/data-security#choose-your-kms-provider) through their own inline `kmsConfig`, so configure a provider inline until it arrives here.

### HashiCorp Vault

Set `TYPE` to `HASHICORP_VAULT`. This example authenticates with a token, one of three auth methods covered below:

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_TYPE=HASHICORP_VAULT
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_URI=https://vault.internal:8200
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_ENGINE=TRANSIT
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_MOUNT=transit
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_AUTH_TYPE=TOKEN
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_AUTH_TOKEN=hvs.CAESIExampleToken
```

For every property a Vault connection accepts, including mutual TLS and connection retry, see the [environment variables reference](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/environment-variables#external-connections-hashicorp-vault-kms).

An external connection reaches less of Vault than inline `kmsConfig` does. We're widening it in future releases, and until then inline configuration is the way to use anything missing here:

* **Secrets engines.** An external connection supports the [Transit secrets engine](https://developer.hashicorp.com/vault/docs/secrets/transit) <Icon icon="up-right-from-square" /> (`MOUNT=transit` above). Inline configuration also supports [Transform](/guide/reference/data-security#vault-kms), which needs Vault Enterprise.
* **Auth methods.** An external connection supports the three below, out of the [eleven inline configuration offers](/guide/reference/data-security#vault-kms).

<Warning>
  Don't put credentials in `URI`. Gateway rejects a URI carrying user information before an `@` and names the connection, so authenticate with `AUTH_TYPE` and its credentials instead.
</Warning>

#### Authenticate with a token

Set `AUTH_TYPE` to `TOKEN` and `AUTH_TOKEN` to the Vault token Gateway authenticates with:

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_AUTH_TYPE=TOKEN
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_AUTH_TOKEN=hvs.CAESIExampleToken
```

For every property this method accepts, see the [environment variables reference](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/environment-variables#external-connections-vault-token-authentication).

<Warning>
  Gateway doesn't renew a token you supply — with `AUTH_TYPE` set to `TOKEN` it never calls Vault's renew endpoint, so the token stays in use until its TTL expires, and recovering means replacing the variable and restarting. AppRole and username/password avoid that: Vault issues a short-lived token and Gateway renews it in the background. If you do use a token, give it a TTL that outlives your deployment window, or keep it fresh outside Gateway. [See Vault's production hardening guidance](https://developer.hashicorp.com/vault/docs/concepts/production-hardening) <Icon icon="up-right-from-square" />.
</Warning>

#### Authenticate with AppRole

Set `AUTH_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](/guide/reference/data-security#vault-kms):

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_AUTH_TYPE=APP_ROLE
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_AUTH_ROLE_ID=59d6d1ca-47bb-4e7e-a40b-8be3bc5a0ba8
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_AUTH_SECRET_ID=84896a0c-1347-aa90-a4f6-aca8b7558780
```

For every property this method accepts, including `AUTH_MOUNT` when you mounted it somewhere other than `approle`, see the [environment variables reference](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/environment-variables#external-connections-vault-approle-authentication).

#### Authenticate with a username and password

Set `AUTH_TYPE` to `USERNAME_PASSWORD` and pass the userpass login. Vault exchanges it for a short-lived token, which Gateway [renews in the background](/guide/reference/data-security#vault-kms):

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_AUTH_TYPE=USERNAME_PASSWORD
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_AUTH_USERNAME=gateway
GATEWAY_EXTERNAL_CONNECTION_PROD_VAULT_CONFIG_AUTH_PASSWORD=s3cr3t
```

For every property this method accepts, including `AUTH_MOUNT` when you mounted it somewhere other than `userpass`, see the [environment variables reference](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/environment-variables#external-connections-vault-username-and-password-authentication).

### AWS KMS

Set `TYPE` 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:

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_TYPE=AWS_KMS
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_REGION=eu-west-1
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_ACCOUNT_ID=123456789012
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_CREDENTIALS_TYPE=BASIC
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_CREDENTIALS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_CREDENTIALS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```

For every property an AWS KMS connection accepts, see the [environment variables reference](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/environment-variables#external-connections-aws-kms).

`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](/guide/reference/data-security#aws-kms).

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

Set `CREDENTIALS_TYPE` to `BASIC` and pass a long-lived access key pair:

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_CREDENTIALS_TYPE=BASIC
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_CREDENTIALS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_CREDENTIALS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```

For every property this type accepts, see the [environment variables reference](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/environment-variables#external-connections-aws-kms-access-keys).

#### Authenticate with temporary credentials

Set `CREDENTIALS_TYPE` to `SESSION` and pass the session token alongside the key pair. Gateway doesn't refresh these, so they stop working when they expire:

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_CREDENTIALS_TYPE=SESSION
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_CREDENTIALS_ACCESS_KEY_ID=ASIAIOSFODNN7EXAMPLE
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_CREDENTIALS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_CREDENTIALS_SESSION_TOKEN=IQoJb3JpZ2luX2VjEXAMPLE
```

For every property this type accepts, see the [environment variables reference](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/environment-variables#external-connections-aws-kms-temporary-credentials).

#### Authenticate with the AWS default provider chain

Set `CREDENTIALS_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:

```bash theme={null}
GATEWAY_EXTERNAL_CONNECTION_PROD_AWS_CONFIG_CREDENTIALS_TYPE=DEFAULT
```

[See how the AWS SDK resolves default credentials](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials-chain.html) <Icon icon="up-right-from-square" />.

## 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](#pass-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](#verify-the-configuration).
* **Secrets are masked** in the startup log. Additional client property values are masked whichever format set them, and their keys stay visible.

Whether Gateway also *contacts* the external system at startup depends on the connection type:

| Connection type                                                      | Contacted at startup                                                                |
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| Schema registry — `CONFLUENT_SCHEMA_REGISTRY`, `AWS_SCHEMA_REGISTRY` | Yes. Gateway fails to start if a registry can't be reached.                         |
| KMS — `HASHICORP_VAULT`, `AWS_KMS`                                   | No. Gateway validates the connection's properties but doesn't contact the provider. |

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](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/environment-variables#external-connections-startup-checks).

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:GetSchemaVersion` and a not-found answer counts as success.

A KMS connection is established when an Interceptor that names it loads, so a wrong token or an unreachable Vault server surfaces then rather than at boot, and Gateway starts normally either way. Check the Interceptor's own status after deploying it, not the startup log.

## Verify the configuration

Gateway logs each schema registry connection's startup check. Look for one line per connection:

```
External connection DEFAULT_SR initialized in 84ms
```

A failure names the connection and the cause, and Gateway then reports how many failed before it stops:

```
External connection PROD_SR failed: ...
1 of 2 external connections failed: PROD_SR
```

These lines cover schema registry connections only, since those are the ones Gateway contacts. With none declared — including when you've declared only KMS connections — Gateway logs `No external connections configured` and starts normally.

Gateway reports KMS connections separately, one line each:

```
Loaded 2 KMS connection(s):
  PROD_VAULT [HASHICORP_VAULT] engine=TRANSIT mount=transit uri=https://vault.internal:8200
  PROD_AWS [AWS_KMS] region=eu-west-1 accountId=123456789012 credentials=BASIC keyUri=aws-kms://arn:aws:kms:eu-west-1:123456789012:<keyId>
```

With none declared, that becomes `No KMS connections configured`. Neither summary includes a credential.

## 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 *`.** A `WHERE` clause is still allowed. See [read schema-encoded topics](/guide/conduktor-concepts/logical-topics#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.

## Related resources

* [Gateway environment variables](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/environment-variables#external-connections-preview)
* [Read schema-encoded topics with a topic view](/guide/conduktor-concepts/logical-topics#read-schema-encoded-topics)
* [Data security Interceptors](/guide/reference/data-security)
* [Kafka data validation policies](/guide/conduktor-in-production/admin/gateway-policies)
* [Configure Gateway listeners](/guide/conduktor-in-production/deploy-artifacts/deploy-gateway/listeners)
