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

syntax = "proto3";

package google.cloud.asset.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/asset/v1/assets.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
import "google/type/expr.proto";

option csharp_namespace = "Google.Cloud.Asset.V1";
option go_package = "google.golang.org/genproto/googleapis/cloud/asset/v1;asset";
option java_multiple_files = true;
option java_outer_classname = "AssetServiceProto";
option java_package = "com.google.cloud.asset.v1";
option php_namespace = "Google\\Cloud\\Asset\\V1";

// Asset service definition.
service AssetService {
  option (google.api.default_host) = "cloudasset.googleapis.com";
  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform";

  // Exports assets with time and resource types to a given Cloud Storage
  // location/BigQuery table. For Cloud Storage location destinations, the
  // output format is newline-delimited JSON. Each line represents a
  // [google.cloud.asset.v1.Asset][google.cloud.asset.v1.Asset] in the JSON format; for BigQuery table
  // destinations, the output table stores the fields in asset proto as columns.
  // This API implements the [google.longrunning.Operation][google.longrunning.Operation] API
  // , which allows you to keep track of the export. We recommend intervals of
  // at least 2 seconds with exponential retry to poll the export operation
  // result. For regular-size resource parent, the export operation usually
  // finishes within 5 minutes.
  rpc ExportAssets(ExportAssetsRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=*/*}:exportAssets"
      body: "*"
    };
    option (google.longrunning.operation_info) = {
      response_type: "google.cloud.asset.v1.ExportAssetsResponse"
      metadata_type: "google.cloud.asset.v1.ExportAssetsRequest"
    };
  }

  // Batch gets the update history of assets that overlap a time window.
  // For IAM_POLICY content, this API outputs history when the asset and its
  // attached IAM POLICY both exist. This can create gaps in the output history.
  // Otherwise, this API outputs history with asset in both non-delete or
  // deleted status.
  // If a specified asset does not exist, this API returns an INVALID_ARGUMENT
  // error.
  rpc BatchGetAssetsHistory(BatchGetAssetsHistoryRequest) returns (BatchGetAssetsHistoryResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=*/*}:batchGetAssetsHistory"
    };
  }

  // Creates a feed in a parent project/folder/organization to listen to its
  // asset updates.
  rpc CreateFeed(CreateFeedRequest) returns (Feed) {
    option (google.api.http) = {
      post: "/v1/{parent=*/*}/feeds"
      body: "*"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets details about an asset feed.
  rpc GetFeed(GetFeedRequest) returns (Feed) {
    option (google.api.http) = {
      get: "/v1/{name=*/*/feeds/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists all asset feeds in a parent project/folder/organization.
  rpc ListFeeds(ListFeedsRequest) returns (ListFeedsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=*/*}/feeds"
    };
    option (google.api.method_signature) = "parent";
  }

  // Updates an asset feed configuration.
  rpc UpdateFeed(UpdateFeedRequest) returns (Feed) {
    option (google.api.http) = {
      patch: "/v1/{feed.name=*/*/feeds/*}"
      body: "*"
    };
    option (google.api.method_signature) = "feed";
  }

  // Deletes an asset feed.
  rpc DeleteFeed(DeleteFeedRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=*/*/feeds/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Searches all Cloud resources within the specified scope, such as a project,
  // folder, or organization. The caller must be granted the
  // `cloudasset.assets.searchAllResources` permission on the desired scope,
  // otherwise the request will be rejected.
  rpc SearchAllResources(SearchAllResourcesRequest) returns (SearchAllResourcesResponse) {
    option (google.api.http) = {
      get: "/v1/{scope=*/*}:searchAllResources"
    };
    option (google.api.method_signature) = "scope,query,asset_types";
  }

  // Searches all IAM policies within the specified scope, such as a project,
  // folder, or organization. The caller must be granted the
  // `cloudasset.assets.searchAllIamPolicies` permission on the desired scope,
  // otherwise the request will be rejected.
  rpc SearchAllIamPolicies(SearchAllIamPoliciesRequest) returns (SearchAllIamPoliciesResponse) {
    option (google.api.http) = {
      get: "/v1/{scope=*/*}:searchAllIamPolicies"
    };
    option (google.api.method_signature) = "scope,query";
  }

  // Analyzes IAM policies to answer which identities have what accesses on
  // which resources.
  rpc AnalyzeIamPolicy(AnalyzeIamPolicyRequest)
      returns (AnalyzeIamPolicyResponse) {
    option (google.api.http) = {
      get: "/v1/{analysis_query.scope=*/*}:analyzeIamPolicy"
    };
  }

  // Exports the answers of which identities have what accesses on which
  // resources to a Google Cloud Storage or a BigQuery destination. For Cloud
  // Storage destination, the output format is the JSON format that represents a
  // [google.cloud.asset.v1.AnalyzeIamPolicyResponse][google.cloud.asset.v1.AnalyzeIamPolicyResponse].
  // This method implements the
  // [google.longrunning.Operation][google.longrunning.Operation], which allows
  // you to track the export status. We recommend intervals of at least 2
  // seconds with exponential retry to poll the export operation result. The
  // metadata contains the request to help callers to map responses to requests.
  rpc ExportIamPolicyAnalysis(ExportIamPolicyAnalysisRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{analysis_query.scope=*/*}:exportIamPolicyAnalysis"
      body: "*"
    };
    option (google.longrunning.operation_info) = {
      response_type: "google.cloud.asset.v1.ExportIamPolicyAnalysisResponse"
      metadata_type: "google.cloud.asset.v1.ExportIamPolicyAnalysisRequest"
    };
  }
}

// Export asset request.
message ExportAssetsRequest {
  // Required. The relative name of the root asset. This can only be an
  // organization number (such as "organizations/123"), a project ID (such as
  // "projects/my-project-id"), or a project number (such as "projects/12345"),
  // or a folder number (such as "folders/123").
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "cloudasset.googleapis.com/Asset"
    }
  ];

  // Timestamp to take an asset snapshot. This can only be set to a timestamp
  // between the current time and the current time minus 35 days (inclusive).
  // If not specified, the current time will be used. Due to delays in resource
  // data collection and indexing, there is a volatile window during which
  // running the same query may get different results.
  google.protobuf.Timestamp read_time = 2;

  // A list of asset types to take a snapshot for. For example:
  // "compute.googleapis.com/Disk".
  //
  // Regular expressions are also supported. For example:
  //
  // * "compute.googleapis.com.*" snapshots resources whose asset type starts
  // with "compute.googleapis.com".
  // * ".*Instance" snapshots resources whose asset type ends with "Instance".
  // * ".*Instance.*" snapshots resources whose asset type contains "Instance".
  //
  // See [RE2](https://github.com/google/re2/wiki/Syntax) for all supported
  // regular expression syntax. If the regular expression does not match any
  // supported asset type, an INVALID_ARGUMENT error will be returned.
  //
  // If specified, only matching assets will be returned, otherwise, it will
  // snapshot all asset types. See [Introduction to Cloud Asset
  // Inventory](https://cloud.google.com/asset-inventory/docs/overview)
  // for all supported asset types.
  repeated string asset_types = 3;

  // Asset content type. If not specified, no content but the asset name will be
  // returned.
  ContentType content_type = 4;

  // Required. Output configuration indicating where the results will be output to.
  OutputConfig output_config = 5 [(google.api.field_behavior) = REQUIRED];
}

// The export asset response. This message is returned by the
// [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] method in the returned
// [google.longrunning.Operation.response][google.longrunning.Operation.response] field.
message ExportAssetsResponse {
  // Time the snapshot was taken.
  google.protobuf.Timestamp read_time = 1;

  // Output configuration indicating where the results were output to.
  OutputConfig output_config = 2;

  // Output result indicating where the assets were exported to. For example, a
  // set of actual Google Cloud Storage object uris where the assets are
  // exported to. The uris can be different from what [output_config] has
  // specified, as the service will split the output object into multiple ones
  // once it exceeds a single Google Cloud Storage object limit.
  OutputResult output_result = 3;
}

// Batch get assets history request.
message BatchGetAssetsHistoryRequest {
  // Required. The relative name of the root asset. It can only be an
  // organization number (such as "organizations/123"), a project ID (such as
  // "projects/my-project-id")", or a project number (such as "projects/12345").
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "cloudasset.googleapis.com/Asset"
    }
  ];

  // A list of the full names of the assets.
  // See: https://cloud.google.com/asset-inventory/docs/resource-name-format
  // Example:
  //
  // `//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1`.
  //
  // The request becomes a no-op if the asset name list is empty, and the max
  // size of the asset name list is 100 in one request.
  repeated string asset_names = 2;

  // Optional. The content type.
  ContentType content_type = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The time window for the asset history. Both start_time and
  // end_time are optional and if set, it must be after the current time minus
  // 35 days. If end_time is not set, it is default to current timestamp.
  // If start_time is not set, the snapshot of the assets at end_time will be
  // returned. The returned results contain all temporal assets whose time
  // window overlap with read_time_window.
  TimeWindow read_time_window = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Batch get assets history response.
message BatchGetAssetsHistoryResponse {
  // A list of assets with valid time windows.
  repeated TemporalAsset assets = 1;
}

// Create asset feed request.
message CreateFeedRequest {
  // Required. The name of the project/folder/organization where this feed
  // should be created in. It can only be an organization number (such as
  // "organizations/123"), a folder number (such as "folders/123"), a project ID
  // (such as "projects/my-project-id")", or a project number (such as
  // "projects/12345").
  string parent = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. This is the client-assigned asset feed identifier and it needs to
  // be unique under a specific parent project/folder/organization.
  string feed_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The feed details. The field `name` must be empty and it will be generated
  // in the format of:
  // projects/project_number/feeds/feed_id
  // folders/folder_number/feeds/feed_id
  // organizations/organization_number/feeds/feed_id
  Feed feed = 3 [(google.api.field_behavior) = REQUIRED];
}

// Get asset feed request.
message GetFeedRequest {
  // Required. The name of the Feed and it must be in the format of:
  // projects/project_number/feeds/feed_id
  // folders/folder_number/feeds/feed_id
  // organizations/organization_number/feeds/feed_id
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "cloudasset.googleapis.com/Feed"
    }
  ];
}

// List asset feeds request.
message ListFeedsRequest {
  // Required. The parent project/folder/organization whose feeds are to be
  // listed. It can only be using project/folder/organization number (such as
  // "folders/12345")", or a project ID (such as "projects/my-project-id").
  string parent = 1 [(google.api.field_behavior) = REQUIRED];
}

message ListFeedsResponse {
  // A list of feeds.
  repeated Feed feeds = 1;
}

// Update asset feed request.
message UpdateFeedRequest {
  // Required. The new values of feed details. It must match an existing feed and the
  // field `name` must be in the format of:
  // projects/project_number/feeds/feed_id or
  // folders/folder_number/feeds/feed_id or
  // organizations/organization_number/feeds/feed_id.
  Feed feed = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Only updates the `feed` fields indicated by this mask.
  // The field mask must not be empty, and it must not contain fields that
  // are immutable or only set by the server.
  google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED];
}

message DeleteFeedRequest {
  // Required. The name of the feed and it must be in the format of:
  // projects/project_number/feeds/feed_id
  // folders/folder_number/feeds/feed_id
  // organizations/organization_number/feeds/feed_id
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "cloudasset.googleapis.com/Feed"
    }
  ];
}

// Output configuration for export assets destination.
message OutputConfig {
  // Asset export destination.
  oneof destination {
    // Destination on Cloud Storage.
    GcsDestination gcs_destination = 1;

    // Destination on BigQuery. The output table stores the fields in asset
    // proto as columns in BigQuery.
    BigQueryDestination bigquery_destination = 2;
  }
}

// Output result of export assets.
message OutputResult {
  // Asset export result.
  oneof result {
    // Export result on Cloud Storage.
    GcsOutputResult gcs_result = 1;
  }
}

// A Cloud Storage output result.
message GcsOutputResult {
  // List of uris of the Cloud Storage objects. Example:
  // "gs://bucket_name/object_name".
  repeated string uris = 1;
}

// A Cloud Storage location.
message GcsDestination {
  // Required.
  oneof object_uri {
    // The uri of the Cloud Storage object. It's the same uri that is used by
    // gsutil. Example: "gs://bucket_name/object_name". See [Viewing and
    // Editing Object
    // Metadata](https://cloud.google.com/storage/docs/viewing-editing-metadata)
    // for more information.
    string uri = 1;

    // The uri prefix of all generated Cloud Storage objects. Example:
    // "gs://bucket_name/object_name_prefix". Each object uri is in format:
    // "gs://bucket_name/object_name_prefix/<asset type>/<shard number> and only
    // contains assets for that type. <shard number> starts from 0. Example:
    // "gs://bucket_name/object_name_prefix/compute.googleapis.com/Disk/0" is
    // the first shard of output objects containing all
    // compute.googleapis.com/Disk assets. An INVALID_ARGUMENT error will be
    // returned if file with the same name "gs://bucket_name/object_name_prefix"
    // already exists.
    string uri_prefix = 2;
  }
}

// A BigQuery destination for exporting assets to.
message BigQueryDestination {
  // Required. The BigQuery dataset in format
  // "projects/projectId/datasets/datasetId", to which the snapshot result
  // should be exported. If this dataset does not exist, the export call returns
  // an INVALID_ARGUMENT error.
  string dataset = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The BigQuery table to which the snapshot result should be
  // written. If this table does not exist, a new table with the given name
  // will be created.
  string table = 2 [(google.api.field_behavior) = REQUIRED];

  // If the destination table already exists and this flag is `TRUE`, the
  // table will be overwritten by the contents of assets snapshot. If the flag
  // is `FALSE` or unset and the destination table already exists, the export
  // call returns an INVALID_ARGUMEMT error.
  bool force = 3;
}

// A Pub/Sub destination.
message PubsubDestination {
  // The name of the Pub/Sub topic to publish to.
  // Example: `projects/PROJECT_ID/topics/TOPIC_ID`.
  string topic = 1;
}

// Output configuration for asset feed destination.
message FeedOutputConfig {
  // Asset feed destination.
  oneof destination {
    // Destination on Pub/Sub.
    PubsubDestination pubsub_destination = 1;
  }
}

// An asset feed used to export asset updates to a destinations.
// An asset feed filter controls what updates are exported.
// The asset feed must be created within a project, organization, or
// folder. Supported destinations are:
// Pub/Sub topics.
message Feed {
  option (google.api.resource) = {
    type: "cloudasset.googleapis.com/Feed"
    pattern: "projects/{project}/feeds/{feed}"
    pattern: "folders/{folder}/feeds/{feed}"
    pattern: "organizations/{organization}/feeds/{feed}"
    history: ORIGINALLY_SINGLE_PATTERN
  };

  // Required. The format will be
  // projects/{project_number}/feeds/{client-assigned_feed_identifier} or
  // folders/{folder_number}/feeds/{client-assigned_feed_identifier} or
  // organizations/{organization_number}/feeds/{client-assigned_feed_identifier}
  //
  // The client-assigned feed identifier must be unique within the parent
  // project/folder/organization.
  string name = 1 [(google.api.field_behavior) = REQUIRED];

  // A list of the full names of the assets to receive updates. You must specify
  // either or both of asset_names and asset_types. Only asset updates matching
  // specified asset_names or asset_types are exported to the feed.
  // Example:
  // `//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1`.
  // See [Resource
  // Names](https://cloud.google.com/apis/design/resource_names#full_resource_name)
  // for more info.
  repeated string asset_names = 2;

  // A list of types of the assets to receive updates. You must specify either
  // or both of asset_names and asset_types. Only asset updates matching
  // specified asset_names or asset_types are exported to the feed.
  // Example: `"compute.googleapis.com/Disk"`
  //
  // See [this
  // topic](https://cloud.google.com/asset-inventory/docs/supported-asset-types)
  // for a list of all supported asset types.
  repeated string asset_types = 3;

  // Asset content type. If not specified, no content but the asset name and
  // type will be returned.
  ContentType content_type = 4;

  // Required. Feed output configuration defining where the asset updates are
  // published to.
  FeedOutputConfig feed_output_config = 5 [(google.api.field_behavior) = REQUIRED];

  // A condition which determines whether an asset update should be published.
  // If specified, an asset will be returned only when the expression evaluates
  // to true.
  // When set, `expression` field in the `Expr` must be a valid [CEL expression]
  // (https://github.com/google/cel-spec) on a TemporalAsset with name
  // `temporal_asset`. Example: a Feed with expression ("temporal_asset.deleted
  // == true") will only publish Asset deletions. Other fields of `Expr` are
  // optional.
  //
  // See our [user
  // guide](https://cloud.google.com/asset-inventory/docs/monitoring-asset-changes#feed_with_condition)
  // for detailed instructions.
  google.type.Expr condition = 6;
}

// Search all resources request.
message SearchAllResourcesRequest {
  // Required. A scope can be a project, a folder, or an organization. The search is
  // limited to the resources within the `scope`. The caller must be granted the
  // [`cloudasset.assets.searchAllResources`](http://cloud.google.com/asset-inventory/docs/access-control#required_permissions)
  // permission on the desired scope.
  //
  // The allowed values are:
  //
  // * projects/{PROJECT_ID} (e.g., "projects/foo-bar")
  // * projects/{PROJECT_NUMBER} (e.g., "projects/12345678")
  // * folders/{FOLDER_NUMBER} (e.g., "folders/1234567")
  // * organizations/{ORGANIZATION_NUMBER} (e.g., "organizations/123456")
  string scope = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The query statement. See [how to construct a
  // query](http://cloud.google.com/asset-inventory/docs/searching-resources#how_to_construct_a_query)
  // for more information. If not specified or empty, it will search all the
  // resources within the specified `scope`. Note that the query string is
  // compared against each Cloud IAM policy binding, including its members,
  // roles, and Cloud IAM conditions. The returned Cloud IAM policies will only
  // contain the bindings that match your query. To learn more about the IAM
  // policy structure, see [IAM policy
  // doc](https://cloud.google.com/iam/docs/policies#structure).
  //
  // Examples:
  //
  // * `name:Important` to find Cloud resources whose name contains
  //   "Important" as a word.
  // * `displayName:Impor*` to find Cloud resources whose display name
  //   contains "Impor" as a prefix.
  // * `description:*por*` to find Cloud resources whose description
  //   contains "por" as a substring.
  // * `location:us-west*` to find Cloud resources whose location is
  //   prefixed with "us-west".
  // * `labels:prod` to find Cloud resources whose labels contain "prod" as
  //   a key or value.
  // * `labels.env:prod` to find Cloud resources that have a label "env"
  //   and its value is "prod".
  // * `labels.env:*` to find Cloud resources that have a label "env".
  // * `Important` to find Cloud resources that contain "Important" as a word
  //   in any of the searchable fields.
  // * `Impor*` to find Cloud resources that contain "Impor" as a prefix
  //   in any of the searchable fields.
  // * `*por*` to find Cloud resources that contain "por" as a substring in
  //   any of the searchable fields.
  // * `Important location:(us-west1 OR global)` to find Cloud
  //   resources that contain "Important" as a word in any of the searchable
  //   fields and are also located in the "us-west1" region or the "global"
  //   location.
  string query = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A list of asset types that this request searches for. If empty, it will
  // search all the [searchable asset
  // types](https://cloud.google.com/asset-inventory/docs/supported-asset-types#searchable_asset_types).
  repeated string asset_types = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The page size for search result pagination. Page size is capped at 500 even
  // if a larger value is given. If set to zero, server will pick an appropriate
  // default. Returned results may be fewer than requested. When this happens,
  // there could be more results as long as `next_page_token` is returned.
  int32 page_size = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. If present, then retrieve the next batch of results from the preceding call
  // to this method. `page_token` must be the value of `next_page_token` from
  // the previous response. The values of all other method parameters, must be
  // identical to those in the previous call.
  string page_token = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A comma separated list of fields specifying the sorting order of the
  // results. The default order is ascending. Add " DESC" after the field name
  // to indicate descending order. Redundant space characters are ignored.
  // Example: "location DESC, name". Only string fields in the response are
  // sortable, including `name`, `displayName`, `description`, `location`. All
  // the other fields such as repeated fields (e.g., `networkTags`), map
  // fields (e.g., `labels`) and struct fields (e.g., `additionalAttributes`)
  // are not supported.
  string order_by = 6 [(google.api.field_behavior) = OPTIONAL];
}

// Search all resources response.
message SearchAllResourcesResponse {
  // A list of Resources that match the search query. It contains the resource
  // standard metadata information.
  repeated ResourceSearchResult results = 1;

  // If there are more results than those appearing in this response, then
  // `next_page_token` is included. To get the next set of results, call this
  // method again using the value of `next_page_token` as `page_token`.
  string next_page_token = 2;
}

// Search all IAM policies request.
message SearchAllIamPoliciesRequest {
  // Required. A scope can be a project, a folder, or an organization. The search is
  // limited to the IAM policies within the `scope`. The caller must be granted
  // the
  // [`cloudasset.assets.searchAllIamPolicies`](http://cloud.google.com/asset-inventory/docs/access-control#required_permissions)
  // permission on the desired scope.
  //
  // The allowed values are:
  //
  // * projects/{PROJECT_ID} (e.g., "projects/foo-bar")
  // * projects/{PROJECT_NUMBER} (e.g., "projects/12345678")
  // * folders/{FOLDER_NUMBER} (e.g., "folders/1234567")
  // * organizations/{ORGANIZATION_NUMBER} (e.g., "organizations/123456")
  string scope = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The query statement. See [how to construct a
  // query](https://cloud.google.com/asset-inventory/docs/searching-iam-policies#how_to_construct_a_query)
  // for more information. If not specified or empty, it will search all the
  // IAM policies within the specified `scope`.
  //
  // Examples:
  //
  // * `policy:amy@gmail.com` to find IAM policy bindings that specify user
  //   "amy@gmail.com".
  // * `policy:roles/compute.admin` to find IAM policy bindings that specify
  //   the Compute Admin role.
  // * `policy.role.permissions:storage.buckets.update` to find IAM policy
  //   bindings that specify a role containing "storage.buckets.update"
  //   permission. Note that if callers don't have `iam.roles.get` access to a
  //   role's included permissions, policy bindings that specify this role will
  //   be dropped from the search results.
  // * `resource:organizations/123456` to find IAM policy bindings
  //   that are set on "organizations/123456".
  // * `Important` to find IAM policy bindings that contain "Important" as a
  //   word in any of the searchable fields (except for the included
  //   permissions).
  // * `*por*` to find IAM policy bindings that contain "por" as a substring
  //   in any of the searchable fields (except for the included permissions).
  // * `resource:(instance1 OR instance2) policy:amy` to find
  //   IAM policy bindings that are set on resources "instance1" or
  //   "instance2" and also specify user "amy".
  string query = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The page size for search result pagination. Page size is capped at 500 even
  // if a larger value is given. If set to zero, server will pick an appropriate
  // default. Returned results may be fewer than requested. When this happens,
  // there could be more results as long as `next_page_token` is returned.
  int32 page_size = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. If present, retrieve the next batch of results from the preceding call to
  // this method. `page_token` must be the value of `next_page_token` from the
  // previous response. The values of all other method parameters must be
  // identical to those in the previous call.
  string page_token = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Search all IAM policies response.
message SearchAllIamPoliciesResponse {
  // A list of IamPolicy that match the search query. Related information such
  // as the associated resource is returned along with the policy.
  repeated IamPolicySearchResult results = 1;

  // Set if there are more results than those appearing in this response; to get
  // the next set of results, call this method again, using this value as the
  // `page_token`.
  string next_page_token = 2;
}

// IAM policy analysis query message.
message IamPolicyAnalysisQuery {
  // The relative name of the root asset. Only resources and IAM policies within
  // the scope will be analyzed.
  //
  // This can only be an organization number (such as "organizations/123"), a
  // folder number (such as "folders/123"), a project ID (such as
  // "projects/my-project-id"), or a project number (such as "projects/12345").
  //
  // To know how to get organization id, visit [here
  // ](https://cloud.google.com/resource-manager/docs/creating-managing-organization#retrieving_your_organization_id).
  //
  // To know how to get folder or project id, visit [here
  // ](https://cloud.google.com/resource-manager/docs/creating-managing-folders#viewing_or_listing_folders_and_projects).
  string scope = 1 [
    (google.api.field_behavior) = REQUIRED
  ];

  // Specifies the resource to analyze for access policies, which may be set
  // directly on the resource, or on ancestors such as organizations, folders or
  // projects.
  message ResourceSelector {
    // The [full resource name]
    // (https://cloud.google.com/asset-inventory/docs/resource-name-format)
    // of a resource of [supported resource
    // types](https://cloud.google.com/asset-inventory/docs/supported-asset-types#analyzable_asset_types).
    string full_resource_name = 1 [(google.api.field_behavior) = REQUIRED];
  }

  // Specifies a resource for analysis.
  ResourceSelector resource_selector = 2
      [(google.api.field_behavior) = OPTIONAL];

  // Specifies an identity for which to determine resource access, based on
  // roles assigned either directly to them or to the groups they belong to,
  // directly or indirectly.
  message IdentitySelector {
    // The identity appear in the form of members in
    // [IAM policy
    // binding](https://cloud.google.com/iam/reference/rest/v1/Binding).
    //
    // The examples of supported forms are:
    // "user:mike@example.com",
    // "group:admins@example.com",
    // "domain:google.com",
    // "serviceAccount:my-project-id@appspot.gserviceaccount.com".
    //
    // Notice that wildcard characters (such as * and ?) are not supported.
    // You must give a specific identity.
    string identity = 1 [(google.api.field_behavior) = REQUIRED];
  }

  // Specifies an identity for analysis.
  IdentitySelector identity_selector = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Specifies roles and/or permissions to analyze, to determine both the
  // identities possessing them and the resources they control. If multiple
  // values are specified, results will include roles or permissions matching
  // any of them.
  message AccessSelector {
    // The roles to appear in result.
    repeated string roles = 1 [(google.api.field_behavior) = OPTIONAL];

    // The permissions to appear in result.
    repeated string permissions = 2 [(google.api.field_behavior) = OPTIONAL];
  }

  // Specifies roles or permissions for analysis. This is optional.
  AccessSelector access_selector = 4 [(google.api.field_behavior) = OPTIONAL];

  // Contains query options.
  message Options {
    // If true, the identities section of the result will expand any
    // Google groups appearing in an IAM policy binding.
    //
    // If
    // [google.cloud.asset.v1.IamPolicyAnalysisQuery.identity_selector][google.cloud.asset.v1.IamPolicyAnalysisQuery.identity_selector]
    // is specified, the identity in the result will be determined by the
    // selector, and this flag is not allowed to set.
    //
    // Default is false.
    bool expand_groups = 1 [(google.api.field_behavior) = OPTIONAL];

    // If true, the access section of result will expand any roles
    // appearing in IAM policy bindings to include their permissions.
    //
    // If
    // [google.cloud.asset.v1.IamPolicyAnalysisQuery.access_selector][google.cloud.asset.v1.IamPolicyAnalysisQuery.access_selector]
    // is specified, the access section of the result will be determined by the
    // selector, and this flag is not allowed to set.
    //
    // Default is false.
    bool expand_roles = 2 [(google.api.field_behavior) = OPTIONAL];

    // If true and
    // [google.cloud.asset.v1.IamPolicyAnalysisQuery.resource_selector][google.cloud.asset.v1.IamPolicyAnalysisQuery.resource_selector]
    // is not specified, the resource section of the result will expand any
    // resource attached to an IAM policy to include resources lower in the
    // resource hierarchy.
    //
    // For example, if the request analyzes for which resources user A has
    // permission P, and the results include an IAM policy with P on a GCP
    // folder, the results will also include resources in that folder with
    // permission P.
    //
    // If true and
    // [google.cloud.asset.v1.IamPolicyAnalysisQuery.resource_selector][google.cloud.asset.v1.IamPolicyAnalysisQuery.resource_selector]
    // is specified, the resource section of the result will expand the
    // specified resource to include resources lower in the resource hierarchy.
    //
    // For example, if the request analyzes for which users have permission P on
    // a GCP folder with this option enabled, the results will include all users
    // who have permission P on that folder or any lower resource(ex. project).
    //
    // Default is false.
    bool expand_resources = 3 [(google.api.field_behavior) = OPTIONAL];

    // If true, the result will output resource edges, starting
    // from the policy attached resource, to any expanded resources.
    // Default is false.
    bool output_resource_edges = 4 [(google.api.field_behavior) = OPTIONAL];

    // If true, the result will output group identity edges, starting
    // from the binding's group members, to any expanded identities.
    // Default is false.
    bool output_group_edges = 5 [(google.api.field_behavior) = OPTIONAL];

    // If true, the response will include access analysis from identities to
    // resources via service account impersonation. This is a very expensive
    // operation, because many derived queries will be executed. We highly
    // recommend you use
    // [google.cloud.asset.v1.AssetService.ExportIamPolicyAnalysis][google.cloud.asset.v1.AssetService.ExportIamPolicyAnalysis]
    // rpc instead.
    //
    // For example, if the request analyzes for which resources user A has
    // permission P, and there's an IAM policy states user A has
    // iam.serviceAccounts.getAccessToken permission to a service account SA,
    // and there's another IAM policy states service account SA has permission P
    // to a GCP folder F, then user A potentially has access to the GCP folder
    // F. And those advanced analysis results will be included in
    // [google.cloud.asset.v1.AnalyzeIamPolicyResponse.service_account_impersonation_analysis][google.cloud.asset.v1.AnalyzeIamPolicyResponse.service_account_impersonation_analysis].
    //
    // Another example, if the request analyzes for who has
    // permission P to a GCP folder F, and there's an IAM policy states user A
    // has iam.serviceAccounts.actAs permission to a service account SA, and
    // there's another IAM policy states service account SA has permission P to
    // the GCP folder F, then user A potentially has access to the GCP folder
    // F. And those advanced analysis results will be included in
    // [google.cloud.asset.v1.AnalyzeIamPolicyResponse.service_account_impersonation_analysis][google.cloud.asset.v1.AnalyzeIamPolicyResponse.service_account_impersonation_analysis].
    //
    // Default is false.
    bool analyze_service_account_impersonation = 6
        [(google.api.field_behavior) = OPTIONAL];

    // The maximum number of fanouts per group when [expand_groups][expand_groups]
    // is enabled. This internal field is to help load testing and determine a
    // proper value, and won't be public in the future.
    int32 max_fanouts_per_group = 7 [
      (google.api.field_behavior) = OPTIONAL
    ];

    // The maximum number of fanouts per parent resource, such as
    // GCP Project etc., when [expand_resources][] is enabled. This internal
    // field is to help load testing and determine a proper value, and won't be
    // public in the future.
    int32 max_fanouts_per_resource = 8 [
      (google.api.field_behavior) = OPTIONAL
    ];
  }

  // The query options.
  Options options = 5 [(google.api.field_behavior) = OPTIONAL];
}

// A request message for
// [google.cloud.asset.v1.AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy].
message AnalyzeIamPolicyRequest {
  // The request query.
  IamPolicyAnalysisQuery analysis_query = 1
      [(google.api.field_behavior) = REQUIRED];

  // Amount of time executable has to complete.  See JSON representation of
  // [Duration](https://developers.google.com/protocol-buffers/docs/proto3#json).
  //
  // If this field is set with a value less than the RPC deadline, and the
  // execution of your query hasn't finished in the specified
  // execution timeout,  you will get a response with partial result.
  // Otherwise, your query's execution will continue until the RPC deadline.
  // If it's not finished until then, you will get a  DEADLINE_EXCEEDED error.
  //
  // Default is empty.
  //
  // (-- We had discussion of whether we should have this field in the    --)
  // (-- request or use the RPC deadline instead. We finally choose this  --)
  // (-- approach for the following reasons (detailed in                  --)
  // (-- go/analyze-iam-policy-deadlines):                                --)
  // (-- * HTTP clients have very limited support of the RPC deadline.    --)
  // (--   There is an X-Server-Timeout header introduced in 2019/09, but --)
  // (--   only implemented in the C++ HTTP server library.               --)
  // (-- * The purpose of the RPC deadline is for RPC clients to          --)
  // (--   communicate its max waiting time to the server. This deadline  --)
  // (--   could be further propagated to the downstream servers. It is   --)
  // (--   mainly used for servers to cancel the request processing       --)
  // (--   to avoid resource wasting. Overloading the RPC deadline for    --)
  // (--   other purposes could make our backend system harder to reason  --)
  // (--   about.                                                         --)
  google.protobuf.Duration execution_timeout = 2
      [(google.api.field_behavior) = OPTIONAL];
}

// A response message for
// [google.cloud.asset.v1.AssetService.AnalyzeIamPolicy][google.cloud.asset.v1.AssetService.AnalyzeIamPolicy].
message AnalyzeIamPolicyResponse {
  // An analysis message to group the query and results.
  message IamPolicyAnalysis {
    // The analysis query.
    IamPolicyAnalysisQuery analysis_query = 1;

    // A list of [google.cloud.asset.v1.IamPolicyAnalysisResult][google.cloud.asset.v1.IamPolicyAnalysisResult]
    // that matches the analysis query, or empty if no result is found.
    repeated IamPolicyAnalysisResult analysis_results = 2;

    // Represents whether all entries in the
    // [analysis_results][analysis_results] have been fully explored to answer
    // the query.
    bool fully_explored = 3;

    // A stats message that contains a set of analysis metrics.
    //
    // Here are some equations to show relationships of the explicitly specified
    // metrics with other implicit metrics:
    // * node_count = discovered_node_count + undiscovered_node_count(implicit)
    // * discovered_node_count = explored_node_count +
    // unexplored_node_count(implicit)
    // * explored_node_count = capped_node_count + uncapped_node_count(implicit)
    // * unexplored_node_count(implicit) = permission_denied_node_count +
    // execution_timeout_node_count + other_unexplored_node_count(implicit)
    // * discovered_node_count = matched_node_count +
    // unmatched_node_count(implicit)
    message Stats {
      // Type of the node.
      enum NodeType {
        // Unspecified node type.
        NODE_TYPE_UNSPECIFIED = 0;
        // IAM Policy Binding node type.
        BINDING = 1;
        // Identity node type.
        IDENTITY = 2;
        // Resource node type.
        RESOURCE = 3;
        // Access node type.
        ACCESS = 4;
      }

      // Node type.
      NodeType node_type = 1;

      // The subtype of a node, such as:
      // * For Identity: Group, User, ServiceAccount etc.
      // * For Resource: resource type name, such as
      // cloudresourcemanager.googleapis.com/Organization, etc.
      // * For Access: Role or Permission
      string node_subtype = 2;

      // The count of discovered nodes.
      int32 discovered_node_count = 3;

      // The count of nodes that match the query. These nodes form a sub-graph
      // of discovered nodes.
      int32 matched_node_count = 4;

      // The count of explored nodes.
      int32 explored_node_count = 5;

      // The count of nodes that get explored, but are capped by max fanout
      // setting.
      int32 capped_node_count = 6;

      // The count of unexplored nodes caused by permission denied error.
      int32 permision_denied_node_count = 7;

      // The count of unexplored nodes caused by execution timeout.
      int32 execution_timeout_node_count = 8;
    }

    // The stats of how the analysis has been explored.
    repeated Stats stats = 4;

    // A list of non-critical errors happened during the query handling.
    repeated IamPolicyAnalysisState non_critical_errors = 5;
  }

  // The main analysis that matches the original request.
  IamPolicyAnalysis main_analysis = 1;

  // The service account impersonation analysis if
  // [google.cloud.asset.v1.AnalyzeIamPolicyRequest.analyze_service_account_impersonation][google.cloud.asset.v1.AnalyzeIamPolicyRequest.analyze_service_account_impersonation]
  // is enabled.
  repeated IamPolicyAnalysis service_account_impersonation_analysis = 2;

  // Represents whether all entries in the [main_analysis][main_analysis] and
  // [service_account_impersonation_analysis][] have been fully explored to
  // answer the query in the request.
  bool fully_explored = 3;
}

// Output configuration for export IAM policy analysis destination.
message IamPolicyAnalysisOutputConfig {
  // A Cloud Storage location.
  message GcsDestination {
    // The uri of the Cloud Storage object. It's the same uri that is used by
    // gsutil. For example: "gs://bucket_name/object_name". See [Viewing and
    // Editing Object
    // Metadata](https://cloud.google.com/storage/docs/viewing-editing-metadata)
    // for more information.
    string uri = 1 [(google.api.field_behavior) = REQUIRED];
  }

  // A BigQuery destination.
  message BigQueryDestination {
    // The BigQuery dataset in format "projects/projectId/datasets/datasetId",
    // to which the analysis results should be exported. If this dataset does
    // not exist, the export call will return an INVALID_ARGUMENT error.
    string dataset = 1 [
      (google.api.field_behavior) = REQUIRED
    ];

    // The prefix of the BigQuery tables to which the analysis results will be
    // written. Tables will be created based on this table_prefix if not exist:
    // * <table_prefix>_analysis table will contain export operation's metadata.
    // * <table_prefix>_analysis_result will contain all the
    //   [IamPolicyAnalysisResult][].
    // When [partition_key] is specified, both tables will be partitioned based
    // on the [partition_key].
    string table_prefix = 2 [
      (google.api.field_behavior) = REQUIRED
    ];

    // This enum determines the partition key column for the bigquery tables.
    // Partitioning can improve query performance and reduce query cost by
    // filtering partitions. Refer to
    // https://cloud.google.com/bigquery/docs/partitioned-tables for details.
    enum PartitionKey {
      // Unspecified partition key. Tables won't be partitioned using this
      // option.
      PARTITION_KEY_UNSPECIFIED = 0;
      // The time when the request is received. If specified as partition key,
      // the result table(s) is partitoned by the RequestTime column, an
      // additional timestamp column representing when the request was received.
      REQUEST_TIME = 1;
    }
    // The partition key for BigQuery partitioned table.
    PartitionKey partition_key = 3;

    // Write mode types if table exists.
    enum WriteMode {
      // Unspecified write mode. We expect one of the following valid modes must
      // be specified when table or partition exists.
      WRITE_MODE_UNSPECIFIED = 0;
      // Abort the export when table or partition exists.
      ABORT = 1;
      // Overwrite the table when table exists. When partitioned, overwrite
      // the existing partition.
      OVERWRITE = 2;
    }
    // The write mode when table exists. WriteMode is ignored when no existing
    // tables, or no existing partitions are found.
    WriteMode write_mode = 4;
  }

  // IAM policy analysis export destination.
  oneof destination {
    // Destination on Cloud Storage.
    GcsDestination gcs_destination = 1;

    // Destination on BigQuery.
    BigQueryDestination bigquery_destination = 2;
  }
}

// A request message for [AssetService.ExportIamPolicyAnalysis][].
message ExportIamPolicyAnalysisRequest {
  // The request query.
  IamPolicyAnalysisQuery analysis_query = 1
      [(google.api.field_behavior) = REQUIRED];

  // Output configuration indicating where the results will be output to.
  IamPolicyAnalysisOutputConfig output_config = 2
      [(google.api.field_behavior) = REQUIRED];
}

// The export IAM policy analysis response.
message ExportIamPolicyAnalysisResponse {}

// Asset content type.
enum ContentType {
  // Unspecified content type.
  CONTENT_TYPE_UNSPECIFIED = 0;

  // Resource metadata.
  RESOURCE = 1;

  // The actual IAM policy set on a resource.
  IAM_POLICY = 2;

  // The Cloud Organization Policy set on an asset.
  ORG_POLICY = 4;

  // The Cloud Access context manager Policy set on an asset.
  ACCESS_POLICY = 5;
}
