> ## Documentation Index
> Fetch the complete documentation index at: https://docs.basaltic.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Buckets

> Criar um bucket, apontar um cliente do S3 para ele e o que é preciso para excluir um.

<a id="creating-a-bucket" />

## Criando um bucket

<Tabs>
  <Tab title="Console">
    Vá para **Storage → Buckets** e escolha **Create Bucket**. **Bucket Name** é a única coisa que você precisa preencher; **Versioning**, **Default
    encryption**, **Deletion protection** e **Tags** estão no mesmo formulário.

    Esses extras são aplicados como chamadas separadas uma vez que o bucket existe, então o bucket é criado mesmo se um deles falhar, e o console informa qual deles falhou.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    POST https://storage.sa-saopaulo-1.basaltic.sh/v1/buckets
    { "name": "my-app-assets" }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic storage bucket create --name my-app-assets
    ```

    Adicione `--object-lock-enabled` aqui se você precisar dele — ele só pode ser usado na chamada que cria o bucket.
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    b, err := storage.New(cfg).CreateBucket(ctx, &storage.CreateBucketRequest{
        Name: "my-app-assets",
    })
    ```
  </Tab>
</Tabs>

Os nomes de bucket seguem as regras do S3 e são verificados na íntegra:

<ResponseField name="name" type="3–63 characters" required>
  Letras minúsculas, dígitos e hífens. Deve começar e terminar com uma letra ou um dígito, não pode conter um **hífen duplo** (`--`) e não deve ter a forma de um endereço IP.
</ResponseField>

<Warning>
  **O nome de um bucket é exclusivo em toda a região, não apenas na sua conta.** Um nome que já está em outra conta retorna `409`. Criar um bucket que você já possui é uma operação bem-sucedida que não altera nada, então uma criação repetida é segura.
</Warning>

A contagem de buckets é limitada pela cota de `buckets` da sua organização; esgotá-la também é um `409` na criação.

<a id="object-lock-has-to-be-decided-here" />

### O bloqueio de objetos tem que ser decidido aqui

```bash theme={null}
POST /v1/buckets
{ "name": "audit-archive", "object_lock_enabled": true }
```

<Warning>
  **O bloqueio de objetos só pode ser ativado na criação.** Não há nenhuma chamada que o ative mais tarde — você teria que criar um novo bucket e copiar os objetos.Ativá-lo também ativa o controle de versão, porque um bloqueio não tem nada para segurar sem versões.
</Warning>

`PUT /v1/buckets/{bucket}/object-lock` atualiza a *regra de retenção padrão* em um bucket que já tem o bloqueio de objetos habilitado. Contra um bucket que não o faz, é um `409` — `object lock must be enabled at bucket creation`.

<Note>
  **A ativação do bloqueio de objetos é apenas para API.** Ele tem que ser executado na chamada que cria o bucket, e o formulário **Create Bucket** do console não o envia — o bucket é criado sem bloqueio de objetos, e a configuração de acompanhamento é recusada com o mesmo `409`. Crie o bucket através da API quando precisar do Object Lock.

  Em um bucket que já o tem, o console edita a regra: o cartão **Object Lock** na guia **Settings** do bucket carrega a **Default retention rule**, com um **Mode** e um **Retention period**.
</Note>

<a id="pointing-an-s3-client-at-it" />

## Apontando um cliente S3 para ele

Defina um endpoint personalizado e assine com sua chave de acesso Basaltic. Nada mais sobre o cliente muda.

