> For the complete documentation index, see [llms.txt](https://docs.carto.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.carto.com/carto-self-hosted/configuration/networking/configure-an-external-proxy.md).

# Configure a forward proxy

CARTO Self-hosted supports operating behind an HTTP or HTTPS proxy. The proxy acts as a gateway, enabling CARTO Self-hosted components to establish connections with essential external services like CARTO licensing system, or `auth.carto.com`. You can find detailed information about these components and services in the [network requirements](/carto-self-hosted/planning/prerequisites/network/egress.md) section.

{% hint style="info" %}
This is a **forward proxy**: it sits between CARTO and the internet and routes CARTO's **outbound (egress)** traffic to external services. It is not a reverse proxy for inbound user traffic — for publishing CARTO to your users, see [Load balancing best practices](/carto-self-hosted/best-practices/deployment/load-balancing-best-practices.md).
{% endhint %}

**CARTO Self-hosted does not provide or install any proxy component**; It's built to connect to an existing proxy software deployed on your side.

A comprehensive list of domains that must be whitelisted by the proxy for the proper operation of CARTO Self-hosted can be found [here](/carto-self-hosted/planning/prerequisites/network/egress.md). Such list includes domains for the core services of CARTO Self-hosted, as well as some optional domains that should be enabled to access specific features.

## **HTTP**

In order to configure an external HTTP proxy on your CARTO Self-hosted installation, you'll have to:

{% tabs %}
{% tab title="Kots" %} <img src="/files/iX0yYSxrIcdJH0mbRf9w" alt="Kots" width="18">

{% tabs %}
{% tab title="Single VM deployment" %}
Update your installation so that it uses an HTTP proxy:

```bash
sudo ./carto install \
    --license license.yaml \
    --https-proxy=http://<your_proxy_host> \
    --http-proxy=http://<your_proxy_host> \
    --no-proxy=dropbox.io
```

The `no-proxy` flag receives a comma-separated list of domains to exclude from proxying.

Once the embedded cluster installation is done, you'll have to edit the config of CARTO Self-Hosted platform from the Admin Console to allow the usage of a forward proxy.
{% endtab %}

{% tab title="Orchestrated container deployment" %}
Update your installation so that it uses an HTTP proxy:

```bash
kubectl kots install carto \
  --namespace <namespace> \
  --http-proxy http://<your_proxy_host> \
  --https-proxy http://<your_proxy_host> \
  --no-proxy "localhost,.svc.cluster.local,<k8s_cluster_ip_service>"
```

The `no-proxy` flag receives a comma-separated list of domains to exclude from proxying. The `.svc.cluster.local` domain must be in the list to allow internal communication between components within your cluster.

In order to obtain the `k8s_cluster_ip_service` IP address is the one that belongs to the Cluster IP service that Kubernetes creates by default in your default namespace. You can obtain it running the following command:

```
kubectl get svc kubernetes -n default
```

Once your installation has been updated, you'll have to edit the config of CARTO Self-Hosted platform from the Admin Console to allow the usage of a forward proxy.

{% hint style="warning" %}
Please, take into account that if you're configuring a forward proxy in a CARTO Self-Hosted installation running in [GKE with Workload Identity](/carto-self-hosted/configuration/security/cloud-identities/use-workload-identity-in-gcp.md) configured, you'll have to add the following excluded domains:

`pubsub.googleapis.com,*.googleapis.com,169.254.169.254,metadata,metadata.google.internal`

These domains are required when authenticating the requests performed from an installation using Workload Identity.
{% endhint %}
{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="Helm" %} <img src="/files/5mQydBQdQ20MZUxbcOKQ" alt="Helm" width="18">

Add the following lines in your <mark style="color:orange;">customizations.yaml</mark> file:

```yaml
externalProxy:
  enabled: true
  host: <Proxy IP/Hostname>
  port: <Proxy port>
  type: http
  excludedDomains: ["localhost,.svc.cluster.local"]
```

The `externalProxy.excludedDomains` property contains a comma-separated list of domains to exclude from proxying. The `.svc.cluster.local` domain must be in the list to allow internal communication between components within your cluster.

{% hint style="warning" %}
Please, take into account that if you're configuring a forward proxy in a CARTO Self-Hosted installation running in [GKE with Workload Identity](/carto-self-hosted/configuration/security/cloud-identities/use-workload-identity-in-gcp.md) configured, you'll have to add the following excluded domains:

`169.254.169.254,metadata,metadata.google.internal`

These domains are required when authenticating the requests performed from an installation using Workload Identity.
{% endhint %}
{% endtab %}
{% endtabs %}

## **HTTPS**

To configure an HTTPS proxy on CARTO Self-hosted, you'll have to change the following configuration:

{% tabs %}
{% tab title="Kots" %} <img src="/files/iX0yYSxrIcdJH0mbRf9w" alt="Kots" width="18">

{% tabs %}
{% tab title="Single VM deployment" %}
Update your installation so that it uses an HTTPS proxy:

```bash
sudo ./carto install \
    --license license.yaml \
    --https-proxy=https://<your_proxy_host> \
    --http-proxy=https://<your_proxy_host> \
    --no-proxy=dropbox.io
```

The `no-proxy` flag receives a comma-separated list of domains to exclude from proxying.

{% hint style="warning" %}
If your proxy requires a custom Certificate Authority (CA), make sure it's already configured on the host where you're installing CARTO Self-Hosted. The installer will automatically inject the CA certificate to enable secure communication with your proxy.
{% endhint %}

Once the embedded cluster installation is done, you'll have to edit the config of CARTO Self-Hosted platform from the Admin Console to allow the usage of a forward proxy.
{% endtab %}

{% tab title="Orchestrated container deployment" %}
Update your installation so that it uses an HTTPS proxy:

```bash
kubectl kots install carto \
  --namespace <namespace> \
  --http-proxy https://<your_proxy_host> \
  --https-proxy https://<your_proxy_host> \
  --private-ca-configmap <your_ca_configmap>
  --no-proxy "localhost,.svc.cluster.local,<k8s_cluster_ip_service>"
```

The `no-proxy` flag receives a comma-separated list of domains to exclude from proxying. The `.svc.cluster.local` domain must be in the list to allow internal communication between components within your cluster.

In order to obtain the `k8s_cluster_ip_service` IP address is the one that belongs to the Cluster IP service that Kubernetes creates by default in your default namespace. You can obtain it running the following command:

```
kubectl get svc kubernetes -n default
```

Once your installation has been updated, you'll have to edit the config of CARTO Self-Hosted platform from the Admin Console to allow the usage of a forward proxy.

{% hint style="warning" %}
Please, take into account that if you're configuring a forward proxy in a CARTO Self-Hosted installation running in [GKE with Workload Identity](/carto-self-hosted/configuration/security/cloud-identities/use-workload-identity-in-gcp.md) configured, you'll have to add the following excluded domains:

`pubsub.googleapis.com,*.googleapis.com,169.254.169.254,metadata,metadata.google.internal`

These domains are required when authenticating the requests performed from an installation using Workload Identity.
{% endhint %}
{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="Helm" %} <img src="/files/5mQydBQdQ20MZUxbcOKQ" alt="Helm" width="18">

Add the following lines in your <mark style="color:orange;">customizations.yaml</mark> file:

```yaml
externalProxy:
  enabled: true
  host: <Proxy IP/Hostname>
  port: <Proxy port>
  type: https
  excludedDomains: ["localhost,.svc.cluster.local"]
  ## NOTE: Please, carefully read CARTO Self-hosted proxy documentation to understand the  the current limitations with [custom CAs].
  sslRejectUnauthorized: true
  # sslCA: |
  #  -----BEGIN CERTIFICATE-----
  #  XXXXXXXXXXXXXXXXXXXXXXXXXXX
  #  -----END CERTIFICATE-----
```

* `externalProxy.excludedDomains` : obtains a comma-separated list of domains to exclude from proxying. The `.svc.cluster.local` domain must be in the list to allow internal communication between components.
* `externalProxy.sslRejectUnauthorized` (optional): Specify if CARTO Self-hosted should check if the proxy certificate is valid or not. For instance, self-signed certificates validation must be skipped.
* `externalProxy.sslCA` (optional): Path to the proxy CA certificate. If the proxy certificate is signed by a **custom CA**, such CA must be included here, but if it's signed by a **well known CA**, there is no need to add it here. Well known CAs are usually part of the [ca-certificates package](https://askubuntu.com/questions/857476/what-is-the-use-purpose-of-the-ca-certificates-package).

{% hint style="warning" %}
Please, take into account that if you're configuring a forward proxy in a CARTO Self-Hosted installation running in [GKE with Workload Identity](/carto-self-hosted/configuration/security/cloud-identities/use-workload-identity-in-gcp.md) configured, you'll have to add the following excluded domains:

`169.254.169.254,metadata,metadata.google.internal`

These domains are required when authenticating the requests performed from an installation using Workload Identity.
{% endhint %}
{% endtab %}
{% endtabs %}

## Support for data warehouses

While certain data warehouses can be configured to work with a proxy, **there are some providers that will inherently bypass it**. This means that the connection to these data warehouses won't be created through the proxy, so CARTO Self-hosted services will try to directly perform requests to the providers.

* **BigQuery**: It supports both HTTP and HTTPs proxy.
* **PostgreSQL and Redshift**: They use a TCP connection instead of HTTP(S), so the proxy is bypassed.
* **Databricks**: Proxy is not supported, so the HTTPS connection will be bypassed.
* **Snowflake:** It supports HTTP proxy, but HTTPS is not supported and will have to be bypassed. In order to bypass it, you'll have to add `snowflakecomputing.com` to the list of excluded domains.
* **Oracle:** It supports HTTP proxy, but HTTPS is not supported and will have to be bypassed. In order to bypass it, you'll have to add `oraclecloud.com` to the list of excluded domains.

{% hint style="info" %}
When the proxy is bypassed, and you have a restrictive network policy in place, you will need to explicitly allow this egress of non-proxied traffic.
{% endhint %}

## Enhanced control over non-proxied egress traffic

{% hint style="info" %}
The following configuration applies only to Helm-based orchestrated container deployments of CARTO Self-Hosted. If you're using the Single VM deployment or Kots, this section can be skipped.
{% endhint %}

When no network policy is enforced, all outgoing traffic that does not pass through a proxy will be permitted.

In restrictive environments, it is indispensable to maintain strict control over connections made by CARTO Self-hosted components. To achieve this, you should configure your proxy to allow only approved external services (whitelisting), while blocking any other outgoing traffic that does not go through the proxy.

To accomplish this, you can apply a custom network policy, such as the one provided in this example:

```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: carto-no-internet-access
  # Optional labels
  labels:
    app.kubernetes.io/instance: <instance-name>
    app.kubernetes.io/managed-by: <managed-by>
    app.kubernetes.io/name: <app-name>
spec:
  # Match all Pods except the proxy Pod.
  # NOTE: Make sure your proxy pod has the label app.kubernetes.io/component: proxy
  # NOTE: Proxy pod is not deployed with the CARTO Self-hosted chart
  podSelector:
    matchExpressions:
      - key: app.kubernetes.io/component
        operator: NotIn
        values:
          - proxy
          - router
  policyTypes:
    - Ingress
    - Egress
  ingress:
    # Allow connections within the same namespace
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: <namespace>
  egress:
    # Allow connections within the same namespace
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: <namespace>
    # Allow DNS resolution
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
        - podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - port: 53
          protocol: UDP
    # Allow connections to external datawarehouses
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
      ports:
        # Postgres
        - port: 5432
          protocol: TCP
        # Redshift
        - port: 5439
          protocol: TCP
        # Valkey
        - port: 6379
          protocol: TCP
    # Allow connections to other datawarehouses hosts on port 443
    - to:
        - ipBlock:
            cidr: <CIDR>
      ports:
        - port: 443
          protocol: TCP
```

## Limitations

Password authentication is not supported for the proxy connection.

[Importing data](https://docs.carto.com/carto-user-manual/data-explorer/importing-data) using an HTTPS Proxy configured with a certificate signed by a Custom CA\
is not supported.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.carto.com/carto-self-hosted/configuration/networking/configure-an-external-proxy.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
