Skip to content

Feat/configurable certificate authorities#1773

Open
JuanmaBM wants to merge 4 commits into
RedHatInsights:masterfrom
JuanmaBM:feat/configurable-certificate-authorities
Open

Feat/configurable certificate authorities#1773
JuanmaBM wants to merge 4 commits into
RedHatInsights:masterfrom
JuanmaBM:feat/configurable-certificate-authorities

Conversation

@JuanmaBM
Copy link
Copy Markdown
Contributor

Add Configurable Certificate Authorities for TLS Connections

Summary

This PR implements configurable certificate authority (CA) support for ClowdApps to use custom certificates when connecting to dependencies via TLS.

Motivation

Previously, Clowder hardcoded the CA certificate source (openshift-service-ca.crt ConfigMap) for all TLS connections between ClowdApps. This created limitations:

  • Platform lock-in: Only worked on OpenShift with the service-ca operator
  • No custom PKI: Teams couldn't use their own certificate infrastructure
  • All-or-nothing: Every app had to use the same CA, preventing gradual migrations
  • No system trust option: Apps couldn't opt-out to use container's built-in trust store

This change provides flexibility while maintaining backward compatibility.

Changes

API Changes

ClowdEnvironment CRD

Added certificateAuthorities field to define a bundle of available CAs:

apiVersion: cloud.redhat.com/v1alpha1
kind: ClowdEnvironment
spec:
  providers:
    web:
      tls:
        enabled: true
        certificateAuthorities:
          - name: internal-ca
            namespace: cert-management
          - name: external-ca
            namespace: cert-management

ClowdApp CRD

Added two mutually exclusive fields for CA configuration:

  1. tlsCertificateAuthorityName: Select from environment's bundle
  2. tlsCertificateAuthoritySecretRef: Use app-managed secret
apiVersion: cloud.redhat.com/v1alpha1
kind: ClowdApp
spec:
  # Option 1: Select from environment bundle
  tlsCertificateAuthorityName: internal-ca
  
  # Option 2: Use own secret (mutually exclusive with option 1)
  tlsCertificateAuthoritySecretRef:
    name: my-team-certs

Implementation

  1. New Certificate Authority Provider (controllers/cloud.redhat.com/providers/certificateauthority/)

    • EnvProvide(): Creates single bundle secret containing all CAs from environment spec
    • Provide(): Validates CA selection and copies bundle to app namespace if needed
    • Bundle secret naming: {envName}-ca-bundle
    • Reserved name validation: system-trust-store cannot be used in certificateAuthorities list
  2. Updated Web Providers (providers/web/default.go, providers/web/local.go)

    • resolveCAForApp(): Determines which CA secret to mount based on app's configuration
    • addCAHashAnnotation(): Adds clowder/ca-secret-hash annotation for automatic rollouts on CA rotation
    • Mounts appropriate volume source (ConfigMap for default, Secret for bundle/override)
  3. Updated Job Provider (providers/job/impl.go)

    • Same CA mounting logic for CronJobs and Jobs
  4. Updated Dependencies Provider (providers/dependencies/impl.go)

    • Populates tlsCAPath in V2 dependency endpoints based on consumer app's CA selection
    • Supports null value for system-trust-store scenario
  5. Webhook Validation (apis/cloud.redhat.com/v1alpha1/clowdapp_webhook.go)

    • Validates tlsCertificateAuthorityName and tlsCertificateAuthoritySecretRef are mutually exclusive

Four Configuration Scenarios

Scenario Configuration Volume Source Mount Path tlsCAPath Use Case
Default None ConfigMap: openshift-service-ca.crt /cdapp/certs /cdapp/certs/service-ca.crt OpenShift, backward compatible
Bundle tlsCertificateAuthorityName: internal-ca Secret: {env}-ca-bundle /cdapp/certs /cdapp/certs/internal-ca.crt Custom PKI, environment-managed
Override tlsCertificateAuthoritySecretRef: {name: my-certs} Secret: my-certs /cdapp/certs /cdapp/certs/ca.crt App-managed certificates
System Trust tlsCertificateAuthorityName: system-trust-store None - null Use container's trust store

Example Usage

Scenario 1: Default (Backward Compatible)

apiVersion: cloud.redhat.com/v1alpha1
kind: ClowdApp
metadata:
  name: my-app
