// Copyright 2026 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.kms.inventory.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.Kms.Inventory.V1";
option go_package = "cloud.google.com/go/kms/inventory/apiv1/inventorypb;inventorypb";
option java_multiple_files = true;
option java_outer_classname = "KeyTrackingServiceProto";
option java_package = "com.google.cloud.kms.inventory.v1";
option php_namespace = "Google\\Cloud\\Kms\\Inventory\\V1";
option (google.api.resource_definition) = {
  type: "kmsinventory.googleapis.com/ProtectedResourceScope"
  pattern: "organizations/{organization}/protectedResourceScope"
  pattern: "projects/{project}/protectedResourceScope"
};

// Returns information about the resources in an org that are protected by a
// given Cloud KMS key via CMEK.
service KeyTrackingService {
  option (google.api.default_host) = "kmsinventory.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Returns aggregate information about the resources protected by the given
  // Cloud KMS [CryptoKey][google.cloud.kms.v1.CryptoKey]. By default,
  // summary of resources within the same Cloud organization as the key will be
  // returned, which requires the KMS organization service account to be
  // configured(refer
  // https://docs.cloud.google.com/kms/docs/view-key-usage#required-roles).
  // If the KMS organization service account is not configured or key's project
  // is not part of an organization, set
  // [fallback_scope][google.cloud.kms.inventory.v1.GetProtectedResourcesSummaryRequest.fallback_scope]
  // to `FALLBACK_SCOPE_PROJECT` to retrieve a summary of protected resources
  // within the key's project.
  rpc GetProtectedResourcesSummary(GetProtectedResourcesSummaryRequest)
      returns (ProtectedResourcesSummary) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/locations/*/keyRings/*/cryptoKeys/**}/protectedResourcesSummary"
    };
    option (google.api.method_signature) = "name";
  }

  // Returns metadata about the resources protected by the given Cloud KMS
  // [CryptoKey][google.cloud.kms.v1.CryptoKey] in the given Cloud
  // organization/project.
  rpc SearchProtectedResources(SearchProtectedResourcesRequest)
      returns (SearchProtectedResourcesResponse) {
    option (google.api.http) = {
      get: "/v1/{scope=organizations/*}/protectedResources:search"
      additional_bindings {
        get: "/v1/{scope=projects/*}/protectedResources:search"
      }
    };
    option (google.api.method_signature) = "scope, crypto_key";
  }
}

// Request message for
// [KeyTrackingService.GetProtectedResourcesSummary][google.cloud.kms.inventory.v1.KeyTrackingService.GetProtectedResourcesSummary].
message GetProtectedResourcesSummaryRequest {
  // Required. The resource name of the
  // [CryptoKey][google.cloud.kms.v1.CryptoKey].
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "kmsinventory.googleapis.com/ProtectedResourcesSummary"
    }
  ];

  // Optional. The scope to use if the kms organization service account is not
  // configured.
  FallbackScope fallback_scope = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Aggregate information about the resources protected by a Cloud KMS key in the
// same Cloud organization/project as the key.
message ProtectedResourcesSummary {
  option (google.api.resource) = {
    type: "kmsinventory.googleapis.com/ProtectedResourcesSummary"
    pattern: "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}/protectedResourcesSummary"
    pattern: "projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}/cryptoKeyVersions/{crypto_key_version}/protectedResourcesSummary"
  };

  // The full name of the ProtectedResourcesSummary resource.
  // Example:
  // projects/test-project/locations/us/keyRings/test-keyring/cryptoKeys/test-key/protectedResourcesSummary
  string name = 5;

  // The total number of protected resources in the same Cloud organization as
  // the key.
  int64 resource_count = 1;

  // The number of distinct Cloud projects in the same Cloud organization as the
  // key that have resources protected by the key.
  int32 project_count = 2;

  // The number of resources protected by the key grouped by resource type.
  map<string, int64> resource_types = 3;

  // The number of resources protected by the key grouped by Cloud product.
  map<string, int64> cloud_products = 6;

  // The number of resources protected by the key grouped by region.
  map<string, int64> locations = 4;

  // Warning messages for the state of response
  // [ProtectedResourcesSummary][google.cloud.kms.inventory.v1.ProtectedResourcesSummary]
  // For example, if the organization service account is not configured,
  // INSUFFICIENT_PERMISSIONS_PARTIAL_DATA warning will be returned.
  repeated Warning warnings = 7;
}

// Request message for
// [KeyTrackingService.SearchProtectedResources][google.cloud.kms.inventory.v1.KeyTrackingService.SearchProtectedResources].
message SearchProtectedResourcesRequest {
  // Required. A scope can be an organization or a project. Resources protected
  // by the crypto key in provided scope will be returned.
  //
  // The following values are allowed:
  //
  // * organizations/{ORGANIZATION_NUMBER} (e.g., "organizations/12345678")
  // * projects/{PROJECT_ID} (e.g., "projects/foo-bar")
  // * projects/{PROJECT_NUMBER} (e.g., "projects/12345678")
  string scope = 2 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "kmsinventory.googleapis.com/ProtectedResourceScope"
    }
  ];

  // Required. The resource name of the
  // [CryptoKey][google.cloud.kms.v1.CryptoKey].
  string crypto_key = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "*" }
  ];

  // The maximum number of resources to return. The service may return fewer
  // than this value.
  // If unspecified, at most 500 resources will be returned.
  // The maximum value is 500; values above 500 will be coerced to 500.
  int32 page_size = 3;

  // A page token, received from a previous
  // [KeyTrackingService.SearchProtectedResources][google.cloud.kms.inventory.v1.KeyTrackingService.SearchProtectedResources]
  // call. Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to
  // [KeyTrackingService.SearchProtectedResources][google.cloud.kms.inventory.v1.KeyTrackingService.SearchProtectedResources]
  // must match the call that provided the page token.
  string page_token = 4;

  // Optional. A list of resource types that this request searches for. If
  // empty, it will search all the [trackable resource
  // types](https://cloud.google.com/kms/docs/view-key-usage#tracked-resource-types).
  //
  // Regular expressions are also supported. For example:
  //
  // * `compute.googleapis.com.*` snapshots resources whose type starts
  // with `compute.googleapis.com`.
  // * `.*Image` snapshots resources whose type ends with `Image`.
  // * `.*Image.*` snapshots resources whose type contains `Image`.
  //
  // See [RE2](https://github.com/google/re2/wiki/Syntax) for all supported
  // regular expression syntax. If the regular expression does not match any
  // supported resource type, an INVALID_ARGUMENT error will be returned.
  repeated string resource_types = 5 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for
// [KeyTrackingService.SearchProtectedResources][google.cloud.kms.inventory.v1.KeyTrackingService.SearchProtectedResources].
message SearchProtectedResourcesResponse {
  // Protected resources for this page.
  repeated ProtectedResource protected_resources = 1;

  // A token that can be sent as `page_token` to retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 2;
}

// Metadata about a resource protected by a Cloud KMS key.
message ProtectedResource {
  option (google.api.resource) = {
    type: "cloudasset.googleapis.com/Asset"
    pattern: "*"
  };

  // The full resource name of the resource.
  // Example:
  // `//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1`.
  string name = 1;

  // Format: `projects/{PROJECT_NUMBER}`.
  string project = 2;

  // The ID of the project that owns the resource.
  string project_id = 9;

  // The Cloud product that owns the resource.
  // Example: `compute`
  string cloud_product = 8;

  // Example: `compute.googleapis.com/Disk`
  string resource_type = 3;

  // Location can be `global`, regional like `us-east1`, or zonal like
  // `us-west1-b`.
  string location = 4;

  // A key-value pair of the resource's labels (v1) to their values.
  map<string, string> labels = 5;

  // The name of the Cloud KMS
  // [CryptoKeyVersion](https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys.cryptoKeyVersions?hl=en)
  // used to protect this resource via CMEK. This field is empty if the
  // Google Cloud product owning the resource does not provide key version data
  // to Asset Inventory. If there are multiple key versions protecting the
  // resource, then this is same value as the first element of
  // crypto_key_versions.
  string crypto_key_version = 6 [(google.api.resource_reference) = {
    type: "cloudkms.googleapis.com/CryptoKeyVersion"
  }];

  // The names of the Cloud KMS
  // [CryptoKeyVersion](https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys.cryptoKeyVersions?hl=en)
  // used to protect this resource via CMEK. This field is empty if the
  // Google Cloud product owning the resource does not provide key versions data
  // to Asset Inventory. The first element of this field is stored in
  // crypto_key_version.
  repeated string crypto_key_versions = 10 [(google.api.resource_reference) = {
    type: "cloudkms.googleapis.com/CryptoKeyVersion"
  }];

  // Output only. The time at which this resource was created. The granularity
  // is in seconds. Timestamp.nanos will always be 0.
  google.protobuf.Timestamp create_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A warning message that indicates potential problems with the response data.
message Warning {
  // Different types of warnings that can be returned to the user.
  // The display_message contains detailed information regarding the
  // warning_code.
  enum WarningCode {
    // Default value. This value is unused.
    WARNING_CODE_UNSPECIFIED = 0;

    // Indicates that the caller or service agent lacks necessary permissions
    // to view some of the requested data. The response may be partial.
    // Example:
    // - KMS organization service agent {service_agent_name} lacks the
    //   `cloudasset.assets.searchAllResources` permission on the scope.
    INSUFFICIENT_PERMISSIONS_PARTIAL_DATA = 1;

    // Indicates that a resource limit has been exceeded, resulting in partial
    // data. Example:
    // - The project has more than 10,000 assets (resources,
    //   crypto keys, key handles, IAM policies, etc).
    RESOURCE_LIMIT_EXCEEDED_PARTIAL_DATA = 2;

    // Indicates that the project exists outside of an organization resource.
    // Thus the analysis is only done for the project level data and results
    // might be partial.
    ORG_LESS_PROJECT_PARTIAL_DATA = 3;
  }

  // The specific warning code for the displayed message.
  WarningCode warning_code = 1;

  // The literal message providing context and details about the warnings.
  string display_message = 2;
}

// Specifies the scope to use if the organization service agent is not
// configured.
enum FallbackScope {
  // Unspecified scope type.
  FALLBACK_SCOPE_UNSPECIFIED = 0;

  // If set to `FALLBACK_SCOPE_PROJECT`, the API will fall back to using key's
  // project as request scope if the kms organization service account is not
  // configured.
  FALLBACK_SCOPE_PROJECT = 1;
}
