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

# Certificate Management for Multi-Tenant Applications

> Implement robust SSL/TLS certificate management for multi-tenant SaaS applications

Learn how to implement robust SSL/TLS certificate management for multi-tenant SaaS applications using dedicated ingresses per tenant on Qovery.

## The Challenge

Single ingress controller approach creates problems:

* Certificate generation failures affecting all domains if one validation fails
* Entire deployment risks from misconfigured domains
* Privacy issues: customers see other tenants' domains in SSL certificates
* Let's Encrypt rate limit concerns with many domains

***

## The Solution: Dedicated Ingresses Per Tenant

<Frame>
  <img src="https://mintcdn.com/qovery/oR5FEQ5ecXf7EXKc/images/certificate_management_for_multi_tenant_infrastructure/archi_overview.png?fit=max&auto=format&n=oR5FEQ5ecXf7EXKc&q=85&s=19aab9d1a96bc5bbe46b7c29f54b6719" alt="Architecture overview" width="3123" height="1627" data-path="images/certificate_management_for_multi_tenant_infrastructure/archi_overview.png" />
</Frame>

### Benefits

* **Isolation**: Tenant certificate/ingress separation
* **Reliability**: One tenant's issues won't cascade to others
* **Privacy**: Certificates contain only specific tenant domains
* **Scalability**: Improved rate limit and renewal management

***

## Prerequisites

* Qovery account with configured cluster
* DNS management access
* Basic understanding of Kubernetes ingress

***

## Implementation Guide

### Step 1: Organize Your Platform (Optional)

Create separate environments for better organization:

1. **Core Environment** – Main application components (frontend, API, database)
2. **Tenants Environment** – Tenant-specific ingress configurations

<Frame>
  <img src="https://mintcdn.com/qovery/oR5FEQ5ecXf7EXKc/images/certificate_management_for_multi_tenant_infrastructure/environment_structure.png?fit=max&auto=format&n=oR5FEQ5ecXf7EXKc&q=85&s=417613faa95edf3f43c52aaeea2c41d4" alt="Environment structure" width="1583" height="667" data-path="images/certificate_management_for_multi_tenant_infrastructure/environment_structure.png" />
</Frame>

<Info>
  Separating core and tenant environments makes it easier to manage and scale your multi-tenant architecture.
</Info>

***

### Step 2: Deploy Your Main Application

<Steps>
  <Step title="Deploy Container">
    Deploy your application via UI, CLI, Terraform, or REST API to the Core environment.
  </Step>

  <Step title="Configure Application Port">
    1. Go to **Settings** → **Ports**
    2. Add your application port

    <Frame>
      <img src="https://mintcdn.com/qovery/DYuxDyyByK2wvJFz/images/certificate_management_for_multi_tenant_infrastructure/edit_port.png?fit=max&auto=format&n=DYuxDyyByK2wvJFz&q=85&s=d17ce4c4b12d701ec8aa32c16f83a111" alt="Configure application port" width="2784" height="1820" data-path="images/certificate_management_for_multi_tenant_infrastructure/edit_port.png" />
    </Frame>
  </Step>

  <Step title="Add Main Domain">
    1. Go to **Settings** → **Domains**
    2. Add your main application domain
  </Step>

  <Step title="Note Environment Variables">
    Your application will have these built-in environment variables:

    * `QOVERY_CONTAINER_XXXXXXX_HOST_INTERNAL`: Internal hostname
    * `QOVERY_KUBERNETES_NAMESPACE_NAME`: Kubernetes namespace

    <Frame>
      <img src="https://mintcdn.com/qovery/DYuxDyyByK2wvJFz/images/certificate_management_for_multi_tenant_infrastructure/list_variables.png?fit=max&auto=format&n=DYuxDyyByK2wvJFz&q=85&s=c4376643c9630175fe8710a028ffa584" alt="Environment variables" width="2784" height="1820" data-path="images/certificate_management_for_multi_tenant_infrastructure/list_variables.png" />
    </Frame>

    Save these values for the next steps.
  </Step>
</Steps>

***

### Step 3: Create Tenant-Specific Ingresses

<Frame>
  <img src="https://mintcdn.com/qovery/oR5FEQ5ecXf7EXKc/images/certificate_management_for_multi_tenant_infrastructure/implementation_flow.png?fit=max&auto=format&n=oR5FEQ5ecXf7EXKc&q=85&s=fb6e177ba778f9587499c4978c505105" alt="Implementation flow" width="1646" height="532" data-path="images/certificate_management_for_multi_tenant_infrastructure/implementation_flow.png" />
</Frame>

<Steps>
  <Step title="Switch to Tenants Environment">
    Navigate to your Tenants environment in Qovery Console.
  </Step>

  <Step title="Create New Helm Service">
    1. Create a new Helm service
    2. Use an empty chart template (or create a minimal chart)
    3. Name it after your tenant (e.g., `tenant-acme-corp`)
    4. Be sure to select the option `Allow cluster-wide resources`
  </Step>

  <Step title="Configure Ingress Port">
    1. Go to **Settings** → **Ports**
    2. Configure:
       * **Service name**: Internal hostname from core application
       * **Service port**: Core application's port number
       * **Namespace**: Kubernetes namespace from core application

    <Frame>
      <img src="https://mintcdn.com/qovery/DYuxDyyByK2wvJFz/images/certificate_management_for_multi_tenant_infrastructure/tenant_port.png?fit=max&auto=format&n=DYuxDyyByK2wvJFz&q=85&s=02766e45ef533eed8dc5d853713d9f8c" alt="Configure tenant port" width="2784" height="1820" data-path="images/certificate_management_for_multi_tenant_infrastructure/tenant_port.png" />
    </Frame>
  </Step>

  <Step title="Add Tenant Custom Domain">
    1. Go to **Settings** → **Domains**
    2. Add the tenant's custom domain (e.g., `acme-corp.example.com`)

    <Frame>
      <img src="https://mintcdn.com/qovery/DYuxDyyByK2wvJFz/images/certificate_management_for_multi_tenant_infrastructure/custom_domain.png?fit=max&auto=format&n=DYuxDyyByK2wvJFz&q=85&s=07dad8cfa03cfc2d47ed7e084f9cca3c" alt="Add custom domain" width="2696" height="1732" data-path="images/certificate_management_for_multi_tenant_infrastructure/custom_domain.png" />
    </Frame>
  </Step>

  <Step title="Deploy">
    Click **Deploy**. Qovery will:

    * Create a dedicated ingress for this tenant
    * Generate an SSL certificate for the tenant's domain
    * Route traffic from the tenant domain to your core application
  </Step>
