From f820540c0def45a09f263d2307ec2f3f0075c211 Mon Sep 17 00:00:00 2001
From: Caleb Doxsey <cdoxsey@pomerium.com>
Date: Tue, 18 Feb 2025 12:02:06 -0700
Subject: [PATCH 1/3] add bearer_token_format and
 idp_access_token_allowed_audiences

---
 apis/ingress/v1/pomerium_types.go             | 11 ++++
 apis/ingress/v1/zz_generated.deepcopy.go      | 14 ++++
 .../bases/ingress.pomerium.io_pomerium.yaml   | 16 +++++
 deployment.yaml                               | 16 +++++
 go.mod                                        |  2 +-
 go.sum                                        |  4 +-
 pomerium/config.go                            | 23 +++++++
 pomerium/ingress_annotations.go               |  2 +
 pomerium/ingress_annotations_test.go          | 13 ++--
 pomerium/proto.go                             | 18 ++++++
 reference.md                                  | 64 +++++++++++++------
 11 files changed, 156 insertions(+), 27 deletions(-)

diff --git a/apis/ingress/v1/pomerium_types.go b/apis/ingress/v1/pomerium_types.go
index 41ea622f..055670af 100644
--- a/apis/ingress/v1/pomerium_types.go
+++ b/apis/ingress/v1/pomerium_types.go
@@ -289,6 +289,17 @@ type PomeriumSpec struct {
 	// +kubebuilder:validation:Optional
 	// +kubebuilder:validation:Enum=auto;http1;http2;http3
 	CodecType *string `json:"codecType,omitempty"`
+
+	// BearerTokenFormat sets the <a href="https://www.pomerium.com/docs/reference/bearer-token-format">Bearer Token Format</a>.
+	//
+	// +kubebuilder:validation:Optional
+	// +kubebuilder:validation:Enum=default;idp_access_token;idp_identity_token
+	BearerTokenFormat *string `json:"bearerTokenFormat,omitempty"`
+
+	// IDPAccessTokenAllowedAudiences specifies the
+	// <a href="https://www.pomerium.com/docs/reference/idp-access-token-allowed-audiences">idp access token allowed audiences</a>
+	// list.
+	IDPAccessTokenAllowedAudiences *[]string `json:"idpAccessTokenAllowedAudiences,omitempty"`
 }
 
 // Timeouts allows to configure global timeouts for all routes.
diff --git a/apis/ingress/v1/zz_generated.deepcopy.go b/apis/ingress/v1/zz_generated.deepcopy.go
index 828fdaae..2b08f788 100644
--- a/apis/ingress/v1/zz_generated.deepcopy.go
+++ b/apis/ingress/v1/zz_generated.deepcopy.go
@@ -272,6 +272,20 @@ func (in *PomeriumSpec) DeepCopyInto(out *PomeriumSpec) {
 		*out = new(string)
 		**out = **in
 	}
