Skip to content

Commit c133a22

Browse files
authored
Merge pull request #111 from restatedev/feat/trusted-ca-certs
feat: support trusted CA certificates in RestateCluster
2 parents a51286b + 836b356 commit c133a22

9 files changed

Lines changed: 298 additions & 11 deletions

File tree

AGENTS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ Instructions for AI coding agents working on this repository.
55
## Release Notes
66

77
When making changes, check whether the change warrants a release note by reviewing the guidelines in `release-notes/README.md`. If it does, create a release note file in `release-notes/unreleased/` as part of the same change.
8+
9+
## Trusted CA Certs Init Container
10+
11+
The trusted CA certs feature (`spec.security.trustedCaCerts`) uses an init container that reads the system CA bundle from `/etc/ssl/certs/ca-certificates.crt` (Debian/Alpine path). If the Restate server base image is changed to a different distro (e.g. RHEL uses `/etc/pki/tls/certs/ca-bundle.crt`), the `SYSTEM_CA_BUNDLE` constant in `src/controllers/restatecluster/reconcilers/compute.rs` must be updated.

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ kubectl delete pod -n restate-operator -l app=restate-operator
261261
- `image.pullPolicy` - Pull policy (default: `IfNotPresent`)
262262
- `awsPodIdentityAssociationCluster` - Enables EKS Pod Identity support
263263
- `gcpWorkloadIdentity` - Enables GCP Workload Identity via Config Connector
264-
- `canaryImage` - Container image for canary jobs (default: `busybox:uclibc`); must provide `grep` and `wget`
264+
- `canaryImage` - Container image for canary jobs and the trusted CA certs init container (default: `busybox:uclibc`); must provide `cat`, `grep` and `wget`
265265
- `operatorNamespace` - Namespace where operator runs
266266
- `operatorLabelName/Value` - Labels for network policy selectors
267267

README.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ This feature is particularly useful for Raft-based metadata clusters where manua
165165
| `awsPodIdentityAssociationRoleArn` | `string` | **Use this to grant your Restate cluster fine-grained access to other AWS resources (like S3) without managing static credentials.** Creates a `PodIdentityAssociation` to grant the cluster an IAM role. Requires the ACK EKS controller. |
166166
| `awsPodSecurityGroups` | `array` | **Use this to isolate your Restate cluster within specific AWS Security Groups for enhanced network control and auditing.** Creates a `SecurityGroupPolicy` to place pods into these security groups. Requires the Security Groups for Pods CRD. |
167167
| `requestSigningPrivateKey` | `object` | Configures a private key to sign outbound requests from this cluster. Can be sourced from a `secret` or a CSI `secretProvider`. See details below. |
168+
| `trustedCaCerts` | `array` | Optional list of Secrets containing trusted CA certificates. Each cert is appended to the system CA bundle via an init container. See details below. |
168169

169170
---
170171

@@ -193,6 +194,30 @@ This feature is particularly useful for Raft-based metadata clusters where manua
193194

194195
---
195196

197+
#### `spec.security.trustedCaCerts`
198+
199+
Use this to trust custom CA certificates (e.g. for calling SDK services behind an internal load balancer with a private certificate, or for object store access via a private CA) without building a custom Restate image.
200+
The operator adds an init container that concatenates the system CA bundle with your custom certificates, and sets `SSL_CERT_FILE` to point to the combined bundle.
201+
202+
Each entry references a Kubernetes Secret:
203+
204+
| Field | Type | Description |
205+
|---|---|---|
206+
| `secretName` | `string` | **Required**. Name of the Secret containing the CA certificate. |
207+
| `key` | `string` | **Required**. Key within the Secret that contains the PEM-encoded certificate. |
208+
209+
**Example:**
210+
211+
```yaml
212+
spec:
213+
security:
214+
trustedCaCerts:
215+
- secretName: internal-ca
216+
key: ca.pem
217+
```
218+
219+
---
220+
196221
#### `spec.config`
197222

198223
This field allows you to provide a TOML-encoded configuration string for the Restate server. This maps directly to the Restate server's configuration file. You can use this to configure aspects like roles, metadata storage, snapshotting, and more.
@@ -645,7 +670,8 @@ the `RestateCluster` spec.
645670
### Canary Image
646671

