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

# TLS

> Create a TLS secret to store SSL/TLS certificates and private keys for custom domains, mTLS authentication, or secure communication.

TLS secrets store SSL/TLS certificates and private keys for secure communication. Use them for custom domains, mTLS authentication, or any scenario requiring certificate-based security.

## Use Cases

* **Custom Domains**: Provide TLS certificates for custom domain names
* **mTLS Authentication**: Mutual TLS for service-to-service authentication
* **Internal Services**: Secure communication between workloads
* **Legacy Integrations**: Connect to systems requiring client certificates

## Configuration Options

| Field   | Description                                        | Required |
| :------ | :------------------------------------------------- | :------- |
| `key`   | Private key in PEM format                          | Yes      |
| `cert`  | Certificate in PEM format                          | Yes      |
| `chain` | Certificate chain/intermediate certs in PEM format | No       |

<Note>
  The private key must match the certificate's public key. For production, use certificates from a trusted Certificate Authority (CA).
</Note>

***

## Create a TLS Secret

<Tabs>
  <Tab title="Console UI">
    <Steps>
      <Step title="Navigate to Secrets">
        In the Console, navigate to **Secrets** and click **New**, or use the **Create** dropdown in the top-right corner and select **Secret**.
      </Step>

      <Step title="Enter basic information">
        Enter a **Name** and optional **Description**.
      </Step>

      <Step title="Select secret type">
        Select **TLS** as the secret type.
      </Step>

      <Step title="Configure certificate data">
        Click **Data** in the left pane. For **TLS Key**, drag and drop your private key file or click to import. For **TLS Cert**, drag and drop your certificate file or click to import. For **TLS Chain** (optional), drag and drop your certificate chain file or click to import.
      </Step>

      <Step title="Create the secret">
        Click **Create**.
      </Step>
    </Steps>
  </Tab>

  <Tab title="CLI">
    Prepare your certificate files, then create the secret:

    ```bash theme={null}
    cpln secret create-tls \
      --name my-domain-tls \
      --key private.key \
      --cert certificate.crt \
      --chain chain.crt \
      --org my-org
    ```

    Without a certificate chain (for self-signed certs):

    ```bash theme={null}
    cpln secret create-tls \
      --name self-signed-tls \
      --key private.key \
      --cert certificate.crt \
      --org my-org
    ```
  </Tab>

  <Tab title="Terraform">
    ```hcl theme={null}
    resource "cpln_secret" "tls" {
      name        = "my-domain-tls"
      description = "TLS certificate for api.example.com"

      tls {
        key   = file("private.key")
        cert  = file("certificate.crt")
        chain = file("chain.crt")
      }
    }
    ```

    Using Let's Encrypt with Terraform:

    ```hcl theme={null}
    resource "tls_private_key" "example" {
      algorithm = "RSA"
      rsa_bits  = 2048
    }

    resource "acme_certificate" "example" {
      # ... ACME configuration ...
    }

    resource "cpln_secret" "tls" {
      name        = "letsencrypt-tls"
      description = "Let's Encrypt certificate"

      tls {
        key   = tls_private_key.example.private_key_pem
        cert  = acme_certificate.example.certificate_pem
        chain = acme_certificate.example.issuer_pem
      }
    }
    ```

    <Warning>
      Never commit private keys to version control. Use Terraform state encryption and secure variable handling.
    </Warning>
  </Tab>

  <Tab title="Pulumi">
    <Tabs>
      <Tab title="TypeScript">
        ```typescript theme={null}
        import * as cpln from "@pulumiverse/cpln";
        import * as pulumi from "@pulumi/pulumi";
        import * as fs from "fs";

        const tlsSecret = new cpln.Secret("my-domain-tls", {
          name: "my-domain-tls",
          description: "TLS certificate for api.example.com",
          tls: {
            key: fs.readFileSync("private.key", "utf8"),
            cert: fs.readFileSync("certificate.crt", "utf8"),
            chain: fs.readFileSync("chain.crt", "utf8"),
          },
        });
        ```
      </Tab>

      <Tab title="Python">
        ```python theme={null}
        import pulumiverse_cpln as cpln

        with open("private.key") as f:
            private_key = f.read()
        with open("certificate.crt") as f:
            certificate = f.read()
        with open("chain.crt") as f:
            chain = f.read()

        tls_secret = cpln.Secret("my-domain-tls",
            name="my-domain-tls",
            description="TLS certificate for api.example.com",
            tls={
                "key": private_key,
                "cert": certificate,
                "chain": chain,
            })
        ```
      </Tab>

      <Tab title="Go">
        ```go theme={null}
        package main

        import (
            "os"
            "github.com/pulumi/pulumi/sdk/v3/go/pulumi"
            "github.com/pulumiverse/pulumi-cpln/sdk/go/cpln"
        )

        func main() {
            pulumi.Run(func(ctx *pulumi.Context) error {
                key, _ := os.ReadFile("private.key")
                cert, _ := os.ReadFile("certificate.crt")
                chain, _ := os.ReadFile("chain.crt")

                _, err := cpln.NewSecret(ctx, "my-domain-tls", &cpln.SecretArgs{
                    Name:        pulumi.String("my-domain-tls"),
                    Description: pulumi.String("TLS certificate for api.example.com"),
                    Tls: &cpln.SecretTlsArgs{
                        Key:   pulumi.String(string(key)),
                        Cert:  pulumi.String(string(cert)),
                        Chain: pulumi.String(string(chain)),
                    },
                })
                return err
            })
        }
        ```
      </Tab>

      <Tab title="C#">
        ```csharp theme={null}
        using System.IO;
        using Pulumi;
        using Pulumiverse.Cpln;
        using Pulumiverse.Cpln.Inputs;

        return await Deployment.RunAsync(() =>
        {
            var tlsSecret = new Secret("my-domain-tls", new SecretArgs
            {
                Name = "my-domain-tls",
                Description = "TLS certificate for api.example.com",
                Tls = new SecretTlsArgs
                {
                    Key = File.ReadAllText("private.key"),
                    Cert = File.ReadAllText("certificate.crt"),
                    Chain = File.ReadAllText("chain.crt"),
                },
            });
        });
        ```
      </Tab>
    </Tabs>
  </Tab>
</Tabs>

***

## Certificate Formats

TLS secrets expect PEM-encoded files:

**Private Key:**

```text theme={null}
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
-----END RSA PRIVATE KEY-----
```

**Certificate:**

```text theme={null}
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJ...
-----END CERTIFICATE-----
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Use certificates from trusted CAs">
    For production, use certificates from trusted Certificate Authorities like Let's Encrypt, DigiCert, or your organization's internal CA.
  </Accordion>

  <Accordion title="Set up certificate rotation">
    Track certificate expiration dates and rotate before they expire. Consider automating renewal with tools like cert-manager or ACME clients.
  </Accordion>

  <Accordion title="Protect private keys">
    Never share private keys via email or chat. Use secure transfer methods and limit access to key files.
  </Accordion>
</AccordionGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Custom Domains" icon="globe" href="/reference/domain">
    Configure custom domains with TLS certificates
  </Card>

  <Card title="Using Secrets in Workloads" icon="cube" href="/guides/create-secret/overview#using-secrets-in-workloads">
    Learn how to grant access and inject secrets
  </Card>
</CardGroup>
