---
policy: /ce/ca/azure/virtual-network/security-group-flow-logs-retention-period-over-90-days
logic: /ce/ca/azure/virtual-network/security-group-flow-logs-retention-period-over-90-days/prod.logic.yaml
executionTime: 2025-04-24T23:46:32.741504699Z
rows:
  - id: test1
    match: true
    status:
      expected: DISAPPEARED
      actual: DISAPPEARED
    conditionIndex:
      expected: 99
      actual: 99
    conditionText:
      expected: isDisappeared(CA10__disappearanceTime__c)
      actual: isDisappeared(CA10__disappearanceTime__c)
    runtimeError: {}
  - id: test2
    match: true
    status:
      expected: INCOMPLIANT
      actual: INCOMPLIANT
    conditionIndex:
      expected: 199
      actual: 199
    conditionText:
      expected: extract('CA10__flowLogsEnabled__c') == false
      actual: extract('CA10__flowLogsEnabled__c') == false
    runtimeError: {}
  - id: test3
    match: true
    status:
      expected: INCOMPLIANT
      actual: INCOMPLIANT
    conditionIndex:
      expected: 299
      actual: 299
    conditionText:
      expected: extract('CA10__flowLogsRetentionPolicyEnabled__c') == false
      actual: extract('CA10__flowLogsRetentionPolicyEnabled__c') == false
    runtimeError: {}
  - id: test4
    match: true
    status:
      expected: INCOMPLIANT
      actual: INCOMPLIANT
    conditionIndex:
      expected: 399
      actual: 399
    conditionText:
      expected: extract('CA10__flowLogsRetentionPolicyDays__c') < number(90.0)
      actual: extract('CA10__flowLogsRetentionPolicyDays__c') < number(90.0)
    runtimeError: {}
  - id: test5
    match: true
    status:
      expected: COMPLIANT
      actual: COMPLIANT
    conditionIndex:
      expected: 400
      actual: 400
    conditionText:
      expected: otherwise
      actual: otherwise
    runtimeError: {}
