# Optimizing Google Cloud Checks

## Example: Changing Check Behavior based on Cloud Storage Bucket Labels

The default settings in Shisho Cloud include check items for Cloud Storage buckets that inspect their public access configuration. While these checks are beneficial in many cases, they often create operational overhead by **triggering alerts even for buckets that are intended to be public**.

Let's modify this check to **change its behavior based on naming conventions or labels attached to the bucket**.

Specifically, we'll configure the check to **not** raise an alert if the label `security-team-accepted-at` is present on the bucket, even if it's publicly accessible. For instance, the `shisho-20231114-user-01-public` bucket in the image below is currently exposed to the internet but is acceptable as it has the `security-team-accepted-at` label attached:

![](/docs/_md-assets/f1dcd04448-target-bucket.ja.png)

Note that in the Shisho Cloud default settings, an alert is generated because the bucket is public:

![](/docs/_md-assets/f7c57a9dc8-target.ja.png)

## Preparation

First, `clone` the repository containing the Shisho Cloud workflow by following the steps below:

```bash
git clone --recurse-submodules https://github.com/flatt-security/shisho-cloud-managed-workflows.git
```

Run the `opa test` command in the cloned directory to ensure that all workflow tests pass:

```bash
$ cd shisho-cloud-managed-workflows
$ opa test -v .

...

workflows/csp/aws-fsbp/elb/logging/decide_test.rego:
data.policy.aws.elb.logging.test_lb_with_log_will_be_allowed: PASS (10.35925ms)
data.policy.aws.elb.logging.test_lb_without_log_will_be_denied: PASS (12.059792ms)

workflows/notification/slack/security-ja/triage/notify_test.rego:
data.notification.triage.test_severity_selected_successfully: PASS (506.667µs)
data.notification.triage.test_critical_severity_selected_as_failsafe_behavior: PASS (273.083µs)
--------------------------------------------------------------------------------
PASS: 186/186
```

## Identify the Policy to Modify

First, you need to identify which policy defines the check you want to modify. The actual identification is easy; just check the detection source information displayed next to the check result details:

![](/docs/_md-assets/86490ba7bb-identify-policy-code.ja.png)

This information tells you which [workflow](/docs/g/concepts/workflow.md) and job detected the result. In this case, you can see that it was detected by the `bucket-accessibility` job of the workflow with the ID `prebundle-googlecloud-storage`.

