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

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

option go_package = "cloud.google.com/go/securityposture/apiv1/securityposturepb;securityposturepb";
option java_multiple_files = true;
option java_outer_classname = "OrgPolicyConfigProto";
option java_package = "com.google.cloud.securityposture.v1";

// A rule used to express this policy.
message PolicyRule {
  // A message that holds specific allowed and denied values.
  // This message can define specific values and subtrees of the Resource
  // Manager resource hierarchy (`Organizations`, `Folders`, `Projects`) that
  // are allowed or denied. This is achieved by using the `under:` and
  // optional `is:` prefixes.
  // The `under:` prefix is used to denote resource subtree values.
  // The `is:` prefix is used to denote specific values, and is required only
  // if the value contains a ":". Values prefixed with "is:" are treated the
  // same as values with no prefix.
  // Ancestry subtrees must be in one of the following formats:
  //
  // - `projects/<project-id>` (for example, `projects/tokyo-rain-123`)
  // - `folders/<folder-id>` (for example, `folders/1234`)
  // - `organizations/<organization-id>` (for example, `organizations/1234`)
  //
  // The `supports_under` field of the associated `Constraint`  defines
  // whether ancestry prefixes can be used.
  message StringValues {
    // List of values allowed at this resource.
    repeated string allowed_values = 1;

    // List of values denied at this resource.
    repeated string denied_values = 2;
  }

  oneof kind {
    // List of values to be used for this policy rule. This field can be set
    // only in policies for list constraints.
    StringValues values = 1;

    // Setting this to true means that all values are allowed. This field can
    // be set only in policies for list constraints.
    bool allow_all = 2;

    // Setting this to true means that all values are denied. This field can
    // be set only in policies for list constraints.
    bool deny_all = 3;

    // If `true`, then the policy is enforced. If `false`, then any
    // configuration is acceptable.
    // This field can be set only in policies for boolean constraints.
    bool enforce = 4;
  }

  // A condition which determines whether this rule is used
  // in the evaluation of the policy. When set, the `expression` field in
  // the `Expr' must include from 1 to 10 subexpressions, joined by the "||"
  // or "&&" operators. Each subexpression must be of the form
  // "resource.matchTag('<ORG_ID>/tag_key_short_name,
  // 'tag_value_short_name')" or "resource.matchTagId('tagKeys/key_id',
  // 'tagValues/value_id')" where key_name and value_name are the resource
  // names for Label Keys and Values. These names are available from the Tag
  // Manager Service. An example expression is:
  // "resource.matchTag('123456789/environment,
  // 'prod')" or "resource.matchTagId('tagKeys/123',
  // 'tagValues/456')".
  google.type.Expr condition = 5;
}

// A custom constraint defined by customers which can *only* be applied to the
// given resource types and organization.
//
// By creating a custom constraint, customers can apply policies of this
// custom constraint. *Creating a custom constraint itself does NOT apply any
// policy enforcement*.
message CustomConstraint {
  // The operation for which this constraint will be applied. To apply this
  // constraint only when creating new VMs, the `method_types` should be
  // `CREATE` only. To apply this constraint when creating or deleting
  // VMs, the `method_types` should be `CREATE` and `DELETE`.
  //
  // `UPDATE` only custom constraints are not supported. Use `CREATE` or
  // `CREATE, UPDATE`.
  enum MethodType {
    // Unspecified. Results in an error.
    METHOD_TYPE_UNSPECIFIED = 0;

    // Constraint applied when creating the resource.
    CREATE = 1;

    // Constraint applied when updating the resource.
    UPDATE = 2;

    // Constraint applied when deleting the resource.
    // Not supported yet.
    DELETE = 3;
  }

  // Allow or deny type.
  enum ActionType {
    // Unspecified. Results in an error.
    ACTION_TYPE_UNSPECIFIED = 0;

    // Allowed action type.
    ALLOW = 1;

    // Deny action type.
    DENY = 2;
  }

  // Immutable. Name of the constraint. This is unique within the organization.
  // Format of the name should be
  //
  // -
  // `organizations/{organization_id}/customConstraints/{custom_constraint_id}`
  //
  // Example: `organizations/123/customConstraints/custom.createOnlyE2TypeVms`
  //
  // The max length is 70 characters and the minimum length is 1. Note that the
  // prefix `organizations/{organization_id}/customConstraints/` is not counted.
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Immutable. The resource instance type on which this policy applies. Format
  // will be of the form : `<canonical service name>/<type>` Example:
  //
  //  - `compute.googleapis.com/Instance`.
  repeated string resource_types = 2 [(google.api.field_behavior) = IMMUTABLE];

  // All the operations being applied for this constraint.
  repeated MethodType method_types = 3;

  // Org policy condition/expression. For example:
  // `resource.instanceName.matches("[production|test]_.*_(\d)+")` or,
  // `resource.management.auto_upgrade == true`
  //
  // The max length of the condition is 1000 characters.
  string condition = 4;

  // Allow or deny type.
  ActionType action_type = 5;

  // One line display name for the UI.
  // The max length of the display_name is 200 characters.
  string display_name = 6;

  // Detailed information about this custom policy constraint.
  // The max length of the description is 2000 characters.
  string description = 7;

  // Output only. The last time this custom constraint was updated. This
  // represents the last time that the `CreateCustomConstraint` or
  // `UpdateCustomConstraint` RPC was called
  google.protobuf.Timestamp update_time = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];
}
