Skip to main content

OCI OKE Ability to Create Pods Should Be Restricted

More Info:

The pods/create permission lets a principal effectively run code as any service account in the namespace. Limit it to controllers and CI accounts and audit any human grant.

Risk Level

High

Address

Compliance, Security

Compliance Standards

  • CIS OKE

Triage and Remediation

Remediation

Using Console

In OKE this is enforced with Kubernetes RBAC, not a direct “toggle” in the OCI Console. You use the OCI Console to get kubeconfig and then apply RBAC that removes create permissions on Pods for everyone except specific roles/groups.

Below are the minimal console-driven steps.


1. Make sure users don’t get cluster‑admin by default

  1. In OCI Console, go to Identity & Security → Policies.
  2. Look for policies like:
    • allow group <some-group> to manage cluster-family in compartment <compartment-name>
    • allow group <some-group> to manage all-resources in compartment <compartment-name>
  3. Either:
    • Remove these broad policies, or
    • Replace them with more limited ones, such as:
      allow group Devs to use cluster in compartment MyCompartment
      allow group Devs to use node-pools in compartment MyCompartment
    This ensures they can connect to the cluster but aren’t automatically full OCI administrators for the cluster.

Note: OCI IAM controls who can talk to the cluster endpoint and perform some OKE‑level actions, but Kubernetes RBAC controls who can create Pods.


2. Use OCI Console to get kubeconfig for an admin user

  1. In OCI Console, go to Developer Services → Kubernetes Clusters (OKE).
  2. Click your cluster.
  3. Click Access Cluster.
  4. Under Kubeconfig, choose Local access (or appropriate method).
  5. Click Copy or Download kubeconfig and configure ~/.kube/config as instructed.

You will use this kubeconfig with kubectl to apply the RBAC restrictions.


3. Create restricted Kubernetes roles (block Pod creation)

Define roles that don’t include create on Pods and bind normal users to them.

  1. Create a file restricted-role.yaml with:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: view-no-pod-create
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"] # no "create", "delete", "update", etc.
- apiGroups: [""]
resources: ["services", "endpoints"]
verbs: ["get", "list", "watch"]
  1. Apply it:
kubectl apply -f restricted-role.yaml

4. Bind restricted role to your OCI‑mapped Kubernetes users/groups

In OKE, OCI groups/users are mapped into Kubernetes users/groups based on authentication method. Common pattern (OIDC / IAM Authenticator) is that a user ends up with groups like oke:group:<oci-group-name>.

  1. Identify the Kubernetes group for your OCI group:
    • Ask a test user to run kubectl config view --minify and kubectl auth can-i --list
    • Or check your OKE IAM Authenticator/OIDC integration docs.

Assume you have a group oke:group:Developers.

  1. Create a RoleBinding or ClusterRoleBinding:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: developers-view-no-pod-create
subjects:
- kind: Group
name: oke:group:Developers # adjust to your actual Kubernetes group
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: view-no-pod-create
apiGroup: rbac.authorization.k8s.io
  1. Apply it:
kubectl apply -f developers-binding.yaml

All users in the OCI group Developers will now have read‑only access to Pods (cannot create them).


5. Remove or narrow any existing roles that let users create Pods

If you previously granted broad roles (e.g., cluster-admin, edit), users might still be able to create Pods.

  1. List current clusterrolebindings:
kubectl get clusterrolebinding
  1. For any that bind regular users/groups to high‑privilege roles (cluster-admin, edit, admin), either:
    • Delete them:
      kubectl delete clusterrolebinding <name>
    • Or replace them with bindings to your restricted role (view-no-pod-create).

6. (Optional) Restrict Pod creation to a small admin group

If some SRE/Platform team must create Pods:

  1. Create an admin ClusterRole if not already using edit/admin:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-admin
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  1. Bind this only to an ops group:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ops-pod-admin
subjects:
- kind: Group
name: oke:group:PlatformOps # OCI group mapped for ops
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: pod-admin
apiGroup: rbac.authorization.k8s.io
  1. Apply it:
kubectl apply -f pod-admin-role.yaml
kubectl apply -f ops-pod-admin-binding.yaml

7. Verify that normal users cannot create Pods

Using a user from the restricted OCI group:

kubectl auth can-i create pods
# should output: no

kubectl auth can-i get pods
# should output: yes

Summary:

  • Use OCI Console for: cluster access (kubeconfig) and OCI IAM policies to prevent broad OKE management.
  • Use kubectl (via kubeconfig from Console) for: Kubernetes RBAC that removes create on Pods for normal users and grants it only to a small admin group.
Using CLI

Below is how to restrict who can create Pods in OCI OKE using OCI CLI + kubectl (kubectl is required for Kubernetes RBAC; OCI CLI is used to get kubeconfig and manage IAM).


1. Get kubeconfig for your OKE cluster (using OCI CLI)

# Set variables
export COMPARTMENT_OCID="<compartment-ocid>"
export CLUSTER_OCID="<oke-cluster-ocid>"
export KUBECONFIG="$HOME/.kube/oke-config"

# Generate kubeconfig
oci ce cluster create-kubeconfig \
--cluster-id $CLUSTER_OCID \
--file $KUBECONFIG \
--region <region> \
--token-version 2.0.0 \
--kube-endpoint PUBLIC_ENDPOINT

# Use that kubeconfig
export KUBECONFIG=$KUBECONFIG

# Test
kubectl get nodes

2. Remove broad permissions to create Pods

If there are existing overly-privileged bindings (e.g., giving create on pods to many users/groups), remove or tighten them.

Example: list current RBAC:

kubectl get clusterrolebindings,rolebindings -A
kubectl get clusterroles,roles -A

If you see something like a ClusterRole giving create on pods bound to many users/groups, remove or edit it.

Example – delete an unsafe binding:

kubectl delete clusterrolebinding <unsafe-binding-name>
# or
kubectl delete rolebinding <unsafe-binding-name> -n <namespace>

If you want to edit a role and remove create on pods:

kubectl edit clusterrole <clusterrole-name>

Then remove create from:

- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch","create","update","delete"]

so it becomes, for example:

- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]

Save and exit.


3. Create a least‑privilege role that can create Pods (if needed)

Define a Role or ClusterRole that only specific users/groups will use to create pods.

Example clusterrole-pod-creator.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-creator
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create","get","list","watch"]

Apply with kubectl:

kubectl apply -f clusterrole-pod-creator.yaml

Bind it only to trusted subjects:

# pod-creator-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: pod-creator-binding
subjects:
- kind: Group
name: "oke-pod-creators" # Kubernetes group mapped from OCI IAM
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: pod-creator
apiGroup: rbac.authorization.k8s.io
kubectl apply -f pod-creator-binding.yaml

4. Map OCI IAM users/groups to Kubernetes RBAC

  1. Create an OCI IAM group (e.g. oke-pod-creators) and add the right users.
oci iam group create --name "oke-pod-creators" --description "Users allowed to create pods"
  1. Let this group access the cluster (OCI IAM policy, using OCI CLI):

Create a policy in the same compartment as the OKE cluster:

oci iam policy create \
--name "oke-pod-creators-policy" \
--compartment-id $COMPARTMENT_OCID \
--description "Allow oke-pod-creators group to use OKE cluster" \
--statements '[
"Allow group oke-pod-creators to use cluster-family in compartment <compartment-name>"
]'
  1. Use OIDC / auth mapping to surface this OCI group into Kubernetes as oke-pod-creators (OKE automatically maps OCI groups to Kubernetes groups when using IAM auth; group name in Kubernetes will match the OCI group display name).

Then the ClusterRoleBinding created earlier will apply to these users.


5. Restrict cluster‑admin / admin access

Ensure only a very small set of admins can still create pods unconstrained.

  1. Identify cluster-admin bindings:
kubectl get clusterrolebindings | grep cluster-admin
  1. Remove or tighten them:
kubectl edit clusterrolebinding <binding-name>
# or
kubectl delete clusterrolebinding <binding-name>
  1. In OCI IAM, keep manage cluster-family in policies only for a very restricted admin group.

Example OCI policy (keep this narrow):

oci iam policy create \
--name "oke-admins-policy" \
--compartment-id $COMPARTMENT_OCID \
--description "Admins for OKE" \
--statements '[
"Allow group oke-admins to manage cluster-family in compartment <compartment-name>"
]'

6. Validate that pod creation is restricted

  1. As a non‑authorized user:
kubectl run test-pod --image=busybox --restart=Never -- echo "test"
# Expect: forbidden (User does not have permission to create pods)
  1. As an authorized user in oke-pod-creators:
kubectl run test-pod --image=busybox --restart=Never -- echo "test"
# Expect: pod created

If you share your current RBAC (e.g. output of kubectl get clusterrolebindings -o yaml), I can give an exact set of edits/commands for your environment.

Using Python

To restrict who can create Pods in OCI OKE, you must use Kubernetes RBAC on your OKE cluster. The Python part is mainly about applying RBAC objects (ClusterRole / RoleBinding) programmatically.

Below is a minimal, practical remediation approach with Python.


1. Prerequisites

  1. An OKE cluster already running.
  2. kubectl access to the cluster (you should be admin or equivalent).
  3. Python installed with:
    pip install kubernetes oci
  4. Your kubeconfig updated for the OKE cluster (via OCI CLI or console), e.g.:
    oci ce cluster create-kubeconfig --cluster-id <cluster-ocid> --file ~/.kube/config --region <region> --token-version 2.0.0
    export KUBECONFIG=~/.kube/config

The Python script below will use ~/.kube/config to talk to the cluster.


2. RBAC Design (what we’re implementing)

Objective:

  • Only a specific group of users (or service accounts) may create Pods.
  • Others can still read/list Pods if you want, but cannot create them.

We will:

  1. Create a ClusterRole that grants create on pods.
  2. Bind that role to a specific Kubernetes subject:
    • Either a service account (safe and recommended).
    • Or users/groups matching your OIDC/OCI IAM integration (advanced).

For simplicity, we’ll assume:

  • Namespace: restricted-apps
  • ServiceAccount: pod-creator
  • You will only allow that service account to create Pods in that namespace.

3. Python Script to Apply RBAC

This script:

  1. Ensures the namespace exists.
  2. Creates a ServiceAccount named pod-creator.
  3. Creates a Role (namespace-scoped) that allows create on pods.
  4. Binds that role to the pod-creator service account via RoleBinding.
from kubernetes import client, config
from kubernetes.client.rest import ApiException

NAMESPACE = "restricted-apps"
SA_NAME = "pod-creator"
ROLE_NAME = "pod-create-role"
ROLEBINDING_NAME = "pod-create-binding"

def ensure_namespace(core_v1):
ns_meta = client.V1ObjectMeta(name=NAMESPACE)
ns_body = client.V1Namespace(metadata=ns_meta)
try:
core_v1.read_namespace(name=NAMESPACE)
print(f"Namespace '{NAMESPACE}' already exists.")
except ApiException as e:
if e.status == 404:
print(f"Creating namespace '{NAMESPACE}'...")
core_v1.create_namespace(ns_body)
else:
raise

def ensure_service_account(core_v1):
sa_meta = client.V1ObjectMeta(name=SA_NAME, namespace=NAMESPACE)
sa_body = client.V1ServiceAccount(metadata=sa_meta)
try:
core_v1.read_namespaced_service_account(name=SA_NAME, namespace=NAMESPACE)
print(f"ServiceAccount '{SA_NAME}' already exists in '{NAMESPACE}'.")
except ApiException as e:
if e.status == 404:
print(f"Creating ServiceAccount '{SA_NAME}' in '{NAMESPACE}'...")
core_v1.create_namespaced_service_account(namespace=NAMESPACE, body=sa_body)
else:
raise

def ensure_role(rbac_v1):
role_meta = client.V1ObjectMeta(name=ROLE_NAME, namespace=NAMESPACE)
rules = [
client.V1PolicyRule(
api_groups=[""],
resources=["pods"],
verbs=["create", "get", "list", "watch"]
)
]
role_body = client.V1Role(metadata=role_meta, rules=rules)
try:
rbac_v1.read_namespaced_role(name=ROLE_NAME, namespace=NAMESPACE)
print(f"Role '{ROLE_NAME}' already exists in '{NAMESPACE}'.")
except ApiException as e:
if e.status == 404:
print(f"Creating Role '{ROLE_NAME}' in '{NAMESPACE}'...")
rbac_v1.create_namespaced_role(namespace=NAMESPACE, body=role_body)
else:
raise

def ensure_rolebinding(rbac_v1):
rb_meta = client.V1ObjectMeta(name=ROLEBINDING_NAME, namespace=NAMESPACE)
subject = client.V1Subject(
kind="ServiceAccount",
name=SA_NAME,
namespace=NAMESPACE
)
role_ref = client.V1RoleRef(
api_group="rbac.authorization.k8s.io",
kind="Role",
name=ROLE_NAME
)
rb_body = client.V1RoleBinding(
metadata=rb_meta,
subjects=[subject],
role_ref=role_ref
)

try:
rbac_v1.read_namespaced_role_binding(name=ROLEBINDING_NAME, namespace=NAMESPACE)
print(f"RoleBinding '{ROLEBINDING_NAME}' already exists in '{NAMESPACE}'.")
except ApiException as e:
if e.status == 404:
print(f"Creating RoleBinding '{ROLEBINDING_NAME}' in '{NAMESPACE}'...")
rbac_v1.create_namespaced_role_binding(namespace=NAMESPACE, body=rb_body)
else:
raise

def main():
# Load kubeconfig (looks at KUBECONFIG or default location)
config.load_kube_config()

core_v1 = client.CoreV1Api()
rbac_v1 = client.RbacAuthorizationV1Api()

ensure_namespace(core_v1)
ensure_service_account(core_v1)
ensure_role(rbac_v1)
ensure_rolebinding(rbac_v1)

print("RBAC configuration applied. Only ServiceAccount "
f"'{SA_NAME}' in namespace '{NAMESPACE}' can create Pods there.")

if __name__ == "__main__":
main()

4. How This Remediates “Ability to Create Pods Should Be Restricted”

  • By default, many OKE clusters grant broad rights via cluster-admin or wide RoleBindings.
  • You must:
    1. Audit and tighten existing RBAC (manually or with additional scripts):
      • Remove or limit any ClusterRoleBinding that gives create on pods to broad subjects like system:authenticated or generic groups.
    2. Use scripts like the above to:
      • Define explicit, narrow permissions for pod creation.
      • Bind them only to the identities that truly need it.

If you show me your current kubectl get clusterrolebinding -o yaml output (redacted), I can give a Python snippet to systematically remove unsafe bindings as well.

Using Terraform
# This finding cannot be remediated on the OKE cluster resource itself.
# The `pods/create` permission is a Kubernetes RBAC right, not an
# `oci_containerengine_cluster` (OKE) property exposed by the OCI provider.

# There is no argument on `oci_containerengine_cluster` (the Terraform
# resource behind "oci-containers-oke-cluster") that controls who has
# Kubernetes RBAC permissions such as `pods/create`. Those are set *inside*
# the cluster via Kubernetes Role/ClusterRole and RoleBinding/ClusterRoleBinding.

# To remediate with Terraform, you must:
# 1. Keep using `oci_containerengine_cluster` for the cluster itself, and
# 2. Add a Kubernetes provider pointing at that OKE cluster, and
# 3. Manage RBAC with Kubernetes resources, for example:

provider "kubernetes" {
host = "https://OKE_API_ENDPOINT_FOR_CLUSTER"
cluster_ca_certificate = base64decode("BASE64_ENCODED_CA_CERT")
token = "K8S_BEARER_TOKEN_OR_EXEC_PLUGIN"
}

# Example: allow pods/create only for a controller service account in a namespace
resource "kubernetes_role" "controller_pod_creator" {
metadata {
name = "controller-pod-creator"
namespace = "TARGET_NAMESPACE" # replace with your namespace
}

rule {
api_groups = [""]
resources = ["pods"]
verbs = ["create"]
}
}

resource "kubernetes_role_binding" "controller_pod_creator_binding" {
metadata {
name = "controller-pod-creator-binding"
namespace = "TARGET_NAMESPACE" # replace with your namespace
}

role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "Role"
name = kubernetes_role.controller_pod_creator.metadata[0].name
}

subject {
kind = "ServiceAccount"
name = "CONTROLLER_SERVICE_ACCOUNT" # replace with your controller SA name
namespace = "TARGET_NAMESPACE" # same namespace as above
}
}

# You must also remove or tighten any existing Role/ClusterRoleBindings
# that give `pods/create` to human users or broad groups; that is done by
# editing or deleting the corresponding Kubernetes RBAC objects via
# Terraform (kubernetes_* resources) or `kubectl`/OCI Console.

# Verification: `terraform plan` should show creation/update of
# kubernetes_role / kubernetes_role_binding resources and no change
# to the oci_containerengine_cluster itself.