Kubernetes Operator
The DriftWise Kubernetes Operator reports live cluster resources to DriftWise for drift detection against Terraform-managed infrastructure. Resources discovered by the operator appear alongside cloud resources in your drift results.
How It Works
- The operator runs in your cluster and watches for resources
- Periodically POSTs discovered resources to
POST /api/v2/operator/report - DriftWise stores them as live resources linked to the cluster
- Drift detection compares them against your Terraform state
Authentication
The operator endpoint requires an org-scoped API key. OIDC
authentication is rejected with 403 — this is a machine-to-machine
path where human attribution would just be misleading.
Create an API key for the operator through the dashboard Settings page, then store it as a Kubernetes secret:
kubectl create secret generic driftwise-operator \
--from-literal=api-key=dw2_...
Reporting Resources
The operator POSTs discovered resources to
POST /api/v2/operator/report on its polling interval. DriftWise
creates a synthetic cloud_accounts row per cluster
(provider=kubernetes) so live_resources.cloud_account_id resolves;
cloud scan workers skip those rows.
See the accounts tag of the API
reference for the request
body shape (OperatorReportRequest) and response
(OperatorReportResponse). Key request fields summarized below.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
cluster_id | string | yes | Unique identifier for the cluster |
namespace | string | yes | Kubernetes namespace being reported |
resources | Resource[] | yes | Array of discovered resources |
generate_iac | bool | no | Generate Terraform from discovered resources |
iac_format | string | no | IaC output format (default: Terraform) |
custom_prompt | string | no | Custom instructions for IaC generation |
Response
{
"report_id": "scan-run-uuid",
"resource_count": 15
}
The report_id is a scan run ID — use it to query drift results via GET /api/v2/orgs/:id/scans/:scan_id/drift.
Resource Structure
Each resource in the resources array:
| Field | Type | Description |
|---|---|---|
id | string | Unique resource identifier within the cluster |
normalized_type | string | Must use the k8s/<kind> format (e.g., k8s/deployment, k8s/pod, k8s/service, k8s/statefulset). Unlike cloud resources, Kubernetes types are kept fine-grained — they are not flattened to broad categories by Cloud Discovery. |
provider_type | string | The Kubernetes kind in lowercase (e.g., deployment, pod, service) |
provider | string | Always "kubernetes" |
name | string | Resource name |
region | string | Cluster region |
tags | object | Labels as key-value pairs |
properties | object | Resource-specific attributes |
Rate Limiting
The operator endpoint allows 120 requests per minute per IP address, designed for the typical ~30-second polling interval.
Drift Detection with K8s Resources
Once resources are reported, they participate in the normal drift detection flow:
- Operator reports resources → stored as live resources
- Terraform state sources provide IaC resources
- Drift computation matches live vs. IaC by resource ID
- Missing/extra/changed items appear in drift results
Resources are grouped by cluster using the cluster_id field (stored as k8s:<cluster_id> internally).