// Copyright 2023 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.

syntax = "proto3";

package google.cloud.securitycentermanagement.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/iam/v1/policy.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";
import "google/type/expr.proto";

option csharp_namespace = "Google.Cloud.SecurityCenterManagement.V1";
option go_package = "cloud.google.com/go/securitycentermanagement/apiv1/securitycentermanagementpb;securitycentermanagementpb";
option java_multiple_files = true;
option java_outer_classname = "SecurityCenterManagementProto";
option java_package = "com.google.cloud.securitycentermanagement.v1";
option php_namespace = "Google\\Cloud\\SecurityCenterManagement\\V1";
option ruby_package = "Google::Cloud::SecurityCenterManagement::V1";
option (google.api.resource_definition) = {
  type: "securitycentermanagement.googleapis.com/OrganizationLocation"
  pattern: "organizations/{organization}/locations/{location}"
};
option (google.api.resource_definition) = {
  type: "securitycentermanagement.googleapis.com/FolderLocation"
  pattern: "folders/{folder}/locations/{location}"
};

// Service describing handlers for resources
service SecurityCenterManagement {
  option (google.api.default_host) = "securitycentermanagement.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Returns a list of all EffectiveSecurityHealthAnalyticsCustomModules for the
  // given parent. This includes resident modules defined at the scope of the
  // parent, and inherited modules, inherited from CRM ancestors (no
  // descendants).
  rpc ListEffectiveSecurityHealthAnalyticsCustomModules(
      ListEffectiveSecurityHealthAnalyticsCustomModulesRequest)
      returns (ListEffectiveSecurityHealthAnalyticsCustomModulesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/effectiveSecurityHealthAnalyticsCustomModules"
      additional_bindings {
        get: "/v1/{parent=folders/*/locations/*}/effectiveSecurityHealthAnalyticsCustomModules"
      }
      additional_bindings {
        get: "/v1/{parent=organizations/*/locations/*}/effectiveSecurityHealthAnalyticsCustomModules"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets details of a single EffectiveSecurityHealthAnalyticsCustomModule.
  rpc GetEffectiveSecurityHealthAnalyticsCustomModule(
      GetEffectiveSecurityHealthAnalyticsCustomModuleRequest)
      returns (EffectiveSecurityHealthAnalyticsCustomModule) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/effectiveSecurityHealthAnalyticsCustomModules/*}"
      additional_bindings {
        get: "/v1/{name=folders/*/locations/*/effectiveSecurityHealthAnalyticsCustomModules/*}"
      }
      additional_bindings {
        get: "/v1/{name=organizations/*/locations/*/effectiveSecurityHealthAnalyticsCustomModules/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Returns a list of all SecurityHealthAnalyticsCustomModules for the given
  // parent. This includes resident modules defined at the scope of the parent,
  // and inherited modules, inherited from CRM ancestors (no descendants).
  rpc ListSecurityHealthAnalyticsCustomModules(
      ListSecurityHealthAnalyticsCustomModulesRequest)
      returns (ListSecurityHealthAnalyticsCustomModulesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/securityHealthAnalyticsCustomModules"
      additional_bindings {
        get: "/v1/{parent=folders/*/locations/*}/securityHealthAnalyticsCustomModules"
      }
      additional_bindings {
        get: "/v1/{parent=organizations/*/locations/*}/securityHealthAnalyticsCustomModules"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Returns a list of all resident SecurityHealthAnalyticsCustomModules under
  // the given CRM parent and all of the parent’s CRM descendants.
  rpc ListDescendantSecurityHealthAnalyticsCustomModules(
      ListDescendantSecurityHealthAnalyticsCustomModulesRequest)
      returns (ListDescendantSecurityHealthAnalyticsCustomModulesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/securityHealthAnalyticsCustomModules:listDescendant"
      additional_bindings {
        get: "/v1/{parent=folders/*/locations/*}/securityHealthAnalyticsCustomModules:listDescendant"
      }
      additional_bindings {
        get: "/v1/{parent=organizations/*/locations/*}/securityHealthAnalyticsCustomModules:listDescendant"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Retrieves a SecurityHealthAnalyticsCustomModule.
  rpc GetSecurityHealthAnalyticsCustomModule(
      GetSecurityHealthAnalyticsCustomModuleRequest)
      returns (SecurityHealthAnalyticsCustomModule) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/securityHealthAnalyticsCustomModules/*}"
      additional_bindings {
        get: "/v1/{name=folders/*/locations/*/securityHealthAnalyticsCustomModules/*}"
      }
      additional_bindings {
        get: "/v1/{name=organizations/*/locations/*/securityHealthAnalyticsCustomModules/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a resident SecurityHealthAnalyticsCustomModule at the scope of the
  // given CRM parent, and also creates inherited
  // SecurityHealthAnalyticsCustomModules for all CRM descendants of the given
  // parent. These modules are enabled by default.
  rpc CreateSecurityHealthAnalyticsCustomModule(
      CreateSecurityHealthAnalyticsCustomModuleRequest)
      returns (SecurityHealthAnalyticsCustomModule) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/securityHealthAnalyticsCustomModules"
      body: "security_health_analytics_custom_module"
      additional_bindings {
        post: "/v1/{parent=folders/*/locations/*}/securityHealthAnalyticsCustomModules"
        body: "security_health_analytics_custom_module"
      }
      additional_bindings {
        post: "/v1/{parent=organizations/*/locations/*}/securityHealthAnalyticsCustomModules"
        body: "security_health_analytics_custom_module"
      }
    };
    option (google.api.method_signature) =
        "parent,security_health_analytics_custom_module";
  }

  // Updates the SecurityHealthAnalyticsCustomModule under the given name based
  // on the given update mask. Updating the enablement state is supported on
  // both resident and inherited modules (though resident modules cannot have an
  // enablement state of "inherited"). Updating the display name and custom
  // config of a module is supported on resident modules only.
  rpc UpdateSecurityHealthAnalyticsCustomModule(
      UpdateSecurityHealthAnalyticsCustomModuleRequest)
      returns (SecurityHealthAnalyticsCustomModule) {
    option (google.api.http) = {
      patch: "/v1/{security_health_analytics_custom_module.name=projects/*/locations/*/securityHealthAnalyticsCustomModules/*}"
      body: "security_health_analytics_custom_module"
      additional_bindings {
        patch: "/v1/{security_health_analytics_custom_module.name=folders/*/locations/*/securityHealthAnalyticsCustomModules/*}"
        body: "security_health_analytics_custom_module"
      }
      additional_bindings {
        patch: "/v1/{security_health_analytics_custom_module.name=organizations/*/locations/*/securityHealthAnalyticsCustomModules/*}"
        body: "security_health_analytics_custom_module"
      }
    };
    option (google.api.method_signature) =
        "security_health_analytics_custom_module,update_mask";
  }

  // Deletes the specified SecurityHealthAnalyticsCustomModule and all of its
  // descendants in the CRM hierarchy. This method is only supported for
  // resident custom modules.
  rpc DeleteSecurityHealthAnalyticsCustomModule(
      DeleteSecurityHealthAnalyticsCustomModuleRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/securityHealthAnalyticsCustomModules/*}"
      additional_bindings {
        delete: "/v1/{name=folders/*/locations/*/securityHealthAnalyticsCustomModules/*}"
      }
      additional_bindings {
        delete: "/v1/{name=organizations/*/locations/*/securityHealthAnalyticsCustomModules/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Simulates a given SecurityHealthAnalyticsCustomModule and Resource.
  rpc SimulateSecurityHealthAnalyticsCustomModule(
      SimulateSecurityHealthAnalyticsCustomModuleRequest)
      returns (SimulateSecurityHealthAnalyticsCustomModuleResponse) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/securityHealthAnalyticsCustomModules:simulate"
      body: "*"
      additional_bindings {
        post: "/v1/{parent=folders/*/locations/*}/securityHealthAnalyticsCustomModules:simulate"
        body: "*"
      }
      additional_bindings {
        post: "/v1/{parent=organizations/*/locations/*}/securityHealthAnalyticsCustomModules:simulate"
        body: "*"
      }
    };
    option (google.api.method_signature) = "parent,custom_config,resource";
  }

  // Returns a list of all EffectiveEventThreatDetectionCustomModules for the
  // given parent. This includes resident modules defined at the scope of the
  // parent, and inherited modules, inherited from CRM ancestors (no
  // descendants). The difference between an EffectiveCustomModule and a
  // CustomModule is that the fields for an EffectiveCustomModule are computed
  // from ancestors if needed. For example, the enablement_state for a
  // CustomModule can be either ENABLED, DISABLED, or INHERITED. Where as the
  // enablement_state for an EffectiveCustomModule is always computed to ENABLED
  // or DISABLED (the effective enablement_state).
  rpc ListEffectiveEventThreatDetectionCustomModules(
      ListEffectiveEventThreatDetectionCustomModulesRequest)
      returns (ListEffectiveEventThreatDetectionCustomModulesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/effectiveEventThreatDetectionCustomModules"
      additional_bindings {
        get: "/v1/{parent=folders/*/locations/*}/effectiveEventThreatDetectionCustomModules"
      }
      additional_bindings {
        get: "/v1/{parent=organizations/*/locations/*}/effectiveEventThreatDetectionCustomModules"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets an effective ETD custom module. Retrieves the effective module at the
  // given level. The difference between an EffectiveCustomModule and a
  // CustomModule is that the fields for an EffectiveCustomModule are computed
  // from ancestors if needed. For example, the enablement_state for a
  // CustomModule can be either ENABLED, DISABLED, or INHERITED. Where as the
  // enablement_state for an EffectiveCustomModule is always computed to ENABLED
  // or DISABLED (the effective enablement_state).
  rpc GetEffectiveEventThreatDetectionCustomModule(
      GetEffectiveEventThreatDetectionCustomModuleRequest)
      returns (EffectiveEventThreatDetectionCustomModule) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/effectiveEventThreatDetectionCustomModules/*}"
      additional_bindings {
        get: "/v1/{name=folders/*/locations/*/effectiveEventThreatDetectionCustomModules/*}"
      }
      additional_bindings {
        get: "/v1/{name=organizations/*/locations/*/effectiveEventThreatDetectionCustomModules/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Returns a list of all EventThreatDetectionCustomModules for the given
  // parent. This includes resident modules defined at the scope of the parent,
  // and inherited modules, inherited from CRM ancestors (no descendants).
  rpc ListEventThreatDetectionCustomModules(
      ListEventThreatDetectionCustomModulesRequest)
      returns (ListEventThreatDetectionCustomModulesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/eventThreatDetectionCustomModules"
      additional_bindings {
        get: "/v1/{parent=folders/*/locations/*}/eventThreatDetectionCustomModules"
      }
      additional_bindings {
        get: "/v1/{parent=organizations/*/locations/*}/eventThreatDetectionCustomModules"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Returns a list of all resident EventThreatDetectionCustomModules under
  // the given CRM parent and all of the parent’s CRM descendants.
  rpc ListDescendantEventThreatDetectionCustomModules(
      ListDescendantEventThreatDetectionCustomModulesRequest)
      returns (ListDescendantEventThreatDetectionCustomModulesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/locations/*}/eventThreatDetectionCustomModules:listDescendant"
      additional_bindings {
        get: "/v1/{parent=folders/*/locations/*}/eventThreatDetectionCustomModules:listDescendant"
      }
      additional_bindings {
        get: "/v1/{parent=organizations/*/locations/*}/eventThreatDetectionCustomModules:listDescendant"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets an ETD custom module. Retrieves the module at the given level. The
  // difference between an EffectiveCustomModule and a CustomModule is that the
  // fields for an EffectiveCustomModule are computed from ancestors if needed.
  // For example, the enablement_state for a CustomModule can be either ENABLED,
  // DISABLED, or INHERITED. Where as the enablement_state for an
  // EffectiveCustomModule is always computed to ENABLED or DISABLED (the
  // effective enablement_state).
  rpc GetEventThreatDetectionCustomModule(
      GetEventThreatDetectionCustomModuleRequest)
      returns (EventThreatDetectionCustomModule) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/eventThreatDetectionCustomModules/*}"
      additional_bindings {
        get: "/v1/{name=folders/*/locations/*/eventThreatDetectionCustomModules/*}"
      }
      additional_bindings {
        get: "/v1/{name=organizations/*/locations/*/eventThreatDetectionCustomModules/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Creates an ETD custom module at the given level. Creating a module has a
  // side-effect of creating modules at all descendants.
  rpc CreateEventThreatDetectionCustomModule(
      CreateEventThreatDetectionCustomModuleRequest)
      returns (EventThreatDetectionCustomModule) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/eventThreatDetectionCustomModules"
      body: "event_threat_detection_custom_module"
      additional_bindings {
        post: "/v1/{parent=folders/*/locations/*}/eventThreatDetectionCustomModules"
        body: "event_threat_detection_custom_module"
      }
      additional_bindings {
        post: "/v1/{parent=organizations/*/locations/*}/eventThreatDetectionCustomModules"
        body: "event_threat_detection_custom_module"
      }
    };
    option (google.api.method_signature) =
        "parent,event_threat_detection_custom_module";
  }

  // Updates an ETD custom module at the given level. All config fields can be
  // updated when updating the module at resident level. Only enablement state
  // can be updated when updating the module at inherited levels. Updating the
  // module has a side-effect that it updates all descendants that are inherited
  // from this module.
  rpc UpdateEventThreatDetectionCustomModule(
      UpdateEventThreatDetectionCustomModuleRequest)
      returns (EventThreatDetectionCustomModule) {
    option (google.api.http) = {
      patch: "/v1/{event_threat_detection_custom_module.name=projects/*/locations/*/eventThreatDetectionCustomModules/*}"
      body: "event_threat_detection_custom_module"
      additional_bindings {
        patch: "/v1/{event_threat_detection_custom_module.name=folders/*/locations/*/eventThreatDetectionCustomModules/*}"
        body: "event_threat_detection_custom_module"
      }
      additional_bindings {
        patch: "/v1/{event_threat_detection_custom_module.name=organizations/*/locations/*/eventThreatDetectionCustomModules/*}"
        body: "event_threat_detection_custom_module"
      }
    };
    option (google.api.method_signature) =
        "event_threat_detection_custom_module,update_mask";
  }

  // Deletes an ETD custom module. Deletion at resident level also deletes
  // modules at all descendants. Deletion at any other level is not supported.
  rpc DeleteEventThreatDetectionCustomModule(
      DeleteEventThreatDetectionCustomModuleRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/locations/*/eventThreatDetectionCustomModules/*}"
      additional_bindings {
        delete: "/v1/{name=folders/*/locations/*/eventThreatDetectionCustomModules/*}"
      }
      additional_bindings {
        delete: "/v1/{name=organizations/*/locations/*/eventThreatDetectionCustomModules/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Validates the given Event Threat Detection custom module.
  rpc ValidateEventThreatDetectionCustomModule(
      ValidateEventThreatDetectionCustomModuleRequest)
      returns (ValidateEventThreatDetectionCustomModuleResponse) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/locations/*}/eventThreatDetectionCustomModules:validate"
      body: "*"
      additional_bindings {
        post: "/v1/{parent=folders/*/locations/*}/eventThreatDetectionCustomModules:validate"
        body: "*"
      }
      additional_bindings {
        post: "/v1/{parent=organizations/*/locations/*}/eventThreatDetectionCustomModules:validate"
        body: "*"
      }
    };
  }
}

// An EffectiveSecurityHealthAnalyticsCustomModule is the representation of
// a Security Health Analytics custom module at a specified level of the
// resource hierarchy: organization, folder, or project. If a custom module is
// inherited from a parent organization or folder, the value of the
// `enablementState` property in EffectiveSecurityHealthAnalyticsCustomModule is
// set to the value that is effective in the parent, instead of  `INHERITED`.
// For example, if the module is enabled in a parent organization or folder, the
// effective enablement_state for the module in all child folders or projects is
// also `enabled`. EffectiveSecurityHealthAnalyticsCustomModule is read-only.
message EffectiveSecurityHealthAnalyticsCustomModule {
  option (google.api.resource) = {
    type: "securitycentermanagement.googleapis.com/EffectiveSecurityHealthAnalyticsCustomModule"
    pattern: "organizations/{organization}/locations/{location}/effectiveSecurityHealthAnalyticsCustomModules/{effective_security_health_analytics_custom_module}"
    pattern: "projects/{project}/locations/{location}/effectiveSecurityHealthAnalyticsCustomModules/{effective_security_health_analytics_custom_module}"
    pattern: "folders/{folder}/locations/{location}/effectiveSecurityHealthAnalyticsCustomModules/{effective_security_health_analytics_custom_module}"
    plural: "effectiveSecurityHealthAnalyticsCustomModules"
    singular: "effectiveSecurityHealthAnalyticsCustomModule"
  };

  // The enablement state of the module.
  enum EnablementState {
    // Unspecified enablement state.
    ENABLEMENT_STATE_UNSPECIFIED = 0;

    // The module is enabled at the given level.
    ENABLED = 1;

    // The module is disabled at the given level.
    DISABLED = 2;
  }

  // Output only. The resource name of the custom module.
  // Its format is
  // "organizations/{organization}/locations/{location}/effectiveSecurityHealthAnalyticsCustomModules/{effective_security_health_analytics_custom_module}",
  // or
  // "folders/{folder}/locations/{location}/effectiveSecurityHealthAnalyticsCustomModules/{effective_security_health_analytics_custom_module}",
  // or
  // "projects/{project}/locations/{location}/effectiveSecurityHealthAnalyticsCustomModules/{effective_security_health_analytics_custom_module}"
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The user-specified configuration for the module.
  CustomConfig custom_config = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The effective state of enablement for the module at the given
  // level of the hierarchy.
  EnablementState enablement_state = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The display name for the custom module. The name must be
  // between 1 and 128 characters, start with a lowercase letter, and contain
  // alphanumeric characters or underscores only.
  string display_name = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Request message for listing effective Security Health Analytics custom
// modules.
message ListEffectiveSecurityHealthAnalyticsCustomModulesRequest {
  // Required. Name of parent to list effective custom modules. Its format is
  // "organizations/{organization}/locations/{location}",
  // "folders/{folder}/locations/{location}",
  // or
  // "projects/{project}/locations/{location}"
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "securitycentermanagement.googleapis.com/EffectiveSecurityHealthAnalyticsCustomModule"
    }
  ];

  // Optional. The maximum number of results to return in a single response.
  // Default is 10, minimum is 1, maximum is 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The value returned by the last call indicating a continuation
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for listing effective Security Health Analytics custom
// modules.
message ListEffectiveSecurityHealthAnalyticsCustomModulesResponse {
  // The list of EffectiveSecurityHealthAnalyticsCustomModule
  repeated EffectiveSecurityHealthAnalyticsCustomModule
      effective_security_health_analytics_custom_modules = 1;

  // A token identifying a page of results the server should return.
  string next_page_token = 2;
}

// Message for getting a EffectiveSecurityHealthAnalyticsCustomModule
message GetEffectiveSecurityHealthAnalyticsCustomModuleRequest {
  // Required. The resource name of the SHA custom module.
  //
  // Its format is:
  //
  //   * "organizations/{organization}/locations/{location}/effectiveSecurityHealthAnalyticsCustomModules/{module_id}".
  //   * "folders/{folder}/locations/{location}/effectiveSecurityHealthAnalyticsCustomModules/{module_id}".
  //   * "projects/{project}/locations/{location}/effectiveSecurityHealthAnalyticsCustomModules/{module_id}".
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "securitycentermanagement.googleapis.com/EffectiveSecurityHealthAnalyticsCustomModule"
    }
  ];
}

// Represents an instance of a Security Health Analytics custom module,
// including its full module name, display name, enablement state, and last
// updated time. You can create a custom module at the organization, folder, or
// project level. Custom modules that you create at the organization or folder
// level are inherited by the child folders and projects.
message SecurityHealthAnalyticsCustomModule {
  option (google.api.resource) = {
    type: "securitycentermanagement.googleapis.com/SecurityHealthAnalyticsCustomModule"
    pattern: "organizations/{organization}/locations/{location}/securityHealthAnalyticsCustomModules/{security_health_analytics_custom_module}"
    pattern: "projects/{project}/locations/{location}/securityHealthAnalyticsCustomModules/{security_health_analytics_custom_module}"
    pattern: "folders/{folder}/locations/{location}/securityHealthAnalyticsCustomModules/{security_health_analytics_custom_module}"
    plural: "securityHealthAnalyticsCustomModules"
    singular: "securityHealthAnalyticsCustomModule"
  };

  // Possible enablement states of a custom module.
  enum EnablementState {
    // Unspecified enablement state.
    ENABLEMENT_STATE_UNSPECIFIED = 0;

    // The module is enabled at the given CRM resource.
    ENABLED = 1;

    // The module is disabled at the given CRM resource.
    DISABLED = 2;

    // State is inherited from an ancestor module. The module will either
    // be effectively ENABLED or DISABLED based on its closest non-inherited
    // ancestor module in the CRM hierarchy. Attempting to set a top level
    // module (module with no parent) to the INHERITED state will result in an
    // INVALID_ARGUMENT error.
    INHERITED = 3;
  }

  // Immutable. The resource name of the custom module.
  // Its format is
  // "organizations/{organization}/locations/{location}/securityHealthAnalyticsCustomModules/{security_health_analytics_custom_module}",
  // or
  // "folders/{folder}/locations/{location}/securityHealthAnalyticsCustomModules/{security_health_analytics_custom_module}",
  // or
  // "projects/{project}/locations/{location}/securityHealthAnalyticsCustomModules/{security_health_analytics_custom_module}"
  //
  // The id {customModule} is server-generated and is not user settable.
  // It will be a numeric id containing 1-20 digits.
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Optional. The display name of the Security Health Analytics custom module.
  // This display name becomes the finding category for all findings that are
  // returned by this custom module. The display name must be between 1 and
  // 128 characters, start with a lowercase letter, and contain alphanumeric
  // characters or underscores only.
  string display_name = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The enablement state of the custom module.
  EnablementState enablement_state = 3 [(google.api.field_behavior) = OPTIONAL];

  // Output only. The time at which the custom module was last updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The editor that last updated the custom module.
  string last_editor = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Specifies the organization or folder from which the custom
  // module is inherited. If empty, indicates that the custom module was created
  // in the organization, folder, or project in which you are viewing the custom
  // module.
  string ancestor_module = 6 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = {
      type: "securitycentermanagement.googleapis.com/SecurityHealthAnalyticsCustomModule"
    }
  ];

  // Optional. The user specified custom configuration for the module.
  CustomConfig custom_config = 7 [(google.api.field_behavior) = OPTIONAL];
}

// Defines the properties in a custom module configuration for Security
// Health Analytics. Use the custom module configuration to create custom
// detectors that generate custom findings for resources that you specify.
message CustomConfig {
  // A set of optional name-value pairs that define custom source properties to
  // return with each finding that is generated by the custom module. The custom
  // source properties that are defined here are included in the finding JSON
  // under `sourceProperties`.
  message CustomOutputSpec {
    // An individual name-value pair that defines a custom source property.
    message Property {
      // Optional. Name of the property for the custom output.
      string name = 1 [(google.api.field_behavior) = OPTIONAL];

      // Optional. The CEL expression for the custom output. A resource property
      // can be specified to return the value of the property or a text string
      // enclosed in quotation marks.
      google.type.Expr value_expression = 2
          [(google.api.field_behavior) = OPTIONAL];
    }

    // Optional. A list of custom output properties to add to the finding.
    repeated Property properties = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  // Resource for selecting resource type.
  message ResourceSelector {
    // Optional. The resource types to run the detector on.
    repeated string resource_types = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  // Defines the valid value options for the severity of a finding.
  enum Severity {
    // Unspecified severity.
    SEVERITY_UNSPECIFIED = 0;

    // Critical severity.
    CRITICAL = 1;

    // High severity.
    HIGH = 2;

    // Medium severity.
    MEDIUM = 3;

    // Low severity.
    LOW = 4;
  }

  // Optional. The CEL expression to evaluate to produce findings. When the
  // expression evaluates to true against a resource, a finding is generated.
  google.type.Expr predicate = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Custom output properties.
  CustomOutputSpec custom_output = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The CAI resource types that the custom module operates on (see
  // go/gcp-cai-doc/supported-asset-types). Each custom module can specify up to
  // 5 resource types.
  ResourceSelector resource_selector = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The severity to assign to findings generated by the module.
  Severity severity = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Text that describes the vulnerability or misconfiguration that
  // the custom module detects. This explanation is returned with each finding
  // instance to help investigators understand the detected issue. The text must
  // be enclosed in quotation marks.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. An explanation of the recommended steps that security teams can
  // take to resolve the detected issue. This explanation is returned with each
  // finding generated by this module in the `nextSteps` property of the finding
  // JSON.
  string recommendation = 6 [(google.api.field_behavior) = OPTIONAL];
}

// Request message for listing Security Health Analytics custom modules.
message ListSecurityHealthAnalyticsCustomModulesRequest {
  // Required. Name of parent to list custom modules. Its format is
  // "organizations/{organization}/locations/{location}",
  // "folders/{folder}/locations/{location}",
  // or
  // "projects/{project}/locations/{location}"
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "securitycentermanagement.googleapis.com/SecurityHealthAnalyticsCustomModule"
    }
  ];

  // Optional. The maximum number of results to return in a single response.
  // Default is 10, minimum is 1, maximum is 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A token identifying a page of results the server should return.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for listing Security Health Analytics custom modules.
message ListSecurityHealthAnalyticsCustomModulesResponse {
  // The list of SecurityHealthAnalyticsCustomModules
  repeated SecurityHealthAnalyticsCustomModule
      security_health_analytics_custom_modules = 1;

  // A token identifying a page of results the server should return.
  string next_page_token = 2;
}

// Request message for listing descendant Security Health Analytics custom
// modules.
message ListDescendantSecurityHealthAnalyticsCustomModulesRequest {
  // Required. Name of parent to list custom modules. Its format is
  // "organizations/{organization}/locations/{location}",
  // "folders/{folder}/locations/{location}",
  // or
  // "projects/{project}/locations/{location}"
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "securitycentermanagement.googleapis.com/SecurityHealthAnalyticsCustomModule"
    }
  ];

  // Optional. The maximum number of results to return in a single response.
  // Default is 10, minimum is 1, maximum is 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A token identifying a page of results the server should return.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for listing descendant Security Health Analytics custom
// modules.
message ListDescendantSecurityHealthAnalyticsCustomModulesResponse {
  // The list of SecurityHealthAnalyticsCustomModules
  repeated SecurityHealthAnalyticsCustomModule
      security_health_analytics_custom_modules = 1;

  // A token identifying a page of results the server should return.
  string next_page_token = 2;
}

// Message for getting a SecurityHealthAnalyticsCustomModule
message GetSecurityHealthAnalyticsCustomModuleRequest {
  // Required. Name of the resource
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "securitycentermanagement.googleapis.com/SecurityHealthAnalyticsCustomModule"
    }
  ];
}

// Message for creating a SecurityHealthAnalyticsCustomModule
message CreateSecurityHealthAnalyticsCustomModuleRequest {
  // Required. Name of the parent for the module. Its format is
  // "organizations/{organization}/locations/{location}",
  // "folders/{folder}/locations/{location}",
  // or
  // "projects/{project}/locations/{location}"
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "securitycentermanagement.googleapis.com/SecurityHealthAnalyticsCustomModule"
    }
  ];

  // Required. The resource being created
  SecurityHealthAnalyticsCustomModule security_health_analytics_custom_module =
      2 [(google.api.field_behavior) = REQUIRED];

  // Optional. When set to true, only validations (including IAM checks) will
  // done for the request (no module will be created). An OK response indicates
  // the request is valid while an error response indicates the request is
  // invalid. Note that a subsequent request to actually create the module could
  // still fail because:
  //  1. the state could have changed (e.g. IAM permission lost) or
  //  2. A failure occurred during creation of the module.
  // Defaults to false.
  bool validate_only = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Message for updating a SecurityHealthAnalyticsCustomModule
message UpdateSecurityHealthAnalyticsCustomModuleRequest {
  // Required. Field mask is used to specify the fields to be overwritten in the
  // SecurityHealthAnalyticsCustomModule resource by the update.
  // The fields specified in the update_mask are relative to the resource, not
  // the full request. A field will be overwritten if it is in the mask. If the
  // user does not provide a mask then all fields will be overwritten.
  google.protobuf.FieldMask update_mask = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The resource being updated
  SecurityHealthAnalyticsCustomModule security_health_analytics_custom_module =
      2 [(google.api.field_behavior) = REQUIRED];

  // Optional. When set to true, only validations (including IAM checks) will
  // done for the request (module will not be updated). An OK response indicates
  // the request is valid while an error response indicates the request is
  // invalid. Note that a subsequent request to actually update the module could
  // still fail because 1. the state could have changed (e.g. IAM permission
  // lost) or
  // 2. A failure occurred while trying to update the module.
  bool validate_only = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Message for deleting a SecurityHealthAnalyticsCustomModule
message DeleteSecurityHealthAnalyticsCustomModuleRequest {
  // Required. The resource name of the SHA custom module.
  //
  // Its format is:
  //
  //   * "organizations/{organization}/locations/{location}/securityHealthAnalyticsCustomModules/{security_health_analytics_custom_module}".
  //   * "folders/{folder}/locations/{location}/securityHealthAnalyticsCustomModules/{security_health_analytics_custom_module}".
  //   * "projects/{project}/locations/{location}/securityHealthAnalyticsCustomModules/{security_health_analytics_custom_module}".
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "securitycentermanagement.googleapis.com/SecurityHealthAnalyticsCustomModule"
    }
  ];

  // Optional. When set to true, only validations (including IAM checks) will
  // done for the request (module will not be deleted). An OK response indicates
  // the request is valid while an error response indicates the request is
  // invalid. Note that a subsequent request to actually delete the module could
  // still fail because 1. the state could have changed (e.g. IAM permission
  // lost) or
  // 2. A failure occurred while trying to delete the module.
  bool validate_only = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request message to simulate a CustomConfig against a given test resource.
// Maximum size of the request is 4 MB by default.
message SimulateSecurityHealthAnalyticsCustomModuleRequest {
  // Manually constructed resource name. If the custom module evaluates against
  // only the resource data, you can omit the `iam_policy_data` field. If it
  // evaluates only the `iam_policy_data` field, you can omit the resource data.
  message SimulatedResource {
    // Required. The type of the resource, for example,
    // `compute.googleapis.com/Disk`.
    string resource_type = 1 [(google.api.field_behavior) = REQUIRED];

    // Optional. A representation of the Google Cloud resource. Should match the
    // Google Cloud resource JSON format.
    google.protobuf.Struct resource_data = 2
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. A representation of the IAM policy.
    google.iam.v1.Policy iam_policy_data = 3
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. The relative resource name of the organization, project, or
  // folder. For more information about relative resource names, see [Relative
  // Resource
  // Name](https://cloud.google.com/apis/design/resource_names#relative_resource_name)
  // Example: `organizations/{organization_id}`.
  string parent = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The custom configuration that you need to test.
  CustomConfig custom_config = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Resource data to simulate custom module against.
  SimulatedResource resource = 3 [(google.api.field_behavior) = REQUIRED];
}

// A subset of the fields of the Security Center Finding proto. The minimum set
// of fields needed to represent a simulated finding from a SHA custom module.
message SimulatedFinding {
  option (google.api.resource) = {
    type: "securitycenter.googleapis.com/Finding"
    pattern: "organizations/{organization}/sources/{source}/findings/{finding}"
    pattern: "folders/{folder}/sources/{source}/findings/{finding}"
    pattern: "projects/{project}/sources/{source}/findings/{finding}"
    plural: "findings"
    singular: "finding"
  };

  // The state of the finding.
  enum State {
    // Unspecified state.
    STATE_UNSPECIFIED = 0;

    // The finding requires attention and has not been addressed yet.
    ACTIVE = 1;

    // The finding has been fixed, triaged as a non-issue or otherwise addressed
    // and is no longer active.
    INACTIVE = 2;
  }

  // The severity of the finding.
  enum Severity {
    // This value is used for findings when a source doesn't write a severity
    // value.
    SEVERITY_UNSPECIFIED = 0;

    // Vulnerability:
    // A critical vulnerability is easily discoverable by an external actor,
    // exploitable, and results in the direct ability to execute arbitrary code,
    // exfiltrate data, and otherwise gain additional access and privileges to
    // cloud resources and workloads. Examples include publicly accessible
    // unprotected user data and public SSH access with weak or no
    // passwords.
    //
    // Threat:
    // Indicates a threat that is able to access, modify, or delete data or
    // execute unauthorized code within existing resources.
    CRITICAL = 1;

    // Vulnerability:
    // A high risk vulnerability can be easily discovered and exploited in
    // combination with other vulnerabilities in order to gain direct access and
    // the ability to execute arbitrary code, exfiltrate data, and otherwise
    // gain additional access and privileges to cloud resources and workloads.
    // An example is a database with weak or no passwords that is only
    // accessible internally. This database could easily be compromised by an
    // actor that had access to the internal network.
    //
    // Threat:
    // Indicates a threat that is able to create new computational resources in
    // an environment but not able to access data or execute code in existing
    // resources.
    HIGH = 2;

    // Vulnerability:
    // A medium risk vulnerability could be used by an actor to gain access to
    // resources or privileges that enable them to eventually (through multiple
    // steps or a complex exploit) gain access and the ability to execute
    // arbitrary code or exfiltrate data. An example is a service account with
    // access to more projects than it should have. If an actor gains access to
    // the service account, they could potentially use that access to manipulate
    // a project the service account was not intended to.
    //
    // Threat:
    // Indicates a threat that is able to cause operational impact but may not
    // access data or execute unauthorized code.
    MEDIUM = 3;

    // Vulnerability:
    // A low risk vulnerability hampers a security organization's ability to
    // detect vulnerabilities or active threats in their deployment, or prevents
    // the root cause investigation of security issues. An example is monitoring
    // and logs being disabled for resource configurations and access.
    //
    // Threat:
    // Indicates a threat that has obtained minimal access to an environment but
    // is not able to access data, execute code, or create resources.
    LOW = 4;
  }

  // Represents what kind of Finding it is.
  enum FindingClass {
    // Unspecified finding class.
    FINDING_CLASS_UNSPECIFIED = 0;

    // Describes unwanted or malicious activity.
    THREAT = 1;

    // Describes a potential weakness in software that increases risk to
    // Confidentiality & Integrity & Availability.
    VULNERABILITY = 2;

    // Describes a potential weakness in cloud resource/asset configuration that
    // increases risk.
    MISCONFIGURATION = 3;

    // Describes a security observation that is for informational purposes.
    OBSERVATION = 4;

    // Describes an error that prevents some SCC functionality.
    SCC_ERROR = 5;

    // Describes a potential security risk due to a change in the security
    // posture.
    POSTURE_VIOLATION = 6;
  }

  // Identifier. The [relative resource
  // name](https://cloud.google.com/apis/design/resource_names#relative_resource_name)
  // of the finding. Example:
  // "organizations/{organization_id}/sources/{source_id}/findings/{finding_id}",
  // "folders/{folder_id}/sources/{source_id}/findings/{finding_id}",
  // "projects/{project_id}/sources/{source_id}/findings/{finding_id}".
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // The relative resource name of the source the finding belongs to. See:
  // https://cloud.google.com/apis/design/resource_names#relative_resource_name
  // This field is immutable after creation time.
  // For example:
  // "organizations/{organization_id}/sources/{source_id}"
  string parent = 2;

  // For findings on Google Cloud resources, the full resource
  // name of the Google Cloud resource this finding is for. See:
  // https://cloud.google.com/apis/design/resource_names#full_resource_name
  // When the finding is for a non-Google Cloud resource, the resourceName can
  // be a customer or partner defined string. This field is immutable after
  // creation time.
  string resource_name = 3;

  // The additional taxonomy group within findings from a given source.
  // This field is immutable after creation time.
  // Example: "XSS_FLASH_INJECTION"
  string category = 4;

  // Output only. The state of the finding.
  State state = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Source specific properties. These properties are managed by the source
  // that writes the finding. The key names in the source_properties map must be
  // between 1 and 255 characters, and must start with a letter and contain
  // alphanumeric characters or underscores only.
  map<string, google.protobuf.Value> source_properties = 6;

  // The time the finding was first detected. If an existing finding is updated,
  // then this is the time the update occurred.
  // For example, if the finding represents an open firewall, this property
  // captures the time the detector believes the firewall became open. The
  // accuracy is determined by the detector. If the finding is later resolved,
  // then this time reflects when the finding was resolved. This must not
  // be set to a value greater than the current timestamp.
  google.protobuf.Timestamp event_time = 7;

  // The severity of the finding. This field is managed by the source that
  // writes the finding.
  Severity severity = 8;

  // The class of the finding.
  FindingClass finding_class = 9;
}

// Response message for simulating a `SecurityHealthAnalyticsCustomModule`
// against a given resource.
message SimulateSecurityHealthAnalyticsCustomModuleResponse {
  // Possible test result.
  message SimulatedResult {
    oneof result {
      // Finding that would be published for the test case,
      // if a violation is detected.
      SimulatedFinding finding = 1;

      // Indicates that the test case does not trigger any violation.
      google.protobuf.Empty no_violation = 2;

      // Error encountered during the test.
      google.rpc.Status error = 3;
    }
  }

  // Result for test case in the corresponding request.
  SimulatedResult result = 1;
}

// An EffectiveEventThreatDetectionCustomModule is the representation of
// EventThreatDetectionCustomModule at a given level taking hierarchy into
// account and resolving various fields accordingly. e.g. if the module is
// enabled at the ancestor level, effective modules at all descendant levels
// will have enablement_state set to ENABLED. Similarly, if module.inherited is
// set, then effective module's config will contain the ancestor's config
// details. EffectiveEventThreatDetectionCustomModule is read-only.
message EffectiveEventThreatDetectionCustomModule {
  option (google.api.resource) = {
    type: "securitycentermanagement.googleapis.com/EffectiveEventThreatDetectionCustomModule"
    pattern: "organizations/{organization}/locations/{location}/effectiveEventThreatDetectionCustomModules/{effective_event_threat_detection_custom_module}"
    pattern: "projects/{project}/locations/{location}/effectiveEventThreatDetectionCustomModules/{effective_event_threat_detection_custom_module}"
    pattern: "folders/{folder}/locations/{location}/effectiveEventThreatDetectionCustomModules/{effective_event_threat_detection_custom_module}"
    plural: "effectiveEventThreatDetectionCustomModules"
    singular: "effectiveEventThreatDetectionCustomModule"
  };

  // The enablement state of the module.
  enum EnablementState {
    // Unspecified enablement state.
    ENABLEMENT_STATE_UNSPECIFIED = 0;

    // The module is enabled at the given level.
    ENABLED = 1;

    // The module is disabled at the given level.
    DISABLED = 2;
  }

  // Immutable. The resource name of the ETD custom module.
  //
  // Its format is:
  //
  //   * "organizations/{organization}/locations/{location}/effectiveEventThreatDetectionCustomModules/{effective_event_threat_detection_custom_module}".
  //   * "folders/{folder}/locations/{location}/effectiveEventThreatDetectionCustomModules/{effective_event_threat_detection_custom_module}".
  //   * "projects/{project}/locations/{location}/effectiveEventThreatDetectionCustomModules/{effective_event_threat_detection_custom_module}".
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. Config for the effective module.
  google.protobuf.Struct config = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The effective state of enablement for the module at the given
  // level of the hierarchy.
  EnablementState enablement_state = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Type for the module. e.g. CONFIGURABLE_BAD_IP.
  string type = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The human readable name to be displayed for the module.
  string display_name = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The description for the module.
  string description = 6 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Request message for listing effective Event Threat Detection custom
// modules.
message ListEffectiveEventThreatDetectionCustomModulesRequest {
  // Required. Name of parent to list effective custom modules. Its format is
  // "organizations/{organization}/locations/{location}",
  // "folders/{folder}/locations/{location}",
  // or
  // "projects/{project}/locations/{location}"
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "securitycentermanagement.googleapis.com/EffectiveEventThreatDetectionCustomModule"
    }
  ];

  // Optional. The maximum number of results to return in a single response.
  // Default is 10, minimum is 1, maximum is 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The value returned by the last call indicating a continuation
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for listing effective Event Threat Detection custom
// modules.
message ListEffectiveEventThreatDetectionCustomModulesResponse {
  // The list of EffectiveEventThreatDetectionCustomModules
  repeated EffectiveEventThreatDetectionCustomModule
      effective_event_threat_detection_custom_modules = 1;

  // A token identifying a page of results the server should return.
  string next_page_token = 2;
}

// Message for getting a EffectiveEventThreatDetectionCustomModule
message GetEffectiveEventThreatDetectionCustomModuleRequest {
  // Required. The resource name of the ETD custom module.
  //
  // Its format is:
  //
  //   * "organizations/{organization}/locations/{location}/effectiveEventThreatDetectionCustomModules/{effective_event_threat_detection_custom_module}".
  //   * "folders/{folder}/locations/{location}/effectiveEventThreatDetectionCustomModules/{effective_event_threat_detection_custom_module}".
  //   * "projects/{project}/locations/{location}/effectiveEventThreatDetectionCustomModules/{effective_event_threat_detection_custom_module}".
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "securitycentermanagement.googleapis.com/EffectiveEventThreatDetectionCustomModule"
    }
  ];
}

// An event threat detection custom module is a Cloud SCC resource that contains
// the configuration and enablement state of a custom module, which enables ETD
// to write certain findings to Cloud SCC.
message EventThreatDetectionCustomModule {
  option (google.api.resource) = {
    type: "securitycentermanagement.googleapis.com/EventThreatDetectionCustomModule"
    pattern: "organizations/{organization}/locations/{location}/eventThreatDetectionCustomModules/{event_threat_detection_custom_module}"
    pattern: "projects/{project}/locations/{location}/eventThreatDetectionCustomModules/{event_threat_detection_custom_module}"
    pattern: "folders/{folder}/locations/{location}/eventThreatDetectionCustomModules/{event_threat_detection_custom_module}"
    plural: "eventThreatDetectionCustomModules"
    singular: "eventThreatDetectionCustomModule"
  };

  // The enablement state of the module.
  enum EnablementState {
    // Unspecified enablement state.
    ENABLEMENT_STATE_UNSPECIFIED = 0;

    // The module is enabled at the given level.
    ENABLED = 1;

    // The module is disabled at the given level.
    DISABLED = 2;

    // State is inherited from an ancestor module. The module will either
    // be effectively ENABLED or DISABLED based on its closest non-inherited
    // ancestor module in the CRM hierarchy. Attempting to set a top level
    // module (module with no parent) to the INHERITED state will result in an
    // error.
    INHERITED = 3;
  }

  // Immutable. The resource name of the ETD custom module.
  //
  // Its format is:
  //
  //   * "organizations/{organization}/locations/{location}/eventThreatDetectionCustomModules/{event_threat_detection_custom_module}".
  //   * "folders/{folder}/locations/{location}/eventThreatDetectionCustomModules/{event_threat_detection_custom_module}".
  //   * "projects/{project}/locations/{location}/eventThreatDetectionCustomModules/{event_threat_detection_custom_module}".
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Optional. Config for the module. For the resident module, its config value
  // is defined at this level. For the inherited module, its config value is
  // inherited from the ancestor module.
  google.protobuf.Struct config = 2 [(google.api.field_behavior) = OPTIONAL];

  // Output only. The closest ancestor module that this module inherits the
  // enablement state from. If empty, indicates that the custom module was
  // created in the requesting parent organization, folder, or project. The
  // format is the same as the EventThreatDetectionCustomModule resource name.
  string ancestor_module = 3 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.resource_reference) = {
      type: "securitycentermanagement.googleapis.com/EventThreatDetectionCustomModule"
    }
  ];

  // Optional. The state of enablement for the module at the given level of the
  // hierarchy.
  EnablementState enablement_state = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Type for the module. e.g. CONFIGURABLE_BAD_IP.
  string type = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The human readable name to be displayed for the module.
  string display_name = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The description for the module.
  string description = 7 [(google.api.field_behavior) = OPTIONAL];

  // Output only. The time the module was last updated.
  google.protobuf.Timestamp update_time = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The editor the module was last updated by.
  string last_editor = 9 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Request message for listing Event Threat Detection custom modules.
message ListEventThreatDetectionCustomModulesRequest {
  // Required. Name of parent to list custom modules. Its format is
  // "organizations/{organization}/locations/{location}",
  // "folders/{folder}/locations/{location}",
  // or
  // "projects/{project}/locations/{location}"
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "securitycentermanagement.googleapis.com/EventThreatDetectionCustomModule"
    }
  ];

  // Optional. The maximum number of modules to return. The service may return
  // fewer than this value. If unspecified, at most 10 configs will be returned.
  // The maximum value is 1000; values above 1000 will be coerced to 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous
  // `ListEventThreatDetectionCustomModules` call. Provide this to retrieve the
  // subsequent page.
  //
  // When paginating, all other parameters provided to
  // `ListEventThreatDetectionCustomModules` must match the call that provided
  // the page token.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for listing Event Threat Detection custom modules.
message ListEventThreatDetectionCustomModulesResponse {
  // The list of EventThreatDetectionCustomModules
  repeated EventThreatDetectionCustomModule
      event_threat_detection_custom_modules = 1;

  // A token identifying a page of results the server should return.
  string next_page_token = 2;
}

// Request message for listing descendant Event Threat Detection custom
// modules.
message ListDescendantEventThreatDetectionCustomModulesRequest {
  // Required. Name of parent to list custom modules. Its format is
  // "organizations/{organization}/locations/{location}",
  // "folders/{folder}/locations/{location}",
  // or
  // "projects/{project}/locations/{location}"
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "securitycentermanagement.googleapis.com/EventThreatDetectionCustomModule"
    }
  ];

  // Optional. The maximum number of modules to return. The service may return
  // fewer than this value. If unspecified, at most 10 configs will be returned.
  // The maximum value is 1000; values above 1000 will be coerced to 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A token identifying a page of results the server should return.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for listing descendant Event Threat Detection custom
// modules.
message ListDescendantEventThreatDetectionCustomModulesResponse {
  // The list of EventThreatDetectionCustomModules
  repeated EventThreatDetectionCustomModule
      event_threat_detection_custom_modules = 1;

  // A token identifying a page of results the server should return.
  string next_page_token = 2;
}

// Message for getting a EventThreatDetectionCustomModule
message GetEventThreatDetectionCustomModuleRequest {
  // Required. The resource name of the ETD custom module.
  //
  // Its format is:
  //
  //   * "organizations/{organization}/locations/{location}/eventThreatDetectionCustomModules/{event_threat_detection_custom_module}".
  //   * "folders/{folder}/locations/{location}/eventThreatDetectionCustomModules/{event_threat_detection_custom_module}".
  //   * "projects/{project}/locations/{location}/eventThreatDetectionCustomModules/{event_threat_detection_custom_module}".
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "securitycentermanagement.googleapis.com/EventThreatDetectionCustomModule"
    }
  ];
}

// Message for creating a EventThreatDetectionCustomModule
message CreateEventThreatDetectionCustomModuleRequest {
  // Required. Name of parent for the module. Its format is
  // "organizations/{organization}/locations/{location}",
  // "folders/{folder}/locations/{location}",
  // or
  // "projects/{project}/locations/{location}"
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "securitycentermanagement.googleapis.com/EventThreatDetectionCustomModule"
    }
  ];

  // Required. The module to create. The
  // event_threat_detection_custom_module.name will be ignored and server
  // generated.
  EventThreatDetectionCustomModule event_threat_detection_custom_module = 3
      [(google.api.field_behavior) = REQUIRED];

  // Optional. When set to true, only validations (including IAM checks) will
  // done for the request (no module will be created). An OK response indicates
  // the request is valid while an error response indicates the request is
  // invalid. Note that a subsequent request to actually create the module could
  // still fail because 1. the state could have changed (e.g. IAM permission
  // lost) or
  // 2. A failure occurred during creation of the module.
  bool validate_only = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Message for updating a EventThreatDetectionCustomModule
message UpdateEventThreatDetectionCustomModuleRequest {
  // Required. Field mask is used to specify the fields to be overwritten in the
  // EventThreatDetectionCustomModule resource by the update.
  // The fields specified in the update_mask are relative to the resource, not
  // the full request. A field will be overwritten if it is in the mask. If the
  // user does not provide a mask then all fields will be overwritten.
  google.protobuf.FieldMask update_mask = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The module being updated
  EventThreatDetectionCustomModule event_threat_detection_custom_module = 2
      [(google.api.field_behavior) = REQUIRED];

  // Optional. When set to true, only validations (including IAM checks) will
  // done for the request (module will not be updated). An OK response indicates
  // the request is valid while an error response indicates the request is
  // invalid. Note that a subsequent request to actually update the module could
  // still fail because 1. the state could have changed (e.g. IAM permission
  // lost) or
  // 2. A failure occurred while trying to update the module.
  bool validate_only = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Message for deleting a EventThreatDetectionCustomModule
message DeleteEventThreatDetectionCustomModuleRequest {
  // Required. The resource name of the ETD custom module.
  //
  // Its format is:
  //
  //   * "organizations/{organization}/locations/{location}/eventThreatDetectionCustomModules/{event_threat_detection_custom_module}".
  //   * "folders/{folder}/locations/{location}/eventThreatDetectionCustomModules/{event_threat_detection_custom_module}".
  //   * "projects/{project}/locations/{location}/eventThreatDetectionCustomModules/{event_threat_detection_custom_module}".
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "securitycentermanagement.googleapis.com/EventThreatDetectionCustomModule"
    }
  ];

  // Optional. When set to true, only validations (including IAM checks) will
  // done for the request (module will not be deleted). An OK response indicates
  // the request is valid while an error response indicates the request is
  // invalid. Note that a subsequent request to actually delete the module could
  // still fail because 1. the state could have changed (e.g. IAM permission
  // lost) or
  // 2. A failure occurred while trying to delete the module.
  bool validate_only = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Request to validate an Event Threat Detection custom module.
message ValidateEventThreatDetectionCustomModuleRequest {
  // Required. Resource name of the parent to validate the Custom Module under.
  //
  // Its format is:
  //
  //   * "organizations/{organization}/locations/{location}".
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "securitycentermanagement.googleapis.com/EventThreatDetectionCustomModule"
    }
  ];

  // Required. The raw text of the module's contents. Used to generate error
  // messages.
  string raw_text = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The type of the module (e.g. CONFIGURABLE_BAD_IP).
  string type = 3 [(google.api.field_behavior) = REQUIRED];
}

// Response to validating an Event Threat Detection custom module.
message ValidateEventThreatDetectionCustomModuleResponse {
  // An error encountered while validating the uploaded configuration of an
  // Event Threat Detection Custom Module.
  message CustomModuleValidationError {
    // A description of the error, suitable for human consumption. Required.
    string description = 1;

    // The path, in RFC 8901 JSON Pointer format, to the field that failed
    // validation. This may be left empty if no specific field is affected.
    string field_path = 2;

    // The initial position of the error in the uploaded text version of the
    // module. This field may be omitted if no specific position applies, or if
    // one could not be computed.
    optional Position start = 3;

    // The end position of the error in the uploaded text version of the
    // module. This field may be omitted if no specific position applies, or if
    // one could not be computed..
    optional Position end = 4;
  }

  // A position in the uploaded text version of a module.
  message Position {
    // The line position in the text
    int32 line_number = 1;

    // The column position in the line
    int32 column_number = 2;
  }

  // A list of errors returned by the validator. If the list is empty, there
  // were no errors.
  repeated CustomModuleValidationError errors = 2;
}
