// 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.cloud.policytroubleshooter.v1;

import "google/api/field_behavior.proto";
import "google/iam/v1/policy.proto";
import "google/type/expr.proto";

option csharp_namespace = "Google.Cloud.PolicyTroubleshooter.V1";
option go_package = "cloud.google.com/go/policytroubleshooter/apiv1/policytroubleshooterpb;policytroubleshooterpb";
option php_namespace = "Google\\Cloud\\PolicyTroubleshooter\\V1";
option ruby_package = "Google::Cloud::PolicyTroubleshooter::V1";

// Information about the principal, resource, and permission to check.
message AccessTuple {
  // Required. The principal whose access you want to check, in the form of
  // the email address that represents that principal. For example,
  // `alice@example.com` or
  // `my-service-account@my-project.iam.gserviceaccount.com`.
  //
  // The principal must be a Google Account or a service account. Other types of
  // principals are not supported.
  string principal = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The full resource name that identifies the resource. For example,
  // `//compute.googleapis.com/projects/my-project/zones/us-central1-a/instances/my-instance`.
  //
  // For examples of full resource names for Google Cloud services, see
  // https://cloud.google.com/iam/help/troubleshooter/full-resource-names.
  string full_resource_name = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The IAM permission to check for the specified principal and
  // resource.
  //
  // For a complete list of IAM permissions, see
  // https://cloud.google.com/iam/help/permissions/reference.
  //
  // For a complete list of predefined IAM roles and the permissions in each
  // role, see https://cloud.google.com/iam/help/roles/reference.
  string permission = 3 [(google.api.field_behavior) = REQUIRED];
}

// Details about how a specific IAM [Policy][google.iam.v1.Policy] contributed
// to the access check.
message ExplainedPolicy {
  // Indicates whether _this policy_ provides the specified permission to the
  // specified principal for the specified resource.
  //
  // This field does _not_ indicate whether the principal actually has the
  // permission for the resource. There might be another policy that overrides
  // this policy. To determine whether the principal actually has the
  // permission, use the `access` field in the
  // [TroubleshootIamPolicyResponse][IamChecker.TroubleshootIamPolicyResponse].
  AccessState access = 1;

  // The full resource name that identifies the resource. For example,
  // `//compute.googleapis.com/projects/my-project/zones/us-central1-a/instances/my-instance`.
  //
  // If the sender of the request does not have access to the policy, this field
  // is omitted.
  //
  // For examples of full resource names for Google Cloud services, see
  // https://cloud.google.com/iam/help/troubleshooter/full-resource-names.
  string full_resource_name = 2;

  // The IAM policy attached to the resource.
  //
  // If the sender of the request does not have access to the policy, this field
  // is empty.
  google.iam.v1.Policy policy = 3;

  // Details about how each binding in the policy affects the principal's
  // ability, or inability, to use the permission for the resource.
  //
  // If the sender of the request does not have access to the policy, this field
  // is omitted.
  repeated BindingExplanation binding_explanations = 4;

  // The relevance of this policy to the overall determination in the
  // [TroubleshootIamPolicyResponse][IamChecker.TroubleshootIamPolicyResponse].
  //
  // If the sender of the request does not have access to the policy, this field
  // is omitted.
  HeuristicRelevance relevance = 5;
}

