Compliance Reports

Policies API v1 endpoints for compliance reports, history, and namespace compliance.

Read compliance reports per standard and target, drill into failing controls, export snapshots, view score history, and read namespace-level compliance.

All paths are relative to /policies/api/v1. See Policies API v1 for authentication and conventions.

Endpoints

OperationMethodPath
Get compliance score or control historyGET/compliance/kyverno/history
Get namespace compliance settingsGET/compliance/kyverno/namespace-config
Update namespace compliance settingsPUT/compliance/kyverno/namespace-config
List current namespace compliance reportsGET/compliance/kyverno/namespace-reports
List compliance reportsGET/compliance/kyverno/reports
Export a compliance snapshotGET/compliance/kyverno/reports/export
List targets with compliance reportsGET/compliance/kyverno/reports/targets
Get a compliance reportGET/compliance/kyverno/reports/{id}
Get a namespace compliance snapshotGET/compliance/kyverno/reports/{reportId}/namespaces/{namespace}
List failing resources for a report controlGET/compliance/kyverno/reports/{id}/controls/{controlId}/findings
List namespace findings for a controlGET/compliance/kyverno/reports/{reportId}/namespaces/{namespace}/controls/{controlId}/findings

Reference

Get compliance score or control history

GET /policies/api/v1/compliance/kyverno/history

Without controlId, returns the score trend for a target and standard; points exist only when results changed, so charts should carry the last value forward. With controlId, returns one point per completed scan for that control. Range defaults to the last 90 days.

Roles: admin, platform, security, devops

Query parameters

NameTypeRequiredDefaultDescription
targetIdstringYes—Target ID (UUID)
standardstringYes—Standard key
controlIdstringNo—Return control-level history for this control instead of score history
fromstringNo—ISO-8601 start; default 90 days before ’to'
tostringNo—ISO-8601 end; default now

Response 200 (application/json)

Array, ascending by time: score points {time, score, passControls, failControls, totalControls, level} or, with controlId, {time, controlId, status, passCount, failCount}

FieldTypeDescription
timestring (date-time)—
scorenumber0-100 (score history)
passControlsinteger—
failControlsinteger—
totalControlsinteger—
levelstringgreen | yellow | red | unknown
controlIdstring(control history)
statusstringpass | fail | not_evaluated | not_automatable (control history)
passCountinteger(control history)
failCountinteger(control history)

Errors

  • 400 — targetId/standard missing, targetId not a UUID, or invalid from/to
  • 400 — Control history range exceeds the maximum points (default 5000; code CONTROL_HISTORY_RANGE_TOO_LARGE) - narrow from/to
  • 401 — Not authenticated
  • 403 — Caller’s role is not in the allowed roles

Get namespace compliance settings

GET /policies/api/v1/compliance/kyverno/namespace-config

Returns the namespace compliance settings for a cluster. If none have been saved, returns a disabled configuration at revision 0.

Roles: admin, security

Query parameters

NameTypeRequiredDefaultDescription
targetIdstringYes—Cluster ID (UUID)

Response 200 (application/json)

NamespaceComplianceConfigDto

FieldTypeDescription
targetIdstring (uuid)Cluster ID
featureEnabledbooleanWhether this deployment supports namespace compliance
enabledboolean—
modestringall | specific (nullable)
namespacesstring[]Selected namespaces (specific mode)
revisionintegerUse as expectedRevision on update
createdBystring—
updatedBystring—
createdAtstring (date-time)—
updatedAtstring (date-time)—

Errors

  • 400 — targetId not a UUID (INVALID_TARGET_ID)
  • 404 — Cluster not found or inaccessible
  • 401 — Not authenticated
  • 403 — Caller’s role is not in the allowed roles

Update namespace compliance settings

PUT /policies/api/v1/compliance/kyverno/namespace-config

Saves which namespaces of a cluster get namespace-level compliance views: all namespaces or a specific list. Uses optimistic concurrency: expectedRevision must equal the current revision (0 to create).

Roles: admin, security

Query parameters

NameTypeRequiredDefaultDescription
targetIdstringYes—Cluster ID (UUID)

Request body (application/json)

