Tenho brincado consideravelmente com o MinIO nesses últimos tempos – afinal, né… Pra que usar cloud onde está tudo na mão se eu posso complicar um pouco fazendo tudo no braço?

Enfim… Me deparei com uma situação aqui e tinha guardado anotado no meu Obsdian, mas achei interessante para colocar aqui no blog (que eu não sei se ainda faz algum sentido manter, para falar bem a verdade).

Qual a ideia:

  • Tenho diversos projetos e quero deixar o acesso aos buckets separados por projeto, para que um não impacte no outro.
  • Quero que cada projeto tenha o seu usuário de acesso, deixando eles isolados.
  • Sim, eu poderia fazer do jeito fácil, criando apenas pastas para cada projeto e ser feliz, mas quem disse que felicidade é uma opção quando trabalhamos com TI? 🙂

Agora, afinal, porque?

Vantagens desta Abordagem

  • **Isolamento**: Cada projeto tem seu próprio espaço de armazenamento
  • **Segurança**: Cada aplicação só tem acesso ao seu próprio bucket
  • **Eficiência operacional**: Uma única instância do MinIO para todos os projetos
  • **Flexibilidade**: Fácil adicionar novos projetos sem reconfigurar toda a infraestrutura

Bom, vamos lá!

Pré-requisitos

  • Docker instalado (para execução do MinIO)
  • Windows PowerShell

1. Configuração do MinIO

1.1 Verificar se o MinIO já está em execução

# Verificar se o MinIO está em execução
docker ps | findstr minio

1.2 Caso o MinIO não esteja em execução

Se o comando acima não retornar nenhum resultado, você precisa criar e iniciar o container do MinIO:

# Criar um diretório para persistência dos dados
mkdir -p d:\Projetos\minio\data

# Executar o container do MinIO
docker run -d \
  --name minio \
  -p 9000:9000 \
  -p 9001:9001 \
  -e "MINIO_ROOT_USER=minioadmin" \
  -e "MINIO_ROOT_PASSWORD=minioadmin" \
  -v d:\Projetos\minio\data:/data \
  minio/minio server /data --console-address ":9001"

O que nós estamos fazendo com isso:

  • Criando um container chamado “minio”
  • Expondo a API do MinIO na porta 9000
  • Expondo a interface web de administração na porta 9001
  • Configurando o usuário e senha padrão como “minioadmin”
  • Montando o diretório local para persistência dos dados

Para acessar o console de administração do MinIO, basta a url: http://localhost:9001 (link desabilitado por motivos óbvios…)

2. Instalação do Cliente MinIO (mc)

# Baixar o cliente MinIO para Windows
Invoke-WebRequest -Uri https://dl.min.io/client/mc/release/windows-amd64/mc.exe -OutFile mc.exe

# Configurar o cliente para se conectar à instância local do MinIO
.\mc.exe alias set local http://localhost:9000 minioadmin minioadmin

Eu poderia (e recomendo, aliás) colocar o .exe em uma pasta no home e colocar no Path, mas por motivos de “praticidade momentânea” – a.k.a preguiça, vamos deixar na pasta raiz do minIO.

3. Criação de Buckets para Projetos

# Listar buckets existentes
.\mc.exe ls local

# Criar buckets para diferentes projetos
.\mc.exe mb local/projeto-a
.\mc.exe mb local/projeto-b

4. Configuração de Políticas de Acesso

4.1 Criação de Usuários

# Criar usuário para o Projeto A
.\mc.exe admin user add local projeto-a-user senha123

# Criar usuário para o Projeto B
.\mc.exe admin user add local projeto-b-user senha456

4.2 Definição de Políticas

É aqui que o bicho pega… saber quais acessos devem ser dados, as ações, etc é chato, mas depois vale a pena.

Para maiores referências sobre o json, vá no final da página.