// Details about how a binding in a policy affects a principal's ability to use
// a permission.
message BindingExplanation {
  // Whether a role includes a specific permission.
  enum RolePermission {
    // Default value. This value is unused.
    ROLE_PERMISSION_UNSPECIFIED = 0;

    // The permission is included in the role.
    ROLE_PERMISSION_INCLUDED = 1;

    // The permission is not included in the role.
    ROLE_PERMISSION_NOT_INCLUDED = 2;

    // The sender of the request is not allowed to access the binding.
    ROLE_PERMISSION_UNKNOWN_INFO_DENIED = 3;
  }

  // Whether the binding includes the principal.
  enum Membership {
    // Default value. This value is unused.
    MEMBERSHIP_UNSPECIFIED = 0;

    // The binding includes the principal. The principal can be included
    // directly or indirectly. For example:
    //
    // * A principal is included directly if that principal is listed in the
    //   binding.
    // * A principal is included indirectly if that principal is in a Google
    //   group or Google Workspace domain that is listed in the binding.
    MEMBERSHIP_INCLUDED = 1;

    // The binding does not include the principal.
    MEMBERSHIP_NOT_INCLUDED = 2;

    // The sender of the request is not allowed to access the binding.
    MEMBERSHIP_UNKNOWN_INFO_DENIED = 3;

    // The principal is an unsupported type. Only Google Accounts and service
    // accounts are supported.
    MEMBERSHIP_UNKNOWN_UNSUPPORTED = 4;
  }

  // Details about whether the binding includes the principal.
  message AnnotatedMembership {
    // Indicates whether the binding includes the principal.
    Membership membership = 1;

    // The relevance of the principal's status to the overall determination for
    // the binding.
    HeuristicRelevance relevance = 2;
  }

  // Required. Indicates whether _this binding_ provides the specified
  // permission to the specified principal for the specified resource.
  //
  // This field does _not_ indicate whether the principal actually has the
  // permission for the resource. There might be another binding that overrides
  // this binding. To determine whether the principal actually has the
  // permission, use the `access` field in the
  // [TroubleshootIamPolicyResponse][IamChecker.TroubleshootIamPolicyResponse].
  AccessState access = 1 [(google.api.field_behavior) = REQUIRED];

  // The role that this binding grants. For example,
  // `roles/compute.serviceAgent`.
  //
  // For a complete list of predefined IAM roles, as well as the permissions in
  // each role, see https://cloud.google.com/iam/help/roles/reference.
  string role = 2;

  // Indicates whether the role granted by this binding contains the specified
  // permission.
  RolePermission role_permission = 3;

  // The relevance of the permission's existence, or nonexistence, in the role
  // to the overall determination for the entire policy.
  HeuristicRelevance role_permission_relevance = 4;

  // Indicates whether each principal in the binding includes the principal
  // specified in the request, either directly or indirectly. Each key
  // identifies a principal in the binding, and each value indicates whether the
  // principal in the binding includes the principal in the request.
  //
  // For example, suppose that a binding includes the following principals:
  //
  // * `user:alice@example.com`
  // * `group:product-eng@example.com`
  //
  // You want to troubleshoot access for `user:bob@example.com`. This user is a
  // principal of the group `group:product-eng@example.com`.
  //
  // For the first principal in the binding, the key is
  // `user:alice@example.com`, and the `membership` field in the value is set to
  // `MEMBERSHIP_NOT_INCLUDED`.
  //
  // For the second principal in the binding, the key is
  // `group:product-eng@example.com`, and the `membership` field in the value is
  // set to `MEMBERSHIP_INCLUDED`.
  map<string, AnnotatedMembership> memberships = 5;

  // The relevance of this binding to the overall determination for the entire
  // policy.
  HeuristicRelevance relevance = 6;

  // A condition expression that prevents this binding from granting access
  // unless the expression evaluates to `true`.
  //
  // To learn about IAM Conditions, see
  // https://cloud.google.com/iam/help/conditions/overview.
  google.type.Expr condition = 7;
}

// Whether a principal has a permission for a resource.
enum AccessState {
  // Default value. This value is unused.
  ACCESS_STATE_UNSPECIFIED = 0;

  // The principal has the permission.
  GRANTED = 1;

  // The principal does not have the permission.
  NOT_GRANTED = 2;

  // The principal has the permission only if a condition expression evaluates
  // to `true`.
  UNKNOWN_CONDITIONAL = 3;

  // The sender of the request does not have access to all of the policies that
  // Policy Troubleshooter needs to evaluate.
  UNKNOWN_INFO_DENIED = 4;
}

// The extent to which a single data point, such as the existence of a binding
// or whether a binding includes a specific principal, contributes to an overall
// determination.
enum HeuristicRelevance {
  // Default value. This value is unused.
  HEURISTIC_RELEVANCE_UNSPECIFIED = 0;

  // The data point has a limited effect on the result. Changing the data point
  // is unlikely to affect the overall determination.
  NORMAL = 1;

  // The data point has a strong effect on the result. Changing the data point
  // is likely to affect the overall determination.
  HIGH = 2;
}