<CodeGroup>
  ```python boto3 theme={null}
  import boto3
  from botocore.config import Config

  s3 = boto3.client(
      "s3",
      endpoint_url="https://objects.sa-saopaulo-1.basaltic.cloud",
      aws_access_key_id=ACCESS_KEY_ID,
      aws_secret_access_key=SECRET_ACCESS_KEY,
      region_name="sa-saopaulo-1",
      config=Config(signature_version="s3v4"),
  )

  s3.put_object(Bucket="my-app-assets", Key="images/logo.png", Body=data)
  ```

  ```bash AWS CLI theme={null}
  aws --endpoint-url https://objects.sa-saopaulo-1.basaltic.cloud \
      s3 cp ./logo.png s3://my-app-assets/images/logo.png
  ```

  ```python Temporary credentials theme={null}
  s3 = boto3.client(
      "s3",
      endpoint_url="https://objects.sa-saopaulo-1.basaltic.cloud",
      aws_access_key_id=creds.access_key_id,
      aws_secret_access_key=creds.secret_access_key,
      aws_session_token=creds.session_token,   # required for STS credentials
      region_name="sa-saopaulo-1",
      config=Config(signature_version="s3v4"),
  )
  ```
</CodeGroup>

<AccordionGroup>
  <Accordion title="Credenciais" icon="key-round">
    As mesmas teclas de acesso que você usa em todos os outros lugares. A chave de longa duração de uma conta de serviço não precisa de nada extra; credenciais temporárias do STS — uma sessão de função ou uma sessão de usuário — também devem carregar o token de sessão e são rejeitadas sem ele.

    Veja [authentication](/pt/authentication) para saber como obter cada um.
  </Accordion>

  <Accordion title="Estilo de endereçamento" icon="route">
    Ambos os estilos funcionam.`https://my-app-assets.objects.sa-saopaulo-1.basaltic.cloud/key`) é o padrão da maioria dos SDKs; path-style (`https://objects.sa-saopaulo-1.basaltic.cloud/my-app-assets/key`) está disponível através da opção de estilo de endereçamento do seu cliente.
  </Accordion>

  <Accordion title="A cadeia de caracteres da região" icon="globe">
    Defina `region_name` para o código da região Basaltic. O valor não é verificado contra a região que serve a solicitação — ele só tem que corresponder ao que seu cliente assinou — então uma ferramenta com conexão rígida para `us-east-1` ainda funciona. `GetBucketLocation` relata a região real.
  </Accordion>

  <Accordion title="URLs de relógio inclinado e pré-assinados" icon="clock">
    Uma solicitação assinada deve estar dentro de **15 minutos** do relógio do servidor, ou ela será rejeitada como muito distorcida. Os URLs pré-assinados são suportados com uma expiração entre 1 segundo e **7 dias**, e um URL datado no futuro além da tolerância de desvio é recusado em vez de se tornar válido mais tarde.
  </Accordion>
</AccordionGroup>

<a id="what-the-s3-endpoint-serves" />

### O que o endpoint do S3 serve

O endpoint é verificado em relação a um SDK real da AWS, em vez de uma especificação nossa — se o boto3 puder fazer isso e obter os códigos de erro do S3, ele funcionará. O que é encaminhado hoje:

<Columns cols={2}>
  <Card title="Buckets" icon="boxes">
    ListBuckets, CreateBucket, HeadBucket, DeleteBucket, GetBucketLocation e os sub-recursos `?policy`, `?cors`, `?lifecycle`, `?versioning`, `?encryption`, `?tagging`, `?object-lock` e `?acl`.
  </Card>

  <Card title="Objetos" icon="file">
    PutObject, GetObject (incluindo solicitações de intervalo), HeadObject, DeleteObject, DeleteObjects, CopyObject, ListObjects, ListObjectsV2, ListObjectVersions e os sub-recursos `?tagging`, `?retention`, `?legal-hold` e `?acl`.
  </Card>

  <Card title="Multipart" icon="layers">
    CriarMultipartUpload, UploadPart, UploadPartCopy, ListaPartes, ListaMultipartUploads, CompletarMultipartUpload, AborterMultipartUpload.
  </Card>

  <Card title="Assinatura de carga útil" icon="shield">
    Cargas assinadas, `UNSIGNED-PAYLOAD` e assinadas `aws-chunked` streaming uploads. O corpo é re-hashado conforme ele é transmitido, então um corpo que não corresponde ao que foi assinado é rejeitado a meio do voo.
  </Card>
