chromium/components/enterprise/common/proto/connectors.proto

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

syntax = "proto2";

option optimize_for = LITE_RUNTIME;

package enterprise_connectors;

// For ClientDownloadRequest.
import "components/safe_browsing/core/common/proto/csd.proto";

// Which connector is calling BinaryUploadService so that the proper rules can
// be triggered.  BinaryUploadService also uses this value to find the URL that
// the payload should be uploaded to.
//
// The values in this enum can be extended in future versions of Chrome to
// support new analysis connectors.
enum AnalysisConnector {
  ANALYSIS_CONNECTOR_UNSPECIFIED = 0;
  FILE_DOWNLOADED = 1;
  FILE_ATTACHED = 2;
  BULK_DATA_ENTRY = 3;
  PRINT = 4;
  FILE_TRANSFER = 5;
}

message ContentMetaData {
  // The URL containing the file download/upload or to which web content is
  // being uploaded.
  optional string url = 1;

  // Name of file on user system (if applicable).
  optional string filename = 2;

  // Sha256 digest of file.
  optional string digest = 3;

  // Specifically for the download case.
  optional safe_browsing.ClientDownloadRequest csd = 4;

  // Optional email address of user.  This field may be empty if the user
  // is not signed in.
  optional string email = 5;

  // MimeType of the field as detected by Chrome.
  optional string content_type = 6;

  // Source information, e.g., url or path.
  optional string source = 7;

  // Destination information, e.g., url or path.
  optional string destination = 8;

  // Name of tab title.
  optional string tab_title = 9;

  // URL of the tab. Only different from `url` for downloads.
  optional string tab_url = 10;

  // Empty for non-print actions.
  message PrintMetadata {
    optional string printer_name = 1;

    enum PrinterType {
      UNKNOWN = 0;
      CLOUD = 1;
      LOCAL = 2;
    }
    optional PrinterType printer_type = 2;
  }
  optional PrintMetadata print_metadata = 11;

  // Password for an encrypted archive.
  optional bytes decryption_key = 12;
}

message ClientMetadata {
  // Describes the browser uploading a scan request.
  message Browser {
    optional string browser_id = 1;
    optional string user_agent = 2;
    optional string chrome_version = 3;

    // This is omitted on scans triggered at the profile level.
    optional string machine_user = 4;
  };
  optional Browser browser = 1;

  // Describes the device uploading a scan request. This is omitted on scans
  // triggered at the profile level.
  message Device {
    optional string dm_token = 1;
    optional string client_id = 2;
    optional string os_version = 3;
    optional string os_platform = 4;
    optional string name = 5;
  };
  optional Device device = 2;

  // Describes the profile uploading a scan request.
  message Profile {
    optional string dm_token = 1;
    optional string gaia_email = 2;
    optional string profile_path = 3;
    optional string profile_name = 4;
    optional string client_id = 5;

    reserved 6;
  };
  optional Profile profile = 3;

  // True if the request comes from a Managed Guest Session on ChromeOS. False
  // in all other cases.
  optional bool is_chrome_os_managed_guest_session = 4;
};

// Analysis request sent from chrome to backend.
// The proto here is the source of truth; the copy in the LCAC Github repo
// should always be in sync with it (https://github.com/chromium/content_analysis_sdk/blob/main/proto/content_analysis/sdk/analysis.proto)
message ContentAnalysisRequest {
  // The TokenID for Enterprise-enrolled devices.  This identifies a specific
  // chrome instance.
  optional string device_token = 1;

  // Firebase Cloud Messaging token used to notify this client of the verdict.
  // This identifies a specific chrome instance.
  optional string fcm_notification_token = 2;

  // Token used to correlate requests and responses. This is different than the
  // FCM token in that it is unique for each request.
  optional string request_token = 5;

  // Which enterprise connector fired this request.
  optional AnalysisConnector analysis_connector = 9;

  // Information about the data that triggered the content analysis request.
  optional ContentMetaData request_data = 10;

  // The tags configured for the URL that triggered the content analysis.
  repeated string tags = 11;

  // Additional information about the browser, device or profile so events can
  // be reported with device/user identifiable information.
  optional ClientMetadata client_metadata = 12;

  oneof content_data {
    // The text content to analyze in local content analysis request. This field
    // is mutually exclusive with file_path.
    string text_content = 13;

    // The full path to the file to analyze in local content analysis request.
    // The path is expressed in a platform dependent way. This field is mutually
    // exclusive with text_content.
    string file_path = 14;
  }

  // The absolute deadline (timestamp in UTC Epoch time) that Chrome will wait
  // until a response from the agent is received.
  optional int64 expires_at = 15;

  // ID for keeping track of analysis requests that belong to the same user
  // action.
  optional string user_action_id = 16;

  // Count of analysis requests that belong to the same user action.
  optional int64 user_action_requests_count = 17;

  // Indicates the exact reason the request was created, ie which user action
  // led to a data transfer.
  enum Reason {
    UNKNOWN = 0;

    // Only possible for the `FILE_ATTACHED` and `BULK_DATA_ENTRY` actions.
    CLIPBOARD_PASTE = 1;
    DRAG_AND_DROP = 2;

    // Only possible for the `FILE_ATTACHED` action.
    FILE_PICKER_DIALOG = 3;

    // Only possible for the `PRINT` analysis connector.
    PRINT_PREVIEW_PRINT = 4;
    SYSTEM_DIALOG_PRINT = 5;

    // Only possible for the `FILE_DOWNLOADED` analysis connector.
    NORMAL_DOWNLOAD = 6;
    SAVE_AS_DOWNLOAD = 7;
  }
  optional Reason reason = 19;

  // Indicates whether request is blocking until verdict given.
  optional bool blocking = 20;

  // Indicates whether the request requires a metadata verdict (applicable to
  // resumable metadata request only).
  //
  // The field is set to true when Chrome sends the metadata of files larger
  // than 50MB or encrypted, because it expects a block or allow verdict from
  // WebProtect right away, and cannot upload full content.
  optional bool require_metadata_verdict = 21;

  // Reserved to make sure there is no overlap with DeepScanningClientRequest.
  reserved 3, 4, 6 to 8;
}

