Skip to content
← Voltar aos artigos
4 min de leitura#aws #iam #security

IAM Role cross-account no AWS: configuração passo a passo

Como configurar uma IAM Role cross-account com External ID para permitir que uma ferramenta externa faça análise read-only da sua conta AWS, sem entregar chave privada.

Compartilhar chave de acesso (AKIA...) com uma ferramenta externa é uma das práticas mais perigosas que ainda sobrevive em cloud. A chave vale pra sempre até ser rotacionada. Vaza em log, em variável de ambiente, chega no Git por acidente. A AWS tem uma resposta pra isso há mais de 15 anos: IAM Role cross-account.

A ideia é simples. Em vez de copiar uma credencial permanente pra fora, você cria uma Role na sua conta e autoriza outra conta (a da ferramenta) a assumi-la temporariamente. Quem usa a Role pega um token que expira em minutos, opera com as permissões mínimas que você definiu, e nunca toca em uma chave privada sua.

O guia abaixo é o passo a passo completo. O exemplo usa WiserOps como a ferramenta externa, mas a mecânica é idêntica pra qualquer SaaS que peça acesso à sua AWS.

O que você vai criar

Na sua conta AWS:

  • Uma IAM Role chamada WiserOpsReadOnly (nome livre).
  • Uma Trust Policy que autoriza a conta da WiserOps (833073837959) a assumir a Role, exigindo um External ID único.
  • Uma ou duas managed policies anexadas: ReadOnlyAccess e, se quiser cobertura completa de cost, job-function/Billing.

Depois você passa o ARN da Role e o External ID pra ferramenta, e acabou. Sem chave, sem secret, sem rotação manual.

Passo 1: gerar o External ID

O External ID é um segredo compartilhado entre você e a ferramenta. Protege contra o problema do confused deputy: mesmo que alguém descubra o ARN da sua Role, sem o External ID correto o sts:AssumeRole falha.

No WiserOps, quando você clica em "Conectar AWS", o painel gera um External ID único por organização. Copie o valor (algo como wops-a3f9b2...). Você vai usar na Trust Policy.

Um detalhe de segurança que vale a pena checar: External IDs devem ser únicos por cliente ou por contexto. Se uma ferramenta te der o mesmo External ID usado em 300 outros clientes, não é seguro. Peça um único pra sua organização.

Passo 2: criar a Role via CloudFormation (recomendado)

A forma mais rápida é CloudFormation Quick-Create, um link que já vem com o template pronto. Você preenche o External ID, clica "Create stack", acabou. Dois minutos.

O template cria exatamente três recursos:

Resources:
  WiserOpsReadOnlyRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: WiserOpsReadOnly
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: "arn:aws:iam::833073837959:root"
            Action: "sts:AssumeRole"
            Condition:
              StringEquals:
                "sts:ExternalId": !Ref ExternalId
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
        - arn:aws:iam::aws:policy/job-function/Billing

A Trust Policy é o coração da configuração. Ela permite apenas a conta WiserOps, apenas se o External ID bater. Qualquer outra tentativa falha com AccessDenied.

Passo 2b: criar manualmente (se preferir)

Se sua política interna não aceita CloudFormation de terceiro, dá pra criar na mão:

  1. Console AWS, IAM, Roles, Create role.
  2. Trusted entity: "Another AWS account", Account ID 833073837959.
  3. Marque "Require external ID" e cole o valor.
  4. Anexe ReadOnlyAccess (e opcionalmente job-function/Billing).
  5. Nome da Role: WiserOpsReadOnly.
  6. Create role.

No final, abra a Role recém-criada e copie o Role ARN (formato arn:aws:iam::SUA_CONTA:role/WiserOpsReadOnly).

Passo 3: conectar no painel

Volta no WiserOps, cola o Role ARN, clica "Validar". A ferramenta faz três chamadas em sequência:

sts:AssumeRole           → token temporário (15min)
sts:GetCallerIdentity    → confirma que a Role é acessível
iam:ListAccountAliases   → confirma permissão read

Se as três passam, tá conectado. O primeiro scan dispara automaticamente.

Quando dá "AccessDenied"

Esse é o erro mais comum, e quase sempre significa uma de cinco coisas:

  • A Trust Policy não autoriza a conta da ferramenta, ou seja, o Principal está errado. Verifique o account ID.
  • O External ID não bate. Confirme o valor exato, espaços em branco extras quebram.
  • A Role existe mas ainda não propagou. IAM tem uns 30 segundos de delay depois do Create, é só esperar.
  • A conta da ferramenta foi autorizada, mas a Role não tem nenhuma policy anexada (então GetCallerIdentity passa e ListAccountAliases falha).
  • Algum SCP no AWS Organizations está bloqueando. Verifique nas SCPs da sua OU.

No WiserOps, o botão "Verificar role" faz esse diagnóstico e devolve qual dos cinco falhou. Se a sua ferramenta só diz "AccessDenied genérico" sem desambiguar, pede suporte. Esse diagnóstico é o que separa uma hora de dor de um Slack rápido.

Revogação

Pra desconectar a qualquer momento, você não precisa avisar a ferramenta. Deleta a Role no IAM (ou remove as policies anexadas). O próximo sts:AssumeRole falha e a ferramenta perde acesso imediatamente. Zero cerimônia.

Por que isso é padrão de mercado

Cross-account Role com External ID é o padrão recomendado pela própria AWS, pelo NIST, pelo CIS Benchmark, e é o que praticamente toda ferramenta cloud-native séria usa (Wiz, Prowler, Vanta, Drata, Datadog, WiserOps). Quando uma ferramenta ainda pede AKIA + Secret Access Key, é sinal vermelho. Ou o produto é antigo, ou alguém tá cortando caminho em segurança. Você não quer nem um, nem outro.


No WiserOps, o setup inteiro leva dois minutos via CloudFormation Quick-Create. Zero chave privada saindo da AWS, zero chance de vazar. Começa grátis.