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

import "google/protobuf/any.proto";
import "google/protobuf/struct.proto";
import "google/rpc/context/attribute_context.proto";
import "google/rpc/status.proto";

option cc_enable_arenas = true;
option go_package = "google.golang.org/genproto/googleapis/cloud/audit;audit";
option java_multiple_files = true;
option java_outer_classname = "AuditLogProto";
option java_package = "com.google.cloud.audit";

// Common audit log format for Google Cloud Platform API operations.
message AuditLog {
  // The name of the API service performing the operation. For example,
  // `"datastore.googleapis.com"`.
  string service_name = 7;

  // The name of the service method or operation.
  // For API calls, this should be the name of the API method.
  // For example,
  //
  //     "google.datastore.v1.Datastore.RunQuery"
  //     "google.logging.v1.LoggingService.DeleteLog"
  string method_name = 8;

  // The resource or collection that is the target of the operation.
  // The name is a scheme-less URI, not including the API service name.
  // For example:
  //
  //     "shelves/SHELF_ID/books"
  //     "shelves/SHELF_ID/books/BOOK_ID"
  string resource_name = 11;

  // The resource location information.
  ResourceLocation resource_location = 20;

  // The resource's original state before mutation. Present only for
  // operations which have successfully modified the targeted resource(s).
  // In general, this field should contain all changed fields, except those
  // that are already been included in `request`, `response`, `metadata` or
  // `service_data` fields.
  // When the JSON object represented here has a proto equivalent,
  // the proto name will be indicated in the `@type` property.
  google.protobuf.Struct resource_original_state = 19;

  // The number of items returned from a List or Query API method,
  // if applicable.
  int64 num_response_items = 12;

  // The status of the overall operation.
  google.rpc.Status status = 2;

  // Authentication information.
  AuthenticationInfo authentication_info = 3;

  // Authorization information. If there are multiple
  // resources or permissions involved, then there is
  // one AuthorizationInfo element for each {resource, permission} tuple.
  repeated AuthorizationInfo authorization_info = 9;

  // Metadata about the operation.
  RequestMetadata request_metadata = 4;

  // The operation request. This may not include all request parameters,
  // such as those that are too large, privacy-sensitive, or duplicated
  // elsewhere in the log record.
  // It should never include user-generated data, such as file contents.
  // When the JSON object represented here has a proto equivalent, the proto
  // name will be indicated in the `@type` property.
  google.protobuf.Struct request = 16;

  // The operation response. This may not include all response elements,
  // such as those that are too large, privacy-sensitive, or duplicated
  // elsewhere in the log record.
  // It should never include user-generated data, such as file contents.
  // When the JSON object represented here has a proto equivalent, the proto
  // name will be indicated in the `@type` property.
  google.protobuf.Struct response = 17;

  // Other service-specific data about the request, response, and other
  // information associated with the current audited event.
  google.protobuf.Struct metadata = 18;

  // Deprecated, use `metadata` field instead.
  // Other service-specific data about the request, response, and other
  // activities.
  google.protobuf.Any service_data = 15;
}

// Authentication information for the operation.
message AuthenticationInfo {
  // The email address of the authenticated user (or service account on behalf
  // of third party principal) making the request. For privacy reasons, the
  // principal email address is redacted for all read-only operations that fail
  // with a "permission denied" error.
  string principal_email = 1;

  // The authority selector specified by the requestor, if any.
  // It is not guaranteed that the principal was allowed to use this authority.
  string authority_selector = 2;

  // The third party identification (if any) of the authenticated user making
  // the request.
  // When the JSON object represented here has a proto equivalent, the proto
  // name will be indicated in the `@type` property.
  google.protobuf.Struct third_party_principal = 4;

  // The name of the service account key used to create or exchange
  // credentials for authenticating the service account making the request.
  // This is a scheme-less URI full resource name. For example:
  //
  // "//iam.googleapis.com/projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}/keys/{key}"
  string service_account_key_name = 5;

  // Identity delegation history of an authenticated service account that makes
  // the request. It contains information on the real authorities that try to
  // access GCP resources by delegating on a service account. When multiple
  // authorities present, they are guaranteed to be sorted based on the original
  // ordering of the identity delegation events.
  repeated ServiceAccountDelegationInfo service_account_delegation_info = 6;

  // String representation of identity of requesting party.
  // Populated for both first and third party identities.
  string principal_subject = 8;
}