FieldTypeRequiredDescription
enabledbooleanYes—
modestringNoall | specific; required when enabled or namespaces non-empty
namespacesstring[]YesValid Kubernetes namespace names; must be empty for all mode, non-empty for specific mode when enabled; use [] when none
expectedRevisionintegerYesCurrent revision from GET (>=0)

Response 200 (application/json)

NamespaceComplianceConfigDto

FieldTypeDescription
targetIdstring (uuid)Cluster ID
featureEnabledbooleanWhether this deployment supports namespace compliance
enabledboolean—
modestringall | specific (nullable)
namespacesstring[]Selected namespaces (specific mode)
revisionintegerUse as expectedRevision on update
createdBystring—
updatedBystring—
createdAtstring (date-time)—
updatedAtstring (date-time)—

Errors

  • 400 — Invalid target, body, mode or namespace selection (e.g. ENABLED_REQUIRED, EXPECTED_REVISION_REQUIRED, NAMESPACES_REQUIRED, NAMESPACE_MODE_REQUIRED, NAMESPACES_NOT_ALLOWED, INVALID_NAMESPACE)
  • 404 — Cluster not found or inaccessible
  • 409 — Revision mismatch (CONFIG_REVISION_CONFLICT) or feature not available in this deployment (NAMESPACE_COMPLIANCE_UNAVAILABLE)
  • 401 — Not authenticated
  • 403 — Caller’s role is not in the allowed roles

Example

{"enabled":true,"mode":"specific","namespaces":["payments","web"],"expectedRevision":0}

List current namespace compliance reports

GET /policies/api/v1/compliance/kyverno/namespace-reports

For a cluster and namespace, returns the latest completed report per standard projected onto that namespace, along with the current scope state. Never falls back to an older snapshot; if the namespace is not selected or data is pending, availability explains why.

Roles: admin, platform, security, devops

Query parameters

NameTypeRequiredDefaultDescription
targetIdstringYes—Cluster ID (UUID)
namespacestringYes—Kubernetes namespace
standardstringNo—Filter by standard key
pageintegerNo00-based page
sizeintegerNo50Page size, clamped to 1-100

Response 200 (application/json)

NamespaceComplianceReportsResponseDto

FieldTypeDescription
targetIdstring (uuid)—
namespacestring—
featureEnabledboolean—
enabledboolean—
modestringall | specific
selectedNamespacesstring[]Empty unless caller has admin/platform/security role
configRevisioninteger—
availabilitystringdisabled | not_selected | pending | available | no_data | projection_unavailable | unsupported_scope
reasonstring—
reportsobjectPage: {content: T[], totalElements, totalPages, number (0-based page), size} of {parentReportId, targetId, namespace, standard, scanTimestamp, projectionVersion, availability, reason, summary: {score (nullable 0-100), passCount, failCount, totalCount, notEvaluatedCount, notAutomatableCount, level}}

Errors

  • 400 — Invalid targetId or namespace
  • 404 — Cluster or namespace not found or inaccessible
  • 401 — Not authenticated
  • 403 — Caller’s role is not in the allowed roles

List compliance reports

GET /policies/api/v1/compliance/kyverno/reports

Lists completed compliance reports. By default (latest=true) returns the most recent completed report for each target and standard combination as an unpaginated array; with latest=false returns all completed reports, newest first, paginated.

Roles: admin, platform, security, devops

Query parameters

NameTypeRequiredDefaultDescription
targetIdstringNo—Filter by target ID (UUID)
targetTypestringNo—Filter by target type, e.g. cluster
standardstringNo—Filter by standard key
levelstringNo—Filter by level: green | yellow | red | unknown
latestbooleanNotrueReturn only the latest report per target and standard
pageintegerNo00-based page (latest=false only)
sizeintegerNo50Page size, clamped to 1-100 (latest=false only)

Response 200 (application/json)

latest=true: ComplianceReportDto[]; latest=false: Page: {content: T[], totalElements, totalPages, number (0-based page), size} of ComplianceReportDto

