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

# Self-hosted security

> Deploy and harden a self-hosted TrueFoundry control plane and AI Gateway — architecture, Helm chart security settings, encryption, and edge protection.

This page describes how to deploy a self-hosted TrueFoundry **control plane** and **AI Gateway** securely, and the settings you should enable on your own infrastructure and in the TrueFoundry Helm chart. For managed SaaS, see [SaaS Security](/docs/platform/saas-security).

<Info>
  Need a detailed self-hosted security review or questionnaire responses? Contact **[security@truefoundry.com](mailto:security@truefoundry.com)** or your TrueFoundry account team. Compliance and trust documentation is at [trust.truefoundry.com](https://trust.truefoundry.com).
</Info>

## Deployment architecture

TrueFoundry ships the control plane and AI Gateway as a Helm chart that you install into your own Kubernetes cluster. TrueFoundry provides the container images (hardened and patched to the [vulnerability SLAs](#vulnerability-management) below); you own the cluster, the network, and the stateful dependencies. Because everything runs in your environment, your configuration, secrets, prompts, responses, logs, and traces stay inside your infrastructure.

A secure deployment has these building blocks:

| Component          | What it is                                              | You should                                                                                          |
| ------------------ | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| **Control plane**  | Dashboard, APIs, configuration, identity                | Run in a dedicated namespace; restrict ingress; terminate TLS 1.2+                                  |
| **AI Gateway**     | LLM and MCP proxy (stateless)                           | Front with a WAF; keep provider keys in a secret store                                              |
| **PostgreSQL**     | Stores configuration, users, and secrets                | Use managed Postgres with encryption at rest (KMS) and SSL                                          |
| **Blob storage**   | Request logs and traces (S3 / Azure Blob / GCS / MinIO) | Enable encryption at rest; grant access via scoped IAM roles                                        |
| **Ingress + WAF**  | Public entry for the dashboard, API, and gateway        | Put a WAF in front; expose nothing else publicly                                                    |
| **Secret manager** | External store for provider keys and secrets            | Use AWS SSM/Secrets Manager, GCP Secret Manager, or Azure Key Vault with a customer-managed KMS key |

Traffic to TrueFoundry's authentication/licensing and analytics servers is **outbound-only** — no inbound ports need to be opened for TrueFoundry. See [What leaves your environment](#what-leaves-your-environment).

For the base install steps and values file, see [Install on-prem](/docs/platform/deploy-control-plane-install-onprem) and the [deployment overview](/docs/platform/deploy-control-plane-and-gateway-plane).

## Harden the Helm installation

The settings below are the ones you should enable to secure the installation. Add them to your `truefoundry-values.yaml` and apply with `helm upgrade`.

### 1. Enforce pod and container security contexts

The chart ships with hardened defaults for first-party components — non-root (`runAsNonRoot: true`), read-only root filesystem (`readOnlyRootFilesystem: true`), and dropped capabilities (`capabilities.drop: [ALL]`). The bundled **NATS** subchart does not get these automatically. If your cluster enforces [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/), apply the security context to NATS explicitly:

```yaml truefoundry-values.yaml theme={"dark"}
tfyNats:
  container:
    merge:
      securityContext:
        capabilities:
          drop:
            - ALL
        readOnlyRootFilesystem: true
        allowPrivilegeEscalation: false
  podTemplate:
    merge:
      spec:
        securityContext:
          fsGroup: 1000
          runAsUser: 1000
          runAsNonRoot: true
```

See [How to configure security context for TrueFoundry components](/docs/platform/deploy-control-plane-faq).

### 2. Enable network policies

Network policies are shipped in the chart but **opt-in** (`networkPolicy.enabled: false` by default). Enabling them applies a default-deny-ingress posture to the control-plane namespace so only the sources you list can reach the pods.

```yaml truefoundry-values.yaml theme={"dark"}
networkPolicy:
  enabled: true
  allowedIngressFrom:
    # Prometheus scrapes
    - namespace: tfy-prometheus
    # Ingress controller (recommended: restrict to controller pods)
    - namespace: ingress-nginx
      podSelector:
        app.kubernetes.io/name: ingress-nginx
```

<Warning>
  Your cluster CNI must **enforce** `NetworkPolicy` (EKS VPC CNI with `enableNetworkPolicy: "true"`, or Calico/Cilium; GKE network policy; Azure CNI with a policy engine; OpenShift OVN/SDN). If `allowedIngressFrom` is empty, cross-namespace ingress — including Prometheus and your ingress controller — is blocked until you add those namespaces.
</Warning>

For the full policy list, prerequisites, and verification steps, see [How to enable Network Policies for Control Plane](/docs/platform/deploy-control-plane-faq).

### 3. Encrypt keys and secrets

Do not store LLM provider keys or other secrets as plaintext in the database or in Helm values. Instead:

* **Use an external secret manager** — connect AWS SSM Parameter Store / Secrets Manager, GCP Secret Manager, or Azure Key Vault as a [Secret Store integration](/docs/integrations-secret-store), and reference secrets by FQN so provider keys live in your KMS-backed store. See [Secret manager in the AI Gateway](/docs/ai-gateway/secret-manager-in-ai-gateway).
* **Use a customer-managed KMS key** — configure a custom KMS Key ARN for the AWS Secret Manager / Parameter Store secret store so you control the encryption key and its rotation.
* **Encrypt the database at rest** — use managed PostgreSQL with encryption at rest enabled (KMS) and require TLS with `DB_SSL_MODE` (`require`, `verify-ca`, or `verify-full`). See [How to enable SSL for PostgreSQL connections](/docs/platform/deploy-control-plane-faq).
* **Encrypt blob storage at rest** — enable server-side encryption (SSE-KMS) on the bucket that holds request logs and traces.

### 4. Encrypt traffic in transit

* Terminate **TLS 1.2+** at your ingress for the dashboard, API, and gateway endpoints.
* Optionally enable in-pod TLS termination on the proxy for end-to-end encryption inside the cluster. See [How to enable in-pod TLS termination](/docs/platform/deploy-control-plane-faq).
* Require SSL to PostgreSQL as above; inject custom CA certificates where needed via [custom CA certificate injection](/docs/infrastructure/custom-ca-certificate-injection).

### 5. Grant least-privilege cloud access

* Give the control plane and gateway access to storage and secrets through **scoped IAM roles** (IRSA on EKS, Workload Identity on GKE, Managed Identity on AKS) rather than long-lived static keys.
* Restrict the S3 (or equivalent) policy to the minimal actions required. See [How to restrict AWS S3 permissions to a minimal set](/docs/platform/deploy-control-plane-faq).
* Ensure your database security group allows traffic only from the Kubernetes node groups.
* **Do not grant anyone in the organization direct access to the TrueFoundry PostgreSQL database or the S3 bucket.** These hold configuration, secrets, request logs, and traces. Access should be limited to the control plane and gateway workloads via their scoped IAM roles — not developers, analysts, or admins. Restrict human access to break-glass procedures only, and audit any such access.

## Edge protection (WAF)

Place a **Web Application Firewall** in front of the ingress for **both** the control plane and the AI Gateway. Network policies protect east-west traffic inside the cluster but do not inspect inbound web traffic — a WAF is what filters malicious requests before they reach your pods.

* Use your platform's WAF — Cloudflare, AWS WAF (with ALB/CloudFront), Azure Front Door / Application Gateway WAF, or GCP Cloud Armor.
* Enable OWASP-style managed rule sets (SQL injection, XSS, path traversal), rate limiting, and bot/DDoS protection at the edge.
* Terminate TLS at the edge and forward only to your ingress; keep origins off the public internet where possible (private endpoints, security groups).
* **Keep the control plane private** — do not expose the control plane URL (dashboard and API) to the public internet. Restrict it to a VPN or your private network. Unlike the gateway, which serves your applications, the control plane is admin-facing and does not need public exposure.

## What leaves your environment

A self-hosted control plane and gateway communicate with TrueFoundry's central authentication/licensing and analytics servers, exchanging the following. **Prompt and response content is never included.**

<AccordionGroup>
  <Accordion title="User login emails">
    The control plane uses TrueFoundry's remote authentication server to authenticate users logging into the platform. With SSO configured, this is a chained flow where the user is validated by both TrueFoundry and your IdP. See the [SSO documentation](/docs/sso). To use your IdP directly without the TrueFoundry Auth Server, see [How to use SSO directly](/docs/platform/deploy-control-plane-faq).
  </Accordion>

  <Accordion title="Control plane telemetry" id="control-plane-analytics">
    The control plane sends operational telemetry to the analytics server (`https://analytics.truefoundry.com`) about once per hour — the control plane version, provider, and connection status. **Prompt and response content is never included.**

    The exact payload structure:

    ```json expandable theme={"dark"}
    {
      "clusters": [
        {
          "clusterName": "example-cluster",
          "kubernetesVersion": "v1.33.4",
          "provider": "aws",
          "tenantName": "tenant1",
          "controlPlaneVersion": "0.90.0",
          "controlPlaneURL": "https://example-company.truefoundry.cloud",
          "truefoundryControlPlane": true,
          "controlPlaneProvider": "aws",
          "isConnected": true
        }
      ]
    }
    ```
  </Accordion>

  <Accordion title="Compute plane analytics (only applicable if you are using the AI Deployment module)" id="compute-plane-analytics">
    If you connect compute clusters through the AI Deployment module, each connected cluster's installed addons (name, version, health, and sync status) and autopilot resource statistics (CPU, memory, and GPU usage and requests) are added to the same hourly payload — one `addons` array and `autopilotStatistics` object per cluster entry. **No prompt or response content is included.**

    ```json expandable theme={"dark"}
    {
      "addons": [
        {
          "name": "truefoundry",
          "version": "0.90.0",
          "healthStatus": "Healthy",
          "syncStatus": "Synced",
          "sourceNamespace": "argocd",
          "destinationNamespace": "truefoundry",
          "addonName": "truefoundry"
        }
      ],
      "autopilotStatistics": {
        "clusterName": "example-cluster",
        "tenantName": "tenant1",
        "autopilot": { "addons": false, "service": false },
        "p50CpuUsage": 4.49,
        "p50CpuRequested": 65.822,
        "p50CpuAllocatable": 211.02,
        "p50MemoryUsage": 133.447,
        "p50MemoryRequested": 255.933,
        "p50MemoryAllocatable": 649.102,
        "p50GpuCountUsage": 0,
        "p50GpuCountRequested": 0,
        "p50GpuCountProvisioned": 0,
        "p50GpuMemoryUsage": 0,
        "p50GpuMemoryProvisioned": 0
      }
    }
    ```
  </Accordion>

  <Accordion title="Gateway analytics" id="gateway-analytics">
    The AI Gateway sends usage and configuration analytics to the same analytics server (`https://analytics.truefoundry.com`) to help understand utilization and improve the service:

    * **Usage metrics** — token consumption, request counts, error rates, provider and model usage breakdown, guardrails execution statistics, routing decisions, and MCP tool calls
    * **Configuration metrics** — counts of configured provider accounts, models, guardrails, MCP servers, rate/budget limit rules, and prompts

    **Prompt and response content is never included.** The exact payload structure:

    ```json expandable theme={"dark"}
    {
      "tenantName": "tenant1",
      "data": {
        "1738800000": {
          "usage": {
            "inputTokens": 125000,
            "outputTokens": 48000,
            "totalTokens": 173000,
            "totalRequestCount": 1250,
            "totalErrorCounts": 12,
            "providerWiseModelCounts": { "openai": 800, "anthropic": 350, "azure": 100 },
            "guardrailsRuntime": {
              "totalEligibleRequests": 1250,
              "guardrailPass": 1200,
              "guardrailFail": 35,
              "guardrailMutate": 10,
              "guardrailRunError": 5
            },
            "routingData": { "totalRouting": 1250, "tfyRateLimited": 8, "tfyBudgetLimited": 3 },
            "totalMCPToolCalls": 75
          },
          "config": {
            "models": { "totalProviderAccounts": 5, "totalModels": 12, "totalVirtualModels": 3 },
            "guardrails": { "totalGuardrailGroups": 4, "totalGuardrailIntegrations": 6 },
            "mcpServers": { "totalMcpGroups": 2, "totalMcpServers": 8 },
            "rules": {
              "totalRateLimitRules": 15,
              "totalBudgetLimitRules": 8,
              "totalGuardrailConfigRules": 6,
              "otelExportConfigured": true
            },
            "prompts": { "totalPrompts": 24, "totalPromptVersions": 67 }
          }
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Public pricing of instance types and models">
    The control plane fetches public pricing from the catalogue server (`https://catalogue.truefoundry.com`) for AWS/GCP/Azure instance types and for LLM models added to the AI Gateway, so pricing can be shown on the dashboard.
  </Accordion>

  <Accordion title="Crash and error logs">
    TrueFoundry uses Sentry to collect crash and error logs from the control plane. Sensitive data such as user prompts and other PII is not sent — [Sentry does not send or log PII by default](https://docs.sentry.io/platforms/python/data-management/sensitive-data/#personally-identifiable-information-pii).
  </Accordion>
</AccordionGroup>

## Vulnerability management

TrueFoundry ships the control plane and gateway as container images that are scanned before release; software is not released with a critical known vulnerability that has a fix available. Vulnerabilities are triaged by CVSS severity and fixes are delivered against these SLAs, triggered from the time you notify us:

| Severity     | CVSS score | Patch SLA                     |
| ------------ | ---------- | ----------------------------- |
| Critical     | 9.0+       | 10 days                       |
| High         | 7.0–8.9    | 30 days                       |
| Medium / Low | below 7.0  | Addressed in regular releases |

**How fixes are delivered**

* **Rolling track** — security fixes ship in the next regular release. Staying within 3 months of the latest release keeps you covered.
* **Stable track** — an on-demand maintenance patch is shipped against your current Stable version within the SLA window. TrueFoundry does not proactively monitor older versions, so notify your Customer Support Manager or the support channel to start the SLA clock.

Because you run the images, applying upgrades is your responsibility — stay on a supported [release track](/docs/platform/control-plane-upgrade#release-tracks) and scan images in your own registry as part of your program. For the full model, see [Releases and Upgrades](/docs/platform/control-plane-upgrade).

<Tip>
  **Upgrade at least once a month** to pick up the latest features, fixes, and security updates from TrueFoundry. Falling behind widens the window in which a known, already-fixed vulnerability remains unpatched in your deployment.
</Tip>

## Logging and monitoring

Security logging and monitoring are your responsibility, using your existing tooling:

* Enable auditing and logging across your systems and network devices, and forward them to your SIEM. For example, integrate AWS CloudTrail with CloudWatch to correlate events and alert on potential incidents.
* Scrape TrueFoundry component metrics with your monitoring stack and alert on anomalies. See [Control plane monitoring](/docs/platform/controlplane-monitoring).
* Maintain monitoring of security alerts for continuous oversight and rapid response.
* Review TrueFoundry [audit logs](/docs/platform/audit-logging) for user and API activity in the platform.

## Security checklist

Use this checklist when you install a self-hosted control plane and gateway, and revisit it in periodic reviews.

### Deployment and network

* [ ] Control plane URL is not exposed to the public internet — access restricted to a VPN or your private network
* [ ] A WAF fronts both the control plane and the AI Gateway
* [ ] Ingress terminates TLS 1.2+ for the dashboard, API, and gateway
* [ ] Origins kept off the public internet where possible (private endpoints, security groups)

### Helm hardening

* [ ] Pod and container security contexts enforced, including the NATS override
* [ ] Network policies enabled (`networkPolicy.enabled: true`) with `allowedIngressFrom` scoped to monitoring and ingress
* [ ] Cluster CNI enforces `NetworkPolicy`

### Data protection

* [ ] Provider keys and secrets stored in an external secret manager with a customer-managed KMS key
* [ ] PostgreSQL encrypted at rest and requires SSL (`DB_SSL_MODE`)
* [ ] Blob storage encrypted at rest (SSE-KMS)
* [ ] No direct human access to the TrueFoundry database or S3 bucket — workloads only, via scoped IAM roles

### Access

* [ ] Storage and secrets accessed through scoped IAM roles (IRSA / Workload Identity / Managed Identity), not static keys
* [ ] S3 (or equivalent) policy restricted to the minimal actions required
* [ ] SSO configured with your IdP and least-privilege roles assigned

### Upgrades and monitoring

* [ ] Upgrade at least once a month to pick up the latest changes and security updates from TrueFoundry
* [ ] Staying on a supported release track
* [ ] TrueFoundry images scanned in your own registry
* [ ] Component metrics scraped and alerting configured
* [ ] Audit logs and infrastructure logs forwarded to your SIEM

## Report a vulnerability

If you discover a security issue in TrueFoundry:

* Email **[security@truefoundry.com](mailto:security@truefoundry.com)**
* We follow responsible disclosure and aim to respond within **48 hours**
* Advisories are published on [trust.truefoundry.com](https://trust.truefoundry.com)
