[{"data":1,"prerenderedAt":10},["ShallowReactive",2],{"public:public\u002Fcontent\u002Fdocs\u002Fgoogle-cloud-storage":3},{"slug":4,"title":5,"description":6,"draft":7,"updated":8,"html":9},"google-cloud-storage","Google Cloud Storage","Give Verestore read-only access to a Cloud Storage bucket through an HMAC interoperability key on a dedicated service account.",false,null,"\u003Ch1>Google Cloud Storage (S3 interoperability)\u003C\u002Fh1>\n\u003Cblockquote>\n\u003Cp>Verified against the provider&#39;s documentation, not against a live account.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>A provider snapshot disappears with the project that holds it; a dump in a bucket you control is the copy that survives, and Verestore proves it restores. For Cloud SQL, see \u003Ca href=\"\u002Fdocs\u002Fcloud-sql-gcs\">Cloud SQL scheduled export to Cloud Storage\u003C\u002Fa> for the write side.\u003C\u002Fp>\n\u003Ch2>1. Write dumps to Cloud Storage\u003C\u002Fh2>\n\u003Cp>From any host with \u003Ccode>gcloud\u003C\u002Fcode> and write access to the bucket:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sh\">pg_dump --format=custom --no-owner &quot;$DATABASE_URL&quot; \\\n  | gcloud storage cp - &quot;gs:\u002F\u002Facme-backups\u002Forders\u002Forders-$(date -u +%Y-%m-%dT%H-%M).dump&quot;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Verestore accepts \u003Ccode>pg_dump\u003C\u002Fcode> custom format (\u003Ccode>-Fc\u003C\u002Fcode>) or plain SQL, optionally gzipped. The format is detected from the content, not the file extension.\u003C\u002Fp>\n\u003Ch2>2. Create a reader service account\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-sh\">gcloud iam service-accounts create verestore-reader \\\n  --project=PROJECT --display-name=&quot;Verestore (read-only)&quot;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Grant it \u003Ccode>roles\u002Fstorage.objectViewer\u003C\u002Fcode> on the bucket only, not on the project:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sh\">gcloud storage buckets add-iam-policy-binding gs:\u002F\u002Facme-backups \\\n  --member=serviceAccount:verestore-reader@PROJECT.iam.gserviceaccount.com \\\n  --role=roles\u002Fstorage.objectViewer\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>3. Optional: restrict it to the prefix\u003C\u002Fh2>\n\u003Cp>The simplest strict scope is a \u003Cstrong>dedicated bucket per database\u003C\u002Fstrong>. If the bucket is shared, add an IAM Condition to the binding instead (the bucket must use uniform bucket-level access). Listing is checked against the bucket itself, so the condition must allow the bucket as well as the objects under the prefix:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sh\">gcloud storage buckets add-iam-policy-binding gs:\u002F\u002Facme-backups \\\n  --member=serviceAccount:verestore-reader@PROJECT.iam.gserviceaccount.com \\\n  --role=roles\u002Fstorage.objectViewer \\\n  --condition=&#39;title=orders-prefix-only,expression=resource.name == &quot;projects\u002F_\u002Fbuckets\u002Facme-backups&quot; || resource.name.startsWith(&quot;projects\u002F_\u002Fbuckets\u002Facme-backups\u002Fobjects\u002Forders\u002F&quot;)&#39;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Use this binding in place of the unconditional one from step 2, not in addition to it. Listing still reveals object \u003Cstrong>names\u003C\u002Fstrong> in the whole bucket, never their content.\u003C\u002Fp>\n\u003Ch2>4. Create an HMAC key\u003C\u002Fh2>\n\u003Cp>Verestore uses the Cloud Storage XML API through its S3 interoperability. Create an HMAC key for the service account:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sh\">gcloud storage hmac create verestore-reader@PROJECT.iam.gserviceaccount.com\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>The output contains the \u003Cstrong>access ID\u003C\u002Fstrong> (the access key ID) and the \u003Cstrong>secret\u003C\u002Fstrong> (the secret access key). The secret is shown once.\u003C\u002Fp>\n\u003Cp>Verestore only lists objects under the prefix (\u003Ccode>ListObjectsV2\u003C\u002Fcode>) and reads \u003Ccode>orders\u002F*\u003C\u002Fcode>, pinned to the listed ETag. It never writes or deletes.\u003C\u002Fp>\n\u003Ch2>5. Add the target in Verestore\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>S3 endpoint: \u003Ccode>https:\u002F\u002Fstorage.googleapis.com\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>Region: \u003Ccode>auto\u003C\u002Fcode> (or leave it empty: it is filled from the endpoint)\u003C\u002Fli>\n\u003Cli>Bucket: \u003Ccode>acme-backups\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>Prefix: \u003Ccode>orders\u002F\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>Access key ID: the HMAC access ID; secret access key: the HMAC secret\u003C\u002Fli>\n\u003C\u002Ful>\n",1794290783589]