Configuring a dedicated ServiceAccount and RBAC so an Argo Events Sensor can securely submit Argo Workflows into a target namespace, avoiding permission errors.
In this lesson you’ll configure a dedicated ServiceAccount and RBAC rules so an Argo Events Sensor can submit Argo Workflows into a target namespace. This resolves “permission denied” errors when the Sensor attempts to create a Workflow using the cluster default ServiceAccount.Why this matters:
Using a scoped ServiceAccount with minimal RBAC permissions is more secure than relying on the default ServiceAccount.
It prevents permission errors and enables the Sensor to create Workflows in a separate namespace.
Problem evidence (sensor error when using the default ServiceAccount):
Copy
{ "namespace": "argo-events", "sensorName": "webhook-sensor", "level": "error", "time": "2025-10-25T11:00:39Z", "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\""}
This shows the Sensor (running in argo-events) attempted to create a Workflow in the argo namespace using the default ServiceAccount and was forbidden.Planned steps:
Create a ServiceAccount in the Sensor’s namespace (argo-events).
Create a Role and RoleBinding in the target namespace (argo) to allow the ServiceAccount to create/read Workflows.
Update the Sensor to use the new ServiceAccount.
Trigger the Sensor and confirm the Workflow is created.
First, list existing ServiceAccounts in the argo-events namespace, then create a new one called workflow-trigger-sa:
Copy
# List ServiceAccounts in the argo-events namespacekubectl -n argo-events get sa# Create the new ServiceAccountkubectl create sa workflow-trigger-sa -n argo-events# Verify it was createdkubectl -n argo-events get sa
Expected output after creation:
Copy
NAME SECRETS AGEargo-events-sa 0 40mdefault 0 40mworkflow-trigger-sa 0 1s
Create a Role in the argo namespace that grants the minimum permissions the Sensor needs for Argo Workflows, and a RoleBinding that binds the workflow-trigger-sa ServiceAccount from the argo-events namespace to that Role.Manifest to apply:
role.rbac.authorization.k8s.io/submit-workflow-role createdrolebinding.rbac.authorization.k8s.io/trigger-workflow-binding created
If you see an error like “unknown command ‘apply’ for ‘kubectl1’”, it likely indicates an alias or PATH issue (for example, k pointing to an unexpected binary). Use the full kubectl binary or fix the alias so k maps to kubectl.
Edit your Sensor manifest to set spec.template.serviceAccountName to the ServiceAccount you created (workflow-trigger-sa). Below is a minimal Sensor snippet showing where to configure this:
4. Trigger the Sensor and Confirm Workflow Creation
Trigger the webhook event source (example using curl):
Copy
curl -d '{"message":"hello"}' -H "Content-Type: application/json" -X POST http://localhost:13000/push
You should receive a success response from the event source (for example, success). Then check logs to confirm the event flow:Example event source logs:
Copy
namespace=argo-events, eventSourceName=webhook, eventName=my-webhook, level=info, time=2025-10-25T11:12:45Z, msg="Succeeded to publish an event"namespace=argo-events, eventSourceName=webhook, eventName=my-webhook, level=info, time=2025-10-25T11:12:59Z, msg="Successfully dispatched the request to the event bus"
Describe the Workflow to inspect labels and the ServiceAccount used by the creator:
Copy
kubectl -n argo describe wf <workflow-name>
You should see labels like workflow.argoproj.io/creator and evidence that the Workflow was submitted by the workflow-trigger-sa ServiceAccount.Check the Workflow pod logs to confirm the job ran successfully (example cowsay output):
Copy
hello-kodekloud-xxxxx: < Hello Kode Kloud from ArgoEvents!! >hello-kodekloud-xxxxx: -------------------------------hello-kodekloud-xxxxx: \ ^__^hello-kodekloud-xxxxx: \ (oo)\_______hello-kodekloud-xxxxx: (__)\ )\/\hello-kodekloud-xxxxx: ||----w |hello-kodekloud-xxxxx: || ||