Skip to content

CRD Reference

Complete field reference for all 9 Zelyo Operator Custom Resource Definitions, including both spec and status fields.

SecurityPolicy

What it does: Defines security rules to continuously evaluate against your Kubernetes workloads. Think of it as a checklist of security requirements that Zelyo Operator checks automatically.

Spec

apiVersion: zelyo.ai/v1alpha1
kind: SecurityPolicy
metadata:
  name: enforce-security
  namespace: zelyo-system
spec:
  # Minimum severity to report. Findings below this level are filtered out.
  # Options: critical | high | medium | low | info
  severity: medium

  # Which pods to scan
  match:
    namespaces: ["production", "staging"]      # Scan pods in these namespaces
    excludeNamespaces: ["kube-system"]         # Skip these namespaces
    labelSelector:                              # Only scan pods with these labels
      matchLabels:
        app: my-app
    resourceKinds: ["Deployment", "StatefulSet"]  # Filter by owner kind

  # What to check
  rules:
    - name: non-root                            # Unique name for this rule
      type: container-security-context          # Scanner to use (see Scanners page)
      enforce: true                             # If true, violations block deployments
      params:                                   # Optional scanner-specific parameters
        key: value

  autoRemediate: false                          # Auto-create fix PRs (requires GitOps repo)
  schedule: "0 */6 * * *"                       # Cron schedule (empty = continuous scanning)
  notificationChannels: ["slack-alerts"]        # Where to send alerts

Available rule types: container-security-context, rbac-audit, image-vulnerability, network-policy, pod-security, secrets-exposure, resource-limits, privilege-escalation

Status

status:
  phase: Active                                 # Pending | Active | Error
  observedGeneration: 3                         # Last processed generation
  violationCount: 12                            # Number of findings from last scan
  lastEvaluated: "2026-03-03T15:30:00Z"         # When the last scan ran
  conditions:
    - type: Ready
      status: "True"
      reason: ReconcileSuccess
      message: "Policy is active and scanning"
      lastTransitionTime: "2026-03-03T15:30:00Z"
      observedGeneration: 3
    - type: ScanCompleted
      status: "True"
      reason: ViolationsFound
      message: "Scan completed: 12 violations found"

ClusterScan

What it does: Runs scheduled security scans across the cluster and saves results as ScanReport resources. Like a scheduled job that produces reports.

Spec

apiVersion: zelyo.ai/v1alpha1
kind: ClusterScan
metadata:
  name: nightly-scan
  namespace: zelyo-system
spec:
  schedule: "0 2 * * *"                         # Cron schedule
  scanners:                                     # Which scanners to run
    - container-security-context
    - resource-limits
    - image-vulnerability
    - pod-security
  scope:
    namespaces: ["production", "staging"]       # Which namespaces to scan
    excludeNamespaces: ["kube-system"]
  complianceFrameworks: ["cis", "nsa-cisa"]     # Compliance checks to include
  suspend: false                                # Pause scheduling
  historyLimit: 10                              # Max ScanReports to keep

Status

status:
  phase: Completed                              # Pending | Running | Completed | Failed
  observedGeneration: 1
  lastScheduleTime: "2026-03-03T02:00:00Z"      # When the scan was last triggered
  completedAt: "2026-03-03T02:05:30Z"           # When the scan finished
  findingsCount: 47                             # Total findings from last scan
  lastReportName: nightly-scan-1709481934       # Name of the latest ScanReport
  conditions:
    - type: ScanCompleted
      status: "True"
      reason: ScanSuccess
      message: "Scan completed: 47 findings across 120 resources"

Key behavior: When a ClusterScan is deleted, all its child ScanReports are automatically cleaned up via a finalizer.


ScanReport

What it does: Stores the results of a ClusterScan run. Created automatically by the ClusterScan controller — you don't create these yourself.

Spec (set by ClusterScan controller)

apiVersion: zelyo.ai/v1alpha1
kind: ScanReport
metadata:
  name: nightly-scan-1709481934
  namespace: zelyo-system
  ownerReferences:                              # Owned by the parent ClusterScan
    - apiVersion: zelyo.ai/v1alpha1
      kind: ClusterScan
      name: nightly-scan
