DEV Community

César Augusto de Fázio
César Augusto de Fázio

Posted on AI-assisted

Policies no OCI: Otimização

Otimizar policies de IAM no OCI é garantir que a pessoa certa tenha a autorização certa para o recurso certo, com o menor número possível de statements.

No começo, é comum que uma tenancy tenha poucas policies, escritas uma de cada vez, conforme surgem novos projetos, equipes e exceções.

Com o tempo, esse acúmulo vira um problema: statements duplicados, permissões redundantes e regras que ninguém sabe mais por que existem.

Neste artigo, veremos por que vale a pena otimizar suas policies, três boas práticas para fazer isso e como os Dynamic Groups entram nessa história.

O que é otimização de policies no OCI IAM?

A otimização de policies no OCI IAM consiste em consolidar permissões por meio de famílias agregadoras, herança de compartments e união de múltiplos grupos em uma única instrução. De acordo com a Oracle, o limite é de 500 statements somando todas as políticas escritas desde o compartimento raiz (root) até o último compartimento. Otimizar as policies evita que a tenancy atinja o limite máximo de statements, reduz o overhead de auditoria de segurança e mantém o princípio do menor privilégio.

Três Razões Para Otimizar Suas Policies no OCI

Otimizar policies não é só uma questão de organização. Uma tenancy com statements demais paga o preço em três frentes: no desempenho das chamadas de API, na proximidade dos limites que a Oracle impõe e no esforço para entender quem pode fazer o quê.

1. Melhor performance e escalabilidade

Cada chamada de API no OCI passa pela avaliação das policies que se aplicam a ela. Quanto mais policies existem, mais statements precisam ser avaliados. Isso torna as chamadas lentas.

2. Evitar os limites do OCI

A Oracle impõe um limite rígido de 500 policies por tenancy. Quando ele é atingido, não há como criar novas regras sem antes remover ou consolidar as existentes. A saída é usar agregadores: menos policies significam mais espaço para a tenancy crescer.

Exemplos de agregadores: virtual-network-family, data-science-family, devops-family...

3. Gerenciamento simplificado

Quanto menos policies, mais fácil é auditar, gerenciar e atualizar. Quando alguém pergunta "quem pode fazer o quê neste compartment?", a resposta deve estar em poucas linhas, não espalhada por dezenas de statements.

As Três Melhores Práticas da Otimização de Policies do OCI

As práticas a seguir não exigem ferramentas nem mudanças na estrutura da tenancy. São ajustes na forma de escrever statements que, aplicados com consistência, reduzem o volume de policies sem abrir mão do menor privilégio.

1. Evite duplicatas: una os grupos

Quando dois grupos precisam exatamente da mesma permissão no mesmo lugar, não há motivo para escrever dois statements. Um único statement pode citar vários grupos:

allow group DomainA/GroupA, DomainB/GroupB to manage instances in compartment XPTO
Enter fullscreen mode Exit fullscreen mode

Em vez de duas linhas quase idênticas, você mantém uma. Se a permissão mudar, a alteração é feita em um só lugar.

2. Evite redundância: confie na herança

No OCI, compartments têm hierarquia, e as permissões concedidas em um compartment são herdadas. Por exemplo, considere esta estrutura:

Compartment A
└── Compartment B
    └── Compartment C
Enter fullscreen mode Exit fullscreen mode

Agora, imagine estas três policies:

# Policy no Compartment A
allow group ops to manage instances in compartment A

# Policy no Compartment B (Redundante)
allow group ops to manage instances in compartment B

# Policy no Compartment C (Ignorada)
allow group ops to manage instances in compartment C where request.permission = 'INSTANCE_READ'
Enter fullscreen mode Exit fullscreen mode

A primeira policy já resolve tudo: pela herança, o grupo ops pode gerenciar instâncias em A, B e C.

A segunda é redundante. Ela concede algo que a herança já garantia, e só ocupa espaço.

A terceira é mais traiçoeira. A intenção parece ser limitar o grupo ops a apenas ler instâncias no Compartment C. Mas ela é ignorada na prática: o grupo continua com acesso total às instâncias de C, herdado de A.

No OCI IAM, a permissão máxima tem precedência; uma policy mais restrita em um compartment filho não retira o que foi concedido acima.

