chromium/third_party/blink/public/mojom/shared_storage/shared_storage.mojom

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

module blink.mojom;

import "mojo/public/mojom/base/string16.mojom";
import "services/network/public/mojom/fetch_api.mojom";
import "third_party/blink/public/mojom/fenced_frame/fenced_frame_config.mojom";
import "third_party/blink/public/mojom/messaging/cloneable_message.mojom";
import "third_party/blink/public/mojom/origin_trial_feature/origin_trial_feature.mojom";
import "url/mojom/origin.mojom";
import "url/mojom/url.mojom";

// The input argument of the shared storage key. The data will be checked at
// mojom boundary to ensure it meets the length requirement. Avoid using this
// type if you don't intend to check the key's length.
struct SharedStorageKeyArgument {
  mojo_base.mojom.String16 data;
};

// The input argument of the shared storage value. The data will be checked at
// mojom boundary to ensure it meets the length requirement. Avoid using this
// type if you don't intend to check the value's length.
struct SharedStorageValueArgument {
  mojo_base.mojom.String16 data;
};

// Bundles a candidate URL for `RunURLSelectionOperationOnWorklet()` with any
// `reporting metadata` (map of each report event type to report URL) for
// event-level reporting.
struct SharedStorageUrlWithMetadata {
  url.mojom.Url url;
  map<string, url.mojom.Url> reporting_metadata;
};

enum SharedStorageGetStatus {
  kSuccess,
  kNotFound,
  kError,
};

// Bundles information passed to the worklet via the `privateAggregationConfig`
// parameter on `sharedStorage.run()` or `sharedStorage.selectURL()`.
struct PrivateAggregationConfig {
  url.mojom.Origin? aggregation_coordinator_origin;
  string? context_id;
  uint32 filtering_id_max_bytes;
};

// Implemented by the browser and exposed to the renderer process on a
// per-worklet basis, to allow initiating worklet operations, etc. Note that
// currently each frame can initialize at most one worklet.
// TODO: Methods in this interface should should be refactored so that all
// possible return values are semantically valid. See details in
// https://chromium.googlesource.com/chromium/src/+/main/docs/security/mojo.md#all-possible-message-values-are-semantically-valid
interface SharedStorageWorkletHost {
  // Handle sharedStorage.selectURL(): run the operation
  // previously registered by register() with matching `name`. Restrictions will
  // be checked at the renderer and enforced at the browser: the length of the
  // `urls` array is below the configured limit number
  // `kSharedStorageURLSelectionOperationInputURLSizeLimit`.
  // `serialized_data.message` is the serialization result of JavaScript value
  // SharedStorageRunOperationMethodOptions.data using
  // SerializedScriptValue::Serialize(). There's no need to sanitize
  // `serialized_data` at the browser process as the data will be only consumed
  // in an environment (i.e. the worklet) in control by the same origin.
  // `keep_alive_after_operation` indicates whether or not the worklet should be
  // kept alive after this operation finishes. `private_aggregation_config`
  // contains (optional) parameters that are passed to Private Aggregation (if
  // enabled).
  SelectURL(string name,
            array<SharedStorageUrlWithMetadata> urls_with_metadata,
            CloneableMessage serialized_data,
            bool keep_alive_after_operation,
            PrivateAggregationConfig private_aggregation_config)
      => (bool success,
          string error_message,
          FencedFrameConfig? config);

  // Handle sharedStorage.run(): run the operation previously
  // registered by register() with matching `name`. `serialized_data.message` is
  // the serialization result of JavaScript value
  // SharedStorageRunOperationMethodOptions.data using
  // SerializedScriptValue::Serialize(). There's no need to sanitize
  // `serialized_data` at the browser process as the data will be only consumed
  // in an environment (i.e. the worklet) in control by the same origin.
  // `keep_alive_after_operation` indicates whether or not the worklet should be
  // kept alive after this operation finishes. The only errors reported are if
  // the API is disabled or if the worklet has expired because the context
  // previously initiated either a `run()` or `selectURL()` call without
  // including the option `keepAlive: true`; other errors are suppressed and
  // reported as success.`private_aggregation_config` contains (optional)
  // parameters that are passed to Private Aggregation (if enabled).
  Run(string name,
      CloneableMessage serialized_data,
      bool keep_alive_after_operation,
      PrivateAggregationConfig private_aggregation_config)
      => (bool success,
          string error_message);
};

// SharedStorage is an origin-keyed storage mechanism where the output is
// carefully guarded to mitigate the risk of cross-site correlation.
// See https://github.com/pythagoraskitty/shared-storage/blob/main/README.md
//
// Implemented by the browser and exposed to the renderer process on a per-frame
// basis, to allow accessing the shared storage and creating the worklet.
// TODO: Methods in this interface should should be refactored so that all
// possible return values are semantically valid. See details in
// https://chromium.googlesource.com/chromium/src/+/main/docs/security/mojo.md#all-possible-message-values-are-semantically-valid
interface SharedStorageDocumentService {
  // Create the worklet, and download and load the module script in the worklet
  // environment. The worklet will be initialized with
  // `origin_trial_features` (i.e. inherit the creator document's OT features).
  CreateWorklet(url.mojom.Url script_source_url,
                url.mojom.Origin data_origin,
                network.mojom.CredentialsMode credentials_mode,
                array<OriginTrialFeature> origin_trial_features,
                pending_associated_receiver<SharedStorageWorkletHost> worklet_host)
      => (bool success,
          string error_message);

  // Handle sharedStorage.get(): get the entry at `key`, or an empty string
  // if `key` is not present. May only be called from a fenced frame with
  // network access restricted. Returns an error if the API is disabled, or if
  // the state of the fenced frame is invalid.
  SharedStorageGet(blink.mojom.SharedStorageKeyArgument key)
      => (SharedStorageGetStatus status, string error_message,
          mojo_base.mojom.String16 value);

  // Handle sharedStorage.set(): set `key`’s entry to `value`. If
  // `ignore_if_present` is true, the entry is not updated if `key` already
  // exists. The only error reported is if the API is disabled; other errors are
  // suppressed and reported as success.
  SharedStorageSet(blink.mojom.SharedStorageKeyArgument key,
                   blink.mojom.SharedStorageValueArgument value,
                   bool ignore_if_present)
      => (bool success,
          string error_message);

  // Handle sharedStorage.append(): append `value` to the entry for `key`.
  // Equivalent to "set" if the `key` is not present. The only error reported
  // is if the API is disabled; other errors are suppressed and reported as
  // success.
  SharedStorageAppend(blink.mojom.SharedStorageKeyArgument key,
                      blink.mojom.SharedStorageValueArgument value)
      => (bool success,
          string error_message);

  // Handle sharedStorage.delete(): delete the entry at the given `key`. The
  // only error reported is if the API is disabled; other errors are suppressed
  // and reported as success.
  SharedStorageDelete(blink.mojom.SharedStorageKeyArgument key)
      => (bool success,
          string error_message);

  // Handle sharedStorage.clear(): delete all entries. The only error reported
  // is if the API is disabled; other errors are suppressed and reported as
  // success.
  SharedStorageClear()
      => (bool success,
          string error_message);
};