RBAC Permissions

Understand the Kubernetes RBAC roles Fission components use, the permissions needed to drive the CLI, and how to scope a user to one namespace.

This guide explains the Kubernetes RBAC that Fission’s components use, the permissions a human (or CI) user needs to drive the Fission CLI, and how to scope a user down to a single namespace.

Fission is built entirely on Kubernetes custom resources in the fission.io API group (Function, Environment, Package, HTTPTrigger, TimeTrigger, MessageQueueTrigger, KubernetesWatchTrigger, CanaryConfig). The CLI talks directly to the Kubernetes API server, so RBAC is the single mechanism that governs who can do what.

RBAC support in the Fission CLI is available from Fission 1.18.0 onward.

RBAC for Fission components

When you install Fission with the Helm chart, each component ships with its own ServiceAccount and namespace-scoped Role/RoleBinding. The chart generates these per component, so each one holds only the permissions it needs. The roles live under charts/fission-all/templates/<component>/ and are generated by the shared templates _fission-component-roles.tpl (Fission CRDs) and _fission-kubernetes-roles.tpl (native Kubernetes resources).

The table below summarizes what each component is granted. Components that run controller-runtime reconcilers also get coordination.k8s.io/leases plus events (create/patch) for native leader election.

ComponentFission CRDs (fission.io)Native Kubernetes resources
executorenvironments, functions, packages (full CRUD); functions/status (update)pods, services, deployments, deployments/scale, replicasets, horizontalpodautoscalers, events, configmaps/secrets (read), customresourcedefinitions (read), metrics.k8s.io/pods (read)
routerenvironments, functions, httptriggers, packages (full CRUD); httptriggers/status (update)networking.k8s.io/ingresses (full CRUD), customresourcedefinitions (read)
buildermgrenvironments, functions, packages (full CRUD); functions/status, packages/status (update)pods, services (create/delete/read/patch), deployments (list/create/delete), configmaps/secrets (read), events, customresourcedefinitions (read)
kubewatcherenvironments, functions, kuberneteswatchtriggers, packages (full CRUD); kuberneteswatchtriggers/status (update)configmaps, pods, secrets, services, replicationcontrollers, events, batch/jobs (read), customresourcedefinitions (read)
timerenvironments, functions, packages, timetriggers (full CRUD); timetriggers/status (update)leases + events only
mqtrigger (KEDA)environments, functions, messagequeuetriggers, packages (full CRUD); messagequeuetriggers/status (update)pods, services, deployments, keda.sh/scaledobjects, keda.sh/scaledjobs, keda.sh/triggerauthentications (full CRUD), customresourcedefinitions (read), metrics.k8s.io/pods (read)
canaryconfigcanaryconfigs, httptriggers (get/list/watch/update); canaryconfigs/status (update)services (list), pods (read), customresourcedefinitions (read)
storagesvcpackages (get/list)leases + events for leader election
The chart binds these roles in the install namespace (defaultNamespace, typically fission) and in any namespace listed in additionalFissionNamespaces. The older builderNamespace and functionNamespace values are deprecated; prefer additionalFissionNamespaces.

RBAC for Fission CLI users

A human or CI user needs permissions on the Fission CRDs (and a few native resources) to run CLI commands such as fission function create, fission spec apply, and fission function log. You can grant these cluster-wide with a ClusterRole, or scope them to one namespace with a Role (see Namespace-scoped user below).

What a user needs

  • Fission CRDsfunctions, environments, packages, and the trigger kinds (httptriggers, timetriggers, messagequeuetriggers, kuberneteswatchtriggers, canaryconfigs) in the fission.io group. Grant the verbs that match the commands the user will run (get/list/create/update/delete).
  • pods and pods/log (get/list) — for fission function log and fission function pod.
  • pods/portforward (create) — for fission function test, which port-forwards to the router.
  • services (list) — to discover the router service.
  • configmaps and secrets (get) — for functions that reference them.

Sample ClusterRole

Below is a ClusterRole that allows a user to perform every action the Fission CLI supports. The comments map each rule to the CLI commands that use it, in the form # <command> <subcommands>.

Save it as fission-user-role.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: fission-user
rules:
# function create/update/run-container; spec apply/destroy
- apiGroups: [""]
  resources: ["configmaps", "secrets"]
  verbs: ["get"]