3. Combine policy statements

Suponha um operador de TI, do grupo ITOperators, que precisa criar uma VM no compartment XPTO. Que permissões ele vai precisar?

Sem agregador, são três statements:

allow group ITOperators to use subnets in compartment XPTO
allow group ITOperators to manage instances in compartment XPTO
allow group ITOperators to read app-catalog-listing in compartment XPTO
Enter fullscreen mode Exit fullscreen mode

Com permissões granulares, tudo cabe em um só:

allow group ITOperators to { PERMISSÃO_1, PERMISSÃO_2, PERMISSÃO_3, TODAS_AS_PERMISSÕES_AQUI } in compartment XPTO
Enter fullscreen mode Exit fullscreen mode

O statement fica mais difícil de ler, mas o número de statements na sua tenancy diminui. Em uma tenancy grande, essa troca costuma valer a pena: potencialmente 1 statement por grupo!

Criando Dynamic Groups

Um Dynamic Group agrupa recursos, como VMs, bancos de dados e funções, e permite que eles acessem outros recursos e serviços dentro do OCI. Assim como um grupo comum reúne usuários, um Dynamic Group reúne recursos, e as policies passam a valer para eles.

A vantagem é que a aplicação rodando em uma VM, por exemplo, pode ler um bucket do Object Storage sem guardar credenciais no código.

Passo 1: crie o Dynamic Group

No console, acesse Identity & Security > Domains, escolha o domínio e abra Dynamic groups.

Dê um nome ao grupo, por exemplo app-vms, e uma descrição.

Passo 2: defina as regras de pertencimento

As regras de pertencimento (matching rules) dizem quais recursos fazem parte do grupo. Por exemplo, para incluir todas as instâncias de um compartment:

ALL {instance.compartment.id = 'ocid1.compartment.oc1..xxxxx'}
Enter fullscreen mode Exit fullscreen mode

Qualquer instância criada nesse compartment entra no grupo automaticamente, sem precisar ser adicionada manualmente.

Passo 3: defina as políticas de acesso

Por fim, escreva a policy que concede ao Dynamic Group o acesso necessário:

allow dynamic-group app-vms to read objects in compartment XPTO
Enter fullscreen mode Exit fullscreen mode

As mesmas boas práticas vistas acima valem aqui: una grupos quando possível, confie na herança e combine statements.

Resource Principal Patterns

Alguns serviços, como OCI Functions e Autonomous Database, agem em nome próprio por meio de resource principals. Em vez de usar credenciais de um usuário, o próprio recurso se autentica no OCI e recebe as permissões definidas para o Dynamic Group ao qual pertence.

Os tipos de resource principal

A Oracle descreve quatro padrões de resource principal, que podem ser combinados para identificar qualquer recurso da nuvem. Três deles importam para quem escreve policies:

Padrão de Principal Mecanismo de Identidade Exemplo de Matching Rule Caso de Uso Típico
Infrastructure Principal Identificador físico da infraestrutura ALL {instance.compartment.id = 'ocid1.compartment...'} Instâncias de Compute (VMs e Bare Metal)
Ephemeral Principal Identidade temporária injetada em runtime ALL {resource.type = 'fnfunc', resource.compartment.id = 'ocid1.compartment...'} OCI Functions e tarefas transitórias
Stacked Principal Identidade lógica projetada sobre infraestrutura gerenciada ALL {resource.type = 'autonomousdatabase', resource.compartment.id = 'ocid1.compartment...'} Bancos de dados gerenciados e caches
Asserted Principal Consolidação de recurso coletivo em identidade única Definido internamente pelo serviço gerenciado Object Storage e pipelines de ingestão

Na prática, a diferença aparece na regra de pertencimento: um Infrastructure Principal é selecionado pelas variáveis de instância, enquanto Ephemeral e Stacked Principals são selecionados por resource.type, resource.id e resource.compartment.id.

Fontes: Identities for Everything (blog Oracle) · Stacked identities for resource principals (patente)

Na prática, o padrão se repete: um Dynamic Group define quais recursos são principals, e uma policy define o que eles podem fazer. O que muda de um padrão para outro é a regra de pertencimento. A variável resource.type vem do próprio OCID do recurso: uma função tem OCID ocid1.fnfunc..., então seu tipo é fnfunc (para OCI Functions).