Criar arquivo de política para o Projeto A (policy-projeto-a.json):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": [
        "arn:aws:s3:::projeto-a"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::projeto-a/*"
      ]
    }
  ]
}

Criar arquivo de política para o Projeto B (policy-projeto-b.json):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": [
        "arn:aws:s3:::projeto-b"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::projeto-b/*"
      ]
    }
  ]
}

4.3 Aplicação das Políticas

Vejam que basicamente, são 3 etapas: Criar o bucket, criar os usuários, criar o json, associas as políticas de acesso aos buckets e, por últimos, vincular a política ao usuário criado.

# Criar políticas a partir dos arquivos JSON
.\mc.exe admin policy create local policy-projeto-a .\policy-projeto-a.json
.\mc.exe admin policy create local policy-projeto-b .\policy-projeto-b.json

# Associar políticas aos usuários
.\mc.exe admin policy attach local policy-projeto-a --user projeto-a-user
.\mc.exe admin policy attach local policy-projeto-b --user projeto-b-user

5. Uso em Aplicações

Exemplo simples de como acessar o bucket do Projeto A

import boto3

s3_client = boto3.client(
    's3',
    endpoint_url='http://localhost:9000',
    aws_access_key_id='projeto-a-user',
    aws_secret_access_key='senha123',
    region_name='us-east-1'  # Região padrão do MinIO
)

# Listar objetos no bucket
response = s3_client.list_objects_v2(Bucket='projeto-a')

6. Adicionando Novos Projetos

Para adicionar um novo projeto, siga estes passos:

  1. Criar um novo bucket:
    • .\mc.exe mb local/nome-do-projeto
  2. Criar um usuário para o projeto:
    • .\mc.exe admin user add local nome-do-projeto-user senha-segura
  3. Criar um arquivo de política JSON (similar aos anteriores)
  4. Aplicar a política:
    • .\mc.exe admin policy create local policy-nome-do-projeto .\policy-nome-do-projeto.json
  5. Associar a política ao usuário:
    • .\mc.exe admin policy attach local policy-nome-do-projeto --user nome-do-projeto-user

Referência de Políticas de Acesso

As políticas de acesso do MinIO seguem o formato JSON do AWS IAM. Abaixo estão os valores válidos para cada campo das políticas:

Estrutura Básica

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": ["s3:<ActionName>", ...],
         "Resource": "arn:aws:s3:::*",
         "Condition": { ... }
      }
   ]
}

Valores Válidos para Cada Campo

1. Version

  • Valor fixo: "2012-10-17" (padrão atual da especificação)

2. Effect

  • Valores válidos: "Allow" ou "Deny"

3. Action

Ações comuns do S3 suportadas pelo MinIO:

  • "s3:*" – Todas as ações
  • "s3:GetObject" – Obter objetos
  • "s3:PutObject" – Enviar objetos
  • "s3:DeleteObject" – Excluir objetos
  • "s3:ListBucket" – Listar conteúdo do bucket
  • "s3:GetBucketLocation" – Obter localização do bucket
  • "s3:CreateBucket" – Criar bucket
  • "s3:DeleteBucket" – Excluir bucket

4. Resource

O formato segue o padrão ARN (Amazon Resource Name):

  • "arn:aws:s3:::*" – Todos os buckets e objetos
  • "arn:aws:s3:::bucket-name" – Um bucket específico
  • "arn:aws:s3:::bucket-name/*" – Todos os objetos em um bucket específico
  • "arn:aws:s3:::bucket-name/prefix/*" – Objetos com um prefixo específico

Suporta caracteres curinga:

  • * – Corresponde a zero ou mais caracteres
  • ? – Corresponde a exatamente um caractere

5. Principal

  • {"AWS": ["*"]} – Qualquer usuário (acesso anônimo)
  • {"AWS": ["arn:aws:iam::account-id:user/username"]} – Usuário específico

6. Condition (Não usado aqui)

Permite definir condições adicionais para a aplicação da política, como:

  • Condições baseadas em IP
  • Condições baseadas em tags
  • Condições baseadas em data/hora

Referências Adicionais

  • [Documentação Oficial do MinIO](https://min.io/docs/minio/linux/administration/identity-access-management/policy-based-access-control.html)
  • [Referência de Elementos de Política JSON IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html)
  • [Formato ARN do S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-arn-format.html)

Comandos Úteis

  • Listar todos os buckets: .\mc.exe ls local
  • Listar objetos em um bucket: .\mc.exe ls local/nome-do-bucket
  • Fazer upload de um arquivo: .\mc.exe cp ./arquivo.txt local/nome-do-bucket/
  • Baixar um arquivo: .\mc.exe cp local/nome-do-bucket/arquivo.txt ./
  • Remover um arquivo: .\mc.exe rm local/nome-do-bucket/arquivo.txt