+	if in.BearerTokenFormat != nil {
+		in, out := &in.BearerTokenFormat, &out.BearerTokenFormat
+		*out = new(string)
+		**out = **in
+	}
+	if in.IDPAccessTokenAllowedAudiences != nil {
+		in, out := &in.IDPAccessTokenAllowedAudiences, &out.IDPAccessTokenAllowedAudiences
+		*out = new([]string)
+		if **in != nil {
+			in, out := *in, *out
+			*out = make([]string, len(*in))
+			copy(*out, *in)
+		}
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PomeriumSpec.
diff --git a/config/crd/bases/ingress.pomerium.io_pomerium.yaml b/config/crd/bases/ingress.pomerium.io_pomerium.yaml
index fb9c6da2..4232b721 100644
--- a/config/crd/bases/ingress.pomerium.io_pomerium.yaml
+++ b/config/crd/bases/ingress.pomerium.io_pomerium.yaml
@@ -83,6 +83,14 @@ spec:
                 items:
                   type: string
                 type: array
+              bearerTokenFormat:
+                description: BearerTokenFormat sets the <a href="https://www.pomerium.com/docs/reference/bearer-token-format">Bearer
+                  Token Format</a>.
+                enum:
+                - default
+                - idp_access_token
+                - idp_identity_token
+                type: string
               caSecrets:
                 description: CASecret should refer to k8s secrets with key <code>ca.crt</code>
                   containing a CA certificate.
@@ -222,6 +230,14 @@ spec:
                 - provider
                 - secret
                 type: object
+              idpAccessTokenAllowedAudiences:
+                description: |-
+                  IDPAccessTokenAllowedAudiences specifies the
+                  <a href="https://www.pomerium.com/docs/reference/idp-access-token-allowed-audiences">idp access token allowed audiences</a>
+                  list.
+                items:
+                  type: string
+                type: array
               jwtClaimHeaders:
                 additionalProperties:
                   type: string
diff --git a/deployment.yaml b/deployment.yaml
index f3d99d22..615273f3 100644
--- a/deployment.yaml
+++ b/deployment.yaml
@@ -225,6 +225,14 @@ spec:
                 items:
                   type: string
                 type: array
+              bearerTokenFormat:
+                description: BearerTokenFormat sets the <a href="https://www.pomerium.com/docs/reference/bearer-token-format">Bearer
+                  Token Format</a>.
+                enum:
+                - default
+                - idp_access_token
+                - idp_identity_token
+                type: string
               caSecrets:
                 description: CASecret should refer to k8s secrets with key <code>ca.crt</code>
                   containing a CA certificate.
@@ -364,6 +372,14 @@ spec:
                 - provider
                 - secret
                 type: object
+              idpAccessTokenAllowedAudiences:
+                description: |-
+                  IDPAccessTokenAllowedAudiences specifies the
+                  <a href="https://www.pomerium.com/docs/reference/idp-access-token-allowed-audiences">idp access token allowed audiences</a>
+                  list.
+                items:
+                  type: string
+                type: array
               jwtClaimHeaders:
                 additionalProperties:
                   type: string
diff --git a/go.mod b/go.mod
index 2f9499e2..af80fc92 100644
--- a/go.mod
+++ b/go.mod
@@ -18,7 +18,7 @@ require (
 	github.com/martinlindhe/base36 v1.1.1
 	github.com/open-policy-agent/opa v1.1.0
 	github.com/pomerium/csrf v1.7.0
-	github.com/pomerium/pomerium v0.28.1-0.20250204182906-81a52db74940
+	github.com/pomerium/pomerium v0.28.1-0.20250218154031-3f5a0416cd8c
 	github.com/rs/zerolog v1.33.0
 	github.com/sergi/go-diff v1.3.1
 	github.com/spf13/cobra v1.8.1
diff --git a/go.sum b/go.sum
index 57625db9..6e5ddae4 100644
--- a/go.sum
+++ b/go.sum
@@ -541,8 +541,8 @@ github.com/pomerium/datasource v0.18.2-0.20221108160055-c6134b5ed524 h1:3YQY1sb5
 github.com/pomerium/datasource v0.18.2-0.20221108160055-c6134b5ed524/go.mod h1:7fGbUYJnU8RcxZJvUvhukOIBv1G7LWDAHMfDxAf5+Y0=
 github.com/pomerium/envoy-custom v1.32.4-0.20250114182541-6f6d2147bea6 h1:QLVgpx23jcbgR9qJzIicJ+uXGjQXO0GAy55SCo0Jd9o=
 github.com/pomerium/envoy-custom v1.32.4-0.20250114182541-6f6d2147bea6/go.mod h1:afbaKE6YfshVUOrYc6XWUWfZcXencWmi1jTc00ki0Oo=
-github.com/pomerium/pomerium v0.28.1-0.20250204182906-81a52db74940 h1:Gi6ZFj2KUoI71thjzNKH4y13ip4LPLjABTQN+33P9IY=
-github.com/pomerium/pomerium v0.28.1-0.20250204182906-81a52db74940/go.mod h1:8Uf1ya/wSjJyeUo5X4TqctlrYxbc5iPfFG18x1t0Deo=
+github.com/pomerium/pomerium v0.28.1-0.20250218154031-3f5a0416cd8c h1:OGo6R2u98pDiX2WKLNfpVfbPjECFRH0wd4/mAsXPwLI=
+github.com/pomerium/pomerium v0.28.1-0.20250218154031-3f5a0416cd8c/go.mod h1:8Uf1ya/wSjJyeUo5X4TqctlrYxbc5iPfFG18x1t0Deo=
 github.com/pomerium/protoutil v0.0.0-20240813175624-47b7ac43ff46 h1:NRTg8JOXCxcIA1lAgD74iYud0rbshbWOB3Ou4+Huil8=
 github.com/pomerium/protoutil v0.0.0-20240813175624-47b7ac43ff46/go.mod h1:QqZmx6ZgPxz18va7kqoT4t/0yJtP7YFIDiT/W2n2fZ4=
 github.com/pomerium/webauthn v0.0.0-20240603205124-0428df511172 h1:TqoPqRgXSHpn+tEJq6H72iCS5pv66j3rPprThUEZg0E=
diff --git a/pomerium/config.go b/pomerium/config.go
index 96eada04..22aee54f 100644
--- a/pomerium/config.go
+++ b/pomerium/config.go
@@ -132,6 +132,29 @@ func applySetOtherOptions(_ context.Context, p *pb.Config, c *model.Config) erro
 	} else {
 		p.Settings.PassIdentityHeaders = nil
 	}
+	if c.Spec.BearerTokenFormat != nil {
+		switch *c.Spec.BearerTokenFormat {
+		case "":
+			p.Settings.BearerTokenFormat = pb.BearerTokenFormat_BEARER_TOKEN_FORMAT_UNKNOWN.Enum()
+		case "default":
+			p.Settings.BearerTokenFormat = pb.BearerTokenFormat_BEARER_TOKEN_FORMAT_DEFAULT.Enum()
+		case "idp_access_token":
+			p.Settings.BearerTokenFormat = pb.BearerTokenFormat_BEARER_TOKEN_FORMAT_IDP_ACCESS_TOKEN.Enum()
+		case "idp_identity_token":
+			p.Settings.BearerTokenFormat = pb.BearerTokenFormat_BEARER_TOKEN_FORMAT_IDP_IDENTITY_TOKEN.Enum()
+		default:
+			return fmt.Errorf("unknown bearerTokenFormat %s", *c.Spec.BearerTokenFormat)
+		}
+	} else {
+		p.Settings.BearerTokenFormat = nil
+	}
+	if c.Spec.IDPAccessTokenAllowedAudiences != nil {
+		p.Settings.IdpAccessTokenAllowedAudiences = &pb.Settings_StringList{
+			Values: *c.Spec.IDPAccessTokenAllowedAudiences,
+		}
+	} else {
+		p.Settings.IdpAccessTokenAllowedAudiences = nil
+	}
 	return nil
 }
 
