Preparar AWS para cosigner

Esta secao mostra o que precisa estar pronto na AWS antes da instalacao do cosigner. O foco aqui e preparar a base da infraestrutura de forma simples, explicando por que cada recurso existe e como ele se encaixa no modelo da Hotwallets.

Antes de instalar o cosigner, voce precisa preparar a AWS corretamente.

Esta secao e propositalmente mais tecnica. O objetivo aqui e mostrar a configuracao da AWS no formato mais proximo do procedimento operacional real.

Arquitetura dos cosigners na AWS

Regras da Hotwallets para esta etapa

Hoje o cosigner da Hotwallets tem estas regras:

  • suporte somente em AWS Nitro Enclaves;
  • operacao com no minimo 2 cosigners;
  • cada cosigner deve ter seu proprio conjunto de recursos.

Na pratica, voce precisa repetir esta preparacao para pelo menos duas instancias separadas.

Visao geral do que sera criado

Para cada cosigner, prepare estes recursos:

  1. uma IAM Role;
  2. um bucket S3 para persistencia;
  3. uma KMS Customer Managed Key (CMK);
  4. as policies da IAM Role;
  5. uma EC2 compativel com Nitro Enclaves.

Step 1.2: criar e configurar a IAM Role

As IAM Roles sao usadas para delegar acesso aos recursos da AWS. Aqui, a role vai ligar a instancia EC2 aos recursos que o cosigner precisa usar.

