From c601a212f64dd08994e02f37b916b3672fb97745 Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Fri, 10 Apr 2026 12:34:26 +0300 Subject: [PATCH] Add `--audience-claim` for GCR Receivers Signed-off-by: Stefan Prodan --- cmd/flux/create_secret_receiver.go | 25 +++++++++++-------- cmd/flux/create_secret_receiver_test.go | 5 ++++ .../secret-receiver-gcr-audience.yaml | 13 ++++++++++ pkg/manifestgen/sourcesecret/options.go | 9 ++++--- pkg/manifestgen/sourcesecret/sourcesecret.go | 6 ++++- 5 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 cmd/flux/testdata/create_secret/receiver/secret-receiver-gcr-audience.yaml diff --git a/cmd/flux/create_secret_receiver.go b/cmd/flux/create_secret_receiver.go index 27861231..50eafbea 100644 --- a/cmd/flux/create_secret_receiver.go +++ b/cmd/flux/create_secret_receiver.go @@ -55,10 +55,11 @@ computed webhook URL.`, } type secretReceiverFlags struct { - receiverType flags.ReceiverType - token string - hostname string - emailClaim string + receiverType flags.ReceiverType + token string + hostname string + emailClaim string + audienceClaim string } var secretReceiverArgs secretReceiverFlags @@ -68,6 +69,7 @@ func init() { createSecretReceiverCmd.Flags().StringVar(&secretReceiverArgs.token, "token", "", "webhook token used for payload validation and URL computation, auto-generated if not specified") createSecretReceiverCmd.Flags().StringVar(&secretReceiverArgs.hostname, "hostname", "", "hostname for the webhook URL e.g. flux.example.com") createSecretReceiverCmd.Flags().StringVar(&secretReceiverArgs.emailClaim, "email-claim", "", "IAM service account email, required for gcr type") + createSecretReceiverCmd.Flags().StringVar(&secretReceiverArgs.audienceClaim, "audience-claim", "", "custom OIDC token audience for gcr type, defaults to the webhook URL") createSecretCmd.AddCommand(createSecretReceiverCmd) } @@ -93,13 +95,14 @@ func createSecretReceiverCmdRun(cmd *cobra.Command, args []string) error { } opts := sourcesecret.Options{ - Name: name, - Namespace: *kubeconfigArgs.Namespace, - Labels: labels, - ReceiverType: secretReceiverArgs.receiverType.String(), - Token: secretReceiverArgs.token, - Hostname: secretReceiverArgs.hostname, - EmailClaim: secretReceiverArgs.emailClaim, + Name: name, + Namespace: *kubeconfigArgs.Namespace, + Labels: labels, + ReceiverType: secretReceiverArgs.receiverType.String(), + Token: secretReceiverArgs.token, + Hostname: secretReceiverArgs.hostname, + EmailClaim: secretReceiverArgs.emailClaim, + AudienceClaim: secretReceiverArgs.audienceClaim, } secret, err := sourcesecret.GenerateReceiver(opts) diff --git a/cmd/flux/create_secret_receiver_test.go b/cmd/flux/create_secret_receiver_test.go index 8d38cbb2..383f2371 100644 --- a/cmd/flux/create_secret_receiver_test.go +++ b/cmd/flux/create_secret_receiver_test.go @@ -56,6 +56,11 @@ func TestCreateReceiverSecret(t *testing.T) { args: "create secret receiver gcr-secret --type=gcr --token=test-token --hostname=flux.example.com --email-claim=sa@project.iam.gserviceaccount.com --namespace=my-namespace --export", assert: assertGoldenFile("testdata/create_secret/receiver/secret-receiver-gcr.yaml"), }, + { + name: "gcr receiver secret with custom audience", + args: "create secret receiver gcr-secret --type=gcr --token=test-token --hostname=flux.example.com --email-claim=sa@project.iam.gserviceaccount.com --audience-claim=https://custom.audience.example.com --namespace=my-namespace --export", + assert: assertGoldenFile("testdata/create_secret/receiver/secret-receiver-gcr-audience.yaml"), + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/cmd/flux/testdata/create_secret/receiver/secret-receiver-gcr-audience.yaml b/cmd/flux/testdata/create_secret/receiver/secret-receiver-gcr-audience.yaml new file mode 100644 index 00000000..9e52a56b --- /dev/null +++ b/cmd/flux/testdata/create_secret/receiver/secret-receiver-gcr-audience.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + annotations: + notification.toolkit.fluxcd.io/webhook: https://flux.example.com/hook/6d6c55e9affb9d1e0d101ce604ae4270880ec1ff24d1bd2d928fcd64243d21a4 + name: gcr-secret + namespace: my-namespace +stringData: + audience: https://custom.audience.example.com + email: sa@project.iam.gserviceaccount.com + token: test-token + diff --git a/pkg/manifestgen/sourcesecret/options.go b/pkg/manifestgen/sourcesecret/options.go index 09f47c11..9fe7b49d 100644 --- a/pkg/manifestgen/sourcesecret/options.go +++ b/pkg/manifestgen/sourcesecret/options.go @@ -90,10 +90,11 @@ type Options struct { GitHubAppBaseURL string // Receiver options - ReceiverType string - Token string - Hostname string - EmailClaim string + ReceiverType string + Token string + Hostname string + EmailClaim string + AudienceClaim string } type VerificationCrt struct { diff --git a/pkg/manifestgen/sourcesecret/sourcesecret.go b/pkg/manifestgen/sourcesecret/sourcesecret.go index 8b8fc946..54cca4e8 100644 --- a/pkg/manifestgen/sourcesecret/sourcesecret.go +++ b/pkg/manifestgen/sourcesecret/sourcesecret.go @@ -306,7 +306,11 @@ func GenerateReceiver(options Options) (*manifestgen.Manifest, error) { return nil, fmt.Errorf("email-claim is required for gcr receiver type") } secret.StringData[EmailSecretKey] = options.EmailClaim - secret.StringData[AudienceSecretKey] = webhookURL + if options.AudienceClaim != "" { + secret.StringData[AudienceSecretKey] = options.AudienceClaim + } else { + secret.StringData[AudienceSecretKey] = webhookURL + } } return secretToManifest(secret, options)