EKS, grupos IAM, "dono do cluster" e system:masters
Published: 2022-02-03 04:22:45

O **EKS** tem uma maneira bem peculiar de lidar com permissões de acesso. Vamos analisar algumas delas?

## Dando permissão a outros usuários no EKS

A principal maneira para viabilizar o acesso a outros usuários é por meio da configuração do ConfigMap **aws-auth** na namespace **kube-system**, como descrito [aqui](https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html). 

Suponha que você tenha um time de administradores Kubernetes em um grupo IAM e queira habilitá-los em todos os clusters criados. Como fazer?

Bem, é possível associar **usuários IAM** e **roles IAM** ao ConfigMap; entretanto, **não** é possível adicionar **grupos IAM**! Vai ter que adicionar um a um. [Esta issue](https://github.com/kubernetes-sigs/aws-iam-authenticator/issues/176) está aberta desde 2018 e não parece ter ninguém trabalhando nisso. 

[Aqui](https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html) está o trecho da documentação que confirma:
> Add your IAM users, roles, or AWS accounts to the ConfigMap. You cannot add IAM groups to the ConfigMap.

O ConfigMap abaixo mostra um exemplo dessa configuração:

```yaml
apiVersion: v1
data:
  mapRoles: |
    - rolearn: arn:aws:iam::111122223333:role/eksctl-my-cluster-nodegroup-standard-wo-NodeInstanceRole-1WP3NUE3O6UCF
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes
  mapUsers: |
    - userarn: arn:aws:iam::111122223333:user/admin
      username: admin
      groups:
        - system:masters
    - userarn: arn:aws:iam::444455556666:user/ops-user
      username: ops-user
      groups:
        - eks-console-dashboard-full-access-group
    - userarn: arn:aws:iam::444455556666:user/ops-user2
      username: ops-user2
      groups:
        - eks-console-dashboard-restricted-access-group
```

Ah, se seu cluster não tem NodeGroups, você vai precisar criar o ConfigMap do zero, ele não vai estar disponível - isso não é um bug!

## O dono da bola... quero dizer, do cluster
Extraído da [documentação oficial](https://docs.aws.amazon.com/eks/latest/userguide/security_iam_service-with-iam.html):

> When you create an Amazon EKS cluster, the AWS Identity and Access Management (IAM) entity user or role, such as a federated user that creates the cluster, is automatically granted system:masters permissions in the cluster's role-based access control (RBAC) configuration in the Amazon EKS control plane. 

Então, temos a definição de um papel específico (vamos chamar de **ClusterOwner**), que é automaticamente atribuído ao usuário que criou o Cluster EKS. Esse usuário automaticamente vira **system:masters**.

(Na verdade, pode ser um usuário, ou pode ser uma Role IAM usada por meio de AssumeRole, por exemplo.)

Qual a parte estranha?

> This IAM entity doesn't appear in any visible configuration, so make sure to keep track of which IAM entity originally created the cluster. 

Se você foi contratado hoje por uma empresa com 100 clusters Kubernetes, se alguém te perguntar quem é o "ClusterOwner" de cada um dos clusters, você simplesmente não tem como saber! Espero alguém tenha os logs de todos os pipelines de infraestrutura que geraram os clusters e os CloudTrails bem guardados!

Um outro inconveniente: seu pipeline tem que finalizar a criação do cluster fornecendo as permissões para as pessoas corretas, ou você precisará assumir a mesma Role do pipeline (ou usar as mesmas credenciais de usuário) para poder configurar seu acesso.

Isso quer dizer que, definitivamente, você não pode ficar criando clusters "de qualquer jeito". Não que se deva criar clusters Kubernetes na mão usando **eksctl** para ambientes de produção, mas, para um serviço "gerenciado", ele exige que você pense bastante na arquitetura de deploy antes mesmo de começar a usar!

Em especial porque, assim como não é possível identificar quem é o "ClusterOwner", também não é possível **revogar o acesso do criador**!

A boa notícia é que este assunto está [sendo](https://github.com/aws/containers-roadmap/issues/554) [trabalhado](https://github.com/aws/containers-roadmap/issues/185) pela AWS. A má notícia é que já faz algum tempo (desde 2020). Vamos torcer que esteja mais perto do que longe!

## "ClusterOwner" e system:masters

O grupo **system:masters** é um dos "grupos" que são harcoded no Kubernetes; se o usuário for reconhecido como parte deste grupo, ele automaticamente é considerado "**root**" (administrador) daquele Cluster.

A pergunta é: **como** o EKS atribui o "ClusterOwner" a este grupo, se não é visível em lugar algum? 

Bem, a AWS não documenta muito bem esse processo, mas podemos tentar inferir a partir de documentações espalhadas por aí.

[Este projeto](https://github.com/kubernetes-sigs/aws-iam-authenticator#full-configuration-format) contém uma ferramenta originalmente criada pela Heptio para viabilizar a autenticação IAM em clusters Kubernetes. Não é exclusiva do EKS, é possível usá-la em um cluster que você mesmo subiu em EC2, por exemplo.

A ideia é executá-lo nos nós de Controlplane expondo portas ao APIServer local.

O API Server pode se comunicar com este programa por meio de uma configuração:

```
--authentication-token-webhook-config-file=/etc/kubernetes/aws-iam-authenticator/kubeconfig.yaml
```

Esse programa conta com a opção de usar múltiplos **backends**. Aparentemente temos três opções:

* EKSConfigMap
* CRD
* MountedFile

O primeiro é bem sugestivo: implementa o uso de um ConfigMap semelhante ao visto acima com o aws-auth. O segundo tem um **alpha** bem grande escrito ao lado e me parece uma opção bem mais interessante que os altamente "error-prone" ConfigMaps da AWS.

Agora a terceira opção aparenta conter nossa resposta: a configuração de [MountedFile](https://github.com/kubernetes-sigs/aws-iam-authenticator#full-configuration-format).

É possível especificar mais de um backend:

```
--backend-mode=EKSConfigMap,MountedFile
```

Então, é bastante provável que, em algum lugar no Controlplane EKS, temos os APIServers apontando para o aws-iam-authenticator configurado com as opções acima, e usando um arquivo com este conteúdo como "Mountedfile":

```
...
  - roleARN: arn:aws:iam::000000000000:role/KubernetesAdmin
    username: admin:{{SessionName}}
    groups:
    - system:masters
...
``` 

Não achei isso documentado de verdade em lugar nenhum, mas acredito que seja um bom palpite!

Se você tem alguma prova mais concreta, comenta aí para eu atualizar o post!