Padrão 1: todos os recursos de um tipo em um compartment

É o padrão mais comum. Toda função criada no compartment entra no grupo automaticamente:

ALL {resource.type = 'fnfunc', resource.compartment.id = 'ocid1.compartment.oc1..xxxxx'}
Enter fullscreen mode Exit fullscreen mode

Padrão 2: um recurso específico

Quando só uma função deve ter acesso, a regra aponta para o OCID dela:

resource.id = 'ocid1.fnfunc.oc1.iad.xxxxx'
Enter fullscreen mode Exit fullscreen mode

É o padrão mais restrito, mas exige atualizar a regra sempre que a função for recriada, porque o OCID muda.

Padrão 3: por tag

A regra seleciona os recursos que têm uma defined tag com determinado valor:

ALL {tag.Mediflow.Instances.value = 'mediflow-vm'}
Enter fullscreen mode Exit fullscreen mode

Basta aplicar a tag a um novo recurso para que ele entre no grupo. Free-form tags não são suportadas nas regras.

Nos três padrões, a policy é a mesma:

allow dynamic-group func-dyn-grp to read objects in compartment XPTO
Enter fullscreen mode Exit fullscreen mode

Padrão 4: sem Dynamic Group

Alguns serviços aceitam uma policy que dispensa o Dynamic Group, usando any-user com uma condição sobre o tipo de principal:

allow any-user to read objects in compartment XPTO where ALL {request.principal.type = 'fnfunc'}
Enter fullscreen mode Exit fullscreen mode

Isso economiza um Dynamic Group, mas any-user é amplo: a condição é a única coisa que restringe o acesso. Para fechar mais, combine o tipo com o OCID do principal:

allow any-user to read objects in compartment XPTO where ALL {request.principal.type = 'fnfunc', request.principal.id = 'ocid1.fnfunc.oc1.iad.xxxxx'}
Enter fullscreen mode Exit fullscreen mode

A própria documentação mostra que as duas formas são equivalentes: a regra ALL {resource.type = '...'} no Dynamic Group produz o mesmo efeito da condição request.principal.type = '...' com any-user.

Fontes: Acessando recursos do OCI a partir de Functions · Regras de pertencimento de Dynamic Groups · Policies de Data Science sem Dynamic Groups

Conclusão

Policies otimizadas são mais rápidas de avaliar, cabem dentro dos limites do OCI e são mais fáceis de auditar. Evitar duplicatas, confiar na herança e combinar statements são passos simples que mantêm a tenancy organizada à medida que ela cresce.

Os Dynamic Groups completam essa otimização: com uma regra de pertencimento por compartment, tipo ou tag, um único statement passa a valer para todos os recursos que se encaixam nela, sem precisar de uma policy para cada recurso.

FAQ

Qual é a diferença entre uma policy e um statement no OCI?

Uma policy é o documento contêiner criado no console ou na API do OCI, enquanto os statements são as linhas de instrução individuais contidas dentro dela. Uma única policy pode abrigar vários statements que concedem permissões específicas a grupos ou recursos.

O que acontece quando se atinge o limite de statements na tenancy?

Quando a tenancy atinge o limite de statements, o OCI bloqueia a inclusão de novas instruções de autorização. Qualquer deploy via console, CLI ou Terraform que tente cadastrar uma nova regra falha até que statements antigos ou redundantes sejam consolidados ou excluídos.

Uma policy em um compartment filho pode bloquear o acesso herdado do pai?

Não. O mecanismo de avaliação do OCI IAM adota permissão aditiva baseada em concessão positiva (allow). Se um nível superior concede autorização a um grupo, uma regra mais restrita no nível inferior não tem a capacidade de revogar o privilégio herdado.

Quando vale a pena usar dynamic groups em vez de usuários normais?

Dynamic Groups devem ser usados sempre que código, tarefas automatizadas, instâncias ou funções precisarem interagir com as APIs do OCI. Isso elimina a necessidade de armazenar credenciais estáticas, senhas ou tokens dentro do código-fonte ou em arquivos de configuração.

Top comments (0)