diff --git a/google/cloud/securitycenter/__init__.py b/google/cloud/securitycenter/__init__.py index b45dff2c..152da218 100644 --- a/google/cloud/securitycenter/__init__.py +++ b/google/cloud/securitycenter/__init__.py @@ -24,6 +24,7 @@ from google.cloud.securitycenter_v1.types.asset import Asset from google.cloud.securitycenter_v1.types.finding import Finding from google.cloud.securitycenter_v1.types.folder import Folder +from google.cloud.securitycenter_v1.types.indicator import Indicator from google.cloud.securitycenter_v1.types.notification_config import NotificationConfig from google.cloud.securitycenter_v1.types.notification_message import ( NotificationMessage, @@ -121,6 +122,7 @@ "Asset", "Finding", "Folder", + "Indicator", "NotificationConfig", "NotificationMessage", "OrganizationSettings", diff --git a/google/cloud/securitycenter_v1/__init__.py b/google/cloud/securitycenter_v1/__init__.py index 9c8fa408..3c579dae 100644 --- a/google/cloud/securitycenter_v1/__init__.py +++ b/google/cloud/securitycenter_v1/__init__.py @@ -20,6 +20,7 @@ from .types.asset import Asset from .types.finding import Finding from .types.folder import Folder +from .types.indicator import Indicator from .types.notification_config import NotificationConfig from .types.notification_message import NotificationMessage from .types.organization_settings import OrganizationSettings @@ -72,6 +73,7 @@ "GroupFindingsRequest", "GroupFindingsResponse", "GroupResult", + "Indicator", "ListAssetsRequest", "ListAssetsResponse", "ListFindingsRequest", diff --git a/google/cloud/securitycenter_v1/services/security_center/async_client.py b/google/cloud/securitycenter_v1/services/security_center/async_client.py index 1fd7472a..f0338337 100644 --- a/google/cloud/securitycenter_v1/services/security_center/async_client.py +++ b/google/cloud/securitycenter_v1/services/security_center/async_client.py @@ -31,6 +31,7 @@ from google.cloud.securitycenter_v1.services.security_center import pagers from google.cloud.securitycenter_v1.types import finding from google.cloud.securitycenter_v1.types import finding as gcs_finding +from google.cloud.securitycenter_v1.types import indicator from google.cloud.securitycenter_v1.types import notification_config from google.cloud.securitycenter_v1.types import ( notification_config as gcs_notification_config, diff --git a/google/cloud/securitycenter_v1/services/security_center/client.py b/google/cloud/securitycenter_v1/services/security_center/client.py index c7546fa6..2993688f 100644 --- a/google/cloud/securitycenter_v1/services/security_center/client.py +++ b/google/cloud/securitycenter_v1/services/security_center/client.py @@ -35,6 +35,7 @@ from google.cloud.securitycenter_v1.services.security_center import pagers from google.cloud.securitycenter_v1.types import finding from google.cloud.securitycenter_v1.types import finding as gcs_finding +from google.cloud.securitycenter_v1.types import indicator from google.cloud.securitycenter_v1.types import notification_config from google.cloud.securitycenter_v1.types import ( notification_config as gcs_notification_config, diff --git a/google/cloud/securitycenter_v1/types/__init__.py b/google/cloud/securitycenter_v1/types/__init__.py index dc6a8bc3..5602ea30 100644 --- a/google/cloud/securitycenter_v1/types/__init__.py +++ b/google/cloud/securitycenter_v1/types/__init__.py @@ -16,6 +16,7 @@ from .asset import Asset from .finding import Finding from .folder import Folder +from .indicator import Indicator from .notification_config import NotificationConfig from .notification_message import NotificationMessage from .organization_settings import OrganizationSettings @@ -57,6 +58,7 @@ "Asset", "Finding", "Folder", + "Indicator", "NotificationConfig", "NotificationMessage", "OrganizationSettings", diff --git a/google/cloud/securitycenter_v1/types/finding.py b/google/cloud/securitycenter_v1/types/finding.py index 40cbb2a2..6a3c3071 100644 --- a/google/cloud/securitycenter_v1/types/finding.py +++ b/google/cloud/securitycenter_v1/types/finding.py @@ -15,6 +15,7 @@ # import proto # type: ignore +from google.cloud.securitycenter_v1.types import indicator as gcs_indicator from google.cloud.securitycenter_v1.types import security_marks as gcs_security_marks from google.protobuf import struct_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore @@ -100,6 +101,14 @@ class Finding(proto.Message): "projects/{project_number}/sources/{source_id}/findings/{finding_id}", depending on the closest CRM ancestor of the resource associated with the finding. + finding_class (google.cloud.securitycenter_v1.types.Finding.FindingClass): + The class of the finding. + indicator (google.cloud.securitycenter_v1.types.Indicator): + Represents what's commonly known as an Indicator of + compromise (IoC) in computer forensics. This is an artifact + observed on a network or in an operating system that, with + high confidence, indicates a computer intrusion. Reference: + https://en.wikipedia.org/wiki/Indicator_of_compromise """ class State(proto.Enum): @@ -116,6 +125,14 @@ class Severity(proto.Enum): MEDIUM = 3 LOW = 4 + class FindingClass(proto.Enum): + r"""Represents what kind of Finding it is.""" + FINDING_CLASS_UNSPECIFIED = 0 + THREAT = 1 + VULNERABILITY = 2 + MISCONFIGURATION = 3 + OBSERVATION = 4 + name = proto.Field(proto.STRING, number=1,) parent = proto.Field(proto.STRING, number=2,) resource_name = proto.Field(proto.STRING, number=3,) @@ -134,6 +151,8 @@ class Severity(proto.Enum): ) severity = proto.Field(proto.ENUM, number=12, enum=Severity,) canonical_name = proto.Field(proto.STRING, number=14,) + finding_class = proto.Field(proto.ENUM, number=17, enum=FindingClass,) + indicator = proto.Field(proto.MESSAGE, number=18, message=gcs_indicator.Indicator,) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/securitycenter_v1/types/indicator.py b/google/cloud/securitycenter_v1/types/indicator.py new file mode 100644 index 00000000..16ead94a --- /dev/null +++ b/google/cloud/securitycenter_v1/types/indicator.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.cloud.securitycenter.v1", manifest={"Indicator",}, +) + + +class Indicator(proto.Message): + r"""Represents what's commonly known as an Indicator of compromise (IoC) + in computer forensics. This is an artifact observed on a network or + in an operating system that, with high confidence, indicates a + computer intrusion. Reference: + https://en.wikipedia.org/wiki/Indicator_of_compromise + + Attributes: + ip_addresses (Sequence[str]): + List of ip addresses associated to the + Finding. + domains (Sequence[str]): + List of domains associated to the Finding. + """ + + ip_addresses = proto.RepeatedField(proto.STRING, number=1,) + domains = proto.RepeatedField(proto.STRING, number=2,) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/tests/unit/gapic/securitycenter_v1/test_security_center.py b/tests/unit/gapic/securitycenter_v1/test_security_center.py index 86b341fa..edbd7bd1 100644 --- a/tests/unit/gapic/securitycenter_v1/test_security_center.py +++ b/tests/unit/gapic/securitycenter_v1/test_security_center.py @@ -45,6 +45,7 @@ ) from google.cloud.securitycenter_v1.types import finding from google.cloud.securitycenter_v1.types import finding as gcs_finding +from google.cloud.securitycenter_v1.types import indicator from google.cloud.securitycenter_v1.types import notification_config from google.cloud.securitycenter_v1.types import ( notification_config as gcs_notification_config, @@ -771,6 +772,7 @@ def test_create_finding( external_uri="external_uri_value", severity=gcs_finding.Finding.Severity.CRITICAL, canonical_name="canonical_name_value", + finding_class=gcs_finding.Finding.FindingClass.THREAT, ) response = client.create_finding(request) @@ -789,6 +791,7 @@ def test_create_finding( assert response.external_uri == "external_uri_value" assert response.severity == gcs_finding.Finding.Severity.CRITICAL assert response.canonical_name == "canonical_name_value" + assert response.finding_class == gcs_finding.Finding.FindingClass.THREAT def test_create_finding_from_dict(): @@ -836,6 +839,7 @@ async def test_create_finding_async( external_uri="external_uri_value", severity=gcs_finding.Finding.Severity.CRITICAL, canonical_name="canonical_name_value", + finding_class=gcs_finding.Finding.FindingClass.THREAT, ) ) response = await client.create_finding(request) @@ -855,6 +859,7 @@ async def test_create_finding_async( assert response.external_uri == "external_uri_value" assert response.severity == gcs_finding.Finding.Severity.CRITICAL assert response.canonical_name == "canonical_name_value" + assert response.finding_class == gcs_finding.Finding.FindingClass.THREAT @pytest.mark.asyncio @@ -4667,6 +4672,7 @@ def test_set_finding_state( external_uri="external_uri_value", severity=finding.Finding.Severity.CRITICAL, canonical_name="canonical_name_value", + finding_class=finding.Finding.FindingClass.THREAT, ) response = client.set_finding_state(request) @@ -4685,6 +4691,7 @@ def test_set_finding_state( assert response.external_uri == "external_uri_value" assert response.severity == finding.Finding.Severity.CRITICAL assert response.canonical_name == "canonical_name_value" + assert response.finding_class == finding.Finding.FindingClass.THREAT def test_set_finding_state_from_dict(): @@ -4736,6 +4743,7 @@ async def test_set_finding_state_async( external_uri="external_uri_value", severity=finding.Finding.Severity.CRITICAL, canonical_name="canonical_name_value", + finding_class=finding.Finding.FindingClass.THREAT, ) ) response = await client.set_finding_state(request) @@ -4755,6 +4763,7 @@ async def test_set_finding_state_async( assert response.external_uri == "external_uri_value" assert response.severity == finding.Finding.Severity.CRITICAL assert response.canonical_name == "canonical_name_value" + assert response.finding_class == finding.Finding.FindingClass.THREAT @pytest.mark.asyncio @@ -5395,6 +5404,7 @@ def test_update_finding( external_uri="external_uri_value", severity=gcs_finding.Finding.Severity.CRITICAL, canonical_name="canonical_name_value", + finding_class=gcs_finding.Finding.FindingClass.THREAT, ) response = client.update_finding(request) @@ -5413,6 +5423,7 @@ def test_update_finding( assert response.external_uri == "external_uri_value" assert response.severity == gcs_finding.Finding.Severity.CRITICAL assert response.canonical_name == "canonical_name_value" + assert response.finding_class == gcs_finding.Finding.FindingClass.THREAT def test_update_finding_from_dict(): @@ -5460,6 +5471,7 @@ async def test_update_finding_async( external_uri="external_uri_value", severity=gcs_finding.Finding.Severity.CRITICAL, canonical_name="canonical_name_value", + finding_class=gcs_finding.Finding.FindingClass.THREAT, ) ) response = await client.update_finding(request) @@ -5479,6 +5491,7 @@ async def test_update_finding_async( assert response.external_uri == "external_uri_value" assert response.severity == gcs_finding.Finding.Severity.CRITICAL assert response.canonical_name == "canonical_name_value" + assert response.finding_class == gcs_finding.Finding.FindingClass.THREAT @pytest.mark.asyncio