Skip to content
Permalink
Browse files

Merge pull request #3459 from forseti-security/master-3232

[CAI] Add IAM Service Account Key Resource
  • Loading branch information
blueandgold committed Nov 19, 2019
2 parents c302a45 + fbdb4be commit c208e6b3ff2341b5ce19ba357ade4b87a0acf71b
@@ -203,6 +203,7 @@ inventory:
# - dns.googleapis.com/Policy
# - iam.googleapis.com/Role
# - iam.googleapis.com/ServiceAccount
# - iam.googleapis.com/ServiceAccountKey
# - k8s.io/Namespace
# - k8s.io/Node
# - k8s.io/Pod
@@ -1362,6 +1362,25 @@ def iter_iam_serviceaccounts(self, project_id, project_number):
for serviceaccount in resources:
yield serviceaccount

def iter_iam_serviceaccount_keys(self, project_id, serviceaccount_id):
"""Iterate Service Account Keys in a project from Cloud Asset data.
Args:
project_id (str): id of the project to query.
serviceaccount_id (str): id of the service account to query.
Yields:
dict: Generator of service account.
"""
resources = self.dao.iter_cai_assets(
ContentTypes.resource,
'iam.googleapis.com/ServiceAccountKey',
'//iam.googleapis.com/projects/{}/serviceAccounts/{}'.format(
project_id, serviceaccount_id),
self.engine)
for serviceaccount_key in resources:
yield serviceaccount_key

def fetch_kms_cryptokey_iam_policy(self, cryptokey):
"""Fetch KMS Cryptokey IAM Policy from Cloud Asset data.
@@ -94,6 +94,7 @@
'k8s.io/Node',
'k8s.io/Pod',
'iam.googleapis.com/ServiceAccount',
'iam.googleapis.com/ServiceAccountKey',
'pubsub.googleapis.com/Subscription',
'pubsub.googleapis.com/Topic',
'rbac.authorization.k8s.io/ClusterRole',
@@ -741,6 +741,15 @@ def iter_iam_serviceaccounts(self, project_id, project_number):
project_number (str): number of the project to query.
"""

@abc.abstractmethod
def iter_iam_serviceaccount_keys(self, project_id, serviceaccount_id):
"""Iterate Service Account Keys in a project from GCP API.
Args:
project_id (str): id of the project to query.
serviceaccount_id (str): id of the service account to query.
"""

@abc.abstractmethod
def fetch_kms_cryptokey_iam_policy(self, cryptokey):
"""Fetch KMS Cryptokey IAM Policy from GCP API.
@@ -2402,6 +2411,19 @@ def iter_iam_serviceaccounts(self, project_id, project_number):
for serviceaccount in self.iam.get_service_accounts(project_id):
yield serviceaccount, None

def iter_iam_serviceaccount_keys(self, project_id, serviceaccount_id):
"""Iterate Service Account Keys in a project from GCP API.
Args:
project_id (str): id of the project to query.
serviceaccount_id (str): id of the service account to query.
Raises:
ResourceNotSupported: Raised for all calls using this class.
"""
raise ResourceNotSupported('Service Account Keys are not supported by '
'this API client.')

def fetch_kms_cryptokey_iam_policy(self, cryptokey):
"""Fetch KMS Cryptokey IAM Policy from GCP API.
@@ -1382,19 +1382,10 @@ def get_iam_policy(self, client=None):
return None


class IamServiceAccountKey(resource_class_factory('serviceaccount_key', None)):
class IamServiceAccountKey(resource_class_factory('serviceaccount_key', 'name',
hash_key=True)):
"""The Resource implementation for IAM ServiceAccountKey."""

def key(self):
"""Get key of this resource.
Key name is in the format:
projects/{project_id}/serviceAccounts/{service_account}/keys/{key_id}
Returns:
str: id key of this resource
"""
return self['name'].split('/')[-1]


# Key Management Service resource classes
class KmsCryptoKey(resource_class_factory('kms_cryptokey', 'name',
@@ -2442,9 +2433,10 @@ class IamServiceAccountIterator(resource_iter_class_factory(


class IamServiceAccountKeyIterator(resource_iter_class_factory(
api_method_name='iter_iam_serviceaccount_exported_keys',
api_method_name='iter_iam_serviceaccount_keys',
resource_name='iam_serviceaccount_key',
api_method_arg_key='name')):
api_method_arg_key='projectId',
additional_arg_keys=['uniqueId'])):
"""The Resource iterator implementation for IAM ServiceAccount Key."""


@@ -66,7 +66,6 @@
'resource': 4},
'role': {'resource': 20},
'serviceaccount': {'iam_policy': 2, 'resource': 2},
'serviceaccount_key': {'resource': 1},
'sink': {'resource': 7},
'snapshot': {'resource': 3},
'subnetwork': {'resource': 24},
@@ -374,7 +373,6 @@ def test_crawling_from_project(self):
'project': {'billing_info': 1, 'enabled_apis': 1, 'iam_policy': 1,
'resource': 1},
'serviceaccount': {'iam_policy': 1, 'resource': 1},
'serviceaccount_key': {'resource': 1},
'sink': {'resource': 2},
'snapshot': {'resource': 2},
'subnetwork': {'resource': 12},
@@ -420,7 +418,6 @@ def test_crawling_from_composite_root(self):
'resource': 2},
'role': {'resource': 1},
'serviceaccount': {'iam_policy': 1, 'resource': 1},
'serviceaccount_key': {'resource': 1},
'sink': {'resource': 3},
'snapshot': {'resource': 2},
'subnetwork': {'resource': 12},
@@ -531,7 +528,6 @@ def _fake_download(full_bucket_path, output_file):
self.assertEqual(0,
progresser.errors,
'No errors should have occurred')