// Scanning response sent from backend to Chrome.
message ContentAnalysisResponse {
  // Token used to correlate requests and responses. Corresponds to field in
  // ContentAnalysisRequest with the same name.
  optional string request_token = 1;

  // Represents the analysis result from a given tag.
  message Result {
    optional string tag = 1;

    // The status of this result.
    enum Status {
      STATUS_UNKNOWN = 0;
      SUCCESS = 1;
      FAILURE = 2;
    }
    optional Status status = 2;

    message CustomMessage {
      option deprecated = true;

      // An admin-provided url that should lead to a page where the user can
      // learn more about the restrictions in place in their organization.
      optional string learn_more_url = 1;
      // An admin-provided message that will be shown to the user when a scan
      // results is not clean. This message should not be more than 200
      // characters long.
      optional string message = 2;
    }

    // Identifies the detection rules that were triggered by the analysis.
    // Only relevant when status is SUCCESS.
    message TriggeredRule {
      enum Action {
        ACTION_UNSPECIFIED = 0;
        REPORT_ONLY = 1;
        WARN = 2;
        BLOCK = 3;
      }
      optional Action action = 1;
      optional string rule_name = 2;
      optional string rule_id = 3;

      // This represents text segment in a custom message defined for DLP
      // rule. For ex: “Please learn more (here)[link] and (here)[link]"
      // is broken into 4 segments.
      message CustomRuleMessageSegment {
        // Required. Text to be displayed in this segment.
        optional string text = 1;

        // Optional. Link to external resource, such as a company's
        // communication policy. This is supposed to be hyperlink on text
        // field above.
        optional string link = 2;
      }

      // This represents the custom rule message defined by admins to be shown
      // to users if the rule is triggered.
      message CustomRuleMessage {
        // Ordered list of text segments comprised of plain text and URLs. These
        // combined represent the custom rule message.
        repeated CustomRuleMessageSegment message_segments = 1;
      }

      // This field contains a custom message that is specific to the rules
      // triggered by this scan, if any. This messages can be shown in addition
      // to the OU-based message found in the client-side policy or at the
      // top-level of the Result message.
      optional CustomMessage custom_message = 4 [deprecated = true];
      // Matched URL Category of the URL.
      optional string url_category = 5;

      // If provided, this field contains a custom message that should be
      // displayed instead of the default one. This is set by admins in Rule
      // definition UI. This is set by admins in Rule definition UI.
      optional CustomRuleMessage custom_rule_message = 6;
    }
    repeated TriggeredRule triggered_rules = 3;

    reserved 4, 5, 6;

    // This field is meant to override the OU-based custom messages set in the
    // client-side policies. When the result requires a
    // warning, if this field has a value it's the one that will be displayed to
    // the user, otherwise the client-side policy's custom message will be used.
    // TODO(b/316008309): Cleanup code once new custom message rolled out.
    optional CustomMessage custom_message = 7 [deprecated = true];

    enum StatusErrorMessage {
      STATUS_ERROR_MESSAGE_UNSPECIFIED = 0;
      DECRYPTION_FAILED = 1;
    }
    optional StatusErrorMessage status_error_message = 8;
  }
  repeated Result results = 4;

  // Reserved to make sure there is no overlap with DeepScanningClientResponse.
  reserved 2 to 3;
}

// An Acknowledgement is sent by the browser following the receipt of a response
// from the agent.
message ContentAnalysisAcknowledgement {
  // Token used to correlate with the corresponding request and response.
  optional string request_token = 1;

  // The action taken by google Chrome with the content analysis response.
  enum Status {
    // The response was handled as specified by the agent.
    SUCCESS = 1;

    // The response from the agent was not properly formatted.
    INVALID_RESPONSE = 2;

    // The response from the agent was too late and Google Chrome took the
    // default action.
    TOO_LATE = 3;
  };
  optional Status status = 2;

  // The final action that chrome took with this request.  This may be different
  // from the action specified in the response if the response was too late or
  // if the original request was part of a user action whose overall final
  // differed from the action of this particular request.
  enum FinalAction {
    ACTION_UNSPECIFIED = 0;
    ALLOW = 1;
    REPORT_ONLY = 2;
    WARN = 3;
    BLOCK = 4;
  };
  optional FinalAction final_action = 3;
}