</Steps>

***

### Step 4: Scale to Multiple Tenants

**Options for adding more tenants:**

1. **Clone Existing Configuration**:
   * Clone the tenant Helm service
   * Update the custom domain
   * Deploy

2. **Create from Scratch**:
   * Repeat Step 3 for each new tenant
   * Each tenant gets isolated ingress and certificate

<Tip>
  Consider automating tenant provisioning using the Qovery API or Terraform for large-scale deployments.
</Tip>

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Certificate Generation Issues">
    **Problem:** SSL certificate not generating for tenant domain

    **Solutions:**

    * Check DNS propagation: `dig _acme-challenge.tenant-domain.com CNAME`
    * Verify CNAME record points to Qovery cluster
    * Check ingress configuration in deployment logs
    * Monitor cert-manager logs for certificate generation details
    * Ensure domain is not behind CDN (or configure properly)
  </Accordion>

  <Accordion title="Routing Issues">
    **Problem:** Traffic not reaching the application

    **Solutions:**

    * Verify internal service name matches application hostname
    * Confirm namespace configuration for multi-environment setups
    * Check that core application is running and healthy
    * Review ingress logs for routing errors
    * Test internal connectivity between namespaces
  </Accordion>

  <Accordion title="Rate Limiting">
    **Problem:** Hit Let's Encrypt rate limits

    **Solutions:**

    * Use Let's Encrypt staging environment for testing
    * Implement certificate caching
    * Stagger tenant onboarding to spread certificate requests
    * Consider using wildcard certificates for subdomains
  </Accordion>

  <Accordion title="Performance Issues">
    **Problem:** Slow response times for tenant requests

    **Solutions:**

    * Check ingress controller resource allocation
    * Monitor core application performance
    * Review network policies
    * Consider scaling ingress controller replicas
    * Implement caching at CDN or application level
  </Accordion>
</AccordionGroup>

***

## Advanced Configurations

### Wildcard Certificates

For subdomains under a single domain:

```yaml theme={null}
# In tenant Helm values
domains:
  - "*.tenants.example.com"
```

### Custom Certificate Providers

Use custom certificate issuers:

```yaml theme={null}
annotations:
  cert-manager.io/cluster-issuer: "custom-issuer"
```

### Automatic Tenant Provisioning

Use Qovery API to automate tenant creation:

```bash theme={null}
# Example using Qovery API
curl -X POST https://api.qovery.com/environment/xxx/helm \
  -H "Authorization: Token YOUR_TOKEN" \
  -d '{
    "name": "tenant-' + TENANT_ID + '",
    "chart": "empty-chart",
    "values_override": {...}
  }'
```

***

## Security Considerations

<AccordionGroup>
  <Accordion title="Tenant Isolation">
    * Each tenant has dedicated ingress
    * SSL certificates are tenant-specific
    * No cross-tenant certificate exposure
    * Network policies can further isolate traffic
  </Accordion>

  <Accordion title="Certificate Management">
    * Automatic renewal before expiration
    * Failed renewals don't affect other tenants
    * Certificate rotation without downtime
    * Private keys never shared between tenants
  </Accordion>

  <Accordion title="Access Control">
    * Use RBAC to control who can add tenants
    * Audit logs track tenant creation
    * Separate environments limit blast radius
    * API tokens for automated provisioning
  </Accordion>
</AccordionGroup>

***

## Monitoring and Maintenance

### Key Metrics to Monitor

* Certificate expiration dates
* Certificate generation success rate
* Ingress response times
* Error rates per tenant
* SSL/TLS handshake failures

### Automated Alerts

Set up alerts for:

* Certificate generation failures
* Certificates expiring within 30 days
* Ingress health check failures
* High error rates for specific tenants

***

## Conclusion

Dedicated ingresses create a robust, scalable, and secure multi-tenant architecture with:

* Better tenant isolation
* Easier troubleshooting
* Improved customer privacy
* Reduced rate limit concerns
* Independent certificate lifecycle management

***

## Related Documentation

<CardGroup cols={2}>
  <Card title="Custom Domains" icon="globe" href="/configuration/application">
    Configure custom domains
  </Card>

  <Card title="Helm Services" icon="https://mintcdn.com/qovery/Nvnl0g5BHzA0XQmy/images/logos/helm-icon.svg?fit=max&auto=format&n=Nvnl0g5BHzA0XQmy&q=85&s=f6c259d3ee3123f80e74bcb99c9f6f1d" href="/configuration/helm" width="24" height="24" data-path="images/logos/helm-icon.svg">
    Deploy with Helm charts
  </Card>

  <Card title="Environment Management" icon="layer-group" href="/configuration/environment">
    Manage environments
  </Card>

  <Card title="Qovery API" icon="code" href="/api-reference/introduction">
    Automate with the API
  </Card>
</CardGroup>