647672
Both EKS Pod Identity and GCP Workload Identity use a canary job to validate that credentials are available before
648-
starting the Restate cluster. By default, this uses the `busybox:uclibc` image from Docker Hub. In environments where
673+
starting the Restate cluster. The trusted CA certs feature also uses this image for its init container.
674+
By default, this uses the `busybox:uclibc` image from Docker Hub. In environments where
649675
nodes cannot pull from Docker Hub (e.g. air-gapped or restricted registries), you can override this with the
650676
`canaryImage` Helm value:
651677

@@ -661,7 +687,7 @@ docker tag busybox:uclibc my-private-registry.example.com/busybox:uclibc
661687
docker push my-private-registry.example.com/busybox:uclibc
662688
```
663689

664-
If using a different base image, it must provide `grep` and `wget`.
690+
If using a different base image, it must provide `cat`, `grep` and `wget`.
665691

666692
### EKS Security Groups for Pods
667693

charts/restate-operator-helm/values.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ podAnnotations: {}
1616
awsPodIdentityAssociationCluster: null
1717
gcpWorkloadIdentity: null
1818
clusterDns: null # defaults to "cluster.local" in the operator binary
19-
canaryImage: null # defaults to "busybox:uclibc"; image must provide grep and wget
19+
canaryImage: null # defaults to "busybox:uclibc"; image must provide cat, grep and wget
2020

2121
podSecurityContext:
2222
fsGroup: 2000

crd/RestateCluster.pkl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ class Security {
150150
/// Annotations to set on the ServiceAccount created for Restate
151151
serviceAccountAnnotations: Mapping<String, String>?
152152

153+
/// Optional list of Secrets containing trusted CA certificates.
154+
/// Each cert is appended to the system CA bundle via an init container.
155+
trustedCaCerts: Listing<TrustedCACert>?
156+
153157
/// Annotations to set on the Service created for Restate
154158
serviceAnnotations: Mapping<String, String>?
155159
}
@@ -202,6 +206,15 @@ class SecretProvider {
202206
provider: String?
203207
}
204208

209+
/// A reference to a Secret containing a trusted CA certificate.
210+
class TrustedCACert {
211+
/// Name of the Secret containing the CA certificate
212+
secretName: String
213+
214+
/// Key within the Secret that contains the PEM-encoded certificate
215+
key: String
216+
}
217+
205218
/// Storage configuration
206219
class Storage {
207220
/// storageClassName is the name of the StorageClass required by the claim. More info:

crd/restateclusters.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,24 @@ spec:
14701470
description: Annotations to set on the Service created for Restate
14711471
nullable: true
14721472
type: object
1473+
trustedCaCerts:
1474+
description: |-
1475+
Optional list of Secrets containing trusted CA certificates.
1476+
Each cert is appended to the system CA bundle via an init container.
1477+
items:
1478+
properties:
1479+
key:
1480+
description: Key within the Secret that contains the PEM-encoded certificate
1481+
type: string
1482+
secretName:
1483+
description: Name of the Secret containing the CA certificate
1484+
type: string
1485+
required:
1486+
- key
1487+
- secretName
1488+
type: object
1489+
nullable: true
1490+
type: array
14731491
type: object
14741492
storage:
14751493
description: Storage configuration
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## Trusted CA Certificates
2+
3+
You can now configure custom trusted CA certificates for RestateCluster via `spec.security.trustedCaCerts`.
4+
This is useful when Restate needs to trust internal CAs, for example when accessing an object store with a private certificate authority.
5+
6+
The operator adds an init container that concatenates the system CA bundle with your custom certificates into a single PEM file,
7+
and sets `SSL_CERT_FILE` on the Restate container to point to the combined bundle. Changing the Secret references (name or key) triggers a pod rollout.
8+
9+
```yaml
10+
spec:
11+
security:
12+
trustedCaCerts:
13+
- secretName: internal-ca
14+
key: ca.pem
15+
```

0 commit comments

Comments
 (0)