// Copyright 2020 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.identity.accesscontextmanager.v1;

import "google/protobuf/timestamp.proto";
import "google/api/annotations.proto";

option csharp_namespace = "Google.Identity.AccessContextManager.V1";
option go_package = "google.golang.org/genproto/googleapis/identity/accesscontextmanager/v1;accesscontextmanager";
option java_multiple_files = true;
option java_outer_classname = "ServicePerimeterProto";
option java_package = "com.google.identity.accesscontextmanager.v1";
option php_namespace = "Google\\Identity\\AccessContextManager\\V1";
option ruby_package = "Google::Identity::AccessContextManager::V1";
option objc_class_prefix = "GACM";

// `ServicePerimeter` describes a set of Google Cloud resources which can freely
// import and export data amongst themselves, but not export outside of the
// `ServicePerimeter`. If a request with a source within this `ServicePerimeter`
// has a target outside of the `ServicePerimeter`, the request will be blocked.
// Otherwise the request is allowed. There are two types of Service Perimeter -
// Regular and Bridge. Regular Service Perimeters cannot overlap, a single
// Google Cloud project can only belong to a single regular Service Perimeter.
// Service Perimeter Bridges can contain only Google Cloud projects as members,
// a single Google Cloud project may belong to multiple Service Perimeter
// Bridges.
message ServicePerimeter {
  // Specifies the type of the Perimeter. There are two types: regular and
  // bridge. Regular Service Perimeter contains resources, access levels, and
  // restricted services. Every resource can be in at most ONE
  // regular Service Perimeter.
  //
  // In addition to being in a regular service perimeter, a resource can also
  // be in zero or more perimeter bridges.  A perimeter bridge only contains
  // resources.  Cross project operations are permitted if all effected
  // resources share some perimeter (whether bridge or regular). Perimeter
  // Bridge does not contain access levels or services: those are governed
  // entirely by the regular perimeter that resource is in.
  //
  // Perimeter Bridges are typically useful when building more complex toplogies
  // with many independent perimeters that need to share some data with a common
  // perimeter, but should not be able to share data among themselves.
  enum PerimeterType {
    // Regular Perimeter.
    PERIMETER_TYPE_REGULAR = 0;

    // Perimeter Bridge.
    PERIMETER_TYPE_BRIDGE = 1;
  }

  // Required. Resource name for the ServicePerimeter.  The `short_name`
  // component must begin with a letter and only include alphanumeric and '_'.
  // Format: `accessPolicies/{policy_id}/servicePerimeters/{short_name}`
  string name = 1;

  // Human readable title. Must be unique within the Policy.
  string title = 2;

  // Description of the `ServicePerimeter` and its use. Does not affect
  // behavior.
  string description = 3;

  // Output only. Time the `ServicePerimeter` was created in UTC.
  google.protobuf.Timestamp create_time = 4;

  // Output only. Time the `ServicePerimeter` was updated in UTC.
  google.protobuf.Timestamp update_time = 5;

  // Perimeter type indicator. A single project is
  // allowed to be a member of single regular perimeter, but multiple service
  // perimeter bridges. A project cannot be a included in a perimeter bridge
  // without being included in regular perimeter. For perimeter bridges,
  // the restricted service list as well as access level lists must be
  // empty.
  PerimeterType perimeter_type = 6;

  // Current ServicePerimeter configuration. Specifies sets of resources,
  // restricted services and access levels that determine perimeter
  // content and boundaries.
  ServicePerimeterConfig status = 7;

  // Proposed (or dry run) ServicePerimeter configuration. This configuration
  // allows to specify and test ServicePerimeter configuration without enforcing
  // actual access restrictions. Only allowed to be set when the
  // "use_explicit_dry_run_spec" flag is set.
  ServicePerimeterConfig spec = 8;

  // Use explicit dry run spec flag. Ordinarily, a dry-run spec implicitly
  // exists  for all Service Perimeters, and that spec is identical to the
  // status for those Service Perimeters. When this flag is set, it inhibits the
  // generation of the implicit spec, thereby allowing the user to explicitly
  // provide a configuration ("spec") to use in a dry-run version of the Service
  // Perimeter. This allows the user to test changes to the enforced config
  // ("status") without actually enforcing them. This testing is done through
  // analyzing the differences between currently enforced and suggested
  // restrictions. use_explicit_dry_run_spec must bet set to True if any of the
  // fields in the spec are set to non-default values.
  bool use_explicit_dry_run_spec = 9;
}

// `ServicePerimeterConfig` specifies a set of Google Cloud resources that
// describe specific Service Perimeter configuration.
message ServicePerimeterConfig {
  // Specifies how APIs are allowed to communicate within the Service
  // Perimeter.
  message VpcAccessibleServices {
    // Whether to restrict API calls within the Service Perimeter to the list of
    // APIs specified in 'allowed_services'.
    bool enable_restriction = 1;

    // The list of APIs usable within the Service Perimeter. Must be empty
    // unless 'enable_restriction' is True.
    repeated string allowed_services = 2;
  }

  // A list of Google Cloud resources that are inside of the service perimeter.
  // Currently only projects are allowed. Format: `projects/{project_number}`
  repeated string resources = 1;

  // A list of `AccessLevel` resource names that allow resources within the
  // `ServicePerimeter` to be accessed from the internet. `AccessLevels` listed
  // must be in the same policy as this `ServicePerimeter`. Referencing a
  // nonexistent `AccessLevel` is a syntax error. If no `AccessLevel` names are
  // listed, resources within the perimeter can only be accessed via Google
  // Cloud calls with request origins within the perimeter. Example:
  // `"accessPolicies/MY_POLICY/accessLevels/MY_LEVEL"`.
  // For Service Perimeter Bridge, must be empty.
  repeated string access_levels = 2;

  // Google Cloud services that are subject to the Service Perimeter
  // restrictions. For example, if `storage.googleapis.com` is specified, access
  // to the storage buckets inside the perimeter must meet the perimeter's
  // access restrictions.
  repeated string restricted_services = 4;

  // Configuration for APIs allowed within Perimeter.
  VpcAccessibleServices vpc_accessible_services = 10;
}
