Cybersecurity

Crossplane Composition Audit Trail Logging

crossplane composition audit trail logging
Crossplane Composition Audit Trail Logging | SiamCafe Blog
2025-12-18· อ. บอม — SiamCafe.net· 8,585 คำ

Crossplane Audit Trail

Crossplane Composition Audit Trail Logging Kubernetes CRD Provider Claim XRD ELK Stack Falco OPA Gatekeeper GitOps Compliance

ComponentRoleData SourceOutput
K8s Audit LogAPI Request Loggingkube-apiserverJSON Log File
FilebeatLog CollectionAudit Log File→ Logstash/ES
LogstashLog ProcessingFilebeat→ Elasticsearch
ElasticsearchLog Storage + SearchLogstashIndex
KibanaDashboard + AlertElasticsearchVisualization
FalcoRuntime SecuritySyscalls + K8s APIAlert

Audit Policy Configuration

# === Kubernetes Audit Policy for Crossplane ===

# /etc/kubernetes/audit-policy.yaml
# apiVersion: audit.k8s.io/v1
# kind: Policy
# rules:
#   # Log all Crossplane resource changes at RequestResponse level
#   - level: RequestResponse
#     resources:
#       - group: "*.crossplane.io"
#       - group: "*.aws.crossplane.io"
#       - group: "*.gcp.crossplane.io"
#       - group: "*.azure.crossplane.io"
#     verbs: ["create", "update", "patch", "delete"]
#
#   # Log Composition and XRD changes
#   - level: RequestResponse
#     resources:
#       - group: "apiextensions.crossplane.io"
#         resources: ["compositions", "compositeresourcedefinitions"]
#     verbs: ["create", "update", "patch", "delete"]
#
#   # Log Claims
#   - level: Metadata
#     resources:
#       - group: "*.crossplane.io"
#     verbs: ["get", "list", "watch"]
#
#   # Log RBAC changes for Crossplane service accounts
#   - level: RequestResponse
#     resources:
#       - group: "rbac.authorization.k8s.io"
#     verbs: ["create", "update", "patch", "delete"]
#     namespaces: ["crossplane-system"]

# kube-apiserver flags
# --audit-policy-file=/etc/kubernetes/audit-policy.yaml
# --audit-log-path=/var/log/kubernetes/audit.log
# --audit-log-maxage=30
# --audit-log-maxbackup=10
# --audit-log-maxsize=100

from dataclasses import dataclass

@dataclass
class AuditRule:
    resource: str
    level: str
    verbs: str
    reason: str

rules = [
    AuditRule("*.crossplane.io (Managed Resources)",
        "RequestResponse",
        "create, update, patch, delete",
        "บันทึกทุกการเปลี่ยนแปลง Cloud Resources"),
    AuditRule("Compositions / XRDs",
        "RequestResponse",
        "create, update, patch, delete",
        "บันทึกการเปลี่ยน Infrastructure Template"),
    AuditRule("Claims",
        "Metadata",
        "get, list, watch",
        "บันทึก Developer ขอ Resource อะไร"),
    AuditRule("RBAC (crossplane-system)",
        "RequestResponse",
        "create, update, patch, delete",
        "บันทึกการเปลี่ยน Permission"),
    AuditRule("Secrets (crossplane-system)",
        "Metadata",
        "create, update, delete",
        "บันทึก Cloud Credentials Change (ไม่เก็บ Value)"),
]

print("=== Audit Rules ===")
for r in rules:
    print(f"  [{r.resource}] Level: {r.level}")
    print(f"    Verbs: {r.verbs}")
    print(f"    Reason: {r.reason}")

ELK Stack Integration

# === ELK Stack for Crossplane Audit ===

# Filebeat config (filebeat.yml)
# filebeat.inputs:
#   - type: log
#     paths:
#       - /var/log/kubernetes/audit.log
#     json.keys_under_root: true
#     json.add_error_key: true
#     fields:
#       log_type: crossplane-audit
#
# output.logstash:
#   hosts: ["logstash:5044"]

# Logstash pipeline (crossplane-audit.conf)
# filter {
#   if [log_type] == "crossplane-audit" {
#     json { source => "message" }
#     mutate {
#       add_field => {
#         "crossplane_action" => "%{[verb]}"
#         "crossplane_user" => "%{[user][username]}"
#         "crossplane_resource" => "%{[objectRef][resource]}"
#         "crossplane_name" => "%{[objectRef][name]}"
#         "crossplane_namespace" => "%{[objectRef][namespace]}"
#       }
#     }
#     # Filter only Crossplane resources
#     if [objectRef][apiGroup] !~ /crossplane/ { drop {} }
#   }
# }
# output {
#   elasticsearch {
#     hosts => ["elasticsearch:9200"]
#     index => "crossplane-audit-%{+YYYY.MM.dd}"
#   }
# }

