This tutorial shows platform security administrators how to view and manage policy violations for Kubernetes resources alongside other vulnerability and security findings in Security Command Center. In this tutorial, you can use either Policy Controller or Open Policy Agent (OPA) Gatekeeper.
Architecture
Policy Controller checks, audits, and enforces your Kubernetes cluster resources' compliance with policies related to security, regulations, or business rules. Policy Controller is built from the OPA Gatekeeper open source project.
The
audit functionality
in Policy Controller and OPA Gatekeeper lets you implement detective controls
that periodically evaluate resources against policies. If an issue is detected,
the controls create violations for resources that don't conform to the policies.
These violations are stored in the cluster, and you can query them using
Kubernetes tools such as kubectl
.
To make these violations visible and to help you take actions, you can use Security Command Center. Security Command Center provides a dashboard and APIs for surfacing, understanding, and remediating security and data risks across an organization for Google Cloud resources, Kubernetes resources, and hybrid or multi-cloud resources.
Security Command Center displays possible security risks and policy violations, called findings. Findings come from sources, which are mechanisms that can detect and report risks and violations. Security Command Center includes built-in services, and you can add third-party sources and your own sources.
This tutorial and associated source code shows you how to create a source and findings in Security Command Center for Policy Controller and OPA Gatekeeper policy violations.
The following diagram shows the architecture that is implemented in this tutorial:
As the preceding diagram shows, in this tutorial you create a source in Security Command Center using a command-line tool. You deploy a controller to a Google Kubernetes Engine (GKE) cluster to synchronize Policy Controller and OPA Gatekeeper constraint violations to findings in Security Command Center.
If you want to see how to synchronize policy violations for Google Cloud resources, try out our tutorial about how to create policy-compliant Google Cloud resources using Config Connector and Policy Controller.
Objectives
- Create a policy and a resource that violates the policy.
- Create a source in Security Command Center.
- Create a finding in Security Command Center from an OPA Gatekeeper policy violation using a command-line tool.
- Deploy a controller to the GKE cluster to periodically synchronize findings in Security Command Center from OPA Gatekeeper policy violations.
- View findings in your terminal and in the Google Cloud console.
Costs
In this document, you use the following billable components of Google Cloud:
To generate a cost estimate based on your projected usage,
use the pricing calculator.
When you finish the tasks that are described in this document, you can avoid continued billing by deleting the resources that you created. For more information, see Clean up.
Before you begin
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
- To complete this tutorial, you must have an appropriate editor role for Security Command Center at the organization level, such as Security Center Admin Editor. Your organization administrator can grant you this role.
-
In the Google Cloud console, activate Cloud Shell.
Preparing the environment
In Cloud Shell, set the Google Cloud project that you want to use for this tutorial:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project ID. When you run this command, Cloud Shell creates an exported environment variable calledGOOGLE_CLOUD_PROJECT
that contains your project ID.Enable the Resource Manager, GKE, Security Command Center, and Service Usage APIs:
gcloud services enable \ cloudresourcemanager.googleapis.com \ container.googleapis.com \ securitycenter.googleapis.com \ serviceusage.googleapis.com
Creating a GKE cluster
In Cloud Shell, create a GKE cluster with Workload Identity enabled:
gcloud container clusters create gatekeeper-securitycenter-tutorial \ --enable-ip-alias \ --release-channel regular \ --workload-pool $GOOGLE_CLOUD_PROJECT.svc.id.goog \ --zone us-central1-f
This command creates the cluster in the
us-central1-f
zone. You can use a different zone or region.Grant yourself the
cluster-admin
cluster role:kubectl create clusterrolebinding cluster-admin-binding \ --clusterrole cluster-admin \ --user $(gcloud config get-value core/account)
You need this role later to create some of the Kubernetes resources used by the controller. You also need it if you install the open source OPA Gatekeeper distribution.
Installing the policy tool
If you have a managed GKE cluster, follow the instructions to install Policy Controller, otherwise install the OPA Gatekeeper distribution.
Policy Controller
Install Policy Controller by following the installation instructions.
Use an audit interval of 60
seconds.
OPA Gatekeeper
In Cloud Shell, define the OPA Gatekeeper version that you want to install:
GATEKEEPER_VERSION=v3.10.0
Install OPA Gatekeeper:
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/$GATEKEEPER_VERSION/deploy/gatekeeper.yaml
Verify that OPA Gatekeeper is installed:
kubectl rollout status deploy gatekeeper-controller-manager \ -n gatekeeper-system
When the installation completes, the output displays
deployment "gatekeeper-controller-manager" successfully rolled out
.
Creating a policy
A policy in Policy Controller and OPA Gatekeeper consists of a constraint template and a constraint. The constraint template contains the policy logic. The constraint specifies where the policy applies and specifies input parameters for the policy logic.
In this section, you create a policy for Kubernetes Pods and a Pod that violates the policy.
In Cloud Shell, clone the OPA Gatekeeper library repository, go to the repository directory, and check out a known commit:
git clone https://github.com/open-policy-agent/gatekeeper-library.git \ ~/gatekeeper-library cd ~/gatekeeper-library git checkout 1da0facae99658accb73c291cb79f497fcddf641
Create a Pod called
nginx-disallowed
in thedefault
namespace:kubectl apply -f library/general/allowedrepos/samples/repo-must-be-openpolicyagent/example_disallowed.yaml
The following is the manifest that you apply to create the Pod:
This Pod uses a container image from a repository that isn't approved by the policy.
Create a constraint template called
k8sallowedrepos
:kubectl apply -f library/general/allowedrepos/template.yaml
The following is the constraint template manifest:
Create a constraint called
repo-is-openpolicyagent
:kubectl apply -f library/general/allowedrepos/samples/repo-must-be-openpolicyagent/constraint.yaml
The following is the constraint manifest:
Auditing constraints
The audit controller in Policy Controller and OPA Gatekeeper periodically evaluates resources against constraints. This auditing lets you detect policy-violating resources that were created before you created the constraint.
In Cloud Shell, view violations for all constraints by querying using the
constraint
category:kubectl get constraint -o json | jq '.items[].status.violations'
The output is the following:
[ { "enforcementAction": "deny", "kind": "Pod", "message": "container <nginx> has an invalid image repo <nginx>, allowed repos are [\"openpolicyagent\"]", "name": "nginx-disallowed", "namespace": "default" } ]
There is a violation for the Pod that you created before you created the constraint. If you see
null
instead of the preceding output, the Policy Controller or OPA Gatekeeper audit hasn't run since you created the constraint. By default, the audit runs every minute. Wait a minute and try again.
Creating a Security Command Center source
Security Command Center records findings against sources. Follow these steps to create a source for findings from Policy Controller and OPA Gatekeeper:
In Cloud Shell, create a Google service account and store the service account name in an environment variable:
SOURCES_ADMIN_SA=$(gcloud iam service-accounts create \ securitycenter-sources-admin \ --display-name "Security Command Center sources admin" \ --format 'value(email)')
You use this Google service account to administer Security Command Center sources.
Define an environment variable that contains your Google Cloud organization ID:
ORGANIZATION_ID=$(gcloud projects get-ancestors $GOOGLE_CLOUD_PROJECT \ --format json | jq -r '.[] | select (.type=="organization") | .id')
Grant the Security Center Sources Admin role to the sources admin Google service account at the organization level:
gcloud organizations add-iam-policy-binding $ORGANIZATION_ID \ --member "serviceAccount:$SOURCES_ADMIN_SA" \ --role roles/securitycenter.sourcesAdmin
This role provides the
securitycenter.sources.*
permissions that are required to administer sources.Grant the Service Usage Consumer role to the sources admin Google service account at the organization level:
gcloud organizations add-iam-policy-binding $ORGANIZATION_ID \ --member "serviceAccount:$SOURCES_ADMIN_SA" \ --role roles/serviceusage.serviceUsageConsumer
This role provides the
serviceusage.services.use
permission to use projects in the organization for quota and billing purposes.Grant yourself the Service Account Token Creator role for the sources admin Google service account:
gcloud iam service-accounts add-iam-policy-binding \ $SOURCES_ADMIN_SA \ --member "user:$(gcloud config get-value account)" \ --role roles/iam.serviceAccountTokenCreator
This role allows your user identity to impersonate, or act as, the Google service account.
Download the latest version of the
gatekeeper-securitycenter
command-line tool for your platform and make it executable:VERSION=v0.4.0 curl -Lo gatekeeper-securitycenter "https://github.com/GoogleCloudPlatform/gatekeeper-securitycenter/releases/download/${VERSION}/gatekeeper-securitycenter_$(uname -s)_$(uname -m)" chmod +x gatekeeper-securitycenter
Use the
gatekeeper-securitycenter
tool to create a Security Command Center source for your organization. Capture the full source name in an environment variable.export SOURCE_NAME=$(./gatekeeper-securitycenter sources create \ --organization $ORGANIZATION_ID \ --display-name "Gatekeeper" \ --description "Reports violations from Policy Controller audits" \ --impersonate-service-account $SOURCES_ADMIN_SA | jq -r '.name')
This command creates a source with the display name
Gatekeeper
. This display name is visible in Security Command Center. You can use a different display name and description.If you get a response with the error message,
The caller does not have permission
, wait a minute, and then try again. This error can happen if the Identity and Access Management (IAM) bindings haven't taken effect yet.
Creating findings using the command line
You can create Security Command Center findings from Policy Controller and OPA Gatekeeper
constraint violations using the gatekeeper-securitycenter
tool as part of a
build pipeline or scheduled task.
In Cloud Shell, create a Google service account and store the service account name in an environment variable:
FINDINGS_EDITOR_SA=$(gcloud iam service-accounts create \ gatekeeper-securitycenter \ --display-name "Security Command Center Gatekeeper findings editor" \ --format 'value(email)')
You use this Google service account to create findings for your Security Command Center source.
Grant the Security Center Findings Editor role to the Google service account for the source:
./gatekeeper-securitycenter sources add-iam-policy-binding \ --source $SOURCE_NAME \ --member "serviceAccount:$FINDINGS_EDITOR_SA" \ --role roles/securitycenter.findingsEditor \ --impersonate-service-account $SOURCES_ADMIN_SA
This role provides the
securitycenter.findings.*
permissions required to create and edit findings. When you run this command, you impersonate the sources admin Google service account.Grant the Service Usage Consumer role to the findings editor Google service account at the organization level:
gcloud organizations add-iam-policy-binding $ORGANIZATION_ID \ --member "serviceAccount:$FINDINGS_EDITOR_SA" \ --role roles/serviceusage.serviceUsageConsumer
Grant your user identity the Service Account Token Creator role for the findings editor Google service account:
gcloud iam service-accounts add-iam-policy-binding \ $FINDINGS_EDITOR_SA \ --member "user:$(gcloud config get-value account)" \ --role roles/iam.serviceAccountTokenCreator
Print findings to the terminal instead of creating them in Security Command Center:
./gatekeeper-securitycenter findings sync --dry-run=true
This command uses your current kubeconfig context by default. If you want to use a different kubeconfig file, use the
--kubeconfig
flag.The output looks similar to the following:
[ { "finding_id": "0be44bcf181ef03162eed40126a500a0", "finding": { "resource_name": "https://API_SERVER/api/v1/namespaces/default/pods/nginx-disallowed", "state": 1, "category": "K8sAllowedRepos", "external_uri": "https://API_SERVER/apis/constraints.gatekeeper.sh/v1beta1/k8sallowedrepos/repo-is-openpolicyagent", "source_properties": { "Cluster": "", "ConstraintName": "repo-is-openpolicyagent", "ConstraintSelfLink": "https://API_SERVER/apis/constraints.gatekeeper.sh/v1beta1/k8sallowedrepos/repo-is-openpolicyagent", "ConstraintTemplateSelfLink": "https://API_SERVER/apis/templates.gatekeeper.sh/v1beta1/constrainttemplates/k8sallowedrepos", "ConstraintTemplateUID": "e35b1c39-15f7-4a7a-afae-1637b44e81b2", "ConstraintUID": "b904dddb-0a23-4f4f-81bb-0103de838d3e", "Explanation": "container \u003cnginx\u003e has an invalid image repo \u003cnginx\u003e, allowed repos are [\"openpolicyagent\"]", "ProjectId": "", "ResourceAPIGroup": "", "ResourceAPIVersion": "v1", "ResourceKind": "Pod", "ResourceName": "nginx-disallowed", "ResourceNamespace": "default", "ResourceSelfLink": "https://API_SERVER/api/v1/namespaces/default/pods/nginx-disallowed", "ResourceStatusSelfLink": "", "ResourceUID": "8ddd752f-e620-43ea-b966-4ae2ae507c67", "ScannerName": "GATEKEEPER" }, "event_time": { "seconds": 1606287680 } } } ]
In the preceding output,
API_SERVER
is the IP address or hostname of your GKE cluster API server.To learn what the fields mean, see the Security Command Center API Finding resource page.
Create findings in Security Command Center:
./gatekeeper-securitycenter findings sync \ --source $SOURCE_NAME \ --impersonate-service-account $FINDINGS_EDITOR_SA
When you run this command, you impersonate the findings editor Google service account.
The output includes
create finding
, which means that thegatekeeper-securitycenter
command-line tool created a finding. ThefindingID
attribute of that output contains the full name of the finding in the format:organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID
In this output:
ORGANIZATION_ID
is your Google Cloud organization IDSOURCE_ID
is your Security Command Center source IDFINDING_ID
is the finding ID
To view the finding, see the Viewing findings section.
If you get a response with the error message,
The caller does not have permission
, wait a minute, and then try again. This error can happen if the Identity and Access Management (IAM) bindings haven't taken effect yet.
Creating findings using a Kubernetes controller
You can deploy gatekeeper-securitycenter
as a
controller
in your GKE cluster. This controller periodically checks
for constraint violations and creates a finding in Security Command Center for each
violation.
If the resource becomes compliant, the controller sets the state of the
existing finding to
INACTIVE
.
In Cloud Shell, create a Workload Identity IAM policy binding to allow the
gatekeeper-securitycenter-controller
Kubernetes service account in thegatekeeper-securitycenter
namespace to impersonate the findings editor Google service account:gcloud iam service-accounts add-iam-policy-binding \ $FINDINGS_EDITOR_SA \ --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.svc.id.goog[gatekeeper-securitycenter/gatekeeper-securitycenter-controller]" \ --role roles/iam.workloadIdentityUser
You create the Kubernetes service account and namespace when you deploy the controller.
Fetch the kpt package for the
gatekeeper-securitycenter
controller:VERSION=v0.4.0 kpt pkg get https://github.com/GoogleCloudPlatform/gatekeeper-securitycenter.git/manifests@$VERSION manifests
This command creates a directory called
manifests
that contains the resource manifests files for the controller.kpt is a command-line tool that lets you manage, manipulate, customize, and apply Kubernetes resources. You use kpt in this tutorial to customize the resource manifests for your environment.
Set the Security Command Center source name:
kpt fn eval manifests \ --image gcr.io/kpt-fn/apply-setters:v0.2 -- \ "source=$SOURCE_NAME"
Set the cluster name:
kpt fn eval manifests \ --image gcr.io/kpt-fn/apply-setters:v0.2 -- \ "cluster=$(kubectl config current-context)"
The controller adds the cluster name as a source property to the findings that it creates in Security Command Center. If you have multiple clusters, this name helps you find which cluster a finding belongs to.
To bind the controller Kubernetes service account to the findings editor Google service account, add the Workload Identity annotation:
kpt fn eval manifests \ --image gcr.io/kpt-fn/set-annotations:v0.1.4 \ --match-kind ServiceAccount \ --match-name gatekeeper-securitycenter-controller \ --match-namespace gatekeeper-securitycenter -- \ "iam.gke.io/gcp-service-account=$FINDINGS_EDITOR_SA"
Initialize the controller package:
kpt live init manifests
Apply the controller resources to your cluster:
kpt live apply manifests --reconcile-timeout 3m --output table
This command creates the following resources in your cluster:
- A namespace called
gatekeeper-securitycenter
. - A service account called
gatekeeper-securitycenter-controller
. - A cluster role that provides
get
andlist
access to all resources in all API groups. This role is required because the controller retrieves the resources that caused policy violations. - A cluster role binding that grants the cluster role to the service account.
- A deployment called
gatekeeper-securitycenter-controller-manager
. - A config map called
gatekeeper-securitycenter-config
that contains configuration values for the deployment.
The command also waits for the resources to be ready.
- A namespace called
Verify that the controller can read constraint violations and communicate with the Security Command Center API by following the controller log:
kubectl logs deployment/gatekeeper-securitycenter-controller-manager \ --namespace gatekeeper-securitycenter --follow --all-containers
You see log entries with the message
syncing findings
.To stop following the log, press
Ctrl+C
.To verify that the controller can create new findings, create a policy and a resource that violates the policy. The Pod uses image digests to refer to container images.
Go to the OPA Gatekeeper library repository directory:
cd ~/gatekeeper-library
Create a Pod called
opa-disallowed
in thedefault
namespace:kubectl apply --namespace default -f \ library/general/imagedigests/samples/container-image-must-have-digest/example_disallowed.yaml
The following is the manifest that you apply to create the Pod:
This Pod specification refers to a container image by tag instead of by digest.
Create a constraint template called
k8simagedigests
:kubectl apply -f library/general/imagedigests/template.yaml
The following is the constraint template manifest:
Create a constraint called
container-image-must-have-digest
:kubectl apply -f library/general/imagedigests/samples/container-image-must-have-digest/constraint.yaml
The following is the constraint manifest:
This constraint only applies to the
default
namespace.Follow the controller log:
kubectl logs deployment/gatekeeper-securitycenter-controller-manager \ --namespace gatekeeper-securitycenter --follow --all-containers
After a few minutes, you see a log entry with the message
create finding
. This message means that thegatekeeper-securitycenter
controller created a finding.To stop following the log, press
Ctrl+C
.To verify that the controller can set the finding state to
INACTIVE
when a violation is no longer reported by Policy Controller or OPA Gatekeeper, delete the Pod calledopa-disallowed
in thedefault
namespace:kubectl delete pod opa-disallowed --namespace default
Follow the controller log:
kubectl logs deployment/gatekeeper-securitycenter-controller-manager \ --namespace gatekeeper-securitycenter --follow --all-containers
After a few minutes, you see a log entry with the message
updating finding state
and the attribute"state":"INACTIVE"
. This message means that the controller set the finding state to inactive.To stop following the log, press
Ctrl+C
.
Viewing findings
You can view Security Command Center findings on the terminal and in the Google Cloud console.
In Cloud Shell, use the gcloud CLI to list findings for your organization and source:
gcloud scc findings list $ORGANIZATION_ID \ --source $(basename $SOURCE_NAME) \ --format json
You use the
basename
command to get the numeric source ID from the full source name.The output looks similar to the following:
[ { "finding": { "category": "K8sAllowedRepos", "createTime": "2020-11-25T06:58:47.213Z", "eventTime": "2020-11-25T06:58:20Z", "externalUri": "https://API_SERVER/apis/constraints.gatekeeper.sh/v1beta1/k8sallowedrepos/repo-is-openpolicyagent", "name": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID", "parent": "organizations/ORGANIZATION_ID/sources/SOURCE_ID", "resourceName": "https://API_SERVER/api/v1/namespaces/default/pods/nginx-disallowed", "securityMarks": { "name": "organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID/securityMarks" }, "sourceProperties": { "Cluster": "cluster-name", "ConstraintName": "repo-is-openpolicyagent", "ConstraintSelfLink": "https://API_SERVER/apis/constraints.gatekeeper.sh/v1beta1/k8sallowedrepos/repo-is-openpolicyagent", "ConstraintTemplateSelfLink": "https://API_SERVER/apis/templates.gatekeeper.sh/v1beta1/constrainttemplates/k8sallowedrepos", "ConstraintTemplateUID": "e35b1c39-15f7-4a7a-afae-1637b44e81b2", "ConstraintUID": "b904dddb-0a23-4f4f-81bb-0103de838d3e", "Explanation": "container <nginx> has an invalid image repo <nginx>, allowed repos are [\"openpolicyagent\"]", "ProjectId": "", "ResourceAPIGroup": "", "ResourceAPIVersion": "v1", "ResourceKind": "Pod", "ResourceName": "nginx-disallowed", "ResourceNamespace": "default", "ResourceSelfLink": "https://API_SERVER/api/v1/namespaces/default/pods/nginx-disallowed", "ResourceStatusSelfLink": "", "ResourceUID": "8ddd752f-e620-43ea-b966-4ae2ae507c67", "ScannerName": "GATEKEEPER" }, "state": "ACTIVE" }, "resource": { "name": "https://API_SERVER/api/v1/namespaces/default/pods/nginx-disallowed" } }, { "finding": { "category": "K8sImageDigests", [...] } ]
In this output:
API_SERVER
is the IP address or hostname of your GKE cluster API serverORGANIZATION_ID
is your Google Cloud organization IDSOURCE_ID
is your Security Command Center source IDFINDING_ID
is the finding ID
To learn what the finding attributes mean, see the Finding resource in the Security Command Center API.
To view the findings in the Google Cloud console, go to the Findings tab of Security Command Center.
Select your organization and click Select.
Click View by Source type.
In the Source type list, click Gatekeeper. If Gatekeeper isn't in the Source type list, clear any filters in the list of findings.
In the list of findings, click a finding to see the finding attributes and source properties.
If a resource no longer causes a violation because of a change to the resource or the policy, the controller sets the finding state to inactive. It can take a few minutes for this change to be visible in Security Command Center.
By default, Security Command Center shows active findings. To see inactive findings, click More options, select Include inactive findings, and click OK.
Troubleshooting
If Policy Controller or OPA Gatekeeper don't report violations in the
status
field of the constraint objects, use Cloud Shell to view logs of the audit controller:kubectl logs deployment/gatekeeper-audit --namespace gatekeeper-system \ --all-containers
If the
gatekeeper-securitycenter
controller doesn't create findings in Security Command Center, you can view logs of the controller manager:kubectl logs deployment/gatekeeper-securitycenter-controller-manager \ --namespace gatekeeper-securitycenter --all-containers
If the
gatekeeper-securitycenter
command-line tool reports errors, you can increase the verbosity of the log output by setting theDEBUG
environment variable totrue
before running thegatekeeper-securitycenter
command:export DEBUG=true
When using the
gatekeeper-securitycenter
command-line tool to create a source in Security Command Center, you might get an error message that ends with the following text:oauth2: cannot fetch token: 400 Bad Request Response: { "error": "invalid_grant", "error_description": "Bad Request" }
In this case, acquire new credentials for use with Application Default Credentials:
gcloud auth application-default login
Use the new credentials to try to create the source again.
If you run into other problems with this tutorial, we recommend that you review the following documents:
Automating the setup
For future deployments, you can automate the steps in this tutorial by
following the instructions in the
gatekeeper-securitycenter
GitHub repository.
Clean up
To avoid incurring further charges to your Google Cloud account for the resources used in this tutorial, delete the individual resources.
Delete the individual resources
In Cloud Shell, delete the GKE cluster:
gcloud container clusters delete gatekeeper-securitycenter-tutorial \ --zone us-central1-f --async --quiet
Delete the
gatekeeper-library
files:rm -rf ~/gatekeeper-library
Delete the IAM policy bindings:
GOOGLE_CLOUD_PROJECT=$(gcloud config get-value core/project) ORGANIZATION_ID=$(gcloud projects get-ancestors $GOOGLE_CLOUD_PROJECT \ --format json | jq -r '.[] | select (.type=="organization") | .id') SOURCE_NAME=$(./gatekeeper-securitycenter sources list \ --organization "$ORGANIZATION_ID" \ --impersonate-service-account "securitycenter-sources-admin@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \ | jq -r ".[] | select (.display_name==\"Gatekeeper\") | .name") ./gatekeeper-securitycenter sources remove-iam-policy-binding \ --source $SOURCE_NAME \ --member "serviceAccount:gatekeeper-securitycenter@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \ --role roles/securitycenter.findingsEditor \ --impersonate-service-account securitycenter-sources-admin@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com gcloud iam service-accounts remove-iam-policy-binding \ gatekeeper-securitycenter@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \ --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.svc.id.goog[gatekeeper-securitycenter/gatekeeper-securitycenter-controller]" \ --role roles/iam.workloadIdentityUser gcloud iam service-accounts remove-iam-policy-binding \ gatekeeper-securitycenter@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \ --member "user:$(gcloud config get-value account)" \ --role roles/iam.serviceAccountTokenCreator gcloud organizations remove-iam-policy-binding $ORGANIZATION_ID \ --member "serviceAccount:gatekeeper-securitycenter@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \ --role roles/serviceusage.serviceUsageConsumer gcloud iam service-accounts remove-iam-policy-binding \ securitycenter-sources-admin@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \ --member "user:$(gcloud config get-value account)" \ --role roles/iam.serviceAccountTokenCreator gcloud organizations remove-iam-policy-binding $ORGANIZATION_ID \ --member "serviceAccount:securitycenter-sources-admin@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \ --role roles/serviceusage.serviceUsageConsumer gcloud organizations remove-iam-policy-binding $ORGANIZATION_ID \ --member "serviceAccount:securitycenter-sources-admin@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \ --role roles/securitycenter.sourcesAdmin
Delete the Google service accounts:
gcloud iam service-accounts delete --quiet \ gatekeeper-securitycenter@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com gcloud iam service-accounts delete --quiet \ securitycenter-sources-admin@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
What's next
- Learn how to create policy-compliant Google Cloud resources using Config Connector and Policy Controller or OPA Gatekeeper.
- Discover how to run Policy Controller validation as part of a continuous integration pipeline in Cloud Build.
- Learn how to set up notifications for Security Command Center findings.
- Learn more about how to access Security Command Center using an SDK.
- Explore reference architectures, diagrams, and best practices about Google Cloud. Take a look at our Cloud Architecture Center.