spec:
  envName: production
  # No CA configuration - uses openshift-service-ca.crt
  dependencies:
  - other-app

Scenario 2: Environment Bundle

apiVersion: cloud.redhat.com/v1alpha1
kind: ClowdApp
metadata:
  name: my-app
spec:
  envName: production
  tlsCertificateAuthorityName: internal-ca  # Selects from environment bundle
  dependencies:
  - other-app

Scenario 3: App-Managed Override

apiVersion: v1
kind: Secret
metadata:
  name: my-team-certs
  namespace: my-namespace
data:
  ca.crt: <base64-encoded-cert>
---
apiVersion: cloud.redhat.com/v1alpha1
kind: ClowdApp
metadata:
  name: my-app
spec:
  envName: production
  tlsCertificateAuthoritySecretRef:
    name: my-team-certs  # App manages this secret
  dependencies:
  - other-app

Scenario 4: System Trust Store

apiVersion: cloud.redhat.com/v1alpha1
kind: ClowdApp
metadata:
  name: my-app
spec:
  envName: production
  tlsCertificateAuthorityName: system-trust-store  # Opt-out, use container's trust
  dependencies:
  - other-app

Automatic Certificate Rotation

When a CA certificate is rotated, deployments automatically restart:

  1. CA secret is updated (in cert-store namespace)
  2. ClowdEnvironment reconciles → bundle secret updated
  3. ClowdApp reconciles → clowder/ca-secret-hash annotation changes
  4. Kubernetes detects annotation change → pods restart with new certificate

Note: This only applies to Secret-based CAs (bundle and override). ConfigMap and system-trust scenarios are unaffected.

Backward Compatibility

Fully backward compatible

  • Existing ClowdApps without CA configuration continue using openshift-service-ca.crt
  • No migration required
  • No breaking changes to existing APIs
  • V1 endpoints continue to work unchanged
  • V2 endpoints already support optional ca_certificate field

Migration Path

  1. No action required for apps that use default OpenShift service CA
  2. Environment admins can define CA bundle in ClowdEnvironment
  3. App teams opt-in by setting tlsCertificateAuthorityName or tlsCertificateAuthoritySecretRef
  4. Gradual adoption - apps can migrate independently

Security Considerations

  • Reserved name system-trust-store prevents accidental misconfiguration
  • Webhook validation ensures mutually exclusive field usage
  • CA bundle secrets are namespace-scoped (no cluster-wide access)
  • HashCache tracks ownership for proper garbage collection
  • Override mode allows apps to manage their own certificate lifecycle

Documentation

Certificate rotation behavior:

  • CA changes trigger automatic pod restarts via hash annotation
  • Apps should be designed to tolerate restarts
  • For zero-downtime updates, ensure proper readiness probes

Related Issues

Closes: (ENGPROD-9704)


Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com

@JuanmaBM JuanmaBM force-pushed the feat/configurable-certificate-authorities branch 5 times, most recently from 78f08eb to 48d9a9c Compare May 13, 2026 12:44
@JuanmaBM
Copy link
Copy Markdown
Contributor Author

/test-e2e

2 similar comments
@JuanmaBM
Copy link
Copy Markdown
Contributor Author

/test-e2e

@JuanmaBM
Copy link
Copy Markdown
Contributor Author

/test-e2e

@JuanmaBM JuanmaBM force-pushed the feat/configurable-certificate-authorities branch 3 times, most recently from 51ab74d to c3e250b Compare May 18, 2026 15:11
@JuanmaBM
Copy link
Copy Markdown
Contributor Author

/test-e2e

JuanmaBM and others added 4 commits May 20, 2026 10:11
Add support for ClowdApps to configure custom CA certificates for TLS
connections to dependencies. This enables multi-environment support
(non-OpenShift), custom PKI infrastructure, and granular security control.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add clowder/ca-secret-hash annotation to deployments that mount CA
secrets. When a CA certificate is rotated, the hash changes and
Kubernetes automatically restarts pods with the new certificate.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@JuanmaBM JuanmaBM force-pushed the feat/configurable-certificate-authorities branch from c3e250b to 2a10caf Compare May 20, 2026 08:11
@JuanmaBM
Copy link
Copy Markdown
Contributor Author

/test-e2e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant