Skip to main content

OCI OKE Should Capture Security-Relevant Events Without

More Info:

Cluster audit logs and security-relevant events should be captured without truncation or sampling so post-incident forensics, anomaly detection, and compliance evidence are reliable. Stream logs to a tamper-evident destination.

Risk Level

High

Address

Compliance, Logging, Security

Compliance Standards

  • CIS OKE

Triage and Remediation

Remediation

Using Console

Below are console-only steps to ensure OKE captures all security‑relevant events without restriction using OCI Logging.

This focuses on:

  • Enabling all available OKE control plane logs (API server, audit, scheduler, controller)
  • Ensuring logs are not filtered and are persisted appropriately

1. Open Your OKE Cluster

  1. Sign in to the OCI Console.
  2. In the left menu, go to Developer Services → Kubernetes Clusters (OKE).
  3. Select the Compartment where your cluster resides.
  4. Click the name of the cluster you want to fix.

2. Enable All Control Plane Logs

  1. On the cluster details page, go to the Logs tab.

  2. For each available log type (names can vary slightly by version/shape), do the following:

    • kube-apiserver or kubernetes API server
    • kube-apiserver audit / kubernetes API server audit
    • kube-controller-manager
    • kube-scheduler
    • Any other OKE control plane logs presented

    For each:

    a. If you see Enable log or Create log:

    • Click Enable log.
    • Choose or create a Log Group:
      • Prefer a dedicated group like oke-control-plane-logs in the same Compartment.
    • Make sure Log Type is set to Service Log.
    • Do not add any filters; keep the default to capture all events.
    • Click Enable or Create.
  3. Confirm that the Status for each key log is now Enabled.


3. Set Log Retention (No Restrictive Filters)

  1. Go to Observability & Management → Logging → Log Groups.
  2. Select the Compartment and choose the log group you used (e.g., oke-control-plane-logs).
  3. Open each OKE log you just enabled.
  4. In each log:
    • Click Edit Log.
    • Ensure there are no “Include/Exclude” filters configured. If filters exist, clear them so that:
      • All severities are captured.
      • All categories/paths are captured.
    • Set an appropriate Retention Period (e.g., 90 days or per your policy).
    • Save changes.

This ensures logs are not restricted at the log configuration level.


To make sure security‑relevant events are preserved and queryable:

  1. Go to Observability & Management → Service Connectors.
  2. Click Create Service Connector.
  3. Configure:
    • Source: Logging
      • Select the Compartment and Log Group used for OKE.
      • Do not configure any filter; select all the OKE logs.
    • Target:
      • Either Object Storage (for long‑term archival)
        • Choose/create a Bucket dedicated for audit/security logs
      • Or Logging Analytics (for search/analytics)
  4. Complete and Create the connector.

This avoids event loss and supports compliance use cases.


5. Verify Events Are Flowing

  1. Go to Observability & Management → Logging.
  2. Open the OKE log group and each log stream (API server, audit, etc.).
  3. Confirm:
    • New log entries appear when you perform actions on the cluster (e.g., kubectl create namespace, kubectl auth can-i).
    • Events show full detail (no indication of dropped or filtered events).

These steps ensure OKE is capturing all security‑relevant control plane events without restriction, with central logging and optional archival or analytics as required by most security benchmarks.

Using CLI

Below are CLI-focused steps to ensure OKE (OCI Container Engine for Kubernetes) captures all security‑relevant events (i.e., all available service logs) without restriction.

Assumptions:
– You have OCI CLI configured (oci setup config) with appropriate permissions.
– You know the OCID of your OKE cluster and your compartment.


1. Identify Required IDs

# Set your compartment OCID
COMPARTMENT_OCID="<your_compartment_ocid>"

# (Optional) List OKE clusters to get the cluster OCID
oci ce cluster list \
--compartment-id "$COMPARTMENT_OCID" \
--all

# Set the OKE cluster OCID
CLUSTER_OCID="<your_oke_cluster_ocid>"

# Get a logging log group (or create a new one)
oci logging log-group list \
--compartment-id "$COMPARTMENT_OCID"

# If none or you want a dedicated one:
LOG_GROUP_NAME="oke-security-logs"
LOG_GROUP_OCID=$(oci logging log-group create \
--compartment-id "$COMPARTMENT_OCID" \
--display-name "$LOG_GROUP_NAME" \
--query 'data.id' --raw-output)

If you already have a log group, just set:

LOG_GROUP_OCID="<existing_log_group_ocid>"

2. Discover All Available OKE Log Categories

You want all categories so you don’t restrict security‑relevant events.

oci logging log list-categories \
--compartment-id "$COMPARTMENT_OCID" \
--service "containerengine"

Note the list of categories returned (examples, actual names may differ by region/version):

  • cluster
  • controlplane
  • apiserver
  • scheduler
  • controller-manager
  • audit
    etc.

You will create a log for each category you want captured.


3. Enable All OKE Service Logs (No Filtering)

For each category from step 2, create a service log associated with the OKE cluster and ensure it is enabled.

Example Bash loop:

# Example: categories derived from `log list-categories`
CATEGORIES=("cluster" "controlplane" "apiserver" "scheduler" "controller-manager" "audit")

for CATEGORY in "${CATEGORIES[@]}"; do
echo "Creating/enabling log for category: $CATEGORY"

oci logging log create \
--log-group-id "$LOG_GROUP_OCID" \
--display-name "oke-${CATEGORY}-log" \
--log-type "SERVICE" \
--is-enabled true \
--configuration '{
"source": {
"category": "'"$CATEGORY"'",
"resource": "'"$CLUSTER_OCID"'",
"service": "containerengine"
}
}'
done

Key points:

  • --log-type "SERVICE" for service logs.
  • --is-enabled true ensures logging is active.
  • No filter/retention restriction is applied here; every event of each category is captured.

4. (Optional) Verify Logs Are Enabled and Active

oci logging log list \
--log-group-id "$LOG_GROUP_OCID" \
--all \
--query 'data[].{name:"display-name",enabled:"is-enabled",category:"configuration.source.category"}'

Ensure all categories you care about are present and is-enabled is true.


OCI Audit is always on at the tenancy level, but ensure you are exporting them centrally:

# List Audit service log categories
oci logging log list-categories \
--compartment-id "$COMPARTMENT_OCID" \
--service "audit"

# Create a log for the audit service (no restriction)
oci logging log create \
--log-group-id "$LOG_GROUP_OCID" \
--display-name "tenancy-audit-log" \
--log-type "SERVICE" \
--is-enabled true \
--configuration '{
"source": {
"category": "audit",
"service": "audit"
}
}'

This configuration ensures OKE control plane / cluster and tenancy audit events are captured via Logging without category‑based restriction, which aligns with the requirement that security‑relevant events be captured comprehensively.

Using Python

Below is how you remediate “OCI OKE should capture security-relevant events without restriction” using Python and the OCI SDK, by enabling OKE service logs (especially audit) with no filters.

1. Prerequisites

  1. Install OCI SDK:
pip install oci
  1. Configure OCI CLI/SDK auth at ~/.oci/config:
[DEFAULT]
user=ocid1.user.oc1..xxxx
fingerprint=xx:xx:xx:xx
key_file=/path/to/private_key.pem
tenancy=ocid1.tenancy.oc1..xxxx
region=eu-frankfurt-1
  1. Collect:
  • compartment_ocid where the OKE cluster lives
  • cluster_ocid for the OKE cluster you want to fix

2. Python script to enable OKE audit (and other) logs without restriction

import oci

# -------- CONFIG --------
PROFILE = "DEFAULT"
COMPARTMENT_ID = "ocid1.compartment.oc1..xxxxx"
CLUSTER_OCID = "ocid1.cluster.oc1..xxxxx"
LOG_GROUP_NAME = "oke-security-logs"
# ------------------------

config = oci.config.from_file("~/.oci/config", PROFILE)
logging_client = oci.logging.LoggingManagementClient(config)

def get_or_create_log_group(compartment_id, log_group_name):
# Check if log group exists
existing = logging_client.list_log_groups(
compartment_id=compartment_id,
display_name=log_group_name,
lifecycle_state="ACTIVE"
).data

if existing:
return existing[0]

# Create if not
create_details = oci.logging.models.CreateLogGroupDetails(
compartment_id=compartment_id,
display_name=log_group_name,
description="Log group for OKE security-relevant logs"
)
response = logging_client.create_log_group(create_details)
oci.wait_until(
logging_client,
logging_client.get_log_group(response.data.id),
"lifecycle_state",
"ACTIVE"
)
return response.data

def find_containerengine_service(compartment_id):
# Discover the Container Engine (OKE) logging service
services = logging_client.list_services(compartment_id=compartment_id).data
for svc in services:
# Service name is usually "containerengine" or "oke"-like; print to verify if needed.
if svc.name.lower() in ("containerengine", "oke"):
return svc
raise RuntimeError("Could not find OKE/containerengine logging service in this compartment.")

def list_oke_log_categories(compartment_id, service_id):
categories = logging_client.list_log_categories(
compartment_id=compartment_id,
service_id=service_id
).data
return categories

def ensure_log_enabled_for_category(log_group_id, service, category_name, cluster_ocid):
# Check if log already exists
existing_logs = logging_client.list_logs(
log_group_id=log_group_id,
display_name=f"OKE-{category_name}",
lifecycle_state="ACTIVE"
).data

if existing_logs:
# Ensure it's enabled
log_id = existing_logs[0].id
log = logging_client.get_log(log_group_id, log_id).data
if not log.is_enabled:
update_details = oci.logging.models.UpdateLogDetails(
is_enabled=True
)
logging_client.update_log(
log_group_id=log_group_id,
log_id=log_id,
update_log_details=update_details
)
return

# Create log: no log_filter = no restriction (captures all events in that category)
create_log_details = oci.logging.models.CreateLogDetails(
display_name=f"OKE-{category_name}",
log_type="SERVICE",
is_enabled=True,
configuration=oci.logging.models.Configuration(
source=oci.logging.models.OciService(
# service / resource / category tell Logging which OKE stream to capture
service=service.name,
resource=CLUSTER_OCID,
category=category_name
)
# log_filter left empty to avoid any restriction
)
)

response = logging_client.create_log(
log_group_id=log_group_id,
create_log_details=create_log_details
)
oci.wait_until(
logging_client,
logging_client.get_log(log_group_id, response.data.id),
"lifecycle_state",
"ACTIVE"
)

def main():
# 1. Ensure log group exists
log_group = get_or_create_log_group(COMPARTMENT_ID, LOG_GROUP_NAME)

# 2. Find OKE (containerengine) logging service
oke_service = find_containerengine_service(COMPARTMENT_ID)

# 3. List available log categories for OKE
categories = list_oke_log_categories(COMPARTMENT_ID, oke_service.id)

# Security-relevant categories (names can vary by region/tenancy; print categories to verify)
# Common: "audit", "kubernetes", "apiserver", etc.
security_categories = {"audit", "kubernetes", "apiserver", "cluster"}

for cat in categories:
if cat.name.lower() in security_categories:
ensure_log_enabled_for_category(
log_group_id=log_group.id,
service=oke_service,
category_name=cat.name,
cluster_ocid=CLUSTER_OCID
)
print(f"Ensured OKE log category '{cat.name}' is enabled and unrestricted.")

if __name__ == "__main__":
main()

3. What this does (in terms of the requirement)

  • Creates (or reuses) a log group dedicated to OKE security logs.
  • Discovers the OKE logging service and its log categories.
  • For each security-relevant category (audit, etc.), creates a SERVICE log:
    • is_enabled=True
    • no log_filter configured → all events in that category are captured (no restriction).
  • Ensures existing logs are enabled if they were disabled.

If you paste the output of list_services / list_log_categories for your tenancy, I can adjust the exact security_categories for your environment.

Using Terraform
# Existing OKE cluster (for reference)
resource "oci_containerengine_cluster" "OKE_CLUSTER" {
# Replace with your existing cluster arguments
name = "OKE_CLUSTER_NAME"
compartment_id = "COMPARTMENT_OCID"
vcn_id = "VCN_OCID"
# ...
}

# Log group to hold OKE control plane / audit logs
resource "oci_logging_log_group" "OKE_LOG_GROUP" {
compartment_id = "COMPARTMENT_OCID" # REPLACE with the compartment that owns the cluster
display_name = "OKE_CLUSTER_SECURITY_LOGS" # REPLACE if desired
description = "Security-relevant OKE control plane logs"
}

# Enable all available OKE service logs (including audit / security-relevant events)
resource "oci_logging_log" "OKE_CLUSTER_ALL_LOGS" {
display_name = "OKE_CLUSTER_ALL_LOGS" # REPLACE if desired
log_group_id = oci_logging_log_group.OKE_LOG_GROUP.id
log_type = "SERVICE"

configuration {
source {
# "all" ensures no category-based truncation and captures every log category
category = "all"
service = "kubernetes" # OKE control plane logs
resource = oci_containerengine_cluster.OKE_CLUSTER.id
}
}

is_enabled = true
}

# (Optional but recommended) Object Storage bucket for tamper-evident archival
resource "oci_objectstorage_bucket" "OKE_LOG_ARCHIVE_BUCKET" {
compartment_id = "COMPARTMENT_OCID" # REPLACE
namespace = "OBJECT_STORAGE_NAMESPACE" # REPLACE
name = "oke-security-logs-archive" # REPLACE
storage_tier = "Standard"

# (Optional) Add retention rules / immutability here if required by your policy
# retention_rules { ... }
}

# (Optional but recommended) Service Connector: stream logs to the archive bucket
resource "oci_sch_service_connector" "OKE_LOG_SERVICE_CONNECTOR" {
compartment_id = "COMPARTMENT_OCID" # REPLACE
display_name = "oke-security-logs-to-objstore"

source {
kind = "logging"

log_sources {
log_group_id = oci_logging_log_group.OKE_LOG_GROUP.id
log_id = oci_logging_log.OKE_CLUSTER_ALL_LOGS.id
}
}

target {
kind = "objectstorage"

bucket {
bucket_name = oci_objectstorage_bucket.OKE_LOG_ARCHIVE_BUCKET.name
namespace = oci_objectstorage_bucket.OKE_LOG_ARCHIVE_BUCKET.namespace
}
}

state = "ACTIVE"
}

This change does not replace the existing oci_containerengine_cluster resource; it only adds logging and streaming resources around it.

To verify, terraform plan should show:

  • + creation of oci_logging_log_group.OKE_LOG_GROUP
  • + creation of oci_logging_log.OKE_CLUSTER_ALL_LOGS with is_enabled = true and category = "all"
  • + creation of oci_objectstorage_bucket.OKE_LOG_ARCHIVE_BUCKET (if included)
  • + creation of oci_sch_service_connector.OKE_LOG_SERVICE_CONNECTOR (if included)
  • ~ no changes to oci_containerengine_cluster.OKE_CLUSTER.