FieldTypeDescription
idstring (uuid)Report ID
targetIdstring (uuid)Scanned target (cluster/repository) ID
targetTypestringTarget type, e.g. cluster, repository
targetNamestringTarget display name
standardstringStandard key, e.g. soc2
standardDisplayNamestringHuman-readable standard name
scanTimestampstring (date-time)When the scan ran
statusstringReport status (lists only return completed)
triggerTypestringscheduled | on_demand | published
summaryobject{score (0-100, null if nothing evaluated), passCount, failCount, totalCount, notEvaluatedCount, notAutomatableCount, level: green|yellow|red|unknown}

Errors

  • 400 — targetId is not a valid UUID
  • 401 — Not authenticated
  • 403 — Caller’s role is not in the allowed roles

Export a compliance snapshot

GET /policies/api/v1/compliance/kyverno/reports/export

Returns the most recent completed report for a target and standard at or before asOf, in the nctl snapshot JSON format (snake_case control fields) so it can be used with nctl compliance diff. Includes per-control findings and structured exception details.

Roles: admin, platform, security, devops

Query parameters

NameTypeRequiredDefaultDescription
targetIdstringYes—Target ID (UUID)
standardstringYes—Standard key
asOfstringNo—ISO-8601 date-time with offset; defaults to now

Response 200 (application/json)

nctl-compatible snapshot

FieldTypeDescription
idstringSnapshot ID in yyyyMMdd-HHmmss form
standardstring—
targetstringTarget name
targetTypestring—
timestampstring (date-time)Scan time
exceptionsstring[]Policy exceptions in effect
exceptionDetailsobject[]{name, namespace, policies[], managed, requestedBy, approvedBy, reason, state, startTime, expiryTime, history[]}
controlsobject[]{id, policy, policy_count, status, pass_count, fail_count, findings[]}

Errors

  • 400 — targetId/standard missing, targetId not a UUID, or invalid asOf
  • 404 — No completed snapshot at or before asOf
  • 401 — Not authenticated
  • 403 — Caller’s role is not in the allowed roles

List targets with compliance reports

GET /policies/api/v1/compliance/kyverno/reports/targets

Returns each target that has at least one completed compliance report, with its most recent name, ordered by type and name. Useful for populating target pickers.

Roles: admin, platform, security, devops

Response 200 (application/json)

Array of {targetId, targetName, targetType}

FieldTypeDescription
targetIdstring (uuid)—
targetNamestring—
targetTypestringcluster | repository | cloud_account

Errors

  • 401 — Not authenticated
  • 403 — Caller’s role is not in the allowed roles

Get a compliance report

GET /policies/api/v1/compliance/kyverno/reports/{id}

Returns one compliance report with its per-control results. For failed scans, errorMessage explains the failure.

Roles: admin, platform, security, devops

Path parameters

NameTypeDescription
idstringReport ID (UUID)

Response 200 (application/json)

ComplianceReportDto with controls[]

FieldTypeDescription
idstring (uuid)Report ID
targetIdstring (uuid)Scanned target (cluster/repository) ID
targetTypestringTarget type, e.g. cluster, repository
targetNamestringTarget display name
standardstringStandard key, e.g. soc2
standardDisplayNamestringHuman-readable standard name
scanTimestampstring (date-time)When the scan ran
statusstringReport status (lists only return completed)
triggerTypestringscheduled | on_demand | published
summaryobject{score (0-100, null if nothing evaluated), passCount, failCount, totalCount, notEvaluatedCount, notAutomatableCount, level: green|yellow|red|unknown}
errorMessagestringSet when status is failed
controlsobject[]{controlId, status: pass|fail|not_evaluated|not_automatable, passCount, failCount, policiesTotal, policiesEvaluated, primaryPolicy, failingPolicies[], allPolicies[], notAutomatableReason}

Errors

  • 400 — id is not a valid UUID
  • 404 — Report not found in this tenant (empty body)
  • 401 — Not authenticated
  • 403 — Caller’s role is not in the allowed roles

Get a namespace compliance snapshot

GET /policies/api/v1/compliance/kyverno/reports/{reportId}/namespaces/{namespace}

Returns the immutable namespace-level view of a cluster compliance report, including per-control results. If no namespace data exists for that report, availability and reason explain why.

Roles: admin, platform, security, devops

Path parameters

NameTypeDescription
reportIdstringParent cluster report ID (UUID)
namespacestringKubernetes namespace