diff --git a/pomerium/ingress_annotations.go b/pomerium/ingress_annotations.go
index ecf87bf2..90812175 100644
--- a/pomerium/ingress_annotations.go
+++ b/pomerium/ingress_annotations.go
@@ -24,6 +24,7 @@ var (
 		"allow_public_unauthenticated_access",
 		"allow_spdy",
 		"allow_websockets",
+		"bearer_token_format",
 		"cors_allow_preflight",
 		"description",
 		"host_path_regex_rewrite_pattern",
@@ -31,6 +32,7 @@ var (
 		"host_rewrite_header",
 		"host_rewrite",
 		"idle_timeout",
+		"idp_access_token_allowed_audiences",
 		"logo_url",
 		"pass_identity_headers",
 		"prefix_rewrite",
diff --git a/pomerium/ingress_annotations_test.go b/pomerium/ingress_annotations_test.go
index 11d52313..b1b3a0e4 100644
--- a/pomerium/ingress_annotations_test.go
+++ b/pomerium/ingress_annotations_test.go
@@ -45,6 +45,7 @@ func TestAnnotations(t *testing.T) {
 					"a/allowed_domains":                         `["a"]`,
 					"a/allowed_idp_claims":                      `key: ["val1", "val2"]`,
 					"a/allowed_users":                           `["a"]`,
+					"a/bearer_token_format":                     `idp_access_token`,
 					"a/cors_allow_preflight":                    "true",
 					"a/description":                             "DESCRIPTION",
 					"a/health_checks":                           `[{"timeout": "10s", "interval": "1m", "healthy_threshold": 1, "unhealthy_threshold": 2, "http_health_check": {"path": "/"}}]`,
@@ -53,6 +54,7 @@ func TestAnnotations(t *testing.T) {
 					"a/host_rewrite_header":                     "rewrite-header",
 					"a/host_rewrite":                            "rewrite",
 					"a/idle_timeout":                            `60s`,
+					"a/idp_access_token_allowed_audiences":      `["x","y","z"]`,
 					"a/kubernetes_service_account_token_secret": "k8s_token",
 					"a/lb_policy":                               "LEAST_REQUEST",
 					"a/logo_url":                                "LOGO_URL",
@@ -191,12 +193,15 @@ func TestAnnotations(t *testing.T) {
 			},
 			SourcePpl: proto.String(`{"allow":{"or":[{"domain":{"is":"pomerium.com"}}]}}`),
 		}},
-		TlsSkipVerify: true,
-		TlsServerName: "my.server.name",
-		Description:   "DESCRIPTION",
-		LogoUrl:       "LOGO_URL",
+		TlsSkipVerify:                  true,
+		TlsServerName:                  "my.server.name",
+		Description:                    "DESCRIPTION",
+		LogoUrl:                        "LOGO_URL",
+		BearerTokenFormat:              pb.BearerTokenFormat_BEARER_TOKEN_FORMAT_IDP_ACCESS_TOKEN.Enum(),
+		IdpAccessTokenAllowedAudiences: &pb.Route_StringList{Values: []string{"x", "y", "z"}},
 	}, cmpopts.IgnoreUnexported(
 		pb.Route{},
+		pb.Route_StringList{},
 		pb.RouteRewriteHeader{},
 		pb.Policy{},
 		structpb.ListValue{},
diff --git a/pomerium/proto.go b/pomerium/proto.go
index 433ac43a..0b07f491 100644
--- a/pomerium/proto.go
+++ b/pomerium/proto.go
@@ -43,6 +43,10 @@ func preprocessAnnotationMessage(md protoreflect.MessageDescriptor, data any) an
 		if v, ok := data.(string); ok {
 			return goDurationStringToProtoJSONDurationString(v)
 		}
+	case "pomerium.config.Route.StringList":
+		if v, ok := data.([]any); ok {
+			return map[string]any{"values": v}
+		}
 	default:
 		// preprocess all the fields
 		if v, ok := data.(map[string]any); ok {
@@ -62,6 +66,20 @@ func preprocessAnnotationMessage(md protoreflect.MessageDescriptor, data any) an
 }
 
 func preprocessAnnotationField(fd protoreflect.FieldDescriptor, data any) any {
+	if fd.Enum() != nil && fd.Enum().FullName() == "pomerium.config.BearerTokenFormat" {
+		if v, ok := data.(string); ok {
+			switch v {
+			case "":
+				return "BEARER_TOKEN_FORMAT_UNKNOWN"
+			case "default":
+				return "BEARER_TOKEN_FORMAT_DEFAULT"
+			case "idp_access_token":
+				return "BEARER_TOKEN_FORMAT_IDP_ACCESS_TOKEN"
+			case "idp_identity_token":
+				return "BEARER_TOKEN_FORMAT_IDP_IDENTITY_TOKEN"
+			}
+		}
+	}
 	// if this is a repeated field, handle each of the field values separately
 	if fd.IsList() {
 		vs, ok := data.([]any)
diff --git a/reference.md b/reference.md
index b79416d2..292156f7 100644
--- a/reference.md
+++ b/reference.md
@@ -8,6 +8,7 @@ Pomerium-specific parameters should be configured via the `ingress.pomerium.io/P
 The default Pomerium deployment is listening to the CRD `global`, that may be customized via command line parameters.
 
 Pomerium posts updates to the CRD <a href="#status">`/status`</a>:
+
 ```shell
 kubectl describe pomerium
 ```
@@ -72,6 +73,22 @@ PomeriumSpec defines Pomerium-specific configuration parameters.
             </td>
         </tr>
 
+        <tr>
+            <td>
+                <p>
+                <code>bearerTokenFormat</code>&#160;&#160;
+
+                    <strong>string</strong>&#160;
+
+                </p>
+                <p>
+
+                    BearerTokenFormat sets the <a href="https://www.pomerium.com/docs/reference/bearer-token-format">Bearer Token Format</a>.
+                </p>
+
+            </td>
+        </tr>
+
         <tr>
             <td>
                 <p>
@@ -157,6 +174,22 @@ PomeriumSpec defines Pomerium-specific configuration parameters.
             </td>
         </tr>
 
+        <tr>
+            <td>
+                <p>
+                <code>idpAccessTokenAllowedAudiences</code>&#160;&#160;
+
+                    <strong>[]string</strong>&#160;
+
+                </p>
+                <p>
+
+                    IDPAccessTokenAllowedAudiences specifies the <a href="https://www.pomerium.com/docs/reference/idp-access-token-allowed-audiences">idp access token allowed audiences</a> list.
+                </p>
+
+            </td>
+        </tr>
+
         <tr>
             <td>
                 <p>
@@ -307,9 +340,8 @@ PomeriumSpec defines Pomerium-specific configuration parameters.
         </tr>
 
     </tbody>
-</table>
-
 
+</table>
 
 ### `authenticate`
 
@@ -356,9 +388,8 @@ Authenticate sets authenticate service parameters. If not specified, a Pomerium-
         </tr>
 
     </tbody>
-</table>
-
 
+</table>
 
 ### `cookie`
 
@@ -453,9 +484,8 @@ Cookie defines Pomerium session cookie options.
         </tr>
 
     </tbody>
-</table>
-
 
+</table>
 
 ### `identityProvider`
 
@@ -605,9 +635,8 @@ IdentityProvider configure single-sign-on authentication and user identity detai
         </tr>
 
     </tbody>
-</table>
-
 
+</table>
 
 ### `postgres`
 
@@ -676,9 +705,8 @@ Postgres specifies PostgreSQL database connection parameters
         </tr>
 
     </tbody>
-</table>
-
 
+</table>
 
 ### `refreshDirectory`
 
@@ -728,9 +756,8 @@ RefreshDirectory is no longer supported, please see <a href="https://docs.pomeri
         </tr>
 
     </tbody>
-</table>
-
 
+</table>
 
 ### `storage`
 
@@ -759,9 +786,8 @@ Storage defines persistent storage for sessions and other data. See <a href="htt
         </tr>
 
     </tbody>
-</table>
-
 
+</table>
 
 ### `timeouts`
 
@@ -830,9 +856,8 @@ Timeout specifies the <a href="https://www.pomerium.com/docs/reference/global-ti
         </tr>
 
     </tbody>
-</table>
-
 
+</table>
 
 ## Status
 
@@ -878,9 +903,8 @@ PomeriumStatus represents configuration and Ingress status.
         </tr>
 
     </tbody>
-</table>
-
 
+</table>
 
 ### `ingress`
 
@@ -975,9 +999,8 @@ ResourceStatus represents the outcome of the latest attempt to reconcile relevan
         </tr>
 
     </tbody>
-</table>
-
 
+</table>
 
 ### `settingsStatus`
 
@@ -1072,4 +1095,5 @@ SettingsStatus represent most recent main configuration reconciliation status.
         </tr>
 
     </tbody>
+
 </table>

From 0b0fe68f1c00fb52e6218d0d63c0577f18c3b503 Mon Sep 17 00:00:00 2001
From: Caleb Doxsey <cdoxsey@pomerium.com>
Date: Tue, 18 Feb 2025 13:05:40 -0700
Subject: [PATCH 2/3] use main commit

---
 go.mod | 2 +-
 go.sum | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/go.mod b/go.mod
index af80fc92..0aeec933 100644
--- a/go.mod
+++ b/go.mod
@@ -18,7 +18,7 @@ require (
 	github.com/martinlindhe/base36 v1.1.1
 	github.com/open-policy-agent/opa v1.1.0
 	github.com/pomerium/csrf v1.7.0
-	github.com/pomerium/pomerium v0.28.1-0.20250218154031-3f5a0416cd8c
+	github.com/pomerium/pomerium v0.28.1-0.20250218200206-b9fd926618e2
 	github.com/rs/zerolog v1.33.0
 	github.com/sergi/go-diff v1.3.1
 	github.com/spf13/cobra v1.8.1
diff --git a/go.sum b/go.sum
index 6e5ddae4..4eb9bd02 100644
--- a/go.sum
+++ b/go.sum
@@ -541,8 +541,8 @@ github.com/pomerium/datasource v0.18.2-0.20221108160055-c6134b5ed524 h1:3YQY1sb5
 github.com/pomerium/datasource v0.18.2-0.20221108160055-c6134b5ed524/go.mod h1:7fGbUYJnU8RcxZJvUvhukOIBv1G7LWDAHMfDxAf5+Y0=
 github.com/pomerium/envoy-custom v1.32.4-0.20250114182541-6f6d2147bea6 h1:QLVgpx23jcbgR9qJzIicJ+uXGjQXO0GAy55SCo0Jd9o=
 github.com/pomerium/envoy-custom v1.32.4-0.20250114182541-6f6d2147bea6/go.mod h1:afbaKE6YfshVUOrYc6XWUWfZcXencWmi1jTc00ki0Oo=
-github.com/pomerium/pomerium v0.28.1-0.20250218154031-3f5a0416cd8c h1:OGo6R2u98pDiX2WKLNfpVfbPjECFRH0wd4/mAsXPwLI=
-github.com/pomerium/pomerium v0.28.1-0.20250218154031-3f5a0416cd8c/go.mod h1:8Uf1ya/wSjJyeUo5X4TqctlrYxbc5iPfFG18x1t0Deo=
+github.com/pomerium/pomerium v0.28.1-0.20250218200206-b9fd926618e2 h1:UtyGKmmFs/DVuvhOUeFowruCv+xObqAbqNmPqhMZ88o=
+github.com/pomerium/pomerium v0.28.1-0.20250218200206-b9fd926618e2/go.mod h1:8Uf1ya/wSjJyeUo5X4TqctlrYxbc5iPfFG18x1t0Deo=
 github.com/pomerium/protoutil v0.0.0-20240813175624-47b7ac43ff46 h1:NRTg8JOXCxcIA1lAgD74iYud0rbshbWOB3Ou4+Huil8=
 github.com/pomerium/protoutil v0.0.0-20240813175624-47b7ac43ff46/go.mod h1:QqZmx6ZgPxz18va7kqoT4t/0yJtP7YFIDiT/W2n2fZ4=
 github.com/pomerium/webauthn v0.0.0-20240603205124-0428df511172 h1:TqoPqRgXSHpn+tEJq6H72iCS5pv66j3rPprThUEZg0E=

From 913a75ee8a0b8a947a897d1bf70de1029c28e692 Mon Sep 17 00:00:00 2001
From: Caleb Doxsey <cdoxsey@pomerium.com>
Date: Tue, 18 Feb 2025 13:27:47 -0700
Subject: [PATCH 3/3] fix bootstrap failing

---
 config/gen_secrets/role.yaml | 1 +
 deployment.yaml              | 1 +
 2 files changed, 2 insertions(+)

diff --git a/config/gen_secrets/role.yaml b/config/gen_secrets/role.yaml
index a3b5784b..70213663 100644
--- a/config/gen_secrets/role.yaml
+++ b/config/gen_secrets/role.yaml
@@ -10,3 +10,4 @@ rules:
       - secrets
     verbs:
       - create
+      - get
diff --git a/deployment.yaml b/deployment.yaml
index 615273f3..fc9e5f09 100644
--- a/deployment.yaml
+++ b/deployment.yaml
@@ -671,6 +671,7 @@ rules:
   - secrets
   verbs:
   - create
+  - get
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding