Access Control And Container Engine For Kubernetes
More Info:
Manage access to OKE clusters using OCI IAM combined with Kubernetes RBAC, granting clusterroles such as cluster-admin only to users who require them.
Risk Level
High
Address
Security
Compliance Standards
- CIS OKE
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
List current OCI IAM access and admin mappings
- Where: Any machine with OCI CLI access.
- Command (list cluster admins via OCI groups/policies):
oci iam policy list --alloci iam group list --alloci iam user list --all
- Review: Identify which OCI users/groups/compartments are allowed to access OKE clusters and whether any broad or overly permissive policies exist (for example, tenancy-wide admins or groups with full
manage cluster-familywhere not required).
-
Enumerate Kubernetes RBAC clusterrolebindings and bindings to cluster-admin
- Where: Any machine with kubectl access to the cluster (using your own kubeconfig for that user).
- Commands:
kubectl get clusterrolebindings -o widekubectl get clusterrolebindings -o jsonpath='{range .items[?(@.roleRef.name=="cluster-admin")]}{.metadata.name}{" => "}{range .subjects[*]}{.kind}:{.name}{" "}{end}{"\n"}{end}'
- Review: Note which users, groups, and service accounts are bound to
cluster-admin. Flag bindings that are not clearly required (e.g., generic groups, automation identities that do not need full cluster-wide admin).
-
Map cluster-admin subjects back to OCI identities and confirm business need
- Where: Any machine with kubectl and OCI CLI access.
- Commands (example lookups):
# For an OCI user OCID seen as a subjectoci iam user get --user-id ocid1.user.oc1..exampleuniqueID# For an OCI group OCID seen as a subjectoci iam group get --group-id ocid1.group.oc1..exampleuniqueID
- Review: For each subject bound to
cluster-admin, confirm with application/operations owners that the identity truly requires cluster-wide admin versus narrower roles.
-
Tighten access: remove unnecessary cluster-admin bindings
- Where: Any machine with kubectl access.
- Commands (for each binding you decide is unnecessary):
# Inspect before removalkubectl get clusterrolebinding <binding-name> -o yaml# Remove the bindingkubectl delete clusterrolebinding <binding-name>
- Operational impact: Identities removed from
cluster-adminimmediately lose cluster-wide admin rights; ensure they have appropriate alternative RBAC before deletion.
-
Grant cluster-admin only where explicitly justified
- Where: Any machine with kubectl access.
- Command (example, per benchmark remediation):
kubectl create clusterrolebinding <my-cluster-admin-binding> \--clusterrole=cluster-admin \--user=<user_OCID>
- Review: Use distinct, descriptive binding names and bind to specific users (or tightly scoped groups) whose need for cluster-admin is documented and approved.
-
Re-verify effective access and document approvals
- Where: Any machine with kubectl access.
- Verification command:
kubectl get clusterrolebindings -o jsonpath='{range .items[?(@.roleRef.name=="cluster-admin")]}{.metadata.name}{" => "}{range .subjects[*]}{.kind}:{.name}{" "}{end}{"\n"}{end}'
- Review: Confirm that only the approved list of users/groups/service accounts have
cluster-admin, and record the final list and approval in your change management or security documentation.
Using kubectl
kubectl cannot remediate this finding because it concerns Oracle Cloud Infrastructure IAM and managed OKE control-plane configuration, which are changed through the OCI Console, OCI CLI, or IaC. To address this finding, follow the guidance in the Manual Steps section for reviewing and adjusting OCI IAM policies and Kubernetes RBAC bindings.
Automation
#!/usr/bin/env bash
# Purpose: Report who has Kubernetes cluster-admin or equivalent privileges
# Scope: Run from any machine with kubectl access and creds for each OKE cluster context
set -euo pipefail
echo "Using kubectl from: $(command -v kubectl)"
echo
# Function to list cluster-admin bindings in current context
check_context() {
local ctx="$1"
echo "==== Context: ${ctx} ===="
kubectl config use-context "${ctx}" >/dev/null
echo "# 1) ClusterRoleBindings that reference cluster-admin"
kubectl get clusterrolebindings -o json \
| jq -r '
.items[]
| select(.roleRef.kind=="ClusterRole" and .roleRef.name=="cluster-admin")
| {
name: .metadata.name,
subjects: (.subjects // [])
}
| "ClusterRoleBinding: \(.name)\n" +
(if (subjects|length)==0
then " [WARN] No subjects (but grants cluster-admin)\n"
else
(subjects[]
| " Subject kind=\(.kind) name=\(.name) namespace=\((.namespace // "-")) apiGroup=\((.apiGroup // "-"))"
)
end
)
'
echo
echo "# 2) Namespaced RoleBindings that reference cluster-admin (effective cluster-wide if bound to system:masters or similar groups)"
kubectl get rolebindings --all-namespaces -o json \
| jq -r '
.items[]
| select(.roleRef.kind=="ClusterRole" and .roleRef.name=="cluster-admin")
| {
ns: .metadata.namespace,
name: .metadata.name,
subjects: (.subjects // [])
}
| "RoleBinding: \(.ns)/\(.name)\n" +
(if (subjects|length)==0
then " [WARN] No subjects (but references cluster-admin)\n"
else
(subjects[]
| " Subject kind=\(.kind) name=\(.name) namespace=\((.namespace // "-")) apiGroup=\((.apiGroup // "-"))"
)
end
)
'
echo
echo "# 3) Subjects that are tenancy / group-level identifiers (OCI-style)"
echo "# Review any user/group OCIDs or broad groups for least-privilege."
kubectl get clusterrolebindings -o json \
| jq -r '
.items[]
| select(.roleRef.kind=="ClusterRole" and .roleRef.name=="cluster-admin")
| . as $crb
| (.subjects // [])
| .[]
| select(.kind=="User" or .kind=="Group")
| "ClusterRoleBinding=\($crb.metadata.name) kind=\(.kind) name=\(.name)"
'
echo
}
# If jq is not present, we cannot parse JSON safely
if ! command -v jq >/dev/null 2>&1; then
echo "ERROR: jq is required for this script. Install jq and re-run." >&2
exit 1
fi
# If user provided specific contexts as args, use them; otherwise use all
if [ "$#" -gt 0 ]; then
contexts=("$@")
else
mapfile -t contexts < <(kubectl config get-contexts -o name)
fi
for ctx in "${contexts[@]}"; do
check_context "${ctx}"
echo
done
How to run (any machine with kubectl access):
chmod +x report-cluster-admin.sh
./report-cluster-admin.sh # all kubeconfig contexts
./report-cluster-admin.sh my-oke-cluster # single OKE context
Output that indicates a potential problem (requires human review):
- Any
ClusterRoleBindingwith:roleRef.name == cluster-adminandSubject kind=UserorSubject kind=Groupusing:- Broad groups (e.g., “Administrators”, “Developers”, generic OCI IAM groups).
- User OCIDs belonging to people who do not strictly need cluster-admin.
- Any binding that uses
cluster-adminwhere a narrower role would suffice. - Any
[WARN] No subjectsentries (misconfiguration that may indicate prior mistakes).
Use this report to compare actual subjects (user/group OCIDs) against your OCI IAM design and the least-privilege intent, then adjust OCI IAM policies and/or RBAC bindings manually as appropriate.