</Columns>

Qualquer coisa fora dessa lista responde `NotImplemented`. As solicitações de verificação prévia `OPTIONS` são respondidas sem uma assinatura, porque os navegadores nunca as assinam.

<a id="deleting-a-bucket" />

## Excluir um bucket

`DELETE /v1/buckets/{bucket}` faz duas coisas bem diferentes dependendo se a proteção de exclusão está ativada. A proteção é deliberadamente **desativada por padrão** para a paridade do S3: ao contrário dos segredos e do KMS, os buckets desprotegidos não têm janela de recuperação.

<Tabs>
  <Tab title="Proteção desligada (padrão)">
    O bucket deve estar **vazio**. Quaisquer objetos, versões ou uploads de várias partes em andamento tornam-no um `409 BucketNotEmpty`. Um bucket vazio é excluído imediatamente e o slot de cota é liberado.
  </Tab>

  <Tab title="Proteção em linha">
    A exclusão é **agendada** para o final da janela de recuperação, em vez de ser executada, e é aceita, independentemente de o bucket estar vazio ou não. `deleted_at` registra quando você solicitou a exclusão e `scheduled_purge_at` registra o prazo de limpeza. Os buckets que já estavam em uma janela de recuperação quando esses campos foram introduzidos mantêm seu prazo e têm um `deleted_at` nulo. Ambos os timestamps são apagados na restauração. `POST /v1/buckets/{bucket}/restore` cancela a qualquer momento antes desse prazo — no console, o bucket agendado carrega uma ação **Cancel deletion** que faz a mesma coisa. Chamar delete novamente enquanto uma exclusão já está agendada é um no-op, não uma segunda janela.

    <Warning>
      Quando o prazo termina, o bucket é esvaziado e purgado — **seus objetos vão com ele**. A proteção oferece uma janela para mudar de ideia, não uma recusa em excluir um bucket com dados nele.
    </Warning>
  </Tab>
</Tabs>

<Tabs>
  <Tab title="Console">
    O cartão **Deletion protection** na guia **Settings** do bucket é um botão ao lado de **Recovery window (days)**. **Save** aplica-se a ambos.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    PUT /v1/buckets/{bucket}/deletion-protection
    { "enabled": true, "recovery_window_days": 14 }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic storage bucket set-deletion-protection <bucket> \
      --enabled --recovery-window-days 14
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    err := storage.New(cfg).PutBucketDeletionProtection(ctx, bucket,
        &storage.PutBucketDeletionProtectionRequest{
            Enabled:      true,
            RecoveryWindowDays: basaltic.Int(14),
        })
    ```
  </Tab>
</Tabs>

`recovery_window_days` aceita números inteiros de **1–30**. Omitir cada campo de janela usa **7 dias**. Valores inválidos retornam `400`, inclusive quando a proteção é desativada.

<a id="release-note-recovery-fields" />

### Nota de lançamento: campos de recuperação

As respostas do bucket expõem `recovery_window_days`, `scheduled_purge_at` e `deleted_at` nulo. O DELETE protegido retorna `200` com `scheduled_purge_at`; o DELETE imediato retorna `204`.

<a id="breaking-behavior-change-invalid-windows-return-400" />

### Alteração de comportamento de quebra: janelas inválidas retornam 400

O serviço anteriormente silenciosamente apertou janelas: valores abaixo de 1 selecionados 7 dias, e valores acima de 30 selecionados 30 dias. Agora ele os rejeita com `400` em vez disso. Por exemplo, a solicitação de 60 dias falha; ele não agenda mais uma limpeza após apenas 30 dias. Zero explícito também é inválido; omita os campos da janela para selecionar o padrão de 7 dias. Dias fracionários são inválidos. Atualize os chamadores que dependem de aperto separadamente da adoção dos novos nomes de campo.

Durante uma implantação contínua, as instâncias de serviço antigas ainda podem aplicar seu comportamento de fixação antigo; a rejeição é universal quando todas as instâncias são atualizadas.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.