return self._get_resource_counts_from_storage(storage)

def tearDown(self):
@@ -592,6 +588,8 @@ def test_cai_crawl_to_memory(self):
'kubernetes_rolebinding': {'resource': 1},
'pubsub_subscription': {'iam_policy': 1, 'resource': 1},
'pubsub_topic': {'iam_policy': 1, 'resource': 1},
'serviceaccount': {'iam_policy': 2, 'resource': 3},
'serviceaccount_key': {'resource': 1},
'spanner_database': {'resource': 1},
'spanner_instance': {'resource': 1},
})
@@ -683,7 +681,8 @@ def test_crawl_cai_api_polling_disabled(self):
'pubsub_subscription': {'iam_policy': 1, 'resource': 1},
'pubsub_topic': {'iam_policy': 1, 'resource': 1},
'role': {'resource': 2},
'serviceaccount': {'iam_policy': 2, 'resource': 2},
'serviceaccount': {'iam_policy': 2, 'resource': 3},
'serviceaccount_key': {'resource': 1},
'snapshot': {'resource': 3},
'spanner_database': {'resource': 1},
'spanner_instance': {'resource': 1},
@@ -74,6 +74,10 @@
{"name":"//dns.googleapis.com/projects/1042/managedZones/9141","asset_type":"dns.googleapis.com/ManagedZone","resource":{"version":"v1alpha2","discovery_document_uri":"https://www.googleapis.com/discovery/v1/apis/dns/v1alpha2/rest","discovery_name":"ManagedZone","parent":"//cloudresourcemanager.googleapis.com/projects/1042","data":{"creationTime":"2017-10-19T20:33:50.317Z","description":"description","dnsName":"test.forseti.","id":"9141","name":"name","nameServers":["ns1.test.","ns2.test.","ns3.test.","ns4.test."]}}}
# DNS Policy (id 915x)
{"name":"//dns.googleapis.com/projects/1042/policies/9151","asset_type":"dns.googleapis.com/Policy","resource":{"version":"v1alpha2","discovery_document_uri":"https://www.googleapis.com/discovery/v1/apis/dns/v1alpha2/rest","discovery_name":"Policy","parent":"//cloudresourcemanager.googleapis.com/projects/1042","data":{"description":"","enableInboundForwarding":true,"id":"9151","internetResolution":"YES","name":"test-policy","networks":[{"networkUrl":"https://www.googleapis.com/compute/v1/projects/project2/global/networks/default"}]}}}
# Service Account
{"name":"//iam.googleapis.com/projects/project2/serviceAccounts/09876543210987654321","asset_type":"iam.googleapis.com/ServiceAccount","resource":{"version":"v1","discovery_document_uri":"https://iam.googleapis.com/$discovery/rest","discovery_name":"ServiceAccount","parent":"//cloudresourcemanager.googleapis.com/projects/1042","data":{"displayName":"App Engine default service account","email":"123-compute@developer.gserviceaccount.com","name":"projects/project2/serviceAccounts/123-compute@developer.gserviceaccount.com","oauth2ClientId":"09876543210987654321","projectId":"project2","uniqueId":"09876543210987654321"}},"ancestors":["projects/1042","organizations/456"]}
# Service Account Key
{"name":"//iam.googleapis.com/projects/project2/serviceAccounts/09876543210987654321/keys/5555abcabcabc444444abcabc","asset_type":"iam.googleapis.com/ServiceAccountKey","resource":{"version":"v1","discovery_document_uri":"https://iam.googleapis.com/$discovery/rest","discovery_name":"ServiceAccountKey","parent":"//iam.googleapis.com/projects/project2/serviceAccounts/09876543210987654321","data":{"keyAlgorithm":"KEY_ALG_RSA_2048","keyOrigin":"GOOGLE_PROVIDED","keyType":"SYSTEM_MANAGED","name":"projects/project2/serviceAccounts/123-compute@developer.gserviceaccount.com/keys/5555abcabcabc444444abcabc","validAfterTime":"2019-11-19T04:15:47Z","validBeforeTime":"2019-12-05T04:15:47Z"}},"ancestors":["projects/1042","organizations/456"]}
# KMS CryptoKey
{"name":"//cloudkms.googleapis.com/projects/project2/locations/us/keyRings/test-kr/cryptoKeys/test-key","asset_type":"cloudkms.googleapis.com/CryptoKey","resource":{"version":"v1","discovery_document_uri":"https://cloudkms.googleapis.com/$discovery/rest","discovery_name":"CryptoKey","data":{"createTime":"2018-11-24T22:57:42.206650064Z","name":"projects/project2/locations/us/keyRings/test-kr/cryptoKeys/test-key","nextRotationTime":"2019-02-22T08:00:00Z","primary":{"algorithm":"GOOGLE_SYMMETRIC_ENCRYPTION","createTime":"2018-11-24T22:57:42.206650064Z","generateTime":"2018-11-24T22:57:42.206650064Z","name":"projects/project2/locations/us/keyRings/test-kr/cryptoKeys/test-key/cryptoKeyVersions/1","protectionLevel":"SOFTWARE","state":"ENABLED"},"purpose":"ENCRYPT_DECRYPT","rotationPeriod":"7776000s","versionTemplate":{"algorithm":"GOOGLE_SYMMETRIC_ENCRYPTION","protectionLevel":"SOFTWARE"}}}}
# KMS CryptoKeyVersion

0 comments on commit c208e6b

Please sign in to comment.
You can’t perform that action at this time.