Skip to main content

Access Roles (SSO)

The platform ships default Kubernetes ClusterRole objects for mapping IAM Identity Center (SSO) permission sets to predictable, least-privilege cluster access on EKS. The roles are installed by the cluster-roles Kustomize addon (addons/kustomize/oss/cluster-roles/) and are enabled automatically on every cluster via enable_core: "true".

Use them together with EKS access entries: IAM principals authenticate to the cluster, kubernetes_groups on the access entry map those principals to Kubernetes groups, and ClusterRoleBinding objects grant those groups the platform role permissions.


Available roles

ClusterRoleKubernetes group (recommended)Purpose
platform-viewerplatform-viewerRead-only access to cluster resources except Secret objects. Includes core workloads, RBAC, CRDs, and common platform API groups (cert-manager, Karpenter, Kyverno, VPA, and others).

Source: addons/kustomize/oss/cluster-roles/base/cluster-roles.yaml.

Group names

The Kubernetes group on the EKS access entry must match the subjects[].name on the ClusterRoleBinding. Using the same name as the ClusterRole (for example platform-viewer) is the simplest convention, but you can use a custom group name as long as the binding references it.


How access flows

  1. Platform deploys ClusterRole resources (platform-viewer, platform-add-nodes).
  2. Tenant deploys ClusterRoleBinding objects that map a group to each role.
  3. Infrastructure (Terraform or CLI) creates EKS access entries that associate SSO IAM role ARNs with kubernetes_groups.
  4. Optional: attach AWS-managed EKS cluster access policies via policy_associations when you want AWS-native scopes in addition to Kubernetes RBAC.

Bind platform roles in the tenant repository

Deploy a ClusterRoleBinding per SSO group. Example for read-only viewers:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: platform-viewer-binding
labels:
app.kubernetes.io/managed-by: argocd
platform.local/type: tenant
subjects:
- kind: Group
name: platform-viewer
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: platform-viewer
apiGroup: rbac.authorization.k8s.io

Example using a custom group name (matches the Terraform / CLI examples below):

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: custom-dev-lead-viewer
subjects:
- kind: Group
name: custom-dev-lead-group
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: platform-viewer
apiGroup: rbac.authorization.k8s.io

Place bindings under workloads/system/ in the tenant repository (see Tenant system workloads).


Terraform — access_entries on EKS

The platform Terraform wrapper passes access_entries to the appvia/eks/aws module (see terraform/main.tf). Use the module access_entries variable to register SSO principals and map them to Kubernetes groups.

RBAC-only (platform platform-viewer)

No AWS access policy is required when Kubernetes RBAC alone defines permissions:

access_entries = {
developer_viewer = {
principal_arn = "arn:aws:iam::123456789012:role/aws-reserved/sso.amazonaws.com/eu-west-2/AWSReservedSSO_DeveloperAccess_abcdef1234567890"
kubernetes_groups = ["platform-viewer"]
}
}

Custom group name → platform-viewer role

access_entries = {
dev_lead = {
principal_arn = "arn:aws:iam::123456789012:role/aws-reserved/sso.amazonaws.com/eu-west-2/AWSReservedSSO_DevLead_abcdef1234567890"
kubernetes_groups = ["custom-dev-lead-group"]
}
}

Pair with the ClusterRoleBinding example above that binds custom-dev-lead-group to platform-viewer.

Node operators (platform-add-nodes)

access_entries = {
platform_ops = {
principal_arn = "arn:aws:iam::123456789012:role/aws-reserved/sso.amazonaws.com/eu-west-2/AWSReservedSSO_PlatformOps_abcdef1234567890"
kubernetes_groups = ["platform-add-nodes"]
}
}

AWS-managed policy + Kubernetes groups

Combine an EKS access policy with kubernetes_groups when you want AWS-scoped permissions and platform RBAC (for example extra CRD visibility from platform-viewer):

access_entries = {
developer_hybrid = {
principal_arn = "arn:aws:iam::123456789012:role/aws-reserved/sso.amazonaws.com/eu-west-2/AWSReservedSSO_DeveloperAccess_abcdef1234567890"
kubernetes_groups = ["platform-viewer"]
policy_associations = {
view = {
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy"
access_scope = {
type = "cluster"
}
}
}
}

cluster_admin = {
principal_arn = "arn:aws:iam::123456789012:role/aws-reserved/sso.amazonaws.com/eu-west-2/AWSReservedSSO_AdministratorAccess_abcdef1234567890"
policy_associations = {
cluster_admin = {
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
access_scope = {
type = "cluster"
}
}
}
}
}

This repository also merges an administrator entry when sso_administrator_role is set (terraform/settings.access.tf).

Variable shape (terraform-aws-eks)

variable "access_entries" {
description = "Map of access entries to add to the cluster."
type = map(object({
kubernetes_groups = optional(list(string), [])
principal_arn = string
policy_associations = optional(map(object({
policy_arn = string
access_scope = object({
namespaces = optional(list(string), [])
type = optional(string, "cluster")
})
})))
}))
default = null
}

AWS CLI

Create access entry (RBAC via kubernetes_groups)

aws eks create-access-entry \
--cluster-name my-cluster \
--principal-arn arn:aws:iam::123456789012:role/AWSReservedSSO_DeveloperAccess_abcdef1234567890 \
--kubernetes-groups platform-viewer \
--type STANDARD

Custom group name (must match ClusterRoleBinding subject):

aws eks create-access-entry \
--cluster-name my-cluster \
--principal-arn arn:aws:iam::123456789012:role/AWSReservedSSO_DevLead_abcdef1234567890 \
--kubernetes-groups custom-dev-lead-group \
--type STANDARD

Associate an AWS-managed access policy (optional)

aws eks associate-access-policy \
--cluster-name my-cluster \
--principal-arn arn:aws:iam::123456789012:role/AWSReservedSSO_DeveloperAccess_abcdef1234567890 \
--policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy \
--access-scope type=cluster

Common policy ARNs:

PolicyARN suffix
Cluster adminAmazonEKSClusterAdminPolicy
AdminAmazonEKSAdminPolicy
EditAmazonEKSEditPolicy
ViewAmazonEKSViewPolicy

Verify

aws eks list-access-entries --cluster-name my-cluster

aws eks describe-access-entry \
--cluster-name my-cluster \
--principal-arn arn:aws:iam::123456789012:role/AWSReservedSSO_DeveloperAccess_abcdef1234567890

After binding, confirm Kubernetes RBAC:

kubectl auth can-i list pods --as-group=platform-viewer
kubectl auth can-i get secrets --as-group=platform-viewer # expect no

Choosing AWS policies vs platform roles

ApproachWhen to use
Platform ClusterRole only (kubernetes_groups, no policy_associations)Full control via GitOps RBAC; consistent across clouds; use platform-viewer to exclude secrets while still reading RBAC and platform CRDs.
AWS access policy onlyQuick baseline aligned with AWS documentation; no tenant ClusterRoleBinding required.
BothAWS policy for baseline namespace/cluster scope; platform roles for supplemental permissions (for example Karpenter or VPA CRDs not covered by AmazonEKSViewPolicy).

Enabling and extending

ItemDetail
Feature flagenable_core: "true" (on by default via cluster registration)
Addon pathaddons/kustomize/oss/cluster-roles/
Sync phaseprimary (deployed early)

To grant read access to additional CRD API groups, extend the rules in cluster-roles.yaml under the platform extension API groups list, or add tenant-specific ClusterRole objects that aggregate to your SSO groups.