turbot/steampipe-mod-oci-compliance

Control: 4.17 Ensure write level Object Storage logging is enabled for all buckets

Description

Object Storage write logs will log all write requests made to objects in a bucket.

Enabling an Object Storage write log, the requestAction property would contain values of PUT, POST, or DELETE. This will provide you more visibility into changes to objects in your buckets.

Remediation

From Console

First, if a log group for holding these logs has not already been created, create a log group by the following steps:

  1. Go to the Log Groups page.
  2. Click the Create Log Groups button in the middle of the screen.
  3. Select the relevant compartment to place these logs.
  4. Type a name for the log group in the Name box.
  5. Add an optional description in the Description box.
  6. Click the Create button in the lower left hand corner.

Second, enable Object Storage write log logging for your bucket(s) by the following steps:

  1. Go to the Logs page.
  2. Click the Enable Service Log button in the middle of the screen.
  3. Select the relevant resource compartment.
  4. Select Object Storage from the Service drop down menu.
  5. Select the relevant bucket from the resource drop down menu.
  6. Select Write Access Events from the Log Category drop down menu.
  7. Type a name for your Object Storage write log in the Log Name drop down menu.
  8. Click the Enable Log button in the lower left hand corner.

From CLI

First, if a log group for holding these logs has not already been created, create a log group by the following steps:

  1. Create a log group:
oci logging log-group create --compartment-id <compartment-id> \ --display-name "<DisplayName>" \ --description "<Description>"

The output of the command gives you a work request id. You can query the work request to see the status of the job by issuing the following command:

oci logging work-request get --work-request-id <output from command above>

Look for status field to be SUCCEEDED.

Second, enable Object Storage write log logging for your bucket(s) by the following steps:

  1. Get the Log group ID needed for creating the Log:
oci logging log-group list --compartment-id <compartment-id> \ --query 'data[?contains("display-name", `'"<DisplayName>"'`)].id|join(`\n`, @)' \ --raw-output
  1. Create a JSON file called config.json with the following content:
{
"compartmentid":"ocid1.compartment.oc1..aaaaaaaamaywlaznovmvdwk3uqx2sedfavssagba5cxufe6wy llqgwzcq43a",
"source": {
"resource": "<bucket-name>",
"service": "ObjectStorage",
"source-type": "OCISERVICE",
"category": "write"
}
}

The compartment-id is the Compartment OCID of where the bucket exists. The resource value is the bucket name.

  1. Create the Service Log:
oci logging log create --log-group-id <value from step 2.> \ --display-name "<DisplayName>" \ --log-type SERVICE --is-enabled TRUE \ --configuration file://config.json

The output of the command gives you a work request id. You can query the work request to see the status of the job by issuing the following command:

oci logging work-request get --work-request-id <output from command above>

Look for the status field to be SUCCEEDED.

Usage

Run the control in your terminal:

powerpipe control run oci_compliance.control.cis_v300_4_17

Snapshot and share results via Turbot Pipes:

powerpipe login
powerpipe control run oci_compliance.control.cis_v300_4_17 --share

SQL

This control uses a named query:

with bucket_logs as (
select
configuration -> 'source' ->> 'resource' as bucket_identifier,
configuration -> 'source' ->> 'category' as category,
lifecycle_state,
title as log_name,
log_group_id,
is_enabled,
retention_duration,
region,
compartment_id as log_compartment_id
from
oci_logging_log
where
configuration -> 'source' ->> 'service' = 'objectstorage'
and configuration -> 'source' ->> 'category' ilike '%write%'
)
select
b.id as resource,
case
when bl.is_enabled and lower(coalesce(bl.lifecycle_state, '')) = 'active' then 'ok'
else 'alarm'
end as status,
case
when bl.is_enabled and lower(coalesce(bl.lifecycle_state, '')) = 'active' then
b.title || ' write access logging enabled in log group ' ||
coalesce(g.display_name, bl.log_group_id, 'unknown') ||
' (log: ' || coalesce(bl.log_name, 'unknown') || ').'
when bl.log_group_id is null then
b.title || ' write access logging disabled (no write log configured).'
when not coalesce(bl.is_enabled, false) then
b.title || ' write access logging log exists but disabled.'
else
b.title || ' write access logging log lifecycle state ' ||
coalesce(bl.lifecycle_state, 'unknown') || '.'
end as reason
, b.region as region, b.tenant_name as tenant
, coalesce(c.name, 'root') as compartment
from
oci_objectstorage_bucket b
left join bucket_logs bl on bl.bucket_identifier in (
b.id,
b.name,
format('%s/%s', b.namespace, b.name),
format('%s_write', b.name)
)
left join oci_logging_log_group g on g.id = bl.log_group_id
left join oci_identity_compartment c on c.id = b.compartment_id;

Tags