usedFiles:
  - path: /ce/ca/azure/virtual-network/security-group-flow-logs-retention-period-over-90-days/policy.yaml
    md5Hash: EB86062686FA1EA3450B44CF9FB5EAA5
    content: |
      ---
      names:
        full: Azure Network Security Group Flow Logs retention period is less than 90 days
        contextual: Security Group Flow Logs retention period is less than 90 days
      description: Flow logs enable capturing information about IP traffic flowing in and
        out of network security groups. Logs can be used to check for anomalies and give
        insight into suspected breaches.
      type: COMPLIANCE_POLICY
      categories:
        - SECURITY
      frameworkMappings:
        - "/frameworks/cis-azure-v2.1.0/06/05"
        - "/frameworks/cis-azure-v3.0.0/07/05"
        - "/frameworks/cloudaware/logging-and-monitoring/logging-and-monitoring-configuration"
      similarPolicies:
        internal:
          - dec-x-e5c05d3e
        cloudConformity:
          - url: https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Network/sufficient-nsg-flow-log-retention-period.html
            name: Check for NSG Flow Log Retention Period
  - path: /ce/ca/azure/virtual-network/security-group-flow-logs-retention-period-over-90-days/prod.logic.yaml
    md5Hash: 21A6DF7D91F4733A8F806D380D41E54E
    content: |
      ---
      inputType: "CA10__CaAzureNetworkSecurityGroup__c"
      importExtracts:
        - file: /types/CA10__CaAzureNetworkSecurityGroup__c/object.extracts.yaml
      testData:
        - file: "test-data.json"
      conditions:
        - status: "INCOMPLIANT"
          currentStateMessage: "Network Security Group Flow Logs are disabled."
          remediationMessage: "Consider enabling Network Security Group Flow Logs."
          check:
            IS_EQUAL:
              left:
                EXTRACT: "CA10__flowLogsEnabled__c"
              right:
                BOOLEAN: false
        - status: "INCOMPLIANT"
          currentStateMessage: "Network Security Group Flow Logs retention policy is disabled."
          remediationMessage: "Consider enabling retention policy for Network Security Group Flow Logs."
          check:
            IS_EQUAL:
              left:
                EXTRACT: "CA10__flowLogsRetentionPolicyEnabled__c"
              right:
                BOOLEAN: false
        - status: "INCOMPLIANT"
          currentStateMessage: "Network Security Group Flow Logs retention period is less than 90 days."
          remediationMessage: "Consider setting the retention period to 'greater then or equal to 90 days'."
          check:
            LESS_THAN:
              left:
                EXTRACT: "CA10__flowLogsRetentionPolicyDays__c"
              right:
                NUMBER: 90.0
      otherwise:
        status: "COMPLIANT"
        currentStateMessage: "Network Security Group Flow Logs are enabled and the retention period is set to 'greater than or equal to 90 days'."
  - path: /ce/ca/azure/virtual-network/security-group-flow-logs-retention-period-over-90-days/test-data.json
    md5Hash: 9060F77EB5BC6C7FDBB8D9FA9BE9A3AE
    content: |-
      [
          {
              "expectedResult": {
                  "status": "DISAPPEARED",
                  "conditionIndex": "99",
                  "conditionText": "isDisappeared(CA10__disappearanceTime__c)",
                  "runtimeError": null
              },
              "context": {
                  "snapshotTime": "2024-06-28T08:24:16Z"
              },
              "Id": "test1",
              "CA10__disappearanceTime__c": "2024-06-10T18:52:40Z",
              "CA10__flowLogsEnabled__c": false,
              "CA10__flowLogsRetentionPolicyEnabled__c": false,
              "CA10__flowLogsRetentionPolicyDays__c": null
          },
          {
              "expectedResult": {
                  "status": "INCOMPLIANT",
                  "conditionIndex": "199",
                  "conditionText": "extract('CA10__flowLogsEnabled__c') == false",
                  "runtimeError": null
              },
              "context": {
                  "snapshotTime": "2024-06-28T08:24:16Z"
              },
              "Id": "test2",
              "CA10__disappearanceTime__c": null,
              "CA10__flowLogsEnabled__c": false,
              "CA10__flowLogsRetentionPolicyEnabled__c": false,
              "CA10__flowLogsRetentionPolicyDays__c": 0
          },
          {
              "expectedResult": {
                  "status": "INCOMPLIANT",
                  "conditionIndex": "299",
                  "conditionText": "extract('CA10__flowLogsRetentionPolicyEnabled__c') == false",
                  "runtimeError": null
              },
              "context": {
                  "snapshotTime": "2024-06-28T08:24:16Z"
              },
              "Id": "test3",
              "CA10__disappearanceTime__c": null,
              "CA10__flowLogsEnabled__c": true,
              "CA10__flowLogsRetentionPolicyEnabled__c": false,
              "CA10__flowLogsRetentionPolicyDays__c": 0
          },
          {
              "expectedResult": {
                  "status": "INCOMPLIANT",
                  "conditionIndex": "399",
                  "conditionText": "extract('CA10__flowLogsRetentionPolicyDays__c') < number(90.0)",
                  "runtimeError": null
              },
              "context": {
                  "snapshotTime": "2024-06-28T08:24:16Z"
              },
              "Id": "test4",
              "CA10__disappearanceTime__c": null,
              "CA10__flowLogsEnabled__c": true,
              "CA10__flowLogsRetentionPolicyEnabled__c": true,
              "CA10__flowLogsRetentionPolicyDays__c": 7
          },
          {
              "expectedResult": {
                  "status": "COMPLIANT",
                  "conditionIndex": "400",
                  "conditionText": "otherwise",
                  "runtimeError": null
              },
              "context": {
                  "snapshotTime": "2024-06-28T08:24:16Z"
              },
              "Id": "test5",
              "CA10__disappearanceTime__c": null,
              "CA10__flowLogsEnabled__c": true,
              "CA10__flowLogsRetentionPolicyEnabled__c": true,
              "CA10__flowLogsRetentionPolicyDays__c": 365
          }
      ]
  - path: /types/CA10__CaAzureNetworkSecurityGroup__c/object.extracts.yaml
    md5Hash: EF77C87EFC93F0E147E29C6B1255AD9E
    content: "---\nextracts:\n# Checkbox. \n  - name: \"CA10__flowLogsEnabled__c\"\
      \n    value: \n      FIELD:\n        path: \"CA10__flowLogsEnabled__c\"\n  \
      \      undeterminedIf:\n          noAccessDelegate:\n            path: \"CA10__flowLogsEnabled__c\"\
      \n            currentStateMessage: \"Unable to determine if Flow Logs are enabled.\
      \ Possible permission issue with Microsoft.Network/networkWatchers/queryFlowLogStatus/action\"\
      \n# Checkbox. \n  - name: \"CA10__flowLogsRetentionPolicyEnabled__c\"\n    value:\
      \ \n      FIELD:\n        path: \"CA10__flowLogsRetentionPolicyEnabled__c\"\n\
      \        undeterminedIf:\n          noAccessDelegate:\n            path: \"\
      CA10__flowLogsRetentionPolicyEnabled__c\"\n            currentStateMessage:\
      \ \"Unable to determine Flow Logs Retention Policy. Possible permission issue\
      \ with Microsoft.Network/networkWatchers/queryFlowLogStatus/action\"\n# Number.\
      \ \n  - name: \"CA10__flowLogsRetentionPolicyDays__c\"\n    value: \n      FIELD:\n\
      \        path: \"CA10__flowLogsRetentionPolicyDays__c\"\n        undeterminedIf:\n\
      \          noAccessDelegate:\n            path: \"CA10__flowLogsRetentionPolicyDays__c\"\
      \n            currentStateMessage: \"Unable to determine Flow Logs Retention\
      \ Policy. Possible permission issue with Microsoft.Network/networkWatchers/queryFlowLogStatus/action\"\
      \n"