# function log/pod
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["list", "get"]

# discover the router service
- apiGroups: [""]
  resources: ["services"]
  verbs: ["list"]

# function test (port-forward to router); timetrigger/archive/package commands
- apiGroups: [""]
  resources: ["pods/portforward"]
  verbs: ["list", "create"]

- apiGroups: ["fission.io"]
  resources: ["canaryconfigs"]
  verbs: ["list", "get", "create", "update", "delete"]

- apiGroups: ["fission.io"]
  resources: ["environments"]
  verbs: ["list", "get", "create", "update", "delete"]

- apiGroups: ["fission.io"]
  resources: ["functions"]
  verbs: ["list", "get", "create", "update", "delete"]

- apiGroups: ["fission.io"]
  resources: ["packages"]
  verbs: ["list", "get", "create", "update", "delete"]

- apiGroups: ["fission.io"]
  resources: ["httptriggers"]
  verbs: ["list", "get", "create", "update", "delete"]

- apiGroups: ["fission.io"]
  resources: ["kuberneteswatchtriggers"]
  verbs: ["list", "get", "create", "delete"]

- apiGroups: ["fission.io"]
  resources: ["messagequeuetriggers"]
  verbs: ["list", "get", "create", "update", "delete"]

- apiGroups: ["fission.io"]
  resources: ["timetriggers"]
  verbs: ["list", "get", "create", "update", "delete"]

Bind it to the user’s ServiceAccount with a ClusterRoleBinding. Save it as fission-user-rolebinding.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: fission-user
subjects:
  - kind: ServiceAccount
    name: fission-user
    namespace: default
roleRef:
  kind: ClusterRole
  name: fission-user
  apiGroup: rbac.authorization.k8s.io

Apply both:

kubectl apply -f fission-user-role.yaml
kubectl apply -f fission-user-rolebinding.yaml

Namespace-scoped user

To confine a user to a single namespace — for example a docs namespace where they may only manage their own functions — use a Role and RoleBinding instead of the cluster-wide variants. A Role grants permissions only within its own namespace.

Save it as fission-docs-user-role.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: fission-docs-user
  namespace: docs
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list"]
- apiGroups: [""]
  resources: ["pods/portforward"]
  verbs: ["create"]
- apiGroups: [""]
  resources: ["services"]
  verbs: ["list"]
- apiGroups: [""]
  resources: ["configmaps", "secrets"]
  verbs: ["get"]
- apiGroups: ["fission.io"]
  resources:
  - functions
  - environments
  - packages
  - httptriggers
  - timetriggers
  - messagequeuetriggers
  - kuberneteswatchtriggers
  - canaryconfigs
  verbs: ["get", "list", "create", "update", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: fission-docs-user
  namespace: docs
subjects:
  - kind: ServiceAccount
    name: fission-docs-user
    namespace: docs
roleRef:
  kind: Role
  name: fission-docs-user
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f fission-docs-user-role.yaml

The user can now create and manage Fission resources in the docs namespace, and nowhere else. Pass -n docs (or set the namespace in the current context) when running CLI commands so they target that namespace.

A namespace-scoped user can read and run functions only in their namespace, but the Fission components must still be allowed to reconcile resources there. Add the namespace to additionalFissionNamespaces in your Helm values so the chart grants the executor, router, and other components a Role in it.

Configure kubectl to use the account

To exercise the role, point your kubeconfig at the service account’s credentials and switch context.

kubectl config set-credentials fission-user \
  --client-certificate=/path/to/certificate.crt \
  --client-key=/path/to/key.key

kubectl config set-context fission-user-context \
  --cluster=kind-kind --user=fission-user

kubectl config use-context fission-user-context

Verify

With the context set, the Fission CLI will act as the configured user. Create an environment and a function to confirm the permissions work:

$ fission env create --name node --image ghcr.io/fission/node-env -n default
poolsize setting default to 3
environment 'node' created

$ fission fn create --name hello --code hello.js --env node
Package 'hello-a2318569-0d2d-4b63-826d-6d4d2665be50' created
function 'hello' created

If a command is denied, the API server returns a forbidden error naming the resource and verb that is missing — add the corresponding rule to the role and re-apply.

  • YAML Specs — the declarative workflow these permissions enable.
  • Functions — create and invoke functions once permissions are in place.
  • Installation — install Fission and its component RBAC.