diff --git a/apis/ingress/v1/pomerium_types.go b/apis/ingress/v1/pomerium_types.go
index 9e8cc160..31e4d560 100644
--- a/apis/ingress/v1/pomerium_types.go
+++ b/apis/ingress/v1/pomerium_types.go
@@ -232,6 +232,10 @@ type PomeriumSpec struct {
// +optional
Certificates []string `json:"certificates"`
+ // CASecret should refer to k8s secrets with key ca.crt
containing a CA certificate.
+ // +optional
+ CASecrets []string `json:"caSecrets"`
+
// Secrets references a Secret with Pomerium bootstrap parameters.
//
//
diff --git a/apis/ingress/v1/zz_generated.deepcopy.go b/apis/ingress/v1/zz_generated.deepcopy.go
index bf346a66..a3f698e0 100644
--- a/apis/ingress/v1/zz_generated.deepcopy.go
+++ b/apis/ingress/v1/zz_generated.deepcopy.go
@@ -186,6 +186,11 @@ func (in *PomeriumSpec) DeepCopyInto(out *PomeriumSpec) {
*out = make([]string, len(*in))
copy(*out, *in)
}
+ if in.CASecrets != nil {
+ in, out := &in.CASecrets, &out.CASecrets
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
if in.Storage != nil {
in, out := &in.Storage, &out.Storage
*out = new(Storage)
diff --git a/config/crd/bases/ingress.pomerium.io_pomerium.yaml b/config/crd/bases/ingress.pomerium.io_pomerium.yaml
index 8ab6e121..08004c0b 100644
--- a/config/crd/bases/ingress.pomerium.io_pomerium.yaml
+++ b/config/crd/bases/ingress.pomerium.io_pomerium.yaml
@@ -63,6 +63,12 @@ spec:
required:
- url
type: object
+ caSecrets:
+ description: CASecret should refer to k8s secrets with key ca.crt
+ containing a CA certificate.
+ items:
+ type: string
+ type: array
certificates:
description: Certificates is a list of secrets of type TLS to use
format: namespace/name
diff --git a/controllers/settings/fetch.go b/controllers/settings/fetch.go
index b356c407..9a411112 100644
--- a/controllers/settings/fetch.go
+++ b/controllers/settings/fetch.go
@@ -101,6 +101,16 @@ func fetchConfigSecrets(ctx context.Context, client client.Client, cfg *model.Co
s := cfg.Spec
return applyAll(
apply("bootstrap secret", required(&s.Secrets), &cfg.Secrets),
+ func() error {
+ for _, caSecret := range s.CASecrets {
+ secret, err := get(caSecret)()
+ if err != nil {
+ return fmt.Errorf("ca: %w", err)
+ }
+ cfg.CASecrets = append(cfg.CASecrets, secret)
+ }
+ return nil
+ },
apply("secret", required(&s.IdentityProvider.Secret), &cfg.IdpSecret),
apply("request params", optional(s.IdentityProvider.RequestParamsSecret), &cfg.RequestParams),
apply("service account", optional(s.IdentityProvider.ServiceAccountFromSecret), &cfg.IdpServiceAccount),
diff --git a/deployment.yaml b/deployment.yaml
index f81f036e..c4d91f05 100644
--- a/deployment.yaml
+++ b/deployment.yaml
@@ -71,6 +71,12 @@ spec:
required:
- url
type: object
+ caSecrets:
+ description: CASecret should refer to k8s secrets with key ca.crt
+ containing a CA certificate.
+ items:
+ type: string
+ type: array
certificates:
description: Certificates is a list of secrets of type TLS to use
format: namespace/name
diff --git a/model/ingress_config.go b/model/ingress_config.go
index b33bb91a..dbacfe4a 100644
--- a/model/ingress_config.go
+++ b/model/ingress_config.go
@@ -80,6 +80,8 @@ type Config struct {
icsv1.Pomerium
// Secrets are key secrets
Secrets *corev1.Secret
+ // CASecrets are ca secrets
+ CASecrets []*corev1.Secret
// Certs are fetched certs from settings.Certificates
Certs map[types.NamespacedName]*corev1.Secret
// RequestParams is a secret from Settings.IdentityProvider.RequestParams
diff --git a/pomerium/config.go b/pomerium/config.go
index 7d9018ba..4fe5de32 100644
--- a/pomerium/config.go
+++ b/pomerium/config.go
@@ -1,10 +1,13 @@
package pomerium
import (
+ "bytes"
"context"
+ "encoding/base64"
"fmt"
"net/url"
+ "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/durationpb"
corev1 "k8s.io/api/core/v1"
@@ -28,6 +31,7 @@ func applyConfig(ctx context.Context, p *pb.Config, c *model.Config) error {
name string
fn func(context.Context, *pb.Config, *model.Config) error
}{
+ {"ca", applyCertificateAuthority},
{"certs", applyCerts},
{"authenticate", applyAuthenticate},
{"idp", applyIDP},
@@ -79,6 +83,22 @@ func applyCookie(_ context.Context, p *pb.Config, c *model.Config) error {
return nil
}
+func applyCertificateAuthority(ctx context.Context, p *pb.Config, c *model.Config) error {
+ if len(c.CASecrets) == 0 {
+ return nil
+ }
+
+ var buf bytes.Buffer
+
+ for _, secret := range c.CASecrets {
+ buf.Write(secret.Data[model.CAKey])
+ buf.WriteRune('\n')
+ }
+
+ p.Settings.CertificateAuthority = proto.String(base64.StdEncoding.EncodeToString(buf.Bytes()))
+ return nil
+}
+
func applyCerts(_ context.Context, p *pb.Config, c *model.Config) error {
if len(c.Certs) != len(c.Spec.Certificates) {
return fmt.Errorf("expected %d cert secrets, only %d was fetched. this is a bug", len(c.Spec.Certificates), len(c.Certs))
diff --git a/pomerium/ctrl/run.go b/pomerium/ctrl/run.go
index 3e99cfaf..758971cb 100644
--- a/pomerium/ctrl/run.go
+++ b/pomerium/ctrl/run.go
@@ -14,9 +14,7 @@ import (
"github.com/pomerium/ingress-controller/pomerium"
)
-var (
- _ = pomerium.ConfigReconciler(new(Runner))
-)
+var _ = pomerium.ConfigReconciler(new(Runner))
// Runner implements pomerium control loop
type Runner struct {