1
votes

I'm currently trying to develop a script that will get all the findings from the security command center on GCP.
I'm having trouble using a service account that has been created for me. The service account was created on the project X but with the permissions on the organisation to view and list findings.
This is what I came with (idea from gcloud python library) :

from google.cloud import securitycenter
from google.oauth2 import service_account

credentials = service_account.Credentials.from_service_account_file('svc-scc.json')

# Create a client.
client = securitycenter.SecurityCenterClient(credentials=credentials)

# organization_id is the numeric ID of the organization. e.g.:
organization_id = "XXXXXXXXX"
org_name = "organizations/{org_id}".format(org_id=organization_id)
# The "sources/-" suffix lists findings across all sources.  You
# also use a specific source_name instead.
all_sources = "{org_name}/sources/-".format(org_name=org_name)
finding_result_iterator = client.list_findings(all_sources)
for i, finding_result in enumerate(finding_result_iterator):
    print("{}: name: {} resource: {}".format(i, finding_result.finding.name, finding_result.finding.resource_name))

svc-scc.json is the json file with the credentials retrieve from the IAM on GCP :

{
    "type": "service_account",
    "project_id": "Project X",
    "private_key_id": "XXXXXXXXXXXXXXXXXXXXXXX",
    "private_key": "-----BEGIN PRIVATE KEY-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
---END PRIVATE KEY-----\n",
    "client_email": "[email protected]",
    "client_id": "XXXXXXXXXXXXXX",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/svc-scc%40xxxxxxxxxxx.iam.gserviceaccount.com"
  }  

This is the permissions for this service account via Terraform :

resource "google_organization_iam_member" "securitycenter-org-permissions" {
  for_each = toset(["securitycenter.assetsViewer", "securitycenter.findingsViewer"])
  org_id   = var.org_id
  role     = "roles/${each.value}"
  member   = "serviceAccount:${module.service_accounts.service_account["svc-scc"].email}"
}

I got this error :

google.api_core.exceptions.PermissionDenied: 403 Security Command Center API has not been used in project X before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/securitycenter.googleapis.com/overview?project=X then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.

Enabling the securitycenter API for Project X is not the best option for us.
Is there a way in the code to specify the organisation as the default project for the API call ?
If not, do I need to change the service account ?

Thank you for your time !

2
Why it's not an option to activate the API in the project X? What's your concern? - guillaume blaquiere
The project X is our IAM project where we give organization permissions for people and service account via Terraform. I don't have the answer from our architect but I guess it's to minimize exposure. - vfack
Ok, so, create another project and use it for organisation management. At the end, you should apply Organisation Policies, manage realtime security with CSS and its new feature,... You have 1 project for the IAM, the other for the security. It makes sense. - guillaume blaquiere
We're going to re-create the account in the security project. - vfack

2 Answers

0
votes

When you use Client libraries, behind the scenes those libraries make API calls to the product you are using and the calls are made through the project associated with the service account, so it is mandatory to have the API activated in the project used when running the code.

If you don't want to activate the securitycenter API for Project X but you may want to use the Project Y which already has the securitycenter API activated, you need to grant permission to your service account ([email protected]) in Project Y and then when creating the credentials you need to set the project that will be in use.

credentials = service_account.Credentials.from_service_account_file('svc-scc.json', project_id='PROJECT-Y')
0
votes

So, following your advices, i've come up with this : We've create the service account in our Security Project but the organization permissions were set on the IAM project (Project X in the questions). Since the Security project have the API enabled, the script is working properly when I want to get all the findings from the organization.

Thank you all for your help.