@dataclass
class KibanaDashboard:
    panel: str
    visualization: str
    query: str
    use_case: str

dashboards = [
    KibanaDashboard("Resource Lifecycle",
        "Time Series (create/update/delete count)",
        "crossplane_action:(create OR update OR delete)",
        "ดู Resource สร้าง/แก้/ลบ ต่อวัน"),
    KibanaDashboard("User Activity",
        "Data Table (user, action, resource, count)",
        "crossplane_user:* | top 20 by count",
        "ดูว่าใครทำอะไรบ้าง กี่ครั้ง"),
    KibanaDashboard("Resource Types",
        "Pie Chart (resource type distribution)",
        "crossplane_resource:* | terms",
        "ดู Resource ประเภทไหนถูกสร้างมากที่สุด"),
    KibanaDashboard("Manual Changes",
        "Table (non-GitOps changes)",
        "crossplane_user:NOT(system:serviceaccount:*)",
        "ตรวจจับ Manual Changes นอก GitOps"),
    KibanaDashboard("Failed Operations",
        "Time Series (responseStatus.code >= 400)",
        "responseStatus.code:[400 TO 599]",
        "ตรวจจับ Permission Denied Validation Error"),
]

print("=== Kibana Dashboards ===")
for d in dashboards:
    print(f"  [{d.panel}] {d.visualization}")
    print(f"    Query: {d.query}")
    print(f"    Use: {d.use_case}")

Alerting & Compliance

# === Audit Alerting ===

@dataclass
class AuditAlert:
    alert: str
    condition: str
    severity: str
    action: str

alerts = [
    AuditAlert("Manual Resource Deletion",
        "verb=delete AND user NOT serviceaccount",
        "Critical",
        "ตรวจสอบว่า Authorized ไหม แจ้ง Team Lead"),
    AuditAlert("Resource Created Outside GitOps",
        "verb=create AND user NOT (flux/argocd/crossplane)",
        "Warning",
        "แจ้ง Developer ให้ใช้ GitOps แทน Manual"),
    AuditAlert("Composition Changed",
        "resource=compositions AND verb=(update|patch)",
        "High",
        "ตรวจสอบ Change ถูกต้อง Review PR"),
    AuditAlert("Permission Escalation",
        "resource=clusterrolebindings AND namespace=crossplane-system",
        "Critical",
        "ตรวจสอบ RBAC Change Security Review"),
    AuditAlert("Cloud Credentials Modified",
        "resource=secrets AND namespace=crossplane-system",
        "Critical",
        "ตรวจสอบ Credentials Rotation หรือ Unauthorized"),
    AuditAlert("High Volume Resource Creation",
        "verb=create count > 50 in 1 hour",
        "Warning",
        "อาจเป็น Misconfigured Composition หรือ Loop"),
]

print("=== Audit Alerts ===")
for a in alerts:
    print(f"  [{a.alert}] Severity: {a.severity}")
    print(f"    Condition: {a.condition}")
    print(f"    Action: {a.action}")

เคล็ดลับ

Crossplane คืออะไร

Infrastructure as Code Kubernetes CRD Provider AWS GCP Azure Composition Claim XRD kubectl apply GitOps Flux ArgoCD Open Source

Composition คืออะไร

Template รวม Managed Resources XRD Schema Claim Developer ขอ Resource Patch Parameters Environment Config Composite Resource

Audit Trail ทำอย่างไร

Kubernetes Audit Policy RequestResponse Falco Runtime OPA Gatekeeper Kyverno Policy ELK Stack Filebeat Logstash Elasticsearch Kibana Dashboard

ELK Stack ตั้งค่าอย่างไร

Filebeat Audit Log JSON Logstash Filter Parse Elasticsearch Index crossplane-audit Kibana Dashboard Lifecycle User Activity Compliance Alert

สรุป

Crossplane Composition Audit Trail Logging Kubernetes CRD ELK Stack Falco OPA GitOps Compliance Dashboard Alert Production

📖 บทความที่เกี่ยวข้อง

Apache Kafka Streams Audit Trail Loggingอ่านบทความ → DNSSEC Implementation Audit Trail Loggingอ่านบทความ → BigQuery Scheduled Query Audit Trail Loggingอ่านบทความ → MetalLB Load Balancer Audit Trail Loggingอ่านบทความ → Snowflake Snowpark Audit Trail Loggingอ่านบทความ →

📚 ดูบทความทั้งหมด →