> For the complete documentation index, see [llms.txt](https://docs.birdie.so/birdie-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.birdie.so/birdie-docs/security/storage-location/storage-in-your-own-gcp-bucket-s.md).

# Storage in your own GCP bucket(s)

This guide shows how to create a Google Cloud Storage bucket, grant Birdie access, configure CORS, and verify the configuration before running a quick test.

***

### Create a bucket

1. In the Google Cloud Console, open the left menu and go to **Storage → Buckets**.
2. Click **Create**.
3. **Name**: enter a unique name, e.g. `acme-screen-recordings`
4. Click **Continue** through the remaining steps, keeping **all** **defaults**:
   * **Public access prevention**: **Enforced** (recommended).
   * **Encryption**: **Google-managed** (default).

> Keep all other defaults unless your security team requires specific settings.

***

### Grant Birdie access

1. After the bucket is created, click its **name** to open the bucket details.
2. Go to the **Permissions** tab.
3. Under **View by principals**, click **+ Grant access**.
4. **New principal**: `birdie@birdie-storage.iam.gserviceaccount.com`
5. Add 2 roles: \
   **Cloud Storage → Storage Object Admin**\
   **Cloud Storage → Storage Bucket Viewer**&#x20;
6. Click **Save**.

> This role allows Birdie to upload, read, list, and delete objects inside **your** bucket. The bucket remains private.

***

### Configure CORS (one-time)

We’ll allow Birdie’s web app to securely upload and play videos from your bucket.

1. In the top-right of the Console, click the **terminal icon** labeled **Activate Cloud Shell**.\
   (Approve any prompts to start the shell.)
2. Paste the commands below.\
   👉 **Replace** `acme-screen-recordings` with **your bucket name**.

```bash
cat > cors.json <<'EOF'
[
  {
    "origin": ["https://app.birdie.so", "https://share.birdie.so"],
    "method": ["GET", "PUT", "POST", "DELETE", "HEAD"],
    "responseHeader": ["*"],
    "maxAgeSeconds": 3600
  },
  {
    "origin": ["*"],
    "method": ["GET", "HEAD"],
    "responseHeader": ["*"],
    "maxAgeSeconds": 1800
  }
]
EOF
gsutil cors set cors.json gs://acme-screen-recordings
```

You should see something like:

```
Setting CORS policies for gs://acme-screen-recordings...
```

#### (Optional) Verify CORS

Run (after replacing the bucket name with yours):

```bash
gsutil cors get gs://acme-screen-recordings
```

Expected output:

```json
[{"maxAgeSeconds": 3600, "method": ["GET", "PUT", "POST", "DELETE", "HEAD"], "origin": ["https://app.birdie.so", "https://share.birdie.so"], "responseHeader": ["*"]},{"maxAgeSeconds": 1800, "method": ["GET", "HEAD"], "origin": ["*"], "responseHeader": ["*"]}]
```

> CORS does **not** make your bucket public; it only permits cross-origin requests from `https://*.birdie.so`.

***

### Verify from Birdie

1. Open: [**https://app.birdie.so/test-gcs**](https://app.birdie.so/test-gcs)
2. Enter **your bucket name** and click **Start Test**.
3. If everything is configured correctly, you’ll see green checkmarks and **“Test Success”.** \
   **Congrats! 🎉**

Finally, share your **bucket name** with Birdie.

***

### Troubleshooting

* **Permission errors (403/Access Denied):**\
  Re-check that you granted `birdie@birdie-storage.iam.gserviceaccount.com` the **Storage Admin** role **on the bucket** (Permissions → **Grant access**).
* **CORS or browser errors:**\
  Re-run the CORS step and ensure the `origin` is exactly `https://*.birdie.so` and the command used **your** bucket name.
* **Need help?**\
  Email **<support@birdie.so>** with your bucket name and any error messages.

***

### What to send to Birdie

{% hint style="warning" %}
Before sending us the information, ensure that the bucket testing on <https://app.birdie.so/test-gcs> is successful.&#x20;
{% endhint %}

* **Bucket name** (e.g., `acme-screen-recordings`)

That’s all we need to connect Birdie to your bucket.
