Skip to content

Enrich Receiver resourceFilter with OIDC claims#1313

Merged
matheuscscp merged 1 commit into
mainfrom
oidc-claims-filter
May 22, 2026
Merged

Enrich Receiver resourceFilter with OIDC claims#1313
matheuscscp merged 1 commit into
mainfrom
oidc-claims-filter

Conversation

@matheuscscp
Copy link
Copy Markdown
Member

Follow-up for #1306

In my setup I have a single Receiver per namespace. In one of them (flux-system) I have two use cases for Receiver:

  • An OCIRepository that is triggered by a GitHub Actions workflow in one repo
  • A ResourceSetInputProvider that is triggered by a GitHub Actions workflow in another repo

I want to allow each repo to trigger only the resources they need to trigger. They can't trigger resources they don't relate to.

Currently, to make the above possible, I have split the Receiver in two. Each Receiver has a strict OIDC validation that allows the repo to trigger only the respective resource it relates to.

If the OIDC claims were injected into the .spec.resourceFilter context, the CEL expression would be more powerful, allowing me to keep a single Receiver per namespace like before (when I was using generic-hmac).

Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
@matheuscscp matheuscscp requested a review from stefanprodan May 22, 2026 20:44
@matheuscscp matheuscscp added enhancement New feature or request area/receiver Webhook receiver related issues and PRs labels May 22, 2026
@matheuscscp matheuscscp changed the title Enrich Receiver resourceFilter with OIDC claims Enrich Receiver resourceFilter with OIDC claims May 22, 2026
@stefanprodan
Copy link
Copy Markdown
Member

Why not send a json payload with what resources you want reconciled same as GAR works. The JWT role would stick to authorization only.

@matheuscscp matheuscscp added the area/security Security related issues and pull requests label May 22, 2026
@matheuscscp
Copy link
Copy Markdown
Member Author

Because any repo (any client) can craft a payload to trigger the other object. This feature allows the restriction to be enforced on the server side. It's a security feature.

@matheuscscp
Copy link
Copy Markdown
Member Author

I'm filing a second PR on top of this one to introduce another feature that will simplify the setup even further, introducing even more authorization flexibility. See below, the setup after this PR, and then the setup after the second PR I'm currently working on (the second is much more powerful and readable).

After this PR:

apiVersion: notification.toolkit.fluxcd.io/v1
kind: Receiver
metadata:
  name: flux-webhook-receiver
  namespace: flux-system
spec:
  type: generic-oidc
  oidcProviders:
    - issuerURL: https://token.actions.githubusercontent.com
      validations:
        - expression: >-
            claims.job_workflow_ref.matches(r"^controlplaneio-fluxcd/d2-fleet/\.github/workflows/push-artifact\.yaml@<< inputs.artifactSubjectGitRef >>$")
            || claims.job_workflow_ref.matches(r"^controlplaneio-fluxcd/flux-appx/\.github/workflows/push-image\.yml@refs/(heads/main|pull/[0-9]+/merge)$")
          message: "token job_workflow_ref is not an allowed d2-fleet/flux-appx workflow"
  resourceFilter: >-
    (claims.repository == 'controlplaneio-fluxcd/d2-fleet' && res.kind == 'OCIRepository') ||
    (claims.repository == 'controlplaneio-fluxcd/flux-appx' && res.kind == 'ResourceSetInputProvider')
  resources:
    - apiVersion: source.toolkit.fluxcd.io/v1
      kind: OCIRepository
      name: flux-system
    - apiVersion: fluxcd.controlplane.io/v1
      kind: ResourceSetInputProvider
      name: '*'
      matchLabels:
        preview: "true"

After the second PR I'm working on:

apiVersion: notification.toolkit.fluxcd.io/v1
kind: Receiver
metadata:
  name: flux-webhook-receiver
  namespace: flux-system
spec:
  type: generic-oidc
  oidcProviders:
    - issuerURL: https://token.actions.githubusercontent.com
      validations:
        - expression: "claims.repository_owner == 'controlplaneio-fluxcd'"
          message: "token is not from the controlplaneio-fluxcd org"
  resources:
    - apiVersion: source.toolkit.fluxcd.io/v1
      kind: OCIRepository
      name: flux-system
      filter: 'claims.job_workflow_ref.matches(r"^controlplaneio-fluxcd/d2-fleet/\.github/workflows/push-artifact\.yaml@<< inputs.artifactSubjectGitRef >>$")'
    - apiVersion: fluxcd.controlplane.io/v1
      kind: ResourceSetInputProvider
      name: '*'
      matchLabels:
        preview: "true"
      filter: 'claims.job_workflow_ref.matches(r"^controlplaneio-fluxcd/flux-appx/\.github/workflows/push-image\.yml@refs/(heads/main|pull/[0-9]+/merge)$")'

@stefanprodan
Copy link
Copy Markdown
Member

The filter per resource kind looks great!

Copy link
Copy Markdown
Member

@stefanprodan stefanprodan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@matheuscscp matheuscscp merged commit 9627a3e into main May 22, 2026
8 checks passed
@matheuscscp matheuscscp deleted the oidc-claims-filter branch May 22, 2026 21:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/receiver Webhook receiver related issues and PRs area/security Security related issues and pull requests enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants