[
  {
    "id": "B01",
    "name": "Create bucket",
    "area": "Buckets and project ownership",
    "local": "limited",
    "other": "limited",
    "description": "Creates a new bucket in a project under a globally unique name, with its location, storage class and optional default access settings.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/buckets/insert",
    "notes": "Basic creation works; project validation and full resource fields differ."
  },
  {
    "id": "B02",
    "name": "List buckets",
    "area": "Buckets and project ownership",
    "local": "available",
    "other": "limited",
    "description": "Lists the buckets in a project and returns each bucket's resource with its name, location and settings.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/buckets/list",
    "notes": "fake-gcs-server lists globally; LocalCloud filters recorded ownership."
  },
  {
    "id": "B03",
    "name": "Read bucket metadata",
    "area": "Buckets and project ownership",
    "local": "limited",
    "other": "limited",
    "description": "Reads one bucket's metadata resource, including its location, storage class, labels and settings such as versioning.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/buckets/get",
    "notes": "Metadata subset; project number and etag are placeholders."
  },
  {
    "id": "B04",
    "name": "Patch supported bucket attributes",
    "area": "Buckets and project ownership",
    "local": "limited",
    "other": "limited",
    "description": "Changes only the bucket fields included in the request, such as labels, versioning or the default object hold, and leaves the rest as they were.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/buckets/patch",
    "notes": "versioning/default hold subset."
  },
  {
    "id": "B05",
    "name": "Delete empty bucket",
    "area": "Buckets and project ownership",
    "local": "available",
    "other": "available",
    "description": "Permanently deletes a bucket after all of its objects have been removed.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/buckets/delete",
    "notes": ""
  },
  {
    "id": "B06",
    "name": "Successful bucket deletion returns empty HTTP 204",
    "area": "Buckets and project ownership",
    "local": "available",
    "other": "unavailable",
    "description": "A successful bucket deletion returns HTTP status 204 No Content with an empty response body.",
    "docs": "https://docs.cloud.google.com/storage/docs/deleting-buckets",
    "notes": ""
  },
  {
    "id": "B07",
    "name": "Reject deleting a nonempty bucket",
    "area": "Buckets and project ownership",
    "local": "available",
    "other": "available",
    "description": "Refuses to delete a bucket that still contains objects and returns an error instead of removing the bucket or its contents.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/buckets/delete",
    "notes": ""
  },
  {
    "id": "B08",
    "name": "Validate bucket names on JSON creation",
    "area": "Buckets and project ownership",
    "local": "limited",
    "other": "limited",
    "description": "Checks a new bucket name against the naming rules, such as length limits, allowed characters, no IP address form and no goog prefix.",
    "docs": "https://docs.cloud.google.com/storage/docs/buckets#naming",
    "notes": "Local format checks; not global uniqueness/domain ownership validation."
  },
  {
    "id": "B09",
    "name": "Bucket-list prefix filtering",
    "area": "Buckets and project ownership",
    "local": "available",
    "other": "available",
    "description": "Narrows a bucket listing to buckets whose names begin with a given string.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/buckets/list",
    "notes": ""
  },
  {
    "id": "B10",
    "name": "Bucket-list pagination",
    "area": "Buckets and project ownership",
    "local": "available",
    "other": "available",
    "description": "Returns a long bucket listing in pages, using a maximum page size and a page token to continue from the previous page.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/buckets/list",
    "notes": ""
  },
  {
    "id": "B11",
    "name": "Associate a new bucket with its requested project",
    "area": "Buckets and project ownership",
    "local": "limited",
    "other": "unavailable",
    "description": "Attaches a newly created bucket to the project named in the request, making that project the bucket's owner.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/buckets/insert",
    "notes": "JSON creates only; no project existence/number resolution."
  },
  {
    "id": "B12",
    "name": "Filter bucket listing by recorded project",
    "area": "Buckets and project ownership",
    "local": "limited",
    "other": "unavailable",
    "description": "Scopes a bucket listing to one project, so only buckets owned by the project named in the request are returned.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/buckets/list",
    "notes": "Exact recorded project string; seeded/gRPC-created buckets are unattributed."
  },
  {
    "id": "B16",
    "name": "Object Versioning",
    "area": "Buckets and project ownership",
    "local": "limited",
    "other": "limited",
    "description": "A bucket setting that keeps older generations of an object as noncurrent versions when it is overwritten or deleted, so they can be listed and restored.",
    "docs": "https://docs.cloud.google.com/storage/docs/object-versioning",
    "notes": "Memory only; no filesystem version history."
  },
  {
    "id": "B18",
    "name": "Default event-based object hold",
    "area": "Buckets and project ownership",
    "local": "limited",
    "other": "limited",
    "description": "A bucket setting that places an event-based hold on every new object, which cannot be deleted or replaced until the hold is released.",
    "docs": "https://docs.cloud.google.com/storage/docs/object-holds",
    "notes": "Flag stored; per-object event hold/enforcement not modeled."
  },
  {
    "id": "B19",
    "name": "Read storage layout endpoint",
    "area": "Buckets and project ownership",
    "local": "available",
    "other": "available",
    "description": "Returns where a bucket stores its data and whether hierarchical namespace is on: its name, location, location type and namespace setting.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/buckets/getStorageLayout",
    "notes": ""
  },
  {
    "id": "B21",
    "name": "List bucket ACL entries",
    "area": "Buckets and project ownership",
    "local": "available",
    "other": "available",
    "description": "Lists the access control entries on a bucket, each pairing an entity such as a user or group with a role.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/list",
    "notes": ""
  },
  {
    "id": "B22",
    "name": "Read one bucket ACL entry",
    "area": "Buckets and project ownership",
    "local": "available",
    "other": "available",
    "description": "Reads the single access control entry that grants one named entity a role on a bucket.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/get",
    "notes": ""
  },
  {
    "id": "B23",
    "name": "Insert bucket ACL entry",
    "area": "Buckets and project ownership",
    "local": "available",
    "other": "available",
    "description": "Adds an access control entry to a bucket, granting a user, group, domain or special group a role such as reader or owner.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/insert",
    "notes": ""
  },
  {
    "id": "B24",
    "name": "Update bucket ACL entry",
    "area": "Buckets and project ownership",
    "local": "available",
    "other": "available",
    "description": "Replaces the role of an existing bucket access control entry for an entity, using a full PUT request.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/update",
    "notes": ""
  },
  {
    "id": "B25",
    "name": "Delete bucket ACL entry",
    "area": "Buckets and project ownership",
    "local": "available",
    "other": "available",
    "description": "Removes the access control entry for a named entity from a bucket, ending the access that entry granted.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/delete",
    "notes": ""
  },
  {
    "id": "B26",
    "name": "Expand predefined bucket ACLs",
    "area": "Buckets and project ownership",
    "local": "limited",
    "other": "limited",
    "description": "Lets a create request name a predefined ACL set, such as private or publicRead, which expands into the full list of bucket access entries.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/buckets/insert",
    "notes": "public/authenticated scopes only."
  },
  {
    "id": "O01",
    "name": "Read object metadata",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Returns an object's metadata, such as its size, content type, checksums, generation and storage class, without its data.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/get",
    "notes": ""
  },
  {
    "id": "O02",
    "name": "Download object bytes",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Returns an object's stored bytes rather than its metadata when a get request asks for media content.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/get",
    "notes": ""
  },
  {
    "id": "O03",
    "name": "HEAD object/download requests",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Returns only the headers of an object, such as size, content type and checksums, with no body, using an XML API HEAD request.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/head-object",
    "notes": ""
  },
  {
    "id": "O04",
    "name": "Download byte ranges",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Returns only a requested byte range of an object through the Range header, useful for resuming a download or reading part of a file.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/get",
    "notes": ""
  },
  {
    "id": "O05",
    "name": "Gzip download transcoding",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Decompresses an object stored with gzip content encoding while serving it, unless the client says it accepts gzip, so the client receives the original bytes.",
    "docs": "https://docs.cloud.google.com/storage/docs/transcoding",
    "notes": ""
  },
  {
    "id": "O06",
    "name": "Preserve compressed download when requested",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Serves a gzip-encoded object still compressed, with a gzip content-encoding header, when the request accepts gzip or the object is marked no-transform.",
    "docs": "https://docs.cloud.google.com/storage/docs/transcoding",
    "notes": ""
  },
  {
    "id": "O07",
    "name": "Download response-header overrides",
    "area": "Objects, listing, metadata, and protection",
    "local": "limited",
    "other": "limited",
    "description": "Lets an authenticated download request override the content type or content disposition returned for that one response without changing the stored object.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/get-object-download",
    "notes": "Local override handling; authenticated XML/RSA restrictions differ."
  },
  {
    "id": "O08",
    "name": "List objects",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Retrieves the objects stored in a bucket as a list of object resources with their metadata.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/list",
    "notes": ""
  },
  {
    "id": "O09",
    "name": "Object-list prefix filtering",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Returns only objects whose names begin with a given prefix, for example everything under a folder-like path.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/list",
    "notes": ""
  },
  {
    "id": "O10",
    "name": "Object-list delimiter/common prefixes",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Groups object names at a delimiter, usually a slash, returning names without the delimiter as items and shared leading parts as prefixes, to mimic directories.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/list",
    "notes": ""
  },
  {
    "id": "O11",
    "name": "Object-list matchGlob filtering",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Returns only objects whose names match a glob pattern, which can use wildcards to select names across path levels.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/list",
    "notes": ""
  },
  {
    "id": "O12",
    "name": "Reject invalid matchGlob patterns",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Responds with an error when the matchGlob value in a listing request is not a valid glob pattern.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/list",
    "notes": ""
  },
  {
    "id": "O13",
    "name": "Object-list start offset",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Returns only objects whose names sort at or after the given value, an inclusive lower bound that begins a name range.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/list",
    "notes": ""
  },
  {
    "id": "O14",
    "name": "Object-list end offset",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Returns only objects whose names sort before the given value, an exclusive upper bound that ends a name range.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/list",
    "notes": ""
  },
  {
    "id": "O15",
    "name": "Include trailing delimiter objects",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "When listing with a delimiter, also returns the metadata of objects whose names end with that delimiter, in addition to listing them as prefixes.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/list",
    "notes": ""
  },
  {
    "id": "O16",
    "name": "Object-list pagination",
    "area": "Objects, listing, metadata, and protection",
    "local": "limited",
    "other": "limited",
    "description": "Returns a long object listing in pages, with a maximum page size and a page token for the next page; each page counts objects and prefixes together.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/list",
    "notes": "object-only maxResults limit does not account for prefixes."
  },
  {
    "id": "O17",
    "name": "List historical object generations",
    "area": "Objects, listing, metadata, and protection",
    "local": "limited",
    "other": "limited",
    "description": "Includes every stored generation of each object, not only the live one, as separate results ordered by increasing generation when versions are requested.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/list",
    "notes": "Memory versioning only."
  },
  {
    "id": "O18",
    "name": "Read a specified historical generation",
    "area": "Objects, listing, metadata, and protection",
    "local": "limited",
    "other": "limited",
    "description": "Reads the metadata or data of one particular generation of an object, identified by its generation number, rather than the latest version.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/get",
    "notes": "Memory versioning only."
  },
  {
    "id": "O19",
    "name": "Delete object",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Removes an object and its metadata from a bucket; with versioning or soft delete turned on, the data can remain recoverable.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/delete",
    "notes": ""
  },
  {
    "id": "O20",
    "name": "Successful object deletion returns empty HTTP 204",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "unavailable",
    "description": "A successful object deletion returns HTTP status 204 No Content with an empty response body.",
    "docs": "https://docs.cloud.google.com/storage/docs/deleting-objects",
    "notes": ""
  },
  {
    "id": "O21",
    "name": "Delete a specified object generation",
    "area": "Objects, listing, metadata, and protection",
    "local": "limited",
    "other": "limited",
    "description": "Permanently deletes one specific generation of an object by naming its generation number, leaving other generations in place.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/delete",
    "notes": "Filesystem has no history."
  },
  {
    "id": "O22",
    "name": "Copy object with copyTo",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Copies a source object to a destination name in a single request, optionally overriding metadata; the copy does not keep the source object's ACLs.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/copy",
    "notes": ""
  },
  {
    "id": "O23",
    "name": "Rewrite object with rewriteTo",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Copies a source object to a destination in one or more calls, returning a rewrite token to continue until the work is done, and can override metadata.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/rewrite",
    "notes": ""
  },
  {
    "id": "O24",
    "name": "Compose objects",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Concatenates up to 32 existing objects from one bucket into a single new object in that bucket, leaving the sources unchanged by default.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/compose",
    "notes": ""
  },
  {
    "id": "O25",
    "name": "Patch object metadata",
    "area": "Objects, listing, metadata, and protection",
    "local": "limited",
    "other": "limited",
    "description": "Updates only the metadata fields named in the request, such as custom metadata or retention, and leaves other fields unchanged.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/patch",
    "notes": "Selected mutable fields; contexts/complete retention semantics differ."
  },
  {
    "id": "O26",
    "name": "Replace object metadata using PUT objects.update",
    "area": "Objects, listing, metadata, and protection",
    "local": "limited",
    "other": "limited",
    "description": "Updates an object's metadata with a PUT request, which can change metadata fields that the request does not mention; patch is generally preferred.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/update",
    "notes": "Supported metadata subset; broader production resource not modeled."
  },
  {
    "id": "O27",
    "name": "PATCH through X-HTTP-Method-Override",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Lets a client that cannot send PATCH use a POST request with the method override header set to PATCH to apply a patch-style update.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api",
    "notes": "POST override to PATCH."
  },
  {
    "id": "O28",
    "name": "Store custom metadata entries",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Lets users attach their own key and value pairs to an object, sent as x-goog-meta headers in the XML API, and returns them with the object.",
    "docs": "https://docs.cloud.google.com/storage/docs/metadata",
    "notes": ""
  },
  {
    "id": "O29",
    "name": "Store content type",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Records the object's media type, such as image/png, which tells browsers and clients how to interpret its bytes.",
    "docs": "https://docs.cloud.google.com/storage/docs/metadata",
    "notes": ""
  },
  {
    "id": "O30",
    "name": "Store content encoding",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Records that an object's bytes are compressed, for example with gzip, while the content type still describes the underlying file.",
    "docs": "https://docs.cloud.google.com/storage/docs/metadata",
    "notes": ""
  },
  {
    "id": "O31",
    "name": "Store content disposition",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Records how a browser should present the object, such as showing it inline or offering it as a download with a given file name.",
    "docs": "https://docs.cloud.google.com/storage/docs/metadata",
    "notes": ""
  },
  {
    "id": "O32",
    "name": "Store content language",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Records the language or languages an object is intended for, using language codes such as en or fr.",
    "docs": "https://docs.cloud.google.com/storage/docs/metadata",
    "notes": ""
  },
  {
    "id": "O33",
    "name": "Store cache-control metadata",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Records caching directives such as max-age or no-transform that control whether caches may store the object and for how long.",
    "docs": "https://docs.cloud.google.com/storage/docs/metadata",
    "notes": ""
  },
  {
    "id": "O34",
    "name": "Store custom time",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Records a user-chosen timestamp on an object, used by lifecycle rules that act a number of days after that time; once set it cannot be moved earlier.",
    "docs": "https://docs.cloud.google.com/storage/docs/metadata",
    "notes": ""
  },
  {
    "id": "O35",
    "name": "Object response projection",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Controls how much of an object's metadata a response includes: full returns every property, while noAcl leaves out the owner and access control list.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/get",
    "notes": ""
  },
  {
    "id": "O36",
    "name": "Object retention mode/retain-until handling",
    "area": "Objects, listing, metadata, and protection",
    "local": "limited",
    "other": "limited",
    "description": "Sets a per-object retention mode, unlocked or locked, and a retain-until time before which the object cannot be deleted or replaced.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/patch",
    "notes": ""
  },
  {
    "id": "O37",
    "name": "List object ACL entries",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Lists the access control entries on an object, each granting an entity a role on that object.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objectAccessControls/list",
    "notes": ""
  },
  {
    "id": "O38",
    "name": "Read one object ACL entry",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Reads the single access control entry for a named entity on an object, for the latest generation or a specified one.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objectAccessControls/get",
    "notes": ""
  },
  {
    "id": "O39",
    "name": "Insert object ACL entry",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Adds an access control entry to an object, granting a user, group or special group a role such as reader or owner on it.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objectAccessControls/insert",
    "notes": ""
  },
  {
    "id": "O40",
    "name": "Update object ACL entry",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Replaces the role of an existing object access control entry for an entity, using a full PUT request.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objectAccessControls/update",
    "notes": ""
  },
  {
    "id": "O41",
    "name": "Delete object ACL entry",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Removes the access control entry for a named entity from an object, ending the access that entry granted.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objectAccessControls/delete",
    "notes": ""
  },
  {
    "id": "O42",
    "name": "Generation-specific object ACL lookup",
    "area": "Objects, listing, metadata, and protection",
    "local": "limited",
    "other": "limited",
    "description": "Looks up an object's access control entry for one specific generation of the object by passing its generation number, instead of the latest version.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objectAccessControls/get",
    "notes": "Memory history."
  },
  {
    "id": "O43",
    "name": "Predefined object ACLs on upload/copy/compose",
    "area": "Objects, listing, metadata, and protection",
    "local": "limited",
    "other": "limited",
    "description": "Applies a predefined access set such as private, publicRead or bucketOwnerRead to an object when it is uploaded, copied or composed.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/insert",
    "notes": "Emulator ACL model."
  },
  {
    "id": "O44",
    "name": "XML object listing",
    "area": "Objects, listing, metadata, and protection",
    "local": "limited",
    "other": "limited",
    "description": "Lists the objects in a bucket through the XML API as a ListBucketResult document, with Contents entries, common prefixes and truncation markers.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/get-bucket-list",
    "notes": "Basic list/prefix/delimiter; continuation/version-listing fields incomplete."
  },
  {
    "id": "O45",
    "name": "Virtual-hosted object download",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Downloads an object through the XML API from an address where the bucket name forms part of the host name and the object name is the path.",
    "docs": "https://docs.cloud.google.com/storage/docs/request-endpoints",
    "notes": ""
  },
  {
    "id": "O46",
    "name": "Path-style object download",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "available",
    "description": "Downloads an object through the XML API from an address where the bucket name is the first segment of the path after the host.",
    "docs": "https://docs.cloud.google.com/storage/docs/request-endpoints",
    "notes": ""
  },
  {
    "id": "O47",
    "name": "Virtual-hosted object DELETE route",
    "area": "Objects, listing, metadata, and protection",
    "local": "available",
    "other": "unavailable",
    "description": "Deletes an object with an XML API DELETE request sent to an address whose host name begins with the bucket name.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/delete-object",
    "notes": ""
  },
  {
    "id": "U01",
    "name": "Simple/media upload",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Uploads an object's bytes in a single request, sending no metadata, with the object name given as a query parameter.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/insert",
    "notes": ""
  },
  {
    "id": "U02",
    "name": "Multipart JSON upload",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Uploads an object's data together with its metadata in one multipart request, so content type and custom metadata are set at creation.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/insert",
    "notes": ""
  },
  {
    "id": "U03",
    "name": "Resumable upload initiation",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Starts a resumable upload by sending the object name and optional metadata, and returns a session URI that later requests use to send the data.",
    "docs": "https://docs.cloud.google.com/storage/docs/performing-resumable-uploads",
    "notes": ""
  },
  {
    "id": "U04",
    "name": "Resumable upload chunks/finalization",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Sends data to the session URI in chunks with a Content-Range header, receiving a 308 response until the final chunk completes the object with 200 or 201.",
    "docs": "https://docs.cloud.google.com/storage/docs/performing-resumable-uploads",
    "notes": ""
  },
  {
    "id": "U05",
    "name": "Resumable upload cancellation",
    "area": "Uploads and conditional operations",
    "local": "limited",
    "other": "limited",
    "description": "Cancels an unfinished resumable upload by sending DELETE to its session URI; the JSON API answers 499 and the session cannot be used again.",
    "docs": "https://docs.cloud.google.com/storage/docs/performing-resumable-uploads",
    "notes": "Handler returns JSON API's 499 status but does not invalidate the stored upload session."
  },
  {
    "id": "U08",
    "name": "Multipart form object upload",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Uploads one object from an HTML form with a POST request, where the form carries the object name, an optional signed policy and the file as its last field.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/post-object-forms",
    "notes": ""
  },
  {
    "id": "U09",
    "name": "Gzipped upload content",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Uploads content that is already gzip-compressed, usually with its content encoding set to gzip, so it is stored compressed and can be transcoded on download.",
    "docs": "https://docs.cloud.google.com/storage/docs/transcoding",
    "notes": ""
  },
  {
    "id": "U11",
    "name": "Calculate MD5 checksum",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Produces a base64 MD5 hash of an object's data, returned in its metadata, for checking integrity; composite objects do not have one.",
    "docs": "https://docs.cloud.google.com/storage/docs/data-validation",
    "notes": ""
  },
  {
    "id": "U12",
    "name": "Calculate CRC32C checksum",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Produces a CRC32C checksum of an object's data, returned in its metadata, which is the recommended hash for integrity checks.",
    "docs": "https://docs.cloud.google.com/storage/docs/data-validation",
    "notes": ""
  },
  {
    "id": "U13",
    "name": "Validate declared MD5 on upload",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Rejects an upload whose data does not match the MD5 hash declared in the request, so corrupted transfers are not stored.",
    "docs": "https://docs.cloud.google.com/storage/docs/data-validation",
    "notes": ""
  },
  {
    "id": "U14",
    "name": "Validate declared CRC32C on upload",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Rejects an upload whose data does not match the CRC32C checksum declared in the request, failing the write instead of storing corrupted data.",
    "docs": "https://docs.cloud.google.com/storage/docs/data-validation",
    "notes": ""
  },
  {
    "id": "U15",
    "name": "ifGenerationMatch precondition",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Runs a request only if the object's current generation equals the given number; zero means it succeeds only when no live object exists.",
    "docs": "https://docs.cloud.google.com/storage/docs/request-preconditions",
    "notes": ""
  },
  {
    "id": "U16",
    "name": "ifGenerationNotMatch precondition",
    "area": "Uploads and conditional operations",
    "local": "limited",
    "other": "limited",
    "description": "Runs a request only if the object's current generation differs from the given number, which guards against acting on one particular version.",
    "docs": "https://docs.cloud.google.com/storage/docs/request-preconditions",
    "notes": "Generic handler accepts missing object for some NotMatch checks."
  },
  {
    "id": "U17",
    "name": "ifMetagenerationMatch precondition",
    "area": "Uploads and conditional operations",
    "local": "limited",
    "other": "limited",
    "description": "Runs a request only if the object's metageneration equals the given number, which detects metadata changes made since it was read.",
    "docs": "https://docs.cloud.google.com/storage/docs/request-preconditions",
    "notes": "Metageneration is fixed at 1."
  },
  {
    "id": "U18",
    "name": "ifMetagenerationNotMatch precondition",
    "area": "Uploads and conditional operations",
    "local": "limited",
    "other": "limited",
    "description": "Runs a request only if the object's metageneration differs from the given number, which shows whether metadata has changed since it was last read.",
    "docs": "https://docs.cloud.google.com/storage/docs/request-preconditions",
    "notes": "Metageneration is fixed at 1."
  },
  {
    "id": "U19",
    "name": "Copy/rewrite source generation conditions",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Makes a copy or rewrite proceed only if the source object's generation matches ifSourceGenerationMatch, so the intended version is the one copied.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/rewrite",
    "notes": ""
  },
  {
    "id": "U20",
    "name": "Copy/rewrite source metageneration conditions",
    "area": "Uploads and conditional operations",
    "local": "limited",
    "other": "limited",
    "description": "Makes a copy or rewrite proceed only if the source object's metageneration matches ifSourceMetagenerationMatch.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/rewrite",
    "notes": "Fixed metageneration."
  },
  {
    "id": "U21",
    "name": "JSON batch requests",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Combines several JSON API calls into one HTTP request, up to 100 calls in a multipart body, and returns one response part for each call.",
    "docs": "https://docs.cloud.google.com/storage/docs/batch",
    "notes": ""
  },
  {
    "id": "U22",
    "name": "Inherit outer Authorization header into batch subrequests",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "unavailable",
    "description": "Applies the Authorization header of the outer batch request to every inner call unless a call sets its own, so credentials are given once.",
    "docs": "https://docs.cloud.google.com/storage/docs/batch",
    "notes": "LocalCloud copies standard Authorization; local identity headers are not GCS features."
  },
  {
    "id": "U23",
    "name": "Import x-goog-meta-* upload headers",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "available",
    "description": "Turns request headers beginning with x-goog-meta- into the custom metadata of the uploaded object, through the XML API.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/reference-headers",
    "notes": ""
  },
  {
    "id": "U24",
    "name": "Import x-amz-meta-* simple-upload headers",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "unavailable",
    "description": "Treats Amazon S3 style x-amz-meta headers on an XML API upload as custom metadata, matching x-goog-meta headers, for S3 interoperability.",
    "docs": "https://docs.cloud.google.com/storage/docs/aws-simple-migration",
    "notes": "XML S3-interoperability spelling; not full S3 support."
  },
  {
    "id": "U25",
    "name": "Preserve declared checksums across resumable chunks",
    "area": "Uploads and conditional operations",
    "local": "available",
    "other": "unavailable",
    "description": "Validates a checksum declared on the final request of a resumable upload against the whole object assembled from all of its chunks.",
    "docs": "https://docs.cloud.google.com/storage/docs/data-validation",
    "notes": "Retains full session entry."
  },
  {
    "id": "U26",
    "name": "Continue resumable upload using bearer session URI",
    "area": "Uploads and conditional operations",
    "local": "limited",
    "other": "available",
    "description": "Lets whoever holds a resumable upload's session URI continue that upload without further credentials, because the URI acts as an authentication token.",
    "docs": "https://docs.cloud.google.com/storage/docs/resumable-uploads#session-uris",
    "notes": "LocalCloud additionally checks initiating key revocation and optional callback."
  },
  {
    "id": "M01",
    "name": "JSON objects.move / moveTo endpoint",
    "area": "Same-bucket object moves",
    "local": "limited",
    "other": "unavailable",
    "description": "Renames an object within its bucket by moving it from a source name to a destination name, replacing any object already at the destination.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": "route/data movement implemented; atomicity, retention and projection gaps below."
  },
  {
    "id": "M02",
    "name": "All-or-nothing atomic object move",
    "area": "Same-bucket object moves",
    "local": "limited",
    "other": "unavailable",
    "description": "Performs the whole move as one atomic transaction, so either every step completes or no change is made.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": "locks/rollback exist; multiple disk writes are not a crash-atomic transaction."
  },
  {
    "id": "M04",
    "name": "Move source ifSourceGenerationMatch precondition",
    "area": "Same-bucket object moves",
    "local": "available",
    "other": "unavailable",
    "description": "Moves the source only when its generation matches ifSourceGenerationMatch, guarding against moving a version that changed since it was read.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": ""
  },
  {
    "id": "M05",
    "name": "Move destination ifGenerationMatch precondition",
    "area": "Same-bucket object moves",
    "local": "available",
    "other": "unavailable",
    "description": "Moves only when the live destination object has the generation given in ifGenerationMatch; zero means the destination must not already exist.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": ""
  },
  {
    "id": "M06",
    "name": "Move source ifSourceMetagenerationMatch precondition",
    "area": "Same-bucket object moves",
    "local": "limited",
    "other": "unavailable",
    "description": "Moves the source only when its metageneration matches ifSourceMetagenerationMatch, guarding against metadata changed since it was read.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": "Fixed metageneration."
  },
  {
    "id": "M07",
    "name": "Move destination ifMetagenerationMatch precondition",
    "area": "Same-bucket object moves",
    "local": "limited",
    "other": "unavailable",
    "description": "Moves only when the live destination object's metageneration matches ifMetagenerationMatch.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": "Fixed metageneration."
  },
  {
    "id": "M08",
    "name": "Preserve source metadata during move",
    "area": "Same-bucket object moves",
    "local": "available",
    "other": "unavailable",
    "description": "Keeps the source object's data and metadata on the destination, apart from its name, generation, metageneration and timestamps.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": ""
  },
  {
    "id": "M09",
    "name": "Assign fresh destination generation on move",
    "area": "Same-bucket object moves",
    "local": "available",
    "other": "unavailable",
    "description": "Gives the destination object a new generation number and resets its metageneration to 1, because the move creates a new object.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": ""
  },
  {
    "id": "M10",
    "name": "Leave data unchanged on failed move preconditions",
    "area": "Same-bucket object moves",
    "local": "available",
    "other": "unavailable",
    "description": "Leaves both the source and the destination unchanged when a move fails because a precondition is not met.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": ""
  },
  {
    "id": "M11",
    "name": "Move source notification semantics",
    "area": "Same-bucket object moves",
    "local": "limited",
    "other": "unavailable",
    "description": "Determines which Pub/Sub notification event is published for the object at its original name when a move takes it away.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": "Source delete/archive path."
  },
  {
    "id": "M12",
    "name": "Emit destination finalize event on move",
    "area": "Same-bucket object moves",
    "local": "available",
    "other": "unavailable",
    "description": "Publishes an object finalize notification for the destination object that a move creates.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": ""
  },
  {
    "id": "M13",
    "name": "Emit overwritten-destination event on move",
    "area": "Same-bucket object moves",
    "local": "available",
    "other": "unavailable",
    "description": "Publishes a delete or archive notification for an existing object at the destination name when a move replaces it.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": ""
  },
  {
    "id": "M14",
    "name": "Move source ifSourceGenerationNotMatch precondition",
    "area": "Same-bucket object moves",
    "local": "available",
    "other": "unavailable",
    "description": "Moves the source only when its generation differs from ifSourceGenerationNotMatch.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": "Metadata conditions use fixed metageneration."
  },
  {
    "id": "M15",
    "name": "Move destination ifGenerationNotMatch precondition",
    "area": "Same-bucket object moves",
    "local": "available",
    "other": "unavailable",
    "description": "Moves only when a live destination object exists whose generation differs from ifGenerationNotMatch.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": "Metadata conditions use fixed metageneration."
  },
  {
    "id": "M16",
    "name": "Move source ifSourceMetagenerationNotMatch precondition",
    "area": "Same-bucket object moves",
    "local": "limited",
    "other": "unavailable",
    "description": "Moves the source only when its metageneration differs from ifSourceMetagenerationNotMatch.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": "Metadata conditions use fixed metageneration."
  },
  {
    "id": "M17",
    "name": "Move destination ifMetagenerationNotMatch precondition",
    "area": "Same-bucket object moves",
    "local": "limited",
    "other": "unavailable",
    "description": "Moves only when the live destination object's metageneration differs from ifMetagenerationNotMatch.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/move",
    "notes": "Metadata conditions use fixed metageneration."
  },
  {
    "id": "A01",
    "name": "Enforce resource IAM permissions on JSON/XML requests",
    "area": "Access control",
    "local": "limited",
    "other": "unavailable",
    "description": "Checks that the caller holds the IAM permission each JSON or XML request needs on the bucket or object, and rejects the request if it does not.",
    "docs": "https://docs.cloud.google.com/storage/docs/access-control/iam",
    "notes": "Requires external callback; open by default; subset of permissions."
  },
  {
    "id": "A05",
    "name": "Require delete permission when overwriting",
    "area": "Access control",
    "local": "limited",
    "other": "unavailable",
    "description": "Requires the delete permission as well as create when an upload replaces an existing object.",
    "docs": "https://docs.cloud.google.com/storage/docs/access-control/iam-permissions",
    "notes": "Create + delete checks when callback configured."
  },
  {
    "id": "A06",
    "name": "Check source-read permission for compose",
    "area": "Access control",
    "local": "limited",
    "other": "unavailable",
    "description": "Requires permission to read every source object, as well as create permission on the destination, when composing objects.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/objects/compose",
    "notes": "Source get checks delegated to callback."
  },
  {
    "id": "A08",
    "name": "Use IAM administration permissions for ACL routes",
    "area": "Access control",
    "local": "limited",
    "other": "unavailable",
    "description": "Requires the IAM administration permissions to read or change ACLs on buckets and objects, such as getIamPolicy and setIamPolicy.",
    "docs": "https://docs.cloud.google.com/storage/docs/access-control/iam-permissions",
    "notes": "Callback checks selected getIamPolicy/setIamPolicy routes."
  },
  {
    "id": "A10",
    "name": "Authorize XML requests as the HMAC key's service account",
    "area": "Access control",
    "local": "limited",
    "other": "unavailable",
    "description": "Treats a request signed with an HMAC key as made by the service account or user that owns the key, so that identity's IAM permissions apply.",
    "docs": "https://docs.cloud.google.com/storage/docs/authentication/hmackeys",
    "notes": "Verified identity delegated; no complete service-account model."
  },
  {
    "id": "K01",
    "name": "Create HMAC key",
    "area": "HMAC key management",
    "local": "limited",
    "other": "unavailable",
    "description": "Creates an HMAC key for a service account and returns the key's access ID and its secret in the response.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/projects/hmacKeys/create",
    "notes": "Generates keys; validates email shape/project suffix rather than an existing Google account."
  },
  {
    "id": "K02",
    "name": "List HMAC key metadata",
    "area": "HMAC key management",
    "local": "available",
    "other": "unavailable",
    "description": "Returns metadata for the HMAC keys in a project, without their secrets.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/projects/hmacKeys/list",
    "notes": ""
  },
  {
    "id": "K03",
    "name": "Read HMAC key metadata",
    "area": "HMAC key management",
    "local": "available",
    "other": "unavailable",
    "description": "Returns the metadata of one HMAC key by its access ID, including its state and service account, but not its secret.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/projects/hmacKeys/get",
    "notes": ""
  },
  {
    "id": "K04",
    "name": "Update HMAC key active/inactive state",
    "area": "HMAC key management",
    "local": "available",
    "other": "unavailable",
    "description": "Changes an HMAC key's state to active or inactive; permanent removal is done with the delete method.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/projects/hmacKeys/update",
    "notes": ""
  },
  {
    "id": "K05",
    "name": "Delete an inactive HMAC key",
    "area": "HMAC key management",
    "local": "available",
    "other": "unavailable",
    "description": "Permanently removes an HMAC key whose state is inactive, making it unusable and unrecoverable.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/projects/hmacKeys/delete",
    "notes": ""
  },
  {
    "id": "K06",
    "name": "Reject key deletion while active",
    "area": "HMAC key management",
    "local": "available",
    "other": "unavailable",
    "description": "Returns an error if a request tries to delete an HMAC key that is still active, so a key must be made inactive first.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/projects/hmacKeys/delete",
    "notes": ""
  },
  {
    "id": "K07",
    "name": "Filter HMAC listing by service-account email",
    "area": "HMAC key management",
    "local": "available",
    "other": "unavailable",
    "description": "Narrows an HMAC key listing to the keys that belong to one service account, identified by its email address.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/projects/hmacKeys/list",
    "notes": ""
  },
  {
    "id": "K08",
    "name": "Paginate HMAC listing",
    "area": "HMAC key management",
    "local": "available",
    "other": "unavailable",
    "description": "Returns a long HMAC key listing in pages, using a maximum page size and a page token to continue.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/projects/hmacKeys/list",
    "notes": ""
  },
  {
    "id": "K09",
    "name": "Include deleted keys when requested",
    "area": "HMAC key management",
    "local": "available",
    "other": "unavailable",
    "description": "Includes keys in the DELETED state in an HMAC key listing, which are left out by default.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/projects/hmacKeys/list",
    "notes": ""
  },
  {
    "id": "K10",
    "name": "Validate update etag when supplied",
    "area": "HMAC key management",
    "local": "available",
    "other": "unavailable",
    "description": "Accepts an etag with a key update and applies the change only if it matches the key's current etag, guarding against overwriting a concurrent change.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/projects/hmacKeys/update",
    "notes": ""
  },
  {
    "id": "K11",
    "name": "Return key secret only on creation",
    "area": "HMAC key management",
    "local": "available",
    "other": "unavailable",
    "description": "Shows an HMAC key's secret only in the response that creates it; later reads return metadata alone, so a lost secret cannot be retrieved.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/projects/hmacKeys",
    "notes": ""
  },
  {
    "id": "K12",
    "name": "Enforce ten nondeleted keys per service account",
    "area": "HMAC key management",
    "local": "available",
    "other": "unavailable",
    "description": "Limits each service account to 10 HMAC keys that are not deleted; deleted keys do not count toward the limit.",
    "docs": "https://docs.cloud.google.com/storage/docs/authentication/hmackeys",
    "notes": ""
  },
  {
    "id": "H04",
    "name": "Verify GOOG1 V2 Authorization header",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Validates an Authorization header of the form GOOG1 followed by an access ID and a V2 signature computed with an HMAC key's secret.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/reference-headers",
    "notes": ""
  },
  {
    "id": "H05",
    "name": "Verify AWS V2 Authorization header",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Validates an Authorization header of the form AWS followed by an access ID and a V2 signature, as sent by S3 style clients.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/reference-headers",
    "notes": ""
  },
  {
    "id": "H06",
    "name": "Verify Google V2 HMAC signed URL",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Validates a V2 signed URL that carries GoogleAccessId, Expires and Signature query parameters and is signed with an HMAC key.",
    "docs": "https://docs.cloud.google.com/storage/docs/access-control/signed-urls-v2",
    "notes": ""
  },
  {
    "id": "H08",
    "name": "Verify GOOG4-HMAC-SHA256 Authorization header",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Validates an Authorization header that uses GOOG4-HMAC-SHA256, whose signature is made with a signing key derived from an HMAC secret.",
    "docs": "https://docs.cloud.google.com/storage/docs/authentication/signatures",
    "notes": ""
  },
  {
    "id": "H09",
    "name": "Verify AWS4-HMAC-SHA256 Authorization header",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Validates an Authorization header that uses AWS4-HMAC-SHA256, the Amazon S3 style V4 signature accepted for XML API interoperability.",
    "docs": "https://docs.cloud.google.com/storage/docs/authentication/signatures",
    "notes": ""
  },
  {
    "id": "H10",
    "name": "Verify Google V4 HMAC signed URL",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Validates a V4 signed URL made with GOOG4-HMAC-SHA256 and its X-Goog-Algorithm, Credential, Date, Expires, SignedHeaders and Signature query parameters.",
    "docs": "https://docs.cloud.google.com/storage/docs/authentication/signatures",
    "notes": ""
  },
  {
    "id": "H11",
    "name": "Verify AWS V4 HMAC signed URL",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Validates a signed URL made with the AWS4-HMAC-SHA256 algorithm of Amazon S3 style V4 signing, accepted by the XML API for interoperability.",
    "docs": "https://docs.cloud.google.com/storage/docs/authentication/signatures",
    "notes": ""
  },
  {
    "id": "H12",
    "name": "Reject expired HMAC signed URLs",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Rejects an HMAC signed URL whose expiration time has already passed, so access ends when the URL expires.",
    "docs": "https://docs.cloud.google.com/storage/docs/access-control/signed-urls",
    "notes": ""
  },
  {
    "id": "H13",
    "name": "Check HMAC header request time window",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Checks that the timestamp in a signed request's date header falls within an allowed window around the server's current time, rejecting stale or future requests.",
    "docs": "https://docs.cloud.google.com/storage/docs/authentication/signatures",
    "notes": "15 minutes."
  },
  {
    "id": "H14",
    "name": "Verify V4 signed headers",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Checks that the signature covers the headers named in the signed headers list, including the mandatory host header, so those headers cannot be altered.",
    "docs": "https://docs.cloud.google.com/storage/docs/authentication/canonical-requests",
    "notes": "Host required."
  },
  {
    "id": "H15",
    "name": "Verify declared V4 payload SHA256 (allow UNSIGNED-PAYLOAD)",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Checks the payload hash declared in a V4 request against the body, and also allows the value UNSIGNED-PAYLOAD to skip hashing the payload.",
    "docs": "https://docs.cloud.google.com/storage/docs/authentication/canonical-requests",
    "notes": "Unsigned payload is permitted by the Google contract."
  },
  {
    "id": "H16",
    "name": "Verify signed-request Content-MD5 when supplied",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Includes the Content-MD5 header in the signed data when a request has one, so a changed body digest invalidates the signature.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/reference-headers",
    "notes": ""
  },
  {
    "id": "H17",
    "name": "Verify V2 HMAC form policy signature",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Validates an HTML form upload policy signed with the V2 scheme, using the GoogleAccessId, Base64 policy and signature form fields.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/post-object-v2",
    "notes": ""
  },
  {
    "id": "H18",
    "name": "Verify V4 HMAC form policy signature",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Validates an HTML form upload policy signed with the V4 scheme, using the x-goog-algorithm, credential, date and signature form fields.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/post-object-forms",
    "notes": ""
  },
  {
    "id": "H19",
    "name": "Enforce form policy expiration",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Rejects a form upload when the policy document's expiration time has passed, so a form stops working after its validity window.",
    "docs": "https://docs.cloud.google.com/storage/docs/authentication/signatures",
    "notes": ""
  },
  {
    "id": "H20",
    "name": "Enforce form policy equality conditions",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Requires a form field to equal the exact value given in a policy condition, such as a fixed content type or object name.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/post-object-forms",
    "notes": ""
  },
  {
    "id": "H21",
    "name": "Enforce form policy prefix conditions",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Requires a form field to start with the value given in a starts-with policy condition, such as an object name prefix.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/post-object-forms",
    "notes": ""
  },
  {
    "id": "H22",
    "name": "Enforce form policy content-length range",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Requires the uploaded file's size to fall between the minimum and maximum bytes set by a content-length-range policy condition.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/post-object-forms",
    "notes": ""
  },
  {
    "id": "H23",
    "name": "Require policy coverage of bucket and key",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Requires a form policy to contain conditions covering every submitted form field, including bucket and key, so uploads cannot be redirected.",
    "docs": "https://docs.cloud.google.com/storage/docs/xml-api/post-object-forms",
    "notes": ""
  },
  {
    "id": "H24",
    "name": "Reject unknown/inactive HMAC credentials",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Rejects a request signed with an access ID that does not exist or whose HMAC key is inactive or deleted.",
    "docs": "https://docs.cloud.google.com/storage/docs/authentication/hmackeys",
    "notes": "And."
  },
  {
    "id": "H25",
    "name": "Reject malformed signed XML authentication",
    "area": "HMAC signing",
    "local": "available",
    "other": "unavailable",
    "description": "Rejects a request whose XML API authentication data is malformed, such as a broken Authorization header or missing signature parameters.",
    "docs": "https://docs.cloud.google.com/storage/docs/authentication/canonical-requests",
    "notes": "Exercised without optional IAM callback."
  },
  {
    "id": "N01",
    "name": "Create notification configuration",
    "area": "Pub/Sub notifications",
    "local": "limited",
    "other": "limited",
    "description": "Creates a notification configuration on a bucket that sends Pub/Sub messages to a topic for chosen events, with a payload format and optional filters.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/notifications/insert",
    "notes": "API exists; production response fields and configuration quotas incomplete."
  },
  {
    "id": "N02",
    "name": "List notification configurations",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "available",
    "description": "Returns all notification configurations defined on a bucket.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/notifications/list",
    "notes": ""
  },
  {
    "id": "N03",
    "name": "Read notification configuration",
    "area": "Pub/Sub notifications",
    "local": "limited",
    "other": "limited",
    "description": "Returns one notification configuration of a bucket by its ID, including its topic, event types and payload format.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/notifications/get",
    "notes": "Selected response fields; etag/selfLink missing."
  },
  {
    "id": "N04",
    "name": "Delete notification configuration",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "available",
    "description": "Deletes a notification configuration by its ID so the bucket stops publishing messages for it.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/notifications/delete",
    "notes": ""
  },
  {
    "id": "N05",
    "name": "Deliver notifications to Pub/Sub",
    "area": "Pub/Sub notifications",
    "local": "limited",
    "other": "limited",
    "description": "Publishes a message to the configured Pub/Sub topic whenever a matching change happens to an object in the bucket.",
    "docs": "https://docs.cloud.google.com/storage/docs/pubsub-notifications",
    "notes": "Publishing implemented; production delivery guarantees differ."
  },
  {
    "id": "N06",
    "name": "Filter notifications by event type",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "available",
    "description": "Limits a configuration to chosen event types, for example only finalize and delete; an empty list sends every event type.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/notifications",
    "notes": ""
  },
  {
    "id": "N07",
    "name": "Filter notifications by object-name prefix",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "available",
    "description": "Limits a configuration to objects whose names start with a given prefix, so other objects do not trigger messages.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/notifications",
    "notes": ""
  },
  {
    "id": "N08",
    "name": "JSON_API_V1 notification payload",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "available",
    "description": "Sends a payload that is the object's metadata resource as a UTF-8 JSON string in the message body.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/notifications",
    "notes": ""
  },
  {
    "id": "N09",
    "name": "NONE notification payload",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "available",
    "description": "Sends the message with no payload, leaving only the event details in the message attributes.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/notifications",
    "notes": ""
  },
  {
    "id": "N10",
    "name": "Custom notification attributes",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "available",
    "description": "Adds user-defined key and value pairs to the attributes of every message that a configuration publishes.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/notifications",
    "notes": ""
  },
  {
    "id": "N11",
    "name": "OBJECT_FINALIZE events",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "available",
    "description": "Fires when a new object, or a new generation of an existing object, is successfully created, including by copy, rewrite or restore.",
    "docs": "https://docs.cloud.google.com/storage/docs/pubsub-notifications",
    "notes": ""
  },
  {
    "id": "N12",
    "name": "OBJECT_DELETE events",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "available",
    "description": "Fires when an object is permanently deleted, including when it is replaced or removed by a lifecycle rule.",
    "docs": "https://docs.cloud.google.com/storage/docs/pubsub-notifications",
    "notes": ""
  },
  {
    "id": "N13",
    "name": "OBJECT_METADATA_UPDATE events",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "available",
    "description": "Fires when the metadata of an existing object changes, for example after a patch or update.",
    "docs": "https://docs.cloud.google.com/storage/docs/pubsub-notifications",
    "notes": ""
  },
  {
    "id": "N14",
    "name": "OBJECT_ARCHIVE events",
    "area": "Pub/Sub notifications",
    "local": "limited",
    "other": "limited",
    "description": "Fires when a live object becomes noncurrent, which happens only in a bucket with Object Versioning, for example on overwrite or delete.",
    "docs": "https://docs.cloud.google.com/storage/docs/pubsub-notifications",
    "notes": "Requires memory versioning."
  },
  {
    "id": "N16",
    "name": "Validate notification topic at creation",
    "area": "Pub/Sub notifications",
    "local": "limited",
    "other": "unavailable",
    "description": "Rejects a new configuration whose Pub/Sub topic is malformed, does not exist or cannot be published to by Cloud Storage.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/notifications/insert",
    "notes": "Validates topic syntax; production topic existence/publish permissions are not checked here."
  },
  {
    "id": "N17",
    "name": "Validate notification payload format at creation",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "unavailable",
    "description": "Rejects a new configuration whose payload format is anything other than JSON_API_V1 or NONE.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/notifications",
    "notes": ""
  },
  {
    "id": "N18",
    "name": "Validate configured event types at creation",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "unavailable",
    "description": "Rejects a new configuration that lists an event type Cloud Storage does not recognize.",
    "docs": "https://docs.cloud.google.com/storage/docs/json_api/v1/notifications",
    "notes": ""
  },
  {
    "id": "N19",
    "name": "Enforce custom attribute count limit",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "unavailable",
    "description": "Allows at most 10 custom attributes on one notification configuration and rejects a configuration that has more.",
    "docs": "https://docs.cloud.google.com/storage/docs/pubsub-notifications",
    "notes": "At most ten."
  },
  {
    "id": "N20",
    "name": "At-least-once notification delivery guarantee",
    "area": "Pub/Sub notifications",
    "local": "limited",
    "other": "limited",
    "description": "Cloud Storage guarantees at-least-once delivery of each notification to Pub/Sub, so duplicate messages are possible and order is not guaranteed.",
    "docs": "https://docs.cloud.google.com/storage/docs/pubsub-notifications",
    "notes": "LocalCloud retries persisted events, but object/outbox write gap can lose events."
  },
  {
    "id": "N23",
    "name": "Retry failed notification publications",
    "area": "Pub/Sub notifications",
    "local": "limited",
    "other": "limited",
    "description": "Retries publishing a notification that fails to reach Pub/Sub; one that stays undeliverable may be deleted after 7 days.",
    "docs": "https://docs.cloud.google.com/storage/docs/pubsub-notifications",
    "notes": "fake-gcs-server client retries within timeout; LocalCloud queue retries; Google failure lifecycle differs."
  },
  {
    "id": "N25",
    "name": "Notification payload reflects the triggering object change",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "limited",
    "description": "Builds each message's payload from the object's metadata after the triggering change, so it describes the object as of that event.",
    "docs": "https://docs.cloud.google.com/storage/docs/pubsub-notifications",
    "notes": "LocalCloud snapshots payload before async delivery."
  },
  {
    "id": "N26",
    "name": "Include notification configuration identifier in attributes",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "unavailable",
    "description": "Adds a notificationConfig attribute to every message, identifying the configuration that produced it.",
    "docs": "https://docs.cloud.google.com/storage/docs/pubsub-notifications",
    "notes": ""
  },
  {
    "id": "N27",
    "name": "Include deletion time in delete-event payload",
    "area": "Pub/Sub notifications",
    "local": "available",
    "other": "unavailable",
    "description": "For delete events with a JSON payload, includes the object's metadata from before deletion plus a timeDeleted property.",
    "docs": "https://docs.cloud.google.com/storage/docs/pubsub-notifications",
    "notes": ""
  }
]
