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

import "google/api/field_behavior.proto";
import "google/api/field_info.proto";
import "google/api/resource.proto";
import "google/protobuf/timestamp.proto";
import "google/type/expr.proto";

option csharp_namespace = "Google.Cloud.Iam.V3";
option go_package = "cloud.google.com/go/iam/apiv3/iampb;iampb";
option java_multiple_files = true;
option java_outer_classname = "PolicyBindingResourcesProto";
option java_package = "com.google.iam.v3";
option php_namespace = "Google\\Cloud\\Iam\\V3";

// IAM policy binding resource.
message PolicyBinding {
  option (google.api.resource) = {
    type: "iam.googleapis.com/PolicyBinding"
    pattern: "organizations/{organization}/locations/{location}/policyBindings/{policy_binding}"
    pattern: "folders/{folder}/locations/{location}/policyBindings/{policy_binding}"
    pattern: "projects/{project}/locations/{location}/policyBindings/{policy_binding}"
    plural: "policyBindings"
    singular: "policyBinding"
  };

  // Target is the full resource name of the resource to which the policy will
  // be bound. Immutable once set.
  message Target {
    // The different types of targets that can be bound to a policy.
    oneof target {
      // Immutable. Full Resource Name used for principal access boundary policy
      // bindings. The principal set must be directly parented by the policy
      // binding's parent or same as the parent if the target is a
      // project/folder/organization.
      //
      // Examples:
      // * For binding's parented by an organization:
      //   * Organization:
      //   `//cloudresourcemanager.googleapis.com/organizations/ORGANIZATION_ID`
      //   * Workforce Identity:
      //   `//iam.googleapis.com/locations/global/workforcePools/WORKFORCE_POOL_ID`
      //   * Workspace Identity:
      //   `//iam.googleapis.com/locations/global/workspace/WORKSPACE_ID`
      // * For binding's parented by a folder:
      //   * Folder:
      //   `//cloudresourcemanager.googleapis.com/folders/FOLDER_ID`
      // * For binding's parented by a project:
      //   * Project:
      //     * `//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER`
      //     * `//cloudresourcemanager.googleapis.com/projects/PROJECT_ID`
      //   * Workload Identity Pool:
      //   `//iam.googleapis.com/projects/PROJECT_NUMBER/locations/LOCATION/workloadIdentityPools/WORKLOAD_POOL_ID`
      string principal_set = 1 [(google.api.field_behavior) = IMMUTABLE];
    }
  }

  // Different policy kinds supported in this binding.
  enum PolicyKind {
    // Unspecified policy kind; Not a valid state
    POLICY_KIND_UNSPECIFIED = 0;

    // Principal access boundary policy kind
    PRINCIPAL_ACCESS_BOUNDARY = 1;
  }

  // Identifier. The name of the policy binding, in the format
  // `{binding_parent/locations/{location}/policyBindings/{policy_binding_id}`.
  // The binding parent is the closest Resource Manager resource (project,
  // folder, or organization) to the binding target.
  //
  // Format:
  //
  // * `projects/{project_id}/locations/{location}/policyBindings/{policy_binding_id}`
  // * `projects/{project_number}/locations/{location}/policyBindings/{policy_binding_id}`
  // * `folders/{folder_id}/locations/{location}/policyBindings/{policy_binding_id}`
  // * `organizations/{organization_id}/locations/{location}/policyBindings/{policy_binding_id}`
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Output only. The globally unique ID of the policy binding. Assigned when
  // the policy binding is created.
  string uid = 2 [
    (google.api.field_info).format = UUID4,
    (google.api.field_behavior) = OUTPUT_ONLY
  ];

  // Optional. The etag for the policy binding.
  // If this is provided on update, it must match the server's etag.
  string etag = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The description of the policy binding. Must be less than or equal
  // to 63 characters.
  string display_name = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. User-defined annotations. See
  // https://google.aip.dev/148#annotations for more details such as format and
  // size limitations
  map<string, string> annotations = 5 [(google.api.field_behavior) = OPTIONAL];

  // Required. Immutable. Target is the full resource name of the resource to
  // which the policy will be bound. Immutable once set.
  Target target = 6 [
    (google.api.field_behavior) = IMMUTABLE,
    (google.api.field_behavior) = REQUIRED
  ];

  // Immutable. The kind of the policy to attach in this binding. This field
  // must be one of the following:
  //
  // - Left empty (will be automatically set to the policy kind)
  // - The input policy kind
  PolicyKind policy_kind = 11 [(google.api.field_behavior) = IMMUTABLE];

  // Required. Immutable. The resource name of the policy to be bound. The
  // binding parent and policy must belong to the same organization.
  string policy = 7 [
    (google.api.field_behavior) = IMMUTABLE,
    (google.api.field_behavior) = REQUIRED
  ];

  // Output only. The globally unique ID of the policy to be bound.
  string policy_uid = 12 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. The condition to apply to the policy binding. When set, the
  // `expression` field in the `Expr` must include from 1 to 10 subexpressions,
  // joined by the
  // "||"(Logical OR), "&&"(Logical AND) or "!"(Logical NOT) operators and
  // cannot contain more than 250 characters.
  //
  // The condition is currently only supported when bound to policies of kind
  // principal access boundary.
  //
  // When the bound policy is a principal access boundary policy, the only
  // supported attributes in any subexpression are `principal.type` and
  // `principal.subject`. An example expression is: "principal.type ==
  // 'iam.googleapis.com/ServiceAccount'" or "principal.subject ==
  // 'bob@example.com'".
  //
  // Allowed operations for `principal.subject`:
  //
  // - `principal.subject == <principal subject string>`
  // - `principal.subject != <principal subject string>`
  // - `principal.subject in [<list of principal subjects>]`
  // - `principal.subject.startsWith(<string>)`
  // - `principal.subject.endsWith(<string>)`
  //
  // Allowed operations for `principal.type`:
  //
  // - `principal.type == <principal type string>`
  // - `principal.type != <principal type string>`
  // - `principal.type in [<list of principal types>]`
  //
  // Supported principal types are Workspace, Workforce Pool, Workload Pool and
  // Service Account. Allowed string must be one of:
  //
  // - iam.googleapis.com/WorkspaceIdentity
  // - iam.googleapis.com/WorkforcePoolIdentity
  // - iam.googleapis.com/WorkloadPoolIdentity
  // - iam.googleapis.com/ServiceAccount
  google.type.Expr condition = 8 [(google.api.field_behavior) = OPTIONAL];

  // Output only. The time when the policy binding was created.
  google.protobuf.Timestamp create_time = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time when the policy binding was most recently updated.
  google.protobuf.Timestamp update_time = 10
      [(google.api.field_behavior) = OUTPUT_ONLY];
}