// Authorization information for the operation.
message AuthorizationInfo {
  // The resource being accessed, as a REST-style string. For example:
  //
  //     bigquery.googleapis.com/projects/PROJECTID/datasets/DATASETID
  string resource = 1;

  // The required IAM permission.
  string permission = 2;

  // Whether or not authorization for `resource` and `permission`
  // was granted.
  bool granted = 3;

  // Resource attributes used in IAM condition evaluation. This field contains
  // resource attributes like resource type and resource name.
  //
  // To get the whole view of the attributes used in IAM
  // condition evaluation, the user must also look into
  // `AuditLog.request_metadata.request_attributes`.
  google.rpc.context.AttributeContext.Resource resource_attributes = 5;
}

// Metadata about the request.
message RequestMetadata {
  // The IP address of the caller.
  // For caller from internet, this will be public IPv4 or IPv6 address.
  // For caller from a Compute Engine VM with external IP address, this
  // will be the VM's external IP address. For caller from a Compute
  // Engine VM without external IP address, if the VM is in the same
  // organization (or project) as the accessed resource, `caller_ip` will
  // be the VM's internal IPv4 address, otherwise the `caller_ip` will be
  // redacted to "gce-internal-ip".
  // See https://cloud.google.com/compute/docs/vpc/ for more information.
  string caller_ip = 1;

  // The user agent of the caller.
  // This information is not authenticated and should be treated accordingly.
  // For example:
  //
  // +   `google-api-python-client/1.4.0`:
  //     The request was made by the Google API client for Python.
  // +   `Cloud SDK Command Line Tool apitools-client/1.0 gcloud/0.9.62`:
  //     The request was made by the Google Cloud SDK CLI (gcloud).
  // +   `AppEngine-Google; (+http://code.google.com/appengine; appid:
  // s~my-project`:
  //     The request was made from the `my-project` App Engine app.
  string caller_supplied_user_agent = 2;

  // The network of the caller.
  // Set only if the network host project is part of the same GCP organization
  // (or project) as the accessed resource.
  // See https://cloud.google.com/compute/docs/vpc/ for more information.
  // This is a scheme-less URI full resource name. For example:
  //
  //     "//compute.googleapis.com/projects/PROJECT_ID/global/networks/NETWORK_ID"
  string caller_network = 3;

  // Request attributes used in IAM condition evaluation. This field contains
  // request attributes like request time and access levels associated with
  // the request.
  //
  //
  // To get the whole view of the attributes used in IAM
  // condition evaluation, the user must also look into
  // `AuditLog.authentication_info.resource_attributes`.
  google.rpc.context.AttributeContext.Request request_attributes = 7;

  // The destination of a network activity, such as accepting a TCP connection.
  // In a multi hop network activity, the destination represents the receiver of
  // the last hop. Only two fields are used in this message, Peer.port and
  // Peer.ip. These fields are optionally populated by those services utilizing
  // the IAM condition feature.
  google.rpc.context.AttributeContext.Peer destination_attributes = 8;
}

// Location information about a resource.
message ResourceLocation {
  // The locations of a resource after the execution of the operation.
  // Requests to create or delete a location based resource must populate
  // the 'current_locations' field and not the 'original_locations' field.
  // For example:
  //
  //     "europe-west1-a"
  //     "us-east1"
  //     "nam3"
  repeated string current_locations = 1;

  // The locations of a resource prior to the execution of the operation.
  // Requests that mutate the resource's location must populate both the
  // 'original_locations' as well as the 'current_locations' fields.
  // For example:
  //
  //     "europe-west1-a"
  //     "us-east1"
  //     "nam3"
  repeated string original_locations = 2;
}

// Identity delegation history of an authenticated service account.
message ServiceAccountDelegationInfo {
  // First party identity principal.
  message FirstPartyPrincipal {
    // The email address of a Google account.
    string principal_email = 1;

    // Metadata about the service that uses the service account.
    google.protobuf.Struct service_metadata = 2;
  }

  // Third party identity principal.
  message ThirdPartyPrincipal {
    // Metadata about third party identity.
    google.protobuf.Struct third_party_claims = 1;
  }

  // Entity that creates credentials for service account and assumes its
  // identity for authentication.
  oneof Authority {
    // First party (Google) identity as the real authority.
    FirstPartyPrincipal first_party_principal = 1;

    // Third party identity as the real authority.
    ThirdPartyPrincipal third_party_principal = 2;
  }
}
