// Copyright 2025 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.iam.v2beta;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/iam/v2beta/deny.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.Iam.V2Beta";
option go_package = "cloud.google.com/go/iam/apiv2beta/iampb;iampb";
option java_multiple_files = true;
option java_outer_classname = "PolicyProto";
option java_package = "com.google.iam.v2beta";
option php_namespace = "Google\\Cloud\\Iam\\V2beta";

// An interface for managing Identity and Access Management (IAM) policies.
service Policies {
  option (google.api.default_host) = "iam.googleapis.com";
  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform";

  // Retrieves the policies of the specified kind that are attached to a
  // resource.
  //
  // The response lists only policy metadata. In particular, policy rules are
  // omitted.
  rpc ListPolicies(ListPoliciesRequest) returns (ListPoliciesResponse) {
    option (google.api.http) = {
      get: "/v2beta/{parent=policies/*/*}"
    };
    option (google.api.method_signature) = "parent";
  }

  // Gets a policy.
  rpc GetPolicy(GetPolicyRequest) returns (Policy) {
    option (google.api.http) = {
      get: "/v2beta/{name=policies/*/*/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a policy.
  rpc CreatePolicy(CreatePolicyRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v2beta/{parent=policies/*/*}"
      body: "policy"
    };
    option (google.api.method_signature) = "parent,policy,policy_id";
    option (google.longrunning.operation_info) = {
      response_type: "Policy"
      metadata_type: "PolicyOperationMetadata"
    };
  }

  // Updates the specified policy.
  //
  // You can update only the rules and the display name for the policy.
  //
  // To update a policy, you should use a read-modify-write loop:
  //
  // 1. Use [GetPolicy][google.iam.v2beta.Policies.GetPolicy] to read the current version of the policy.
  // 2. Modify the policy as needed.
  // 3. Use `UpdatePolicy` to write the updated policy.
  //
  // This pattern helps prevent conflicts between concurrent updates.
  rpc UpdatePolicy(UpdatePolicyRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      put: "/v2beta/{policy.name=policies/*/*/*}"
      body: "policy"
    };
    option (google.longrunning.operation_info) = {
      response_type: "Policy"
      metadata_type: "PolicyOperationMetadata"
    };
  }

  // Deletes a policy. This action is permanent.
  rpc DeletePolicy(DeletePolicyRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      delete: "/v2beta/{name=policies/*/*/*}"
    };
    option (google.api.method_signature) = "name";
    option (google.longrunning.operation_info) = {
      response_type: "Policy"
      metadata_type: "PolicyOperationMetadata"
    };
  }
}

// Data for an IAM policy.
message Policy {
  // Immutable. The resource name of the `Policy`, which must be unique. Format:
  // `policies/{attachment_point}/denypolicies/{policy_id}`
  //
  //
  // The attachment point is identified by its URL-encoded full resource name,
  // which means that the forward-slash character, `/`, must be written as
  // `%2F`. For example,
  // `policies/cloudresourcemanager.googleapis.com%2Fprojects%2Fmy-project/denypolicies/my-deny-policy`.
  //
  // For organizations and folders, use the numeric ID in the full resource
  // name. For projects, requests can use the alphanumeric or the numeric ID.
  // Responses always contain the numeric ID.
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Immutable. The globally unique ID of the `Policy`. Assigned automatically when the
  // `Policy` is created.
  string uid = 2 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. The kind of the `Policy`. Always contains the value `DenyPolicy`.
  string kind = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // A user-specified description of the `Policy`. This value can be up to 63
  // characters.
  string display_name = 4;

  // A key-value map to store arbitrary metadata for the `Policy`. Keys
  // can be up to 63 characters. Values can be up to 255 characters.
  map<string, string> annotations = 5;

  // An opaque tag that identifies the current version of the `Policy`. IAM uses
  // this value to help manage concurrent updates, so they do not cause one
  // update to be overwritten by another.
  //
  // If this field is present in a [CreatePolicy][] request, the value is
  // ignored.
  string etag = 6;

  // Output only. The time when the `Policy` was created.
  google.protobuf.Timestamp create_time = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

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

  // Output only. The time when the `Policy` was deleted. Empty if the policy is not deleted.
  google.protobuf.Timestamp delete_time = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // A list of rules that specify the behavior of the `Policy`. All of the rules
  // should be of the `kind` specified in the `Policy`.
  repeated PolicyRule rules = 10;
}

// A single rule in a `Policy`.
message PolicyRule {
  oneof kind {
    // A rule for a deny policy.
    DenyRule deny_rule = 2;
  }

  // A user-specified description of the rule. This value can be up to 256
  // characters.
  string description = 1;
}

// Request message for `ListPolicies`.
message ListPoliciesRequest {
  // Required. The resource that the policy is attached to, along with the kind of policy
  // to list. Format:
  // `policies/{attachment_point}/denypolicies`
  //
  //
  // The attachment point is identified by its URL-encoded full resource name,
  // which means that the forward-slash character, `/`, must be written as
  // `%2F`. For example,
  // `policies/cloudresourcemanager.googleapis.com%2Fprojects%2Fmy-project/denypolicies`.
  //
  // For organizations and folders, use the numeric ID in the full resource
  // name. For projects, you can use the alphanumeric or the numeric ID.
  string parent = 1 [(google.api.field_behavior) = REQUIRED];

  // The maximum number of policies to return. IAM ignores this value and uses
  // the value 1000.
  int32 page_size = 2;

  // A page token received in a [ListPoliciesResponse][google.iam.v2beta.ListPoliciesResponse]. Provide this token to
  // retrieve the next page.
  string page_token = 3;
}

// Response message for `ListPolicies`.
message ListPoliciesResponse {
  // Metadata for the policies that are attached to the resource.
  repeated Policy policies = 1;

  // A page token that you can use in a [ListPoliciesRequest][google.iam.v2beta.ListPoliciesRequest] to retrieve the
  // next page. If this field is omitted, there are no additional pages.
  string next_page_token = 2;
}

// Request message for `GetPolicy`.
message GetPolicyRequest {
  // Required. The resource name of the policy to retrieve. Format:
  // `policies/{attachment_point}/denypolicies/{policy_id}`
  //
  //
  // Use the URL-encoded full resource name, which means that the forward-slash
  // character, `/`, must be written as `%2F`. For example,
  // `policies/cloudresourcemanager.googleapis.com%2Fprojects%2Fmy-project/denypolicies/my-policy`.
  //
  // For organizations and folders, use the numeric ID in the full resource
  // name. For projects, you can use the alphanumeric or the numeric ID.
  string name = 1 [(google.api.field_behavior) = REQUIRED];
}

// Request message for `CreatePolicy`.
message CreatePolicyRequest {
  // Required. The resource that the policy is attached to, along with the kind of policy
  // to create. Format: `policies/{attachment_point}/denypolicies`
  //
  //
  // The attachment point is identified by its URL-encoded full resource name,
  // which means that the forward-slash character, `/`, must be written as
  // `%2F`. For example,
  // `policies/cloudresourcemanager.googleapis.com%2Fprojects%2Fmy-project/denypolicies`.
  //
  // For organizations and folders, use the numeric ID in the full resource
  // name. For projects, you can use the alphanumeric or the numeric ID.
  string parent = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The policy to create.
  Policy policy = 2 [(google.api.field_behavior) = REQUIRED];

  // The ID to use for this policy, which will become the final component of
  // the policy's resource name. The ID must contain 3 to 63 characters. It can
  // contain lowercase letters and numbers, as well as dashes (`-`) and periods
  // (`.`). The first character must be a lowercase letter.
  string policy_id = 3;
}

// Request message for `UpdatePolicy`.
message UpdatePolicyRequest {
  // Required. The policy to update.
  //
  // To prevent conflicting updates, the `etag` value must match the value that
  // is stored in IAM. If the `etag` values do not match, the request fails with
  // a `409` error code and `ABORTED` status.
  Policy policy = 1 [(google.api.field_behavior) = REQUIRED];
}

// Request message for `DeletePolicy`.
message DeletePolicyRequest {
  // Required. The resource name of the policy to delete. Format:
  // `policies/{attachment_point}/denypolicies/{policy_id}`
  //
  //
  // Use the URL-encoded full resource name, which means that the forward-slash
  // character, `/`, must be written as `%2F`. For example,
  // `policies/cloudresourcemanager.googleapis.com%2Fprojects%2Fmy-project/denypolicies/my-policy`.
  //
  // For organizations and folders, use the numeric ID in the full resource
  // name. For projects, you can use the alphanumeric or the numeric ID.
  string name = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The expected `etag` of the policy to delete. If the value does not match
  // the value that is stored in IAM, the request fails with a `409` error code
  // and `ABORTED` status.
  //
  // If you omit this field, the policy is deleted regardless of its current
  // `etag`.
  string etag = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Metadata for long-running `Policy` operations.
message PolicyOperationMetadata {
  // Timestamp when the `google.longrunning.Operation` was created.
  google.protobuf.Timestamp create_time = 1;
}
