Guide to creating an Argo Events webhook Sensor that triggers Argo Workflows or Kubernetes objects and explains RBAC service account setup and troubleshooting
In this lesson you’ll create an Argo Events Sensor that listens to a webhook EventSource and triggers an Argo Workflow. Sensors can trigger many target resources — for example Argo Workflows, AWS Lambda, HTTP endpoints, or generic Kubernetes objects. If a built-in trigger doesn’t meet your needs, Argo Events provides extension points to implement a custom trigger.
High-level flow: the EventSource receives an incoming webhook request, publishes an event to the EventBus, and a Sensor subscribed to that EventBus evaluates dependencies and, when satisfied, executes the configured trigger(s). Below is the “trigger a workflow” diagram for reference.
A Sensor lists one or more dependencies. Each dependency references an EventSource by name and a named event defined in that EventSource (the event name).
When a dependency is satisfied (an event is published), the Sensor evaluates any dependency expressions (if configured) and then executes the configured trigger(s).
Example dependency referencing the EventSource named webhook and the event my-webhook:
EventSource names and event names are defined in your EventSource manifest. Use eventSourceName to reference the EventSource metadata.name and eventName to reference the specific event key under spec.
How to find the eventSourceName and eventName
The EventSource resource contains the top-level name (EventSource metadata.name) and under its spec you will see one or more events (each with its own name). Example (abridged):
In the Sensor dependency above, use eventSourceName: webhook and eventName: my-webhook. The Sensor will only react when that specific event is emitted.
Below is a Sensor trigger configured to submit an Argo Workflow when the dependency matches. The trigger uses the argoWorkflow trigger type and embeds the Workflow manifest as the resource.
Prepare to send an event to the webhook EventSource
Confirm the EventSource service exists in the argo-events namespace and get its service name and port.
Port-forward the EventSource service to localhost so you can POST to it.
Example commands:
Copy
# List services in argo-eventskubectl -n argo-events get svc# Example service you should see:# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE# Port-forward the webhook EventSource service to localhost:13000kubectl port-forward -n argo-events svc/webhook-eventsource-svc 13000:13000
namespace=argo-events, eventSourceName=webhook, eventName=my-webhook, level=info, msg="route is activated"namespace=argo-events, eventSourceName=webhook, eventName=my-webhook, level=info, msg="a request received, processing it..."namespace=argo-events, eventSourceName=webhook, eventName=my-webhook, level=info, msg="Succeeded to publish an event"namespace=argo-events, eventSourceName=webhook, eventName=my-webhook, level=info, msg="successfully dispatched the request to the event bus"
Sensor logs (abridged):
Copy
namespace=argo-events, sensorName=webhook-sensor, level=info, msg="Sensor started."namespace=argo-events, sensorName=webhook-sensor, level=info, msg="Dependency expression for trigger hello-workflow-trigger: my-webhook-dep"namespace=argo-events, sensorName=webhook-sensor, level=info, msg="Connected to NATS server."namespace=argo-events, sensorName=webhook-sensor, level=error, msg="Create request failed" error="workflows.argoproj.io is forbidden: User \"system:serviceaccount:argo-events:default\" cannot create resource \"workflows\" in API group \"argoproj.io\" in the namespace \"argo\""namespace=argo-events, sensorName=webhook-sensor, level=info, msg="Error: Failed to submit workflow: rpc error: code = PermissionDenied desc = workflows.argoproj.io is forbidden: User \"system:serviceaccount:argo-events:default\" cannot create resource \"workflows\" in the namespace \"argo\""
The Sensor attempted to create an Argo Workflow in the argo namespace, but the service account used by the Sensor (system:serviceaccount:argo-events:default in this example) does not have RBAC permissions to create workflows.argoproj.io in the argo namespace. This caused the PermissionDenied error in the Sensor logs.
Ensure the service account configured for the Sensor (via spec.template.serviceAccountName or in the Sensor controller pod) has appropriate RBAC permissions to create the target resources (Argo Workflows or Kubernetes objects) in the target namespace.
Create or select a service account that has a Role or ClusterRole with permissions to create/submit the target resource (e.g., workflows.argoproj.io) in the target namespace.
Create a RoleBinding or ClusterRoleBinding that binds the Role/ClusterRole to the service account.
Configure your Sensor to use that service account, for example via spec.template.serviceAccountName: <name>.
Re-trigger the webhook; the Sensor should now be able to submit the Workflow.
Quick RBAC reference:
Resource Type
Use Case
Example
Role / RoleBinding
Grant namespace-scoped permissions for Sensor service account
Grant create on workflows.argoproj.io in argo namespace
ClusterRole / ClusterRoleBinding
Grant cluster-scoped permissions if needed across namespaces
Grant create on workflows.argoproj.io cluster-wide
ServiceAccount
Token identity used by Sensor to act against the API server
Triggers can also create generic Kubernetes objects (Pods, Deployments, Jobs, etc.). For such triggers, grant the service account the required permissions for the relevant Kubernetes API resources.
Example Sensor that specifies a service account and creates a Pod via the k8s trigger:
Copy
apiVersion: argoproj.io/v1alpha1kind: Sensormetadata: name: webhook namespace: argo-eventsspec: template: serviceAccountName: create-pod-sa # use a service account with privileges to create pods dependencies: - name: test-dep eventSourceName: webhook eventName: example triggers: - template: name: webhook-pod-trigger k8s: operation: create source: resource: apiVersion: v1 kind: Pod metadata: generateName: hello-world- spec: containers: - name: hello-container image: busybox command: ["/bin/sh", "-c"] args: ["echo hello-world"] parameters: - src: dependencyName: test-dep # optionally map event data into the pod manifest via parameters