RBAC Permissions for Kubernetes API Approach
This document details the RBAC permissions required for the Kubernetes API scanning approach.
Minimum RBAC Requirements
The minimum RBAC permissions required are:
| apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: scanner-role
namespace: ${NAMESPACE}
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
resourceNames: ["${POD_NAME}"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
resourceNames: ["${POD_NAME}"]
|
These permissions follow the principle of least privilege by:
- Limiting access to a specific namespace
- Restricting exec access to only the target pod
- Providing only the necessary permissions for scanning
RoleBinding Configuration
The Role must be bound to a service account:
| apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: scanner-rolebinding
namespace: ${NAMESPACE}
subjects:
- kind: ServiceAccount
name: scanner-service-account
namespace: ${NAMESPACE}
roleRef:
kind: Role
name: scanner-role
apiGroup: rbac.authorization.k8s.io
|
Service Account Creation
| apiVersion: v1
kind: ServiceAccount
metadata:
name: scanner-service-account
namespace: ${NAMESPACE}
|
Security Advantages
This RBAC configuration offers significant security advantages:
- Limited Scope: Access is constrained to only the required resources
- Pod-Specific Restrictions: The
resourceNames
field restricts exec access to only the target pod
- Namespace Isolation: Permissions are limited to a specific namespace
- Temporary Nature: The service account can be created just before scanning and removed afterwards
- No Privileged Access: No elevated permissions are required
Dynamic RBAC Generation
The scan-container.sh
script dynamically generates:
- A temporary service account
- A role with minimal permissions tailored to the target pod
- A role binding to connect the two
- A short-lived authentication token
This ensures that:
- Each scan uses fresh credentials
- Credentials expire automatically (typically after 1 hour)
- Only the minimum required permissions are granted
RBAC Templates
The following template is used by the scan-container.sh
script:
| apiVersion: v1
kind: ServiceAccount
metadata:
name: scanner-sa-${RANDOM_SUFFIX}
namespace: ${NAMESPACE}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: scanner-role-${RANDOM_SUFFIX}
namespace: ${NAMESPACE}
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
resourceNames: ["${POD_NAME}"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
resourceNames: ["${POD_NAME}"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: scanner-binding-${RANDOM_SUFFIX}
namespace: ${NAMESPACE}
subjects:
- kind: ServiceAccount
name: scanner-sa-${RANDOM_SUFFIX}
namespace: ${NAMESPACE}
roleRef:
kind: Role
name: scanner-role-${RANDOM_SUFFIX}
apiGroup: rbac.authorization.k8s.io
|
Cluster-Wide Alternative
For scanning across multiple namespaces, a more permissive but still restricted ClusterRole can be used:
| apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: multi-namespace-scanner-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
|
Security Consideration
The cluster-wide approach is less secure than the namespace-specific approach since it grants broader access. Use only when necessary and implement additional controls like:
- Short-lived tokens
- Audit logging
- Pod security policies to restrict which pods can be executed in
Label-Based RBAC
For more advanced scenarios, label-based RBAC can be used:
| apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: label-based-scanner-role
namespace: ${NAMESPACE}
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods/exec", "pods/log"]
verbs: ["create", "get"]
resourceNames: []
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: label-based-scanner-binding
namespace: ${NAMESPACE}
subjects:
- kind: ServiceAccount
name: scanner-service-account
namespace: ${NAMESPACE}
roleRef:
kind: Role
name: label-based-scanner-role
apiGroup: rbac.authorization.k8s.io
|
This can be combined with label selectors in your scanning tools to only scan pods with specific labels.