No console da AWS:

  1. abra o servico IAM;
  2. entre em Roles;
  3. clique em Create role;
  4. em Trusted entity type, escolha AWS service;
  5. em Service or use case, escolha EC2;
  6. clique em Next;
  7. na tela Add permissions, nao selecione nada ainda;
  8. clique em **Next`;
  9. defina um nome para a role, por exemplo hotwallets-cosigner-1-role;
  10. crie a role sem alterar a trust policy.

O que copiar nessa etapa

Abra a role criada e copie o IAM ARN. Ele segue este formato:

arn:aws:iam::{ACCOUNT-ID}:role/{ROLE-NAME}

Exemplo:

arn:aws:iam::123456789012:role/hotwallets-cosigner-1-role

O que voce deve ver ao final

Ao terminar esta etapa, a area Permissions policies ainda deve estar vazia. Isso e esperado. As permissoes vao ser adicionadas depois que o bucket S3 e a chave KMS forem criados.

Step 1.3: criar e configurar o bucket S3

Crie o bucket que vai servir como persistencia do cosigner.

No console da AWS:

  1. abra o servico Amazon S3;
  2. clique em Create bucket;
  3. informe o nome do bucket;
  4. deixe o restante como padrao;
  5. crie o bucket;
  6. abra o bucket criado;
  7. entre na aba Permissions;
  8. na secao Bucket policy, clique em Edit;
  9. cole a policy abaixo;
  10. clique em Save changes.

Exemplo de nome

hotwallets-cosigner-1-storage

Bucket policy de exemplo

Troque:

  • {BUCKET-NAME} pelo nome real do bucket;
  • {ACCOUNT-ID} pelo ID da sua conta AWS;
  • {ROLE-NAME} pelo nome da role criada no passo anterior.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:ListBucket",
        "s3:ListBucketMultipartUploads",
        "s3:AbortMultipartUpload",
        "s3:GetObjectAcl",
        "s3:PutObjectAcl",
        "s3:RestoreObject"
      ],
      "Resource": [
        "arn:aws:s3:::{BUCKET-NAME}",
        "arn:aws:s3:::{BUCKET-NAME}/*"
      ],
      "Condition": {
        "ArnNotEquals": {
          "aws:PrincipalArn": "arn:aws:iam::{ACCOUNT-ID}:role/{ROLE-NAME}"
        }
      }
    }
  ]
}

O que copiar nessa etapa

Copie o Bucket ARN. Ele segue este formato:

arn:aws:s3:::{BUCKET-NAME}

Exemplo:

arn:aws:s3:::hotwallets-cosigner-1-storage

Step 1.4: criar e configurar a KMS Customer Managed Key

Crie a KMS Customer Managed Key que vai proteger o material sensivel do cosigner.

Criar a chave

No console da AWS:

  1. abra o servico AWS KMS;
  2. clique em Create key;
  3. em Key type, escolha Symmetric;
  4. em Key usage, escolha Encrypt and decrypt;
  5. abra Advanced options;
  6. em Key material origin, escolha KMS;
  7. em Regionality, escolha Single-Region key;
  8. clique em Next.

Observacao:

  • use Multi-Region key somente se a EC2 estiver em outra regiao.

Adicionar labels

Na tela Add labels:

  • em Alias, defina algo como hotwallets-cosigner-1;
  • opcionalmente preencha Description e Tags;
  • clique em Next.

Configurar permissoes administrativas

Na tela Define key administrative permissions:

  • deixe Key administrators em branco;
  • mantenha a opcao de Key deletion marcada;
  • clique em Next.

Na tela Define key usage permissions:

  • deixe Key users em branco;
  • clique em Next.

Finalizar a key policy

Na tela Review:

  1. role ate a secao Key policy;
  2. cole a policy abaixo;
  3. clique em Finish.

Troque:

  • {ACCOUNT-ID} pelo ID da sua conta;
  • {ROLE-NAME} pelo nome da IAM Role;
  • {PCR8-VALUE} pelo valor correspondente ao seu ambiente.

Valores de PCR8

Use o valor correto para o ambiente:

  • Global: da1d9eca20ce98ab4fdbc51f8e5a2307fd4c61829b7d8bff40976cd6676862c8f3476ff4bdd0f65ecf4a48d6eb3099a8
  • Europe: fffc94d68a150b49dc39b23954c793cd1a4f7972f528a1ee258dc130b6cd9454e29ae72ef66bd9697a55e774e17a2d49
  • Swiss: 69b1fbe9fb4ea49e084fe6f9f9623d871bd22ceb5efad47b1a8d3708e6674868cad8bf088ced3976c2194360c7d58219

KMS key policy

{
  "Version": "2012-10-17",
  "Id": "key-consolepolicy-4",
  "Statement": [
    {
      "Sid": "Enable enclave data processing for specific role",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::{ACCOUNT-ID}:role/{ROLE-NAME}"
      },
      "Action": [
        "kms:Decrypt",
        "kms:Encrypt",
        "kms:GenerateDataKey",
        "kms:GenerateDataKeyPair",
        "kms:GenerateDataKeyWithoutPlaintext",
        "kms:GenerateDataKeyPairWithoutPlaintext",
        "kms:GenerateRandom",
        "kms:GetKeyPolicy"
      ],
      "Resource": "*",
      "Condition": {
        "StringEqualsIgnoreCase": {
          "kms:RecipientAttestation:PCR8": "{PCR8-VALUE}"
        }
      }
    },
    {
      "Sid": "Allow GetKeyPolicy to co-signer",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::{ACCOUNT-ID}:role/{ROLE-NAME}"
      },
      "Action": "kms:GetKeyPolicy",
      "Resource": "*"
    },
    {
      "Sid": "Allow policy management to root user",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::{ACCOUNT-ID}:root"
      },
      "Action": [
        "kms:DescribeKey",
        "kms:GetKeyPolicy",
        "kms:PutKeyPolicy",
        "kms:CreateAlias"
      ],
      "Resource": "*"
    }
  ]
}

Aviso de policy no KMS

Ao colar essa policy, a AWS pode mostrar um aviso parecido com:

Unsupported Action For Condition Key

Nesta configuracao, esse aviso pode ser ignorado, porque a checagem de kms:RecipientAttestation:PCR8 so e avaliada nas chamadas que carregam atestado do enclave. Nem toda action usa esse contexto.

O que copiar nessa etapa

Abra a key criada e copie o KMS ARN. Ele segue este formato:

arn:aws:kms:{KEY-REGION}:{ACCOUNT-ID}:key/{KEY-ID}

Exemplo:

arn:aws:kms:us-east-1:123456789012:key/abcd1234-abcd-1234-abcd-1234567890ab

Step 1.5: editar a policy da IAM Role

Agora volte ao IAM e complete as permissoes da role criada no Step 1.2.

Anexar policy gerenciada

Na role criada:

  1. abra a secao Permissions policies;
  2. clique em Attach policies;
  3. selecione AmazonSSMManagedInstanceCore;
  4. clique em Add permissions.

Criar inline policy

Depois:

  1. ainda na secao Permissions policies, clique em Create inline policy;
  2. escolha a aba JSON;
  3. cole a policy abaixo;
  4. crie a policy com um nome claro.

Troque:

  • {BUCKET-NAME} pelo bucket real;
  • {KEY-REGION} pela regiao da KMS;
  • {ACCOUNT-ID} pelo ID da conta;
  • {KEY-ID} pelo ID real da key.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ListBuckets",
      "Effect": "Allow",
      "Action": "s3:ListAllMyBuckets",
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": "arn:aws:s3:::{BUCKET-NAME}"
    },
    {
      "Sid": "WritePermissionsOnBucket",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:PutObjectAcl",
        "s3:GetObject",
        "s3:GetObjectAcl",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::{BUCKET-NAME}/*"
    },
    {
      "Sid": "AccessToTheKey",
      "Effect": "Allow",
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:GenerateDataKey",
        "kms:GenerateDataKeyPair",
        "kms:GenerateDataKeyWithoutPlaintext",
        "kms:GenerateDataKeyPairWithoutPlaintext",
        "kms:GenerateRandom",
        "kms:GetKeyPolicy"
      ],
      "Resource": [
        "arn:aws:kms:{KEY-REGION}:{ACCOUNT-ID}:key/{KEY-ID}"
      ]
    }
  ]
}

Step 1.6: criar e configurar a instancia EC2

Requisito importante

Use apenas estes tipos de instancia:

  • c5.xlarge
  • c5a.xlarge

Motivo:

  • o enclave precisa de no minimo 2 vCPUs dedicadas e 4 GB de memoria;
  • o Nitro Enclaves pode usar ate 50% dos recursos da instancia host;
  • por isso o minimo recomendado aqui e 4 vCPUs e 8 GB de RAM.

Criar a instancia

No console da AWS:

  1. abra o servico EC2;
  2. clique em Launch instances;
  3. informe o nome da instancia;
  4. escolha a AMI Amazon Linux 2023 AMI com arquitetura 64-bit (x86);
  5. em Instance type, escolha c5.xlarge;
  6. se c5.xlarge nao estiver disponivel na sua regiao, use c5a.xlarge;
  7. em Network settings, restrinja o acesso SSH o maximo possivel;
  8. em Advanced details, configure:
    • IAM instance profile: a role criada nos passos anteriores;
    • Nitro Enclave: Enable;
    • Metadata version: V2 only (token required);
    • Metadata response hop limit: minimo de 2;
  9. revise a configuracao;
  10. clique em Launch instance.

Exemplo de configuracao

  • Name: hotwallets-cosigner-1-ec2
  • AMI: Amazon Linux 2023 AMI
  • Architecture: 64-bit (x86)
  • Instance type: c5.xlarge
  • IAM instance profile: hotwallets-cosigner-1-role
  • Nitro Enclave: Enabled
  • IMDS: V2 only
  • Hop limit: 2

Step 1.7: recomendacoes adicionais de seguranca

E altamente recomendado controlar acesso de usuarios e trafego de rede no ambiente AWS e na instancia EC2.

Na pratica:

  • restrinja SSH ao menor conjunto de IPs possivel;
  • revise VPC e subnet para evitar exposicao desnecessaria;
  • use security groups bem restritas;
  • nao compartilhe bucket, key e role entre cosigners diferentes;
  • repita o mesmo nivel de endurecimento no cosigner-2.

Repetir para o segundo cosigner obrigatorio

Como a Hotwallets exige no minimo 2 cosigners, nao pare no primeiro.

Repita o mesmo fluxo para o segundo cosigner:

  1. crie a segunda IAM Role;
  2. crie o segundo bucket S3;
  3. crie a segunda KMS key;
  4. anexe a policy da segunda role;
  5. crie a segunda EC2 com Nitro Enclaves.

Checklist final antes do instalador

Antes de executar install-ec2.sh, confirme para cada cosigner:

  • existe uma IAM Role dedicada;
  • existe um bucket S3 dedicado;
  • existe uma KMS key dedicada;
  • a role tem AmazonSSMManagedInstanceCore;
  • a role tem a inline policy correta;
  • a EC2 usa Amazon Linux 2023 AMI;
  • a EC2 usa c5.xlarge ou c5a.xlarge;
  • a EC2 esta com Nitro Enclave habilitado;
  • a EC2 esta com Metadata version em V2 only;
  • a EC2 esta com Metadata response hop limit em 2 ou mais;
  • o segundo cosigner obrigatorio tambem esta preparado.