spec:
  scanRef: nightly-scan                         # Parent ClusterScan name
  startedAt: "2026-03-03T02:00:00Z"
  completedAt: "2026-03-03T02:05:30Z"
  summary:
    totalFindings: 47
    critical: 3
    high: 12
    medium: 22
    low: 8
    info: 2
    resourcesScanned: 120
    passedControls: 340
    failedControls: 47
  findings:
    - ruleType: container-security-context
      severity: critical
      title: Container "app" runs as privileged
      description: "The container has privileged: true..."
      resourceKind: Pod
      resourceNamespace: production
      resourceName: my-app-6d8f9b4c5d-x2k9p
      recommendation: "Set privileged: false..."

Status

status:
  phase: Complete                               # Pending | Complete
  observedGeneration: 1
  acknowledged: false                           # Set to true after review

ZelyoConfig

What it does: Global operator configuration. Cluster-scoped, and only one instance is allowed (singleton).

Spec

apiVersion: zelyo.ai/v1alpha1
kind: ZelyoConfig
metadata:
  name: default                                 # Must be "default"
spec:
  mode: audit                                   # audit | protect

  llm:
    provider: openrouter                        # openrouter | openai | anthropic | azure-openai | ollama | custom
    model: "anthropic/claude-sonnet-4-20250514"
    apiKeySecret: zelyo-llm                  # Secret must have an "api-key" data key
    temperature: "0.1"
    maxTokensPerRequest: 4096

  tokenBudget:
    hourlyTokenLimit: 50000
    dailyTokenLimit: 500000
    monthlyTokenLimit: 10000000
    alertThresholdPercent: 80
    enableCaching: true
    batchingEnabled: true

  dashboard:
    enabled: true
    port: 8080

  telemetry:
    prometheusEnabled: true
    otelEnabled: false

Status

status:
  phase: Active                                 # Pending | Active | Degraded | Error
  observedGeneration: 1
  conditions:
    - type: Ready
      status: "True"
      reason: ReconcileSuccess
    - type: SecretResolved
      status: "True"
      reason: SecretFound
      message: "LLM API key secret validated"

Key behavior: If you try to create a second ZelyoConfig, the controller marks it as Degraded and records a warning event.


GitOpsRepository

What it does: Onboards a Git repository for drift detection and automated remediation PRs.

Spec

apiVersion: zelyo.ai/v1alpha1
kind: GitOpsRepository
metadata:
  name: infra-repo
  namespace: zelyo-system
spec:
  url: https://github.com/my-org/k8s-manifests
  branch: main
  paths: ["clusters/production/", "clusters/staging/"]
  provider: github                              # github | gitlab | bitbucket
  authSecret: github-creds                      # Secret with auth credentials
  syncStrategy: poll                            # poll | webhook
  pollIntervalSeconds: 300
  enableDriftDetection: true
  namespaceMapping:
    - repoPath: "clusters/production/"
      namespace: production

Status

status:
  phase: Synced                                 # Pending | Syncing | Synced | Error
  observedGeneration: 1
  lastSyncedCommit: "abc123def456"
  lastSyncTime: "2026-03-03T15:00:00Z"
  discoveredManifests: 42
  driftCount: 3
  lastError: ""
  conditions:
    - type: Ready
      status: "True"
      reason: ReconcileSuccess
    - type: SecretResolved
      status: "True"
      reason: SecretFound
    - type: GitOpsConnected
      status: "True"
      reason: RepoSynced

RemediationPolicy

What it does: Configures how Zelyo Operator generates and submits GitOps PRs for detected violations.

Spec

apiVersion: zelyo.ai/v1alpha1
kind: RemediationPolicy
metadata:
  name: auto-fix
  namespace: zelyo-system
spec:
  targetPolicies: ["enforce-security"]          # Empty = all policies
  gitOpsRepository: infra-repo                  # Must reference existing GitOpsRepository
  prTemplate:
    titlePrefix: "[Zelyo Operator]"
    labels: ["security", "auto-fix"]
    assignees: ["team-lead"]
    branchPrefix: "zelyo-operator/fix-"
  dryRun: false
  maxConcurrentPRs: 5
  autoMerge: false
  severityFilter: high

Status

status:
  phase: Active                                 # Pending | Active | Error
  observedGeneration: 1
  remediationsApplied: 15
  openPRs: 3
  lastRun: "2026-03-03T14:00:00Z"

