Introduction
In Week 1, we defined the framework architecture and set the direction.
In Week 2, we explored the RSC GraphQL schema and the Connection -> Node pattern.
In Week 3, we implemented rkRscGetToken() for secure, reusable OAuth2 authentication.
In Week 4, we executed our first real GraphQL query and established the execution pattern the framework follows.
In Week 5, we extended rkGetSLAs() with cursor-based pagination and retention normalization.
In Week 6, we introduced the Snappable model and built rkGetSnapshotCount() to retrieve snapshot statistics across VMware VMs and filesets.
Snapshot counts give you operational visibility. But they do not answer the question that matters most in any backup environment.
Which workloads are actually protected?
Knowing that a VM has 42 snapshots tells you about history. It does not tell you whether Rubrik considers that workload protected today, or whether it is meeting its SLA objectives. Those are separate evaluations, and Rubrik Security Cloud performs them internally and exposes the results through GraphQL.
This week, we build on the Snappable model to introduce a new helper:
rkGetProtectionStatus()This function retrieves workload protection intelligence directly from RSC: effective SLA assignment, protection state, and compliance state, all in one query.
Reusing the Snappable Model
In Week 6, we used snappableConnection to retrieve snapshot statistics. This week, we use the exact same object to retrieve protection intelligence.
The workload types are identical: VMware VMs, filesets, MSSQL databases, Oracle databases, NAS shares, cloud workloads, and Kubernetes objects. The query structure is identical. Only the fields we request change.
This is one of the practical benefits of the RSC GraphQL design: a single operational object supports multiple reporting and automation workflows without requiring separate API surface for each.
Understanding Protection Status
Protection status in RSC is not a simple snapshot-exists check. When RSC evaluates a workload, it considers the effective SLA assignment, snapshot availability, backup freshness, compliance against SLA objectives, and recovery capability. The result of that evaluation is exposed directly through GraphQL.
This means the framework does not need to recreate protection logic. RSC has already done that work. We consume the result.
The three fields that matter:
effectiveSlaDomain {
id
name
}
protectionStatus
complianceStatus
Understanding Effective SLA Domains
The field name effectiveSlaDomain is deliberate and worth understanding.
An SLA applied to a workload is not always assigned directly to that object. It can be inherited from a VM assignment, a cluster assignment, a vCenter assignment, or organizational hierarchy. RSC resolves those inheritance rules and surfaces the final governing policy through effectiveSlaDomain.
This is the SLA that actually controls protection behavior. When evaluating protection gaps, this is the field to query.
Protection and Compliance States
Common values for protectionStatus:
Common values for complianceStatus:
In practice: no SLA assignment typically produces UNPROTECTED. Missing or stale snapshots typically produce NON_COMPLIANT. These two states together cover the majority of protection gaps in real environments.
Practitioner Tip "Do not use snapshot counts alone when evaluating protection. A workload can have snapshots and still be considered non-compliant by RSC. Always rely on protectionStatus and complianceStatus. These fields already encode RSC's internal protection evaluation logic. Trust the platform's assessment rather than rebuilding your own evaluation rules on top of raw counts." |
The Query
The snappableConnection query this week adds protection fields to what we built in Week 6:
query SnappableProtectionStatus {
snappableConnection(
filter: {
objectType: VmwareVirtualMachine
}
first: 1000
) {
nodes {
name
fid
objectType
effectiveSlaDomain {
id
name
}
protectionStatus
complianceStatus
totalSnapshots
localSnapshots
}
}
} A single query returns workload identity, applied SLA, protection state, compliance state, and snapshot counts. Everything needed for a protection audit in one call.
Validate this in the RSC GraphQL Playground before writing PHP against it. Confirm that protectionStatus and complianceStatus return the expected enum values for known workloads in your environment before building automation on top of them.
Implementing rkGetProtectionStatus()
The function follows the same structure established in Week 6: sanitize the enum, build the query, execute via rkCallGraphQL(), validate the response, normalize, and optionally filter by object name.
<?php
/**
* Retrieve workload protection information
* from Rubrik Security Cloud.
*
* @param string $accessToken
* @param string|null $objectName
* @param string $objectType
*
* @return array|null
*/
function rkGetProtectionStatus(
string $accessToken,
?string $objectName = null,
string $objectType = 'VmwareVirtualMachine'
): ?array
{
// ----------------------------------------
// Sanitize GraphQL enum
// ----------------------------------------
$objectTypeEnum = preg_replace(
'/[^A-Za-z0-9_]/',
'',
$objectType
);
// ----------------------------------------
// Build query
// ----------------------------------------
$query = <<<GQL
query SnappableProtectionStatus {
snappableConnection(
filter: {
objectType: $objectTypeEnum
}
first: 1000
) {
nodes {
name
fid
objectType
effectiveSlaDomain {
id
name
}
protectionStatus
complianceStatus
totalSnapshots
localSnapshots
}
}
}
GQL;
// ----------------------------------------
// Execute query
// ----------------------------------------
$response = rkCallGraphQL($accessToken, $query);
// ----------------------------------------
// Validate response structure
// ----------------------------------------
if (!isset($response['data']['snappableConnection']['nodes']))
{
throw new RuntimeException(
'Unexpected GraphQL response structure in rkGetProtectionStatus().'
);
}
// ----------------------------------------
// Normalize results
// ----------------------------------------
$results = [];
foreach ($response['data']['snappableConnection']['nodes'] as $node)
{
$results[] = [
'name' => $node['name'] ?? '',
'fid' => $node['fid'] ?? '',
'objectType' => $node['objectType'] ?? '',
'slaName' => $node['effectiveSlaDomain']['name'] ?? 'NONE',
'protectionStatus' => $node['protectionStatus'] ?? 'UNKNOWN',
'complianceStatus' => $node['complianceStatus'] ?? 'UNKNOWN',
'totalSnapshots' => $node['totalSnapshots'] ?? 0,
'localSnapshots' => $node['localSnapshots'] ?? 0,
];
}
// ----------------------------------------
// Return full result set if no name filter
// ----------------------------------------
if ($objectName === null || $objectName === '')
{
return $results;
}
// ----------------------------------------
// Return single matching object
// ----------------------------------------
foreach ($results as $item)
{
if ($item['name'] === $objectName)
{
return $item;
}
}
return null;
}CLI Usage
#!/usr/bin/env php
<?php
require_once 'RscFramework.php';
$token = rkRscGetToken();
$result = rkGetProtectionStatus(
$token,
'PROD-VM-01',
'VmwareVirtualMachine'
);
print_r($result); Expected output:
Array
(
[name] => PROD-VM-01
[fid] => 12345678-aaaa-bbbb-cccc-1234567890ab
[objectType] => VmwareVirtualMachine
[slaName] => Gold
[protectionStatus] => PROTECTED
[complianceStatus] => COMPLIANT
[totalSnapshots] => 42
[localSnapshots] => 30
) Detecting Unprotected Workloads
With the full result set, identifying protection gaps is direct. Four conditions cover the majority of real-world cases:
Any workload matching one or more of these conditions warrants investigation. These four fields are sufficient to build a daily protection audit script, a compliance report, or an automated alert workflow.
What This Unlocks
rkGetProtectionStatus() is a small function. What it enables is not small.
With protection state queryable from PHP, the framework can now drive: daily protection audits, SLA coverage reporting, compliance validation against internal standards, backup health dashboards, security posture assessments, and automated remediation workflows that flag or action non-compliant workloads without manual review.
This is the shift the series has been building toward: from retrieving data to acting on it.
Commit of the Week
/core/rkGetProtectionStatus.php
What's Next
The framework can now answer: "Is this workload protected?"
The next question is harder: "Can we prove that protection is happening as expected?"
A workload marked PROTECTED and COMPLIANT still leaves operational questions open. When was the last successful backup? How many recovery points exist? Are snapshots being created at the expected frequency? Is the workload meeting its recovery time objectives?
In Week 8, we move beyond protection status into actual backup history. We will retrieve individual snapshot records directly from RSC and begin building the foundation for backup validation and compliance reporting. The goal is to answer not just whether a workload is protected, but to produce verifiable evidence that protection is occurring on schedule.
Contributed by

Frederic Lhoest
Senior Technology Architect, PCCW Global

Mike Preston
Staff Technical Marketing Manager, Rubrik