This workflow is defined in the following path in [flatt-security/shisho-cloud-managed-workflows](https://github.com/flatt-security/shisho-cloud-managed-workflows):

```bash
workflows/cis-benchmark/googlecloud-v1.3.0/storage/bucket-accessibility
```

Currently, the following files are included in this path:

- `decide.graphql`: Definition of the data to be inspected
- `decide.rego`: Inspection logic
- `decide_test.rego`: Test code

These files are the building blocks of workflows in Shisho Cloud. As illustrated in the image below, Shisho Cloud collects the inspection target data defined by the GraphQL query and executes Rego code using it as input to perform security checks:

![](/docs/_md-assets/2aa0a73b37-decide-block.png)

For example, `decide.graphql`, which defines the inspection target data, is defined to retrieve a list of buckets, ACLs, and IAM policies, as shown below:

```graphql title="workflows/cis-benchmark/googlecloud-v1.3.0/storage/bucket-accessibility/decide.graphql"
{
  googleCloud {
    projects {
      cloudStorage {
        buckets {
          metadata {
            id
          }
          name
          acl {
            entity
            role
          }
          iamPolicy {
            bindings {
              role
              members {
                id
              }
            }
          }
        }
      }
    }
  }
}
```

The content of the inspection logic using this data is as follows. Based on the GraphQL query results stored under `input`, the inspection results are stored in a variable called `decisions`:

```rego title="workflows/cis-benchmark/googlecloud-v1.3.0/storage/bucket-accessibility/decide.rego"
package policy.googlecloud.storage.bucket_accessibility

import data.shisho

decisions[d] {

        project := input.googleCloud.projects[_],
        bucket := project.cloudStorage.buckets[_],

        policy_bindings := public_policy_bindings(bucket.iamPolicy.bindings),
        acl_bindings := public_acl_rules(bucket.acl),

        d := shisho.decision.googlecloud.storage.bucket_accessibility({
                "allowed": (count(policy_bindings) + count(acl_bindings)) == 0,
                "subject": bucket.metadata.id,
                "payload": shisho.decision.googlecloud.storage.bucket_accessibility_payload({
                        "public_policy_bindings": policy_bindings,
                        "public_acl_rules": acl_bindings,
                }),
        })
}

is_public_principal(p) {
        p == "allAuthenticatedUsers"
} else {
        p == "allUsers"
} else = false

is_public_entity(p) := is_public_principal(p)

public_acl_rules(acl) := x {
        x := [{
                "role": a.role,
                "entity": a.entity,
        } |
                a := acl[_],
                is_public_entity(a.entity)
        ]
} else := []

public_policy_bindings(bindings) := x {
        x := [{
                "role": binding.role,
                "principal": member.id,
        } |
                binding := bindings[_],
                member := binding.members[_],
                is_public_principal(member.id)
        ]
} else := []
```

You have now identified the Shisho Cloud workflow to modify! In the following sections, we will modify this workflow so that its behavior changes based on labels.

## Get Labels as Inspection Target Data

Next, let's modify the Shisho Cloud workflow to include Cloud Storage labels in the inspection target data. Access the Shisho Cloud [GraphQL Playground](https://cloud.shisho.dev/*/playground/query).

![](/docs/_md-assets/bb70f6ce29-playground.png)

Paste the query from `workflows/cis-benchmark/googlecloud-v1.3.0/storage/bucket-accessibility/decide.graphql` there and search under the `buckets` field to find a field called `labels`. Modify the GraphQL query to include this field and retrieve labels as inspection target data:

```graphql title="workflows/cis-benchmark/googlecloud-v1.3.0/storage/bucket-accessibility/decide.graphql"
{
  googleCloud {
    projects {
      cloudStorage {
        buckets {
          metadata {
            id
          }
          name
          acl {
            entity
            role
          }
          iamPolicy {
            bindings {
              role
              members {
                id
              }
            }
          }

          labels {
            key
            value
          }
        }
      }
    }
  }
}
```

## Modify the Tests

Now that the definition of the inspection target data has been modified, let's modify the tests. Tests are used to verify that the inspection logic is working correctly.

In this case, we decided that if the `security-team-accepted-at` label is present, the bucket should be allowed even if it's public. Therefore, let's add a test to verify that the check result is `allowed` for buckets that have the `security-team-accepted-at` label:

```rego title="workflows/cis-benchmark/googlecloud-v1.3.0/storage/bucket-accessibility/decide_test.rego"
package policy.googlecloud.storage.bucket_accessibility

import data.shisho
import future.keywords

test_whether_proper_accessibility_is_configured_for_storage_buckets if {

        # ... snipped ...

# highlight-start
        # Check if the label will supress the alert
        count([d |
                decisions[d]
                shisho.decision.is_allowed(d)
        ]) == 1 with input as {"googleCloud": {"projects": [{"cloudStorage": {"buckets": [{
                "metadata": {"id": "google-cloud-bq-dataset|514893259785|test-1"},
                "labels": [{"key": "security-team-accepted-at", "value": "2023-11-14"}],
                "acl": [
                        {
                                "role": "WRITER",
                                "entity": "allUsers",
                        },
                        {
                                "role": "OWNER",
                                "entity": "projectWriters",
                        },
                ],
                "iamPolicy": {"bindings": []},
        }]}}]}}
# highlight-end
}
```

At this point, you can also check that the added test fails when the `opa test` command is executed:

```
$ opa test workflows/cis-benchmark/googlecloud-v1.3.0/storage/bucket-accessibility ./sdk

...

workflows/cis-benchmark/googlecloud-v1.3.0/storage/bucket-accessibility/decide_test.rego:
data.policy.googlecloud.storage.bucket_accessibility.test_whether_proper_accessibility_is_configured_for_storage_buckets: FAIL (9.491125ms)
--------------------------------------------------------------------------------
PASS: 1/2
FAIL: 1/2
```

The next step is to modify the inspection logic so that this test passes.

## Modify the Inspection Logic to Evaluate Labels

Now, let's modify the inspection logic to evaluate labels. There are several ways to implement this, but this time, we will add a function called `should_allow` to evaluate labels as follows:

```rego title="workflows/cis-benchmark/googlecloud-v1.3.0/storage/bucket-accessibility/decide.rego"
package policy.googlecloud.storage.bucket_accessibility

import data.shisho

decisions[d] {
        project := input.googleCloud.projects[_],
        bucket := project.cloudStorage.buckets[_],

        policy_bindings := public_policy_bindings(bucket.iamPolicy.bindings),
        acl_bindings := public_acl_rules(bucket.acl),

        d := shisho.decision.googlecloud.storage.bucket_accessibility({
# highlight-next-line
                "allowed": should_allow(bucket, policy_bindings, acl_bindings),
                "subject": bucket.metadata.id,
                "payload": shisho.decision.googlecloud.storage.bucket_accessibility_payload({
                        "public_policy_bindings": policy_bindings,
                        "public_acl_rules": acl_bindings,
                }),
        })
}

# highlight-start
should_allow(bucket, policy_bindings, acl_bindings) {
        l := bucket.labels[_],
        l.key == "security-team-accepted-at",
        l.value != ""
} else {
        count(policy_bindings) + count(acl_bindings) == 0
} else := false
# highlight-end

is_public_principal(p) {
        p == "allAuthenticatedUsers"
} else {
        p == "allUsers"
} else = false

is_public_entity(p) := is_public_principal(p)

public_acl_rules(acl) := x {
        x := [{
                "role": a.role,
                "entity": a.entity,
        } |
                a := acl[_],
                is_public_entity(a.entity)
        ]
} else := []

public_policy_bindings(bindings) := x {
        x := [{
                "role": binding.role,
                "principal": member.id,
        } |
                binding := bindings[_],
                member := binding.members[_],
                is_public_principal(member.id)
        ]
} else := []
```

## Check the Test Results

Now, the test should pass. Let's run the `opa test` command:

```
$ opa test workflows/cis-benchmark/googlecloud-v1.3.0/storage/bucket-accessibility ./sdk

...

workflows/cis-benchmark/googlecloud-v1.3.0/storage/bucket-accessibility/decide_test.rego:
data.policy.googlecloud.storage.bucket_accessibility.test_whether_proper_accessibility_is_configured_for_storage_buckets: PASS (96.768375ms)
--------------------------------------------------------------------------------
PASS: 2/2
```

The test now passes! All that's left is to deploy this fix to Shisho Cloud and see it in action.

## Deployment

Deploy the modified workflow by running the following command:

```bash
$ shishoctl workflow apply --org $SHISHO_ORG_ID -f workflows/cis-benchmark/googlecloud-v1.3.0/storage
Applying 1 manifest files...
succeeded to update a manifest; id=prebundle-googlecloud-storage, snapshot=WS01HF4PBYFYHVRRYEG6B9F0VFB4
```

## Run the Workflow and Verify the Behavior

Run the modified workflow immediately by running the following command:

```bash
$ shishoctl workflow run --org $SHISHO_ORG_ID prebundle-googlecloud-storage
```

If you access the workflow list page, you should see the execution status of the workflow:

![](/docs/_md-assets/0aa4607b65-run-list.ja.png)

After the execution is complete, access the check results list page. You can confirm that no alerts are generated for buckets with the `security-team-accepted-at` label:

![](/docs/_md-assets/2d266d462b-run.ja.png)

## Summary

This concludes the example of modifying a Shisho Cloud workflow. You can customize the behavior of checks in Shisho Cloud by modifying workflows in this manner.

These modifications can also be deployed via [continuous deployment using a Git repository](/docs/g/getting-started/deploy-policies-with-git-repositories/index.md). By centrally managing workflow code and approving changes through code review before deployment, you can achieve more secure operations. Try setting it up.