Response 200 (application/json)

NamespaceComplianceReportDetailDto

FieldTypeDescription
parentReportIdstring (uuid)—
targetIdstring (uuid)—
namespacestring—
standardstring—
scanTimestampstring (date-time)—
projectionVersioninteger—
configRevisioninteger—
selectionModestringall | specific
selectedNamespacesstring[]Empty unless caller has cluster-wide access
availabilitystringdisabled | not_selected | pending | available | no_data | projection_unavailable | unsupported_scope
reasonstring—
summaryobject{score (nullable 0-100), passCount, failCount, totalCount, notEvaluatedCount, notAutomatableCount, level}
controlsobject[]{controlId, status: pass|fail|not_evaluated|not_automatable, passCount, failCount, policiesTotal, policiesEvaluated, primaryPolicy, failingPolicies[], allPolicies[], notAutomatableReason}

Errors

  • 400 — Invalid reportId (INVALID_REPORT_ID) or namespace (INVALID_NAMESPACE)
  • 404 — Report, cluster or namespace not found or inaccessible
  • 500 — Stored snapshot is invalid (NAMESPACE_SNAPSHOT_CORRUPT)
  • 401 — Not authenticated
  • 403 — Caller’s role is not in the allowed roles

List failing resources for a report control

GET /policies/api/v1/compliance/kyverno/reports/{id}/controls/{controlId}/findings

Returns a paginated list of the failing or warning resources captured for one control of a report, ordered by namespace, kind and name. Returns an empty page if no evidence was captured for the control (including older reports).

Roles: admin, platform, security, devops

Path parameters

NameTypeDescription
idstringReport ID (UUID)
controlIdstringControl ID within the standard, e.g. CC6.1

Query parameters

NameTypeRequiredDefaultDescription
pageintegerNo00-based page
sizeintegerNo50Page size, clamped to 1-100

Response 200 (application/json)

Page: {content: T[], totalElements, totalPages, number (0-based page), size} of findings

FieldTypeDescription
policyNamestringKyverno policy
ruleNamestringPolicy rule
resourceKindstringResource kind
resourceNamestringResource name
resourceNamespacestringResource namespace
messagestringPolicy result message
resultstringPolicy result, e.g. fail or warn

Errors

  • 400 — id is not a valid UUID (code INVALID_ID)
  • 404 — Report not found in this tenant (code REPORT_NOT_FOUND)
  • 401 — Not authenticated
  • 403 — Caller’s role is not in the allowed roles

List namespace findings for a control

GET /policies/api/v1/compliance/kyverno/reports/{reportId}/namespaces/{namespace}/controls/{controlId}/findings

Returns a page of the retained failing-resource evidence for one control in a namespace snapshot. Evidence is sampled (up to 50 per control); totalElements counts retained findings and aggregateFailCount gives the true failure count.

Roles: admin, platform, security, devops

Path parameters

NameTypeDescription
reportIdstringParent report ID (UUID)
namespacestringKubernetes namespace
controlIdstringControl ID

Query parameters

NameTypeRequiredDefaultDescription
pageintegerNo00-based page
sizeintegerNo50Page size, clamped to 1-100

Response 200 (application/json)

{content: Finding[], totalElements, totalPages, number, size, sampleLimit, sampled, aggregateFailCount}

FieldTypeDescription
policyNamestringKyverno policy
ruleNamestringPolicy rule
resourceKindstringResource kind
resourceNamestringResource name
resourceNamespacestringResource namespace
messagestringPolicy result message
resultstringPolicy result, e.g. fail or warn
sampleLimitintegerMax findings retained per control (50)
sampledbooleanTrue when failures exceed retained evidence
aggregateFailCountintegerTotal failing evaluations

Errors

  • 400 — Invalid reportId, namespace, or blank controlId
  • 404 — Report/namespace not found or inaccessible, or CONTROL_NOT_FOUND
  • 409 — No available namespace snapshot for this report (NAMESPACE_SNAPSHOT_UNAVAILABLE)
  • 500 — NAMESPACE_SNAPSHOT_CORRUPT
  • 401 — Not authenticated
  • 403 — Caller’s role is not in the allowed roles