Introduction
A common question I get when giving an overview/demo of Cloud Guard is:
Can I export the problems to a CSV file?
I get asked this a lot so I decided to write this post to answer this question.
Short answer:
Not currently via the Oracle Cloud Infrastructure (OCI)I Console, however, it is very simple to create a CSV file via the OCI CLI and jq. This post will show you how to create a CSV file with all the problems in your tenancy and some examples use cases.
Long Answer (aka Details)
First we obtain the data. This CLI command will list all the ‘problems’ in a tenancy, like so:
oci cloud-guard problem list --compartment-id <YOUR_TENANCY_OCID> --compartment-id-in-subtree true --access-level ACCESSIBLE --all
Let’s dissect this command; the first four option arguments should be self-explanatory. The ‘–comaprtment-id-in-subtree’ needs to be true so we can get all the problems in the root tenancy compartment and below.
Note: The ‘–compartment-id-in-subtree true‘ flag must be accompanied with the ‘–access-level ACCESSIBLE‘ flag. For more information see our documentation here.
Now let’s examine an entry for a single problem. Take a look and see what attributes interest you to place in a CSV file.
{
"compartment-id": "ocid1.compartment.oc1.....",
"detector-rule-id": "BUCKET_ENCRYPTED_WITH_ORACLE_MANAGED_KEY",
"id": "ocid1.cloudguardproblem.oc1.iad....",
"labels": [
"KMS",
"CIS_OCI_V1.1_OBJECTSTORAGE",
"ObjectStorage"
],
"lifecycle-detail": "OPEN",
"lifecycle-state": "ACTIVE",
"locks": null,
"region": "us-ashburn-1",
"regions": [
"us-ashburn-1"
],
"resource-id": "ociateam/oci-logs._flowlogs.ocid1.compartment.oc1.....",
"resource-name": "oci-logs._flowlogs.ocid1.compartment.oc1......",
"resource-type": "Bucket",
"risk-level": "MINOR",
"risk-score": null,
"target-id": "ocid1.cloudguardtarget.oc1.iad....",
"time-first-detected": "2025-04-28T11:05:29.947000+00:00",
"time-last-detected": "2025-12-08T19:53:39.479000+00:00"
}
Notice that there are two attributes that are JSON arrays, ‘labels’ and ‘regions’. If you do not require these attributes in your CSV file than it is simple to convert.
In order to convert to a CSV file using the ‘@csv’ command, ‘jq’ requires an array as input. So lets convert the JSON data to an array of elements you want to have in the .csv file.
jq -r '.data.items[] | [."compartment-id", ."detector-id", ."detector-rule-id", ."resource-id", ."resource-type", ."resource-name", ."risk-level"] | @csv'
Note that you can add any or all the attributes (except ‘labels’ and ‘regions’) defined in the output above.
The full command is now:
oci cloud-guard problem list --compartment-id <YOUR_TENANCY_OCID> --compartment-id-in-subtree true --access-level ACCESSIBLE --all | jq -r '.data.items[] |[."compartment-id", ."detector-id", ."detector-rule-id", ."resource-id", ."resource-type", ."resource-name", ."risk-level"] | @csv'
Remember this will only work if you do NOT need the ‘labels’ and/or ‘regions’ attribute in the original output.
To add headers to your CSV, you can prepend a header row to the output:
echo "Compartment,Detector,Rule,ResourceID. ResourceType,ResourceName,RiskLevel" > output.csv && oci cloud-guard problem list --compartment-id <YOUR_TENANCY_OCID> --compartment-id-in-subtree true --access-level ACCESSIBLE --all | jq -r '.data.items[] |[."compartment-id", ."detector-id", ."detector-rule-id", ."resource-id", ."resource-type", ."resource-name", ."risk-level"] | @csv' >> output.csv
Now you have a CSV file with headers!
If you need the ‘labels’ and/or the ‘regions’ attributes, then we need to convert the JSON arrays into a single string.
To change the ‘labels’ attribute to a single string with a delimiter of ‘:’ you run the following commands.
Let’s get all the data again but this time create a file for the output:
oci cloud-guard problem list --compartment-id <YOUR_TENANCY_OCID> --compartment-id-in-subtree true --access-level ACCESSIBLE --all > problems.json
Now lets change the ‘labels’ attribute to a single string value:
jq '.data.items[].labels|= join(":")' problems.json > problemsWithLabels.json
If you also need the ‘regions’ data run the above command first and then run the command:
jq '.data.items[].regions|= join(":")' problemsWithLabels.json > problemsWithLabelsAndRegions.json
Take a look at the file problemsWithLabelAndRegions.json, you should now see a single value for the ‘labels and ‘regions’ attribute.
Time to create the CSV file:
cat problemsWithLabelsAndRegions.json | jq -r '.data.items[] | [."compartment-id", ."detector-id", ."detector-rule-id", ."resource-id", ."resource-type", ."resource-name", ."risk-level", ."labels", ."regions"] | @csv'
Now we have ‘labels’ and ‘regions’ in our CSV file. To complete the file add headers as described above.
The CSV file as described above will give you all the ‘Problems’ in a tenancy. Let’s take a look at some examples of specific use cases.
A list of unique compartments where ‘Problems’ exists and their count:
oci cloud-guard problem list --compartment-id <YOUR_TENANCY_OCID> --compartment-id-in-subtree true --access-level ACCESSIBLE --all | jq -r '.data.items[]."compartment-id"' | sort | uniq -c
Another example is list all the problems where ‘resource-type’ equals Instance:
oci cloud-guard problem list --compartment-id <YOUR_TENANCY_OCID> --compartment-id-in-subtree true --access-level ACCESSIBLE --all | jq -r '.data.items[] | select(."resource-type" == "Instance")'
Check out the jq documentation where you can write powerful filters to view specific data.
Summary
The full command to create a CSV file with headers is:
echo "Compartment,Detector,Rule,ResourceID. ResourceType,ResourceName,RiskLevel" > output.csv && oci cloud-guard problem list --compartment-id <YOUR_TENANCY_OCID> --compartment-id-in-subtree true --access-level ACCESSIBLE --all | jq -r '.data.items[] |[."compartment-id", ."detector-id", ."detector-rule-id", ."resource-id", ."resource-type", ."resource-name", ."risk-level"] | @csv' >> output.csv
This will only work if you do not need the ‘labels’ or ‘regions’ attributes. These attributes are JSON arrays and need to be converted to a single string before making the @csv call in ‘jq’. To covert both the ‘labels’ and ‘regions’ attribute run the following two commands:
oci cloud-guard problem list --compartment-id <YOUR_TENANCY_OCID> --compartment-id-in-subtree true --access-level ACCESSIBLE --all > problems.json
jq '.data.items[].labels|= join(":")' problems.json > problems2.jsonoci
and then for regions and the final command:
jq '.data.items[].regions|= join(":")' problems2.json > problems3.json
echo "Compartment,Detector,Rule,ResourceID. ResourceType,ResourceName,RiskLevel, Labels, Regions" > output.csv &&
cat problems3.json | jq -r '.data.items[] | [."compartment-id", ."detector-id", ."detector-rule-id", ."resource-id", ."resource-type", ."resource-name", ."risk-level", ."labels", ."regions"] | @csv' > output.csv
Using jq filtering you can create specific use cases for the output of your CSV file.
Thanks for reading and Good Luck!