script: |-
  CREATE TEMP FUNCTION mock_ExpectedResult()
  RETURNS ARRAY<STRUCT<
          Id STRING,
          expectedResult STRUCT<status STRING, conditionIndex DECIMAL, conditionText STRING, runtimeError STRING>
      >>
  DETERMINISTIC
  LANGUAGE js
  AS r"""
    return [ {
    "Id" : "test1",
    "expectedResult" : {
      "status" : "DISAPPEARED",
      "conditionIndex" : "99",
      "conditionText" : "isDisappeared(CA10__disappearanceTime__c)",
      "runtimeError" : null
    }
  }, {
    "Id" : "test2",
    "expectedResult" : {
      "status" : "INCOMPLIANT",
      "conditionIndex" : "199",
      "conditionText" : "extract('CA10__flowLogsEnabled__c') == false",
      "runtimeError" : null
    }
  }, {
    "Id" : "test3",
    "expectedResult" : {
      "status" : "INCOMPLIANT",
      "conditionIndex" : "299",
      "conditionText" : "extract('CA10__flowLogsRetentionPolicyEnabled__c') == false",
      "runtimeError" : null
    }
  }, {
    "Id" : "test4",
    "expectedResult" : {
      "status" : "INCOMPLIANT",
      "conditionIndex" : "399",
      "conditionText" : "extract('CA10__flowLogsRetentionPolicyDays__c') < number(90.0)",
      "runtimeError" : null
    }
  }, {
    "Id" : "test5",
    "expectedResult" : {
      "status" : "COMPLIANT",
      "conditionIndex" : "400",
      "conditionText" : "otherwise",
      "runtimeError" : null
    }
  } ];
  """;

  CREATE TEMP FUNCTION mock_CA10__CaAzureNetworkSecurityGroup__c()
  RETURNS ARRAY<STRUCT<
      Id STRING,
      CA10__disappearanceTime__c TIMESTAMP,
      CA10__flowLogsEnabled__c BOOLEAN,
      CA10__flowLogsRetentionPolicyEnabled__c BOOLEAN,
      CA10__flowLogsRetentionPolicyDays__c FLOAT64,
      context STRUCT<
          snapshotTime TIMESTAMP
      >
  >>
  DETERMINISTIC
  LANGUAGE js
  AS r"""
    return [ {
    "context" : {
      "snapshotTime" : new Date("2024-06-28T08:24:16Z")
    },
    "Id" : "test1",
    "CA10__disappearanceTime__c" : new Date("2024-06-10T18:52:40Z"),
    "CA10__flowLogsEnabled__c" : false,
    "CA10__flowLogsRetentionPolicyEnabled__c" : false,
    "CA10__flowLogsRetentionPolicyDays__c" : null
  }, {
    "context" : {
      "snapshotTime" : new Date("2024-06-28T08:24:16Z")
    },
    "Id" : "test2",
    "CA10__flowLogsEnabled__c" : false,
    "CA10__flowLogsRetentionPolicyEnabled__c" : false,
    "CA10__flowLogsRetentionPolicyDays__c" : 0
  }, {
    "context" : {
      "snapshotTime" : new Date("2024-06-28T08:24:16Z")
    },
    "Id" : "test3",
    "CA10__flowLogsEnabled__c" : true,
    "CA10__flowLogsRetentionPolicyEnabled__c" : false,
    "CA10__flowLogsRetentionPolicyDays__c" : 0
  }, {
    "context" : {
      "snapshotTime" : new Date("2024-06-28T08:24:16Z")
    },
    "Id" : "test4",
    "CA10__flowLogsEnabled__c" : true,
    "CA10__flowLogsRetentionPolicyEnabled__c" : true,
    "CA10__flowLogsRetentionPolicyDays__c" : 7
  }, {
    "context" : {
      "snapshotTime" : new Date("2024-06-28T08:24:16Z")
    },
    "Id" : "test5",
    "CA10__flowLogsEnabled__c" : true,
    "CA10__flowLogsRetentionPolicyEnabled__c" : true,
    "CA10__flowLogsRetentionPolicyDays__c" : 365
  } ];
  """;

  CREATE TEMP FUNCTION process_CA10__CaAzureNetworkSecurityGroup__c(
      obj STRUCT<
          Id STRING,
          CA10__disappearanceTime__c TIMESTAMP,
          CA10__flowLogsEnabled__c BOOLEAN,
          CA10__flowLogsRetentionPolicyEnabled__c BOOLEAN,
          CA10__flowLogsRetentionPolicyDays__c FLOAT64
      >,
      snapshotTime TIMESTAMP
  )
  RETURNS STRUCT<status STRING, conditionIndex DECIMAL, conditionText STRING, currentStateMessage STRING, currentStateReferences STRING, remediation STRING, runtimeError STRING>
  DETERMINISTIC
  LANGUAGE js
  AS r"""
      var IsEmptyLib = new function () {
          this.simpleIsEmpty = function(arg) {
              return arg == null;
          };
          this.simpleIsNotEmpty = function(arg) {
              return arg != null;
          };
      }();
      var references1 = [];
      // condition[0], conditionIndex:[0..99]
      references1.push('Deleted From Azure [CA10__disappearanceTime__c]: ' + obj.CA10__disappearanceTime__c);
      if (obj.CA10__disappearanceTime__c != null) {
          return {status: 'DISAPPEARED', conditionIndex: 99, conditionText: "isDisappeared(CA10__disappearanceTime__c)", currentStateMessage: "Object is deleted in the source", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null};
      }
      // condition[1], conditionIndex:[100..199]
      function fieldChecked4() {
          if (IsEmptyLib.simpleIsEmpty(obj.CA10__flowLogsEnabled__c)) {
              throw new Error("UNDETERMINED condition:101", {cause: {status: 'UNDETERMINED', conditionIndex: 101, conditionText: "CA10__flowLogsEnabled__c.delegatedTo(CA10__flowLogsEnabled__c).isEmpty()", currentStateMessage: "Unable to determine if Flow Logs are enabled. Possible permission issue with Microsoft.Network/networkWatchers/queryFlowLogStatus/action", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}});
          }
          return obj.CA10__flowLogsEnabled__c;
      }
      function extract3() { if (!this.out) { this.out = fieldChecked4(); } return this.out; };
      references1.push('Flow Logs: Enabled [obj.CA10__flowLogsEnabled__c]: ' + obj.CA10__flowLogsEnabled__c);
      try {
          if (extract3.call(extract3) == false) {
              return {status: 'INCOMPLIANT', conditionIndex: 199, conditionText: "extract('CA10__flowLogsEnabled__c') == false", currentStateMessage: "Network Security Group Flow Logs are disabled.", currentStateReferences: references1.join('\n'), remediation: "Consider enabling Network Security Group Flow Logs.", runtimeError: null};
          }
      } catch (err) {
          if (err.cause && err.cause.status) { return err.cause; } else { throw err; }
      }
      // condition[2], conditionIndex:[200..299]
      function fieldChecked7() {
          if (IsEmptyLib.simpleIsEmpty(obj.CA10__flowLogsRetentionPolicyEnabled__c)) {
              throw new Error("UNDETERMINED condition:201", {cause: {status: 'UNDETERMINED', conditionIndex: 201, conditionText: "CA10__flowLogsRetentionPolicyEnabled__c.delegatedTo(CA10__flowLogsRetentionPolicyEnabled__c).isEmpty()", currentStateMessage: "Unable to determine Flow Logs Retention Policy. Possible permission issue with Microsoft.Network/networkWatchers/queryFlowLogStatus/action", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}});
          }
          return obj.CA10__flowLogsRetentionPolicyEnabled__c;
      }
      function extract6() { if (!this.out) { this.out = fieldChecked7(); } return this.out; };
      references1.push('Flow Logs: Retention Policy Enabled [obj.CA10__flowLogsRetentionPolicyEnabled__c]: ' + obj.CA10__flowLogsRetentionPolicyEnabled__c);
      try {
          if (extract6.call(extract6) == false) {
              return {status: 'INCOMPLIANT', conditionIndex: 299, conditionText: "extract('CA10__flowLogsRetentionPolicyEnabled__c') == false", currentStateMessage: "Network Security Group Flow Logs retention policy is disabled.", currentStateReferences: references1.join('\n'), remediation: "Consider enabling retention policy for Network Security Group Flow Logs.", runtimeError: null};
          }
      } catch (err) {
          if (err.cause && err.cause.status) { return err.cause; } else { throw err; }
      }
      // condition[3], conditionIndex:[300..399]
      function fieldChecked11() {
          if (IsEmptyLib.simpleIsEmpty(obj.CA10__flowLogsRetentionPolicyDays__c)) {
              throw new Error("UNDETERMINED condition:301", {cause: {status: 'UNDETERMINED', conditionIndex: 301, conditionText: "CA10__flowLogsRetentionPolicyDays__c.delegatedTo(CA10__flowLogsRetentionPolicyDays__c).isEmpty()", currentStateMessage: "Unable to determine Flow Logs Retention Policy. Possible permission issue with Microsoft.Network/networkWatchers/queryFlowLogStatus/action", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}});
          }
          return obj.CA10__flowLogsRetentionPolicyDays__c;
      }
      function extract10() { if (!this.out) { this.out = fieldChecked11(); } return this.out; };
      references1.push('Flow Logs: Retention Policy Days [obj.CA10__flowLogsRetentionPolicyDays__c]: ' + obj.CA10__flowLogsRetentionPolicyDays__c);
      try {
          if (extract10.call(extract10) != null && 90.0 != null && extract10.call(extract10) < 90.0) {
              return {status: 'INCOMPLIANT', conditionIndex: 399, conditionText: "extract('CA10__flowLogsRetentionPolicyDays__c') < number(90.0)", currentStateMessage: "Network Security Group Flow Logs retention period is less than 90 days.", currentStateReferences: references1.join('\n'), remediation: "Consider setting the retention period to 'greater then or equal to 90 days'.", runtimeError: null};
          }
      } catch (err) {
          if (err.cause && err.cause.status) { return err.cause; } else { throw err; }
      }
      return {status: 'COMPLIANT', conditionIndex: 400, conditionText: "otherwise", currentStateMessage: "Network Security Group Flow Logs are enabled and the retention period is set to 'greater than or equal to 90 days'.", currentStateReferences: references1.join('\n'), remediation: null, 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.Id AS Id,
          sObject.CA10__disappearanceTime__c AS CA10__disappearanceTime__c,
          sObject.CA10__flowLogsEnabled__c AS CA10__flowLogsEnabled__c,
          sObject.CA10__flowLogsRetentionPolicyEnabled__c AS CA10__flowLogsRetentionPolicyEnabled__c,
          sObject.CA10__flowLogsRetentionPolicyDays__c AS CA10__flowLogsRetentionPolicyDays__c,
          process_CA10__CaAzureNetworkSecurityGroup__c(
              STRUCT(
                  sObject.Id AS Id,
                  sObject.CA10__disappearanceTime__c AS CA10__disappearanceTime__c,
                  sObject.CA10__flowLogsEnabled__c AS CA10__flowLogsEnabled__c,
                  sObject.CA10__flowLogsRetentionPolicyEnabled__c AS CA10__flowLogsRetentionPolicyEnabled__c,
                  sObject.CA10__flowLogsRetentionPolicyDays__c AS CA10__flowLogsRetentionPolicyDays__c
              ),
              sObject.context.snapshotTime
          ) as result
      FROM UNNEST(mock_CA10__CaAzureNetworkSecurityGroup__c()) AS sObject
  ) sObject ON sObject.Id = expectedResult.Id;
