--- policy: /ce/ca/oracle/compute/block-volume-cmk-encryption logic: /ce/ca/oracle/compute/block-volume-cmk-encryption/prod.logic.yaml executionTime: 2026-05-02T12:07:20.37113726Z generationMs: 62 executionMs: 2073 rows: - id: test1 match: true status: expected: DISAPPEARED actual: DISAPPEARED conditionIndex: expected: 99 actual: 99 conditionText: expected: isDisappeared(CA10O1__disappearanceTime__c) actual: isDisappeared(CA10O1__disappearanceTime__c) runtimeError: {} - id: test2 match: true status: expected: INAPPLICABLE actual: INAPPLICABLE conditionIndex: expected: 199 actual: 199 conditionText: expected: "not(setOfText(['caOracleIaasBlockVolume']).contains(RecordType.DeveloperName))" actual: "not(setOfText(['caOracleIaasBlockVolume']).contains(RecordType.DeveloperName))" runtimeError: {} - id: test3 match: true status: expected: INAPPLICABLE actual: INAPPLICABLE conditionIndex: expected: 299 actual: 299 conditionText: expected: extract('CA10O1__lifecycleState__c') != 'AVAILABLE' actual: extract('CA10O1__lifecycleState__c') != 'AVAILABLE' runtimeError: {} - id: test4 match: true status: expected: COMPLIANT actual: COMPLIANT conditionIndex: expected: 399 actual: 399 conditionText: expected: extract('CA10O1__kmsKeyOcid__c').isNotEmpty() actual: extract('CA10O1__kmsKeyOcid__c').isNotEmpty() runtimeError: {} - id: test5 match: true status: expected: INCOMPLIANT actual: INCOMPLIANT conditionIndex: expected: 400 actual: 400 conditionText: expected: otherwise actual: otherwise runtimeError: {} usedFiles: - path: /ce/ca/oracle/compute/block-volume-cmk-encryption/policy.yaml md5Hash: BF7468CF868E05BAB9C0036D3E86ED26 content: | --- names: full: "Oracle IAAS Block Volume is not encrypted with a customer managed key" contextual: "IAAS Block Volume is not encrypted with a customer managed key" description: > Ensure that Oracle block volumes use customer managed keys from OCI Vault for encryption at rest. Customer managed keys provide stronger control over key access, rotation, auditing, and revocation than provider-managed encryption keys. type: "COMPLIANCE_POLICY" categories: - "SECURITY" frameworkMappings: - "/frameworks/cis-oracle-v3.1.0/05/02/01" - "/frameworks/cloudaware/resource-security/data-encryption" similarPolicies: internal: - "dec-x-ae60c87e" - path: /ce/ca/oracle/compute/block-volume-cmk-encryption/prod.logic.yaml md5Hash: CDD8B91348BD02858EC9FB266F98411E content: | --- inputType: "CA10O1__CaOracleIaasVolume__c" recordTypes: - "caOracleIaasBlockVolume" testData: - file: "test-data.json" importExtracts: - file: "/types/CA10O1__CaOracleIaasVolume__c/object.extracts.yaml" conditions: - status: "INAPPLICABLE" currentStateMessage: "The block volume is not available." check: NOT_EQUAL: left: EXTRACT: "CA10O1__lifecycleState__c" right: TEXT: "AVAILABLE" - status: "COMPLIANT" currentStateMessage: "The block volume is encrypted with a customer managed key." check: NOT_EMPTY: arg: EXTRACT: "CA10O1__kmsKeyOcid__c" otherwise: status: "INCOMPLIANT" currentStateMessage: "The block volume is not encrypted with a customer managed key." remediationMessage: "Configure the block volume to use a customer managed key from OCI Vault." - path: /ce/ca/oracle/compute/block-volume-cmk-encryption/test-data.json md5Hash: 041FB0E49F9709B9042E87F84E81E1D2 content: | [ { "expectedResult": { "status": "DISAPPEARED", "conditionIndex": "99", "conditionText": "isDisappeared(CA10O1__disappearanceTime__c)", "runtimeError": null }, "context": { "snapshotTime": "2026-04-12T00:00:00Z" }, "Id": "test1", "CA10O1__disappearanceTime__c": "2026-04-11T00:00:00Z", "RecordTypeId": "RecordType1", "RecordType": { "Id": "RecordType1", "DeveloperName": "caOracleIaasBlockVolume" }, "CA10O1__lifecycleState__c": "AVAILABLE", "CA10O1__kmsKeyOcid__c": "" }, { "expectedResult": { "status": "INAPPLICABLE", "conditionIndex": "199", "conditionText": "not(setOfText(['caOracleIaasBlockVolume']).contains(RecordType.DeveloperName))", "runtimeError": null }, "context": { "snapshotTime": "2026-04-12T00:00:00Z" }, "Id": "test2", "CA10O1__disappearanceTime__c": null, "RecordTypeId": "RecordType2", "RecordType": { "Id": "RecordType2", "DeveloperName": "caOracleIaasBootVolume" }, "CA10O1__lifecycleState__c": "AVAILABLE", "CA10O1__kmsKeyOcid__c": "" }, { "expectedResult": { "status": "INAPPLICABLE", "conditionIndex": "299", "conditionText": "extract('CA10O1__lifecycleState__c') != 'AVAILABLE'", "runtimeError": null }, "context": { "snapshotTime": "2026-04-12T00:00:00Z" }, "Id": "test3", "CA10O1__disappearanceTime__c": null, "RecordTypeId": "RecordType1", "RecordType": { "Id": "RecordType1", "DeveloperName": "caOracleIaasBlockVolume" }, "CA10O1__lifecycleState__c": "TERMINATED", "CA10O1__kmsKeyOcid__c": "" }, { "expectedResult": { "status": "COMPLIANT", "conditionIndex": "399", "conditionText": "extract('CA10O1__kmsKeyOcid__c').isNotEmpty()", "runtimeError": null }, "context": { "snapshotTime": "2026-04-12T00:00:00Z" }, "Id": "test4", "CA10O1__disappearanceTime__c": null, "RecordTypeId": "RecordType1", "RecordType": { "Id": "RecordType1", "DeveloperName": "caOracleIaasBlockVolume" }, "CA10O1__lifecycleState__c": "AVAILABLE", "CA10O1__kmsKeyOcid__c": "ocid1.key.oc1..cmk" }, { "expectedResult": { "status": "INCOMPLIANT", "conditionIndex": "400", "conditionText": "otherwise", "runtimeError": null }, "context": { "snapshotTime": "2026-04-12T00:00:00Z" }, "Id": "test5", "CA10O1__disappearanceTime__c": null, "RecordTypeId": "RecordType1", "RecordType": { "Id": "RecordType1", "DeveloperName": "caOracleIaasBlockVolume" }, "CA10O1__lifecycleState__c": "AVAILABLE", "CA10O1__kmsKeyOcid__c": "" } ] - path: /types/CA10O1__CaOracleIaasVolume__c/object.extracts.yaml md5Hash: 29D15263C90A3304C9D8774185E00633 content: | --- extracts: - name: "Name" value: FIELD: path: "Name" - name: "CA10O1__kmsKeyOcid__c" value: FIELD: path: "CA10O1__kmsKeyOcid__c" - name: "CA10O1__lifecycleState__c" value: FIELD: path: "CA10O1__lifecycleState__c" script: |- CREATE TEMP FUNCTION mock_ExpectedResult() RETURNS ARRAY >> DETERMINISTIC LANGUAGE js AS r""" return [ { "Id" : "test1", "expectedResult" : { "status" : "DISAPPEARED", "conditionIndex" : "99", "conditionText" : "isDisappeared(CA10O1__disappearanceTime__c)", "runtimeError" : null } }, { "Id" : "test2", "expectedResult" : { "status" : "INAPPLICABLE", "conditionIndex" : "199", "conditionText" : "not(setOfText(['caOracleIaasBlockVolume']).contains(RecordType.DeveloperName))", "runtimeError" : null } }, { "Id" : "test3", "expectedResult" : { "status" : "INAPPLICABLE", "conditionIndex" : "299", "conditionText" : "extract('CA10O1__lifecycleState__c') != 'AVAILABLE'", "runtimeError" : null } }, { "Id" : "test4", "expectedResult" : { "status" : "COMPLIANT", "conditionIndex" : "399", "conditionText" : "extract('CA10O1__kmsKeyOcid__c').isNotEmpty()", "runtimeError" : null } }, { "Id" : "test5", "expectedResult" : { "status" : "INCOMPLIANT", "conditionIndex" : "400", "conditionText" : "otherwise", "runtimeError" : null } } ]; """; CREATE TEMP FUNCTION mock_CA10O1__CaOracleIaasVolume__c() RETURNS ARRAY >> DETERMINISTIC LANGUAGE js AS r""" return [ { "context" : { "snapshotTime" : new Date("2026-04-12T00:00:00Z") }, "CA10O1__disappearanceTime__c" : new Date("2026-04-11T00:00:00Z"), "CA10O1__lifecycleState__c" : "AVAILABLE", "CA10O1__kmsKeyOcid__c" : "", "Id" : "test1", "RecordTypeId" : "RecordType1" }, { "context" : { "snapshotTime" : new Date("2026-04-12T00:00:00Z") }, "CA10O1__lifecycleState__c" : "AVAILABLE", "CA10O1__kmsKeyOcid__c" : "", "Id" : "test2", "RecordTypeId" : "RecordType2" }, { "context" : { "snapshotTime" : new Date("2026-04-12T00:00:00Z") }, "CA10O1__lifecycleState__c" : "TERMINATED", "CA10O1__kmsKeyOcid__c" : "", "Id" : "test3", "RecordTypeId" : "RecordType1" }, { "context" : { "snapshotTime" : new Date("2026-04-12T00:00:00Z") }, "CA10O1__lifecycleState__c" : "AVAILABLE", "CA10O1__kmsKeyOcid__c" : "ocid1.key.oc1..cmk", "Id" : "test4", "RecordTypeId" : "RecordType1" }, { "context" : { "snapshotTime" : new Date("2026-04-12T00:00:00Z") }, "CA10O1__lifecycleState__c" : "AVAILABLE", "CA10O1__kmsKeyOcid__c" : "", "Id" : "test5", "RecordTypeId" : "RecordType1" } ]; """; CREATE TEMP FUNCTION mock_RecordType() RETURNS ARRAY >> DETERMINISTIC LANGUAGE js AS r""" return [ { "context" : { "snapshotTime" : new Date("2026-04-12T00:00:00Z") }, "DeveloperName" : "caOracleIaasBlockVolume", "Id" : "RecordType1" }, { "context" : { "snapshotTime" : new Date("2026-04-12T00:00:00Z") }, "DeveloperName" : "caOracleIaasBootVolume", "Id" : "RecordType2" } ]; """; CREATE TEMP FUNCTION process_CA10O1__CaOracleIaasVolume__c( obj STRUCT< CA10O1__disappearanceTime__c TIMESTAMP, CA10O1__lifecycleState__c STRING, CA10O1__kmsKeyOcid__c STRING, Id STRING, RecordTypeId STRING, RecordType STRUCT< DeveloperName STRING, Id STRING > >, snapshotTime TIMESTAMP ) RETURNS STRUCT DETERMINISTIC LANGUAGE js AS r""" var BytesLib = new function () { this.normalize = function(arg) { return arg == null ? '' : arg; }; this.isEmpty = function(arg) { return this.normalize(arg) == ''; }; this.isNotEmpty = function(arg) { return this.normalize(arg) != ''; }; this.equal = function(left, right) { return this.normalize(left) == this.normalize(right); }; this.notEqual = function(left, right) { return this.normalize(left) != this.normalize(right); }; this.startsWith = function(arg, substring) { return this.normalize(arg).startsWith(this.normalize(substring)); }; this.endsWith = function(arg, substring) { return this.normalize(arg).endsWith(this.normalize(substring)); }; this.contains = function(arg, substring) { return this.normalize(arg).includes(this.normalize(substring)); }; this.containsAll = function(arg, substrings) { if (substrings == null || substrings.length === 0) return false; let normalizedArg = this.normalize(arg); return substrings.every(sub => normalizedArg.includes(this.normalize(sub))); }; this.containsAny = function(arg, substrings) { if (substrings == null || substrings.length === 0) return false; let normalizedArg = this.normalize(arg); return substrings.some(sub => normalizedArg.includes(this.normalize(sub))); }; }(); var TextLib = new function () { this.normalize = function(arg) { return arg == null ? '' : arg.replace(/\s+/g, ' ').trim().toLowerCase(); }; this.isEmpty = function(arg) { return this.normalize(arg) == ''; }; this.isNotEmpty = function(arg) { return this.normalize(arg) != ''; }; this.equal = function(left, right) { return this.normalize(left) == this.normalize(right); }; this.notEqual = function(left, right) { return this.normalize(left) != this.normalize(right); }; this.startsWith = function(arg, substring) { return this.normalize(arg).startsWith(this.normalize(substring)); }; this.endsWith = function(arg, substring) { return this.normalize(arg).endsWith(this.normalize(substring)); }; this.contains = function(arg, substring) { return this.normalize(arg).includes(this.normalize(substring)); }; this.containsAll = function(arg, substrings) { if (substrings == null || substrings.length === 0) return false; let normalizedArg = this.normalize(arg); return substrings.every(sub => normalizedArg.includes(this.normalize(sub))); }; this.containsAny = function(arg, substrings) { if (substrings == null || substrings.length === 0) return false; let normalizedArg = this.normalize(arg); return substrings.some(sub => normalizedArg.includes(this.normalize(sub))); }; }(); var CollectionLib = new function () { this.parse = function(arg, separator, skipEmpty, skipDuplicates, sort, normalize) { if (arg == null) return []; let parts = arg.split(separator); return this.fromArray(parts, skipEmpty, skipDuplicates, sort, normalize); }; this.fromArray = function(arr, skipEmpty, skipDuplicates, sort, normalize) { if (arr == null) return []; let result = []; let seen = new Set(); arr.forEach(el => { let normalized = normalize ? TextLib.normalize(el) : BytesLib.normalize(el); if (!skipEmpty || (normalize ? TextLib.isNotEmpty(el) : BytesLib.isNotEmpty(el))) { if (!skipDuplicates || !seen.has(normalized)) { if (skipDuplicates) seen.add(normalized); result.push(normalized); } } }); if (sort) result.sort(); return result; }; this.equal = function(left, right) { left = left == null ? [] : left; right = right == null ? [] : right; if (left.length !== right.length) return false; for (let i = 0; i < left.length; i++) { if (left[i] !== right[i]) return false; } return true; }; this.notEqual = function(left, right) { return !this.equal(left, right); }; this.size = function(collection) { return collection == null ? 0 : collection.length; }; this.startsWith = function(collection, search, normalize) { if (collection == null || collection.length === 0) return false; let normalizedSearch = normalize ? TextLib.normalize(search) : BytesLib.normalize(search); return collection[0] === normalizedSearch; }; this.endsWith = function(collection, search, normalize) { if (collection == null || collection.length === 0) return false; let normalizedSearch = normalize ? TextLib.normalize(search) : BytesLib.normalize(search); return collection[collection.length - 1] === normalizedSearch; }; this.contains = function(collection, search, normalize) { if (collection == null || collection.length === 0) return false; return collection.includes(normalize ? TextLib.normalize(search) : BytesLib.normalize(search)); }; this.containsAll = function(collection, searchArray, normalize) { if (collection == null || collection.length === 0 || searchArray == null || searchArray.length === 0) return false; return searchArray.every(search => collection.includes(normalize ? TextLib.normalize(search) : BytesLib.normalize(search))); }; this.containsAny = function(collection, searchArray, normalize) { if (collection == null || collection.length === 0 || searchArray == null || searchArray.length === 0) return false; return searchArray.some(search => collection.includes(normalize ? TextLib.normalize(search) : BytesLib.normalize(search))); }; }(); var references1 = []; // condition[0], conditionIndex:[0..99] references1.push('Deleted From Oracle [CA10O1__disappearanceTime__c]: ' + obj.CA10O1__disappearanceTime__c); if (obj.CA10O1__disappearanceTime__c != null) { return {status: 'DISAPPEARED', conditionIndex: 99, conditionText: "isDisappeared(CA10O1__disappearanceTime__c)", currentStateMessage: "Object is deleted in the source", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; } // condition[1], conditionIndex:[100..199] references1.push('Record Type Name [obj.RecordType.DeveloperName]: ' + obj.RecordType.DeveloperName); if (!CollectionLib.contains(CollectionLib.fromArray(['caOracleIaasBlockVolume'], true, true, true, true), obj.RecordType.DeveloperName, true)) { return {status: 'INAPPLICABLE', conditionIndex: 199, conditionText: "not(setOfText(['caOracleIaasBlockVolume']).contains(RecordType.DeveloperName))", currentStateMessage: "Object record type is not applicable", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; } // condition[2], conditionIndex:[200..299] function extract4() { if (!this.out) { this.out = obj.CA10O1__lifecycleState__c; } return this.out; }; references1.push('Lifecycle State [obj.CA10O1__lifecycleState__c]: ' + obj.CA10O1__lifecycleState__c); if (TextLib.notEqual(extract4.call(extract4), 'AVAILABLE')) { return {status: 'INAPPLICABLE', conditionIndex: 299, conditionText: "extract('CA10O1__lifecycleState__c') != 'AVAILABLE'", currentStateMessage: "The block volume is not available.", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; } // condition[3], conditionIndex:[300..399] function extract7() { if (!this.out) { this.out = obj.CA10O1__kmsKeyOcid__c; } return this.out; }; references1.push('KMS Key OCID [obj.CA10O1__kmsKeyOcid__c]: ' + obj.CA10O1__kmsKeyOcid__c); if (TextLib.isNotEmpty(extract7.call(extract7))) { return {status: 'COMPLIANT', conditionIndex: 399, conditionText: "extract('CA10O1__kmsKeyOcid__c').isNotEmpty()", currentStateMessage: "The block volume is encrypted with a customer managed key.", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; } return {status: 'INCOMPLIANT', conditionIndex: 400, conditionText: "otherwise", currentStateMessage: "The block volume is not encrypted with a customer managed key.", currentStateReferences: references1.join('\n'), remediation: "Configure the block volume to use a customer managed key from OCI Vault.", runtimeError: null}; """; SELECT expectedResult.Id as Id, IF ( IFNULL(expectedResult.expectedResult.status, '') = IFNULL(sObject.result.status, '') AND IFNULL(expectedResult.expectedResult.conditionIndex, -1) = IFNULL(sObject.result.conditionIndex, -1) AND IFNULL(expectedResult.expectedResult.conditionText, '') = IFNULL(sObject.result.conditionText, '') AND IFNULL(expectedResult.expectedResult.runtimeError, '') = IFNULL(sObject.result.runtimeError, ''), "MATCH", "FAIL" ) as match, expectedResult.expectedResult.status as expectedStatus, sObject.result.status as actualStatus, expectedResult.expectedResult.conditionIndex as expectedConditionIndex, sObject.result.conditionIndex as actualConditionIndex, expectedResult.expectedResult.conditionText as expectedConditionText, sObject.result.conditionText as actualConditionText, expectedResult.expectedResult.runtimeError as expectedRuntimeError, sObject.result.runtimeError as actualRuntimeError FROM UNNEST(mock_ExpectedResult()) expectedResult LEFT JOIN ( SELECT sObject.CA10O1__disappearanceTime__c AS CA10O1__disappearanceTime__c, sObject.CA10O1__lifecycleState__c AS CA10O1__lifecycleState__c, sObject.CA10O1__kmsKeyOcid__c AS CA10O1__kmsKeyOcid__c, sObject.Id AS Id, sObject.RecordTypeId AS RecordTypeId, STRUCT ( `RecordType`.DeveloperName AS DeveloperName, `RecordType`.Id AS Id ) AS RecordType, process_CA10O1__CaOracleIaasVolume__c( STRUCT( sObject.CA10O1__disappearanceTime__c AS CA10O1__disappearanceTime__c, sObject.CA10O1__lifecycleState__c AS CA10O1__lifecycleState__c, sObject.CA10O1__kmsKeyOcid__c AS CA10O1__kmsKeyOcid__c, sObject.Id AS Id, sObject.RecordTypeId AS RecordTypeId, STRUCT ( `RecordType`.DeveloperName AS DeveloperName, `RecordType`.Id AS Id ) AS RecordType ), sObject.context.snapshotTime ) as result FROM UNNEST(mock_CA10O1__CaOracleIaasVolume__c()) AS sObject LEFT JOIN UNNEST(mock_RecordType()) AS `RecordType` ON sObject.RecordTypeId = `RecordType`.Id ) sObject ON sObject.Id = expectedResult.Id;