CostPolicy

What it does: Monitors pod resource usage and identifies rightsizing and cost optimization opportunities.

Spec

apiVersion: zelyo.ai/v1alpha1
kind: CostPolicy
metadata:
  name: optimize-costs
  namespace: zelyo-system
spec:
  targetNamespaces: ["production"]
  resizeStrategy: conservative                  # conservative | moderate | aggressive
  budgetLimits:
    monthlyBudgetUSD: "5000"
    costIncreaseThresholdPercent: 20
  idleDetection:
    enabled: true
    cpuThresholdPercent: 5
    memoryThresholdPercent: 5
    idleDurationMinutes: 60

Status

status:
  phase: Active                                 # Pending | Active | Error
  observedGeneration: 1
  estimatedMonthlyCostUSD: "3200"
  rightsizingRecommendations: 8
  idleWorkloads: 2
  lastEvaluated: "2026-03-03T15:30:00Z"

MonitoringPolicy

What it does: Configures real-time monitoring, event filtering, and anomaly detection.

Spec

apiVersion: zelyo.ai/v1alpha1
kind: MonitoringPolicy
metadata:
  name: realtime-watch
  namespace: zelyo-system
spec:
  targetNamespaces: ["production"]
  notificationChannels: ["slack-alerts"]        # Must reference existing NotificationChannels
  eventFilters:
    types: ["Warning"]
    reasons: ["OOMKilled", "CrashLoopBackOff", "FailedScheduling"]
  logMonitoring:
    enabled: true
    patterns:
      - name: error-detection
        regex: "(?i)(error|exception|fatal|panic)"
        severity: high
  nodeMonitoring:
    enabled: true
    conditions: ["MemoryPressure", "DiskPressure"]
  anomalyDetection:
    enabled: true
    baselineDurationHours: 168                  # 7 days baseline
    sensitivityPercent: 80

Status

status:
  phase: Active                                 # Pending | Active | Error
  observedGeneration: 1
  activeIncidents: 0
  eventsProcessed: 15420
  lastEventTime: "2026-03-03T15:29:45Z"

NotificationChannel

What it does: Configures a destination for Zelyo Operator alerts and reports.

Spec

# Slack example
apiVersion: zelyo.ai/v1alpha1
kind: NotificationChannel
metadata:
  name: slack-alerts
  namespace: zelyo-system
spec:
  type: slack                                   # slack | msteams | pagerduty | alertmanager |
                                                # telegram | whatsapp | webhook | email
  credentialSecret: slack-token                 # Secret with channel credentials
  severityFilter: medium                        # Only alert on this severity and above
  rateLimit:
    maxPerHour: 60
    aggregateSeconds: 30
  slack:
    channel: "#zelyo-operator-alerts"

Status

status:
  phase: Active                                 # Pending | Active | Error
  observedGeneration: 1
  lastSentAt: "2026-03-03T15:25:00Z"
  notificationsSent: 342
  lastError: ""

Supported types: slack, msteams, pagerduty, alertmanager, telegram, whatsapp, webhook, email


Understanding Status Phases

Every Zelyo Operator resource goes through lifecycle phases. Here's what they mean:

Phase Meaning What to Do
Pending Resource was just created, not yet reconciled Wait — the controller will process it shortly
Active Resource is working correctly Nothing — everything is healthy
Synced (GitOps only) Repository is synced Nothing — everything is healthy
Completed (Scan only) Scan finished successfully Check the findings
Degraded Partially working (e.g., second ZelyoConfig) Check Events for details
Error Something went wrong Check conditions and Events for the error
Running (Scan only) Scan is currently in progress Wait for completion

Understanding Conditions

Every resource has a conditions array providing detailed status. The most common conditions:

Condition What It Means
Ready = True The resource is fully reconciled and operational
Ready = False Something is wrong — check the message field
SecretResolved = True A referenced Secret was found and validated
SecretResolved = False A referenced Secret is missing or invalid
ScanCompleted = True A scan has finished
GitOpsConnected = True A referenced GitOps repository is accessible

Checking Conditions

# Quick status check
kubectl get securitypolicies -A

# Detailed conditions
kubectl get securitypolicy my-policy -o jsonpath='{.status.conditions}' | jq .

# Or use describe
kubectl describe securitypolicy my-policy