---
title: Buckets
description: Conecte seu próprio bucket compatível com S3 para assets do CMS — e as permissões IAM que ele precisa
icon: HardDrive
---

import Callout from "../../../../components/ui/Callout.astro";

## O que são buckets?

Um **bucket** é um object store compatível com S3 que você conecta ao Studio para guardar **assets do CMS** — os arquivos que você envia e referencia no conteúdo que constrói (imagens, slides, decks). Você configura buckets no nível da org em **Settings → Buckets**, e as credentials são criptografadas em repouso e nunca retornadas pela API.

<Callout type="note">
Este é o bucket que **você** traz e configura na UI, usado apenas para assets do CMS. Ele **não** é o object store que lastreia o sistema de arquivos da org (org-fs) em um deployment self-hosted — esse é configurado via variáveis de ambiente no deployment, não aqui. Esta página é sobre o bucket configurado pelo usuário.
</Callout>

O Studio funciona com qualquer provider compatível com S3:

| Provider | Endpoint | Force path-style |
|---|---|---|
| **AWS S3** | deixe em branco (padrão) | desligado |
| **Cloudflare R2** | `https://<account>.r2.cloudflarestorage.com` | desligado |
| **Google Cloud Storage** | `https://storage.googleapis.com` | **ligado** |
| **MinIO** | a URL do seu MinIO | normalmente **ligado** |

## Adicionando um bucket

Clique em **Add bucket** e preencha:

| Campo | Obrigatório | Observações |
|---|---|---|
| **Name** | ✅ | Letras, dígitos, underscore, ponto, hífen. Único dentro da org. |
| **Bucket** | ✅ | O nome do bucket. |
| **Region** | ✅ | ex: `us-east-1`. |
| **Endpoint** | — | Obrigatório para providers não-AWS (R2, GCS, MinIO). Deixe em branco para AWS. |
| **Force path-style URLs** | — | Obrigatório para GCS e a maioria dos setups MinIO. |
| **Key prefix** | — | Todas as chaves de objeto são gravadas sob esse prefixo — útil para buckets multi-tenant ou credentials com escopo em um sub-caminho. A barra final é adicionada automaticamente. |
| **Public URL base** | — | Host usado para montar as URLs públicas retornadas para cada asset (domínio dev do R2, CDN, host customizado). Deixe em branco para usar o host S3 do bucket. |
| **Credentials** | ✅ | Um par de chaves estático, ou uma sessão temporária STS (veja abaixo). |

### Tipos de credential

- **Static key pair (long-lived)** — um `Access key ID` e um `Secret access key`, usados como estão. A escolha mais comum.
- **Temporary session (STS, auto-refreshed)** — armazena apenas uma URL de refresh endpoint e uma API key. As credentials de curta duração são buscadas sob demanda e renovadas automaticamente; nenhum secret S3 é armazenado.

## Permissões IAM da AWS

O Studio toca o bucket de apenas duas formas: ele faz **upload** de assets para ele e **lista** objetos para alimentar o seletor de assets. Ele nunca lê objetos de volta pelo servidor, nunca os deleta e nunca mexe na configuração do bucket. Então, para um bucket S3 da AWS conectado via **par de chaves estático**, o usuário (ou role) IAM por trás da access key precisa de muito pouco:

| O que o Studio faz | Operação S3 | Ação IAM |
|---|---|---|
| Fazer upload de um asset (streaming via multipart para arquivos grandes) | `Upload` (multipart `PutObject`) | `s3:PutObject` |
| Limpar um upload multipart que falhou | `AbortMultipartUpload` | `s3:AbortMultipartUpload` |
| Listar objetos para o seletor de assets | `ListObjectsV2` | `s3:ListBucket` |

<Callout type="note">
O Studio **não** lê os assets enviados de volta. O seletor e o seu CMS apontam para a **URL pública** de cada objeto (o `Public URL base` que você define, ou a URL S3 canônica do bucket), que o navegador busca diretamente. Por isso a credential do Studio **não** precisa de `s3:GetObject` — em vez disso, os objetos precisam ser publicamente legíveis (ou estar atrás de uma CDN) para que essas URLs resolvam. Isso é uma preocupação separada desta policy IAM: uma bucket policy / ACL de objeto / configuração de Block Public Access, ou uma CDN na frente.
</Callout>

### Política mínima

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "StudioUploads",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:AbortMultipartUpload"
      ],
      "Resource": "arn:aws:s3:::YOUR_BUCKET/*"
    },
    {
      "Sid": "StudioListBucket",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::YOUR_BUCKET"
    }
  ]
}
```

<Callout type="warning">
**`s3:ListBucket` é uma ação em nível de bucket** — o `Resource` dela é o ARN do bucket (`arn:aws:s3:::YOUR_BUCKET`), **sem** o sufixo `/*`. A ação de objeto (`s3:PutObject`, `s3:AbortMultipartUpload`) opera sobre objetos, então o `Resource` dela **termina** em `/*`. Apontar o `ListBucket` para o ARN com `/*` é a causa mais comum de `AccessDenied` ao listar.
</Callout>

### Escopando por prefixo (opcional)

Se você definir um **Key prefix** no bucket, pode travar a credential somente nesse caminho:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "StudioUploads",
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:AbortMultipartUpload"],
      "Resource": "arn:aws:s3:::YOUR_BUCKET/YOUR_PREFIX/*"
    },
    {
      "Sid": "StudioListBucket",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::YOUR_BUCKET",
      "Condition": { "StringLike": { "s3:prefix": ["YOUR_PREFIX/*"] } }
    }
  ]
}
```

---

<Callout type="info">
As credentials são armazenadas criptografadas no vault de credentials do Studio e nunca são retornadas pela API. Remover a configuração de um bucket apaga as credentials armazenadas — o bucket em si e seu conteúdo permanecem intactos.
</Callout>
