<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[sozua.dev]]></title><description><![CDATA[sozua.dev]]></description><link>https://sozua.dev</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 04:14:39 GMT</lastBuildDate><atom:link href="https://sozua.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Entendendo OpenFGA: Fundamentos, Modelagem e Otimização]]></title><description><![CDATA[A arquitetura de autorização apoia-se frequentemente em modelos estabelecidos, cada um com seus trade-offs. O RBAC (Role-Based Access Control) é eficiente para estruturas estáticas, enquanto o ABAC (Attribute-Based) e OPA (Policy-as-Code) trazem flex...]]></description><link>https://sozua.dev/entendendo-openfga</link><guid isPermaLink="true">https://sozua.dev/entendendo-openfga</guid><category><![CDATA[openfga ]]></category><category><![CDATA[rebac]]></category><category><![CDATA[authorization]]></category><category><![CDATA[Security]]></category><dc:creator><![CDATA[Diogo de Souza]]></dc:creator><pubDate>Mon, 01 Dec 2025 02:24:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1764555832020/4c80b251-fe6a-4f39-b9d0-9e8d6b3356d7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A arquitetura de autorização apoia-se frequentemente em modelos estabelecidos, cada um com seus <em>trade-offs</em>. O <strong>RBAC</strong> (Role-Based Access Control) é eficiente para estruturas estáticas, enquanto o <strong>ABAC</strong> (Attribute-Based) e <strong>OPA</strong> (Policy-as-Code) trazem flexibilidade via atributos. No entanto, essas abordagens degradam em performance quando a permissão depende de uma topologia de dados complexa e profundidade hierárquica (ex: pastas aninhadas).</p>
<p>O <strong>OpenFGA</strong> resolve esse gargalo adotando o modelo do Google Zanzibar: a autorização deixa de ser uma verificação de regras para se tornar uma navegação em grafo de relacionamentos (ReBAC).</p>
<h2 id="heading-1-modelagem-o-caso-google-drive">1. Modelagem: O Caso "Google Drive"</h2>
<p>Ao projetar sistemas de permissão hierárquicos, caímos em um dilema clássico. Modelos mais normalizados reduzem redundância e evitam atualizações em massa, mas tornam a leitura de hierarquias profundas dependente de queries recursivas custosas. Modelos mais desnormalizados aceleram algumas leituras, mas aumentam drasticamente o volume de escrita: mover uma pasta com 100.000 arquivos pode exigir atualizar 100.000 registros de permissão para manter a consistência.</p>
<p>O OpenFGA resolve esse dilema alterando a natureza da verificação para um “cálculo de rota” num grafo. A complexidade de escrita mantém-se constante (O(1)), pois basta alterar uma aresta (como o pai da pasta) para que o acesso seja propagado instantaneamente, sem os custos de latência de leitura das abordagens puramente relacionais.</p>
<p>A unidade fundamental para construir esse grafo é a <strong>Tupla</strong>: <code>User [...] Relation [...] Object</code>.</p>
<p>Para ilustrar, vamos modelar esse sistema de arquivos:</p>
<h3 id="heading-a-dsl-e-a-resolucao-de-grafos">A DSL e a Resolução de Grafos</h3>
<pre><code class="lang-xml">model
  schema 1.1

type user

type folder
  relations
    define viewer: [user]

type document
  relations
    define parent: [folder]
    define viewer: [user] or viewer from parent
</code></pre>
<p>O ponto-chave é a cláusula <strong>viewer from parent</strong>.</p>
<p>Ela permite que o sistema deduza permissões sem duplicar informação. Quando o OpenFGA precisa saber se <em>anne</em> pode ver <code>document:A</code>, ele simplesmente segue a relação até <code>folder:Pai</code>. Se <em>anne</em> já é viewer da pasta, o acesso é permitido.</p>
<p>Esse encadeamento reduz o tamanho do conjunto de dados e mantém a verificação rápida, mesmo em <em>hierarquias profundas</em>.</p>
<h2 id="heading-2-arquitetura-e-resiliencia-no-caminho-critico">2. Arquitetura e Resiliência no Caminho Crítico</h2>
<p>No dia-a-dia, utilizar o OpenFGA significará que cada requisição da aplicação depende da autorização do serviço do OpenFGA, então qualquer variação de latência afeta todo o sistema diretamente.</p>
<p>A solução para reduzir esse problema passa primeiro pela imutabilidade dos modelos: como um modelo em produção nunca muda enquanto está sendo usado, não há risco de uma alteração gerar comportamentos inconsistentes ou erros intermitentes no meio do fluxo. A lógica de autorização permanece fixa, o que evita surpresas no ponto onde a aplicação mais precisa de previsibilidade.</p>
<p>A escolha por consistência eventual segue a mesma linha prática. Em ambientes distribuídos, buscar sempre a leitura mais atual implica adicionar latência constante a cada verificação. Como autorizações acontecem o tempo todo e criações de permissão são menos frequentes, vale mais a pena aceitar alguns milissegundos de defasagem na escrita para manter o caminho de leitura o mais rápido possível.</p>
<p>E a topologia entra fechando o ciclo: quanto menos rede houver entre a aplicação e o serviço de autorização, menor a latência você irá experimentar. Executar o OpenFGA como sidecar ou manter cache local reduz a verificação praticamente a uma operação local. Isso aumenta um pouco o consumo de recursos no nó (caso esteja utilizando o Kubernetes), mas elimina hops de rede e estabiliza a latência onde ela realmente importa.</p>
<h2 id="heading-3-dicas-de-otimizacao">3. Dicas de Otimização</h2>
<h3 id="heading-a-implicito-vs-explicito">A. Implícito vs. Explícito</h3>
<p>A API do OpenFGA permite que você faça requisições utilizando 2 abordagens quanto ao authorization model:</p>
<ol>
<li><p><strong>Implícita:</strong> O servidor busca qual é o modelo de autorização "mais recente" no banco.</p>
</li>
<li><p><strong>Explícita:</strong> O cliente envia o <code>authorization_model_id</code> diretamente.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763937981619/34d80762-26a9-4ad0-b9ef-7ddf49975040.png" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763937984214/7534554b-424f-4ca0-ac21-eaf5e1e39aea.png" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763937969796/ed7ec76e-884f-4684-b75b-7f05360973f2.png" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763937966422/4c019044-1f00-46ef-9a6f-474fb5bda910.png" alt /></p>
<p>Como mostram os testes, enviar o <code>authorization_model_id</code> reduz a latência de forma bem consistente. A abordagem implícita sempre adiciona um custo de latência que só piora conforme o modelo cresce.</p>
<h3 id="heading-b-evite-utilizar-operacoes-and-e-but-not">B. Evite utilizar operações AND e BUT NOT</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764553062748/9b98bf5a-defb-4a7e-82b3-a9857a9423cf.png" alt class="image--center mx-auto" /></p>
<p>Operadores como <strong>AND</strong> e <strong>BUT NOT</strong> custam mais porque obrigam o servidor a compor resultados de múltiplas consultas internas. Em vez de avaliar uma única relação, ele precisa buscar dois conjuntos, cruzar ou subtrair itens e só então montar a resposta final. O gráfico reflete <strong>exatamente esse trabalho extra</strong>. Quando a regra pode ser expressa sem esses operadores, o <code>ListObjects</code> tende a ter uma latência muito menor.</p>
]]></content:encoded></item><item><title><![CDATA[Prefix Delegation e Limites de Pods no EKS]]></title><description><![CDATA[Uma coisa que estranhei ao usar o EKS pela primeira vez foi que alguns Pods simplesmente paravam de funcionar ou ficavam em Pending, mesmo quando o Node tinha CPU e memória de sobra. Em outras plataformas, isso não costuma acontecer. A partir dessa o...]]></description><link>https://sozua.dev/eks-prefix-delegation</link><guid isPermaLink="true">https://sozua.dev/eks-prefix-delegation</guid><category><![CDATA[AWS]]></category><category><![CDATA[EKS]]></category><category><![CDATA[Kubernetes]]></category><dc:creator><![CDATA[Diogo de Souza]]></dc:creator><pubDate>Tue, 18 Nov 2025 04:09:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1763439205899/ed59b4c7-5299-4926-b4f1-6b3a75cce5ec.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Uma coisa que estranhei ao usar o EKS pela primeira vez foi que alguns Pods simplesmente paravam de funcionar ou ficavam em <em>Pending</em>, mesmo quando o Node tinha CPU e memória de sobra. Em outras plataformas, isso não costuma acontecer. A partir dessa observação, ficou claro que entender “capacidade” no EKS exige olhar além das métricas tradicionais.</p>
<p>Acontece que a capacidade do Node depende da quantidade de IPs que a instância (do EC2) pode receber da VPC. Se os IPs acabam, os Pods param, mesmo que o resto dos recursos esteja disponível.</p>
<h2 id="heading-entendendo-o-limite">Entendendo o limite</h2>
<p>No EKS, cada Pod consome um IP da VPC, e <a target="_blank" href="https://github.com/awslabs/amazon-eks-ami/blob/main/templates/shared/runtime/eni-max-pods.txt">cada instância tem um limite fixo de IPs disponíveis pelas suas ENIs</a>.</p>
<p>Para confirmar, você pode olhar o <code>Allocatable</code>:</p>
<pre><code class="lang-bash">kubectl describe nodes | grep -i pods:
</code></pre>
<p>Se o número parecer baixo demais para o Node escolhido, geralmente é isso.</p>
<h2 id="heading-prefix-delegation">Prefix Delegation</h2>
<p>Prefix Delegation surge então como solução para esta dependência de IP individual. Em vez de solicitar IP por IP, o CNI passa a solicitar blocos, como um <code>/28</code>. Isso dá ao Node uma margem maior sem precisar subir para tipos de instância mais caros só por conta desta questão.</p>
<p>Para configurar, rode os comandos</p>
<pre><code class="lang-bash">aws eks update-addon \
  --cluster-name &lt;cluster&gt; \
  --addon-name vpc-cni \
  --resolve-conflicts PRESERVE
</code></pre>
<p>E depois:</p>
<pre><code class="lang-bash">kubectl <span class="hljs-built_in">set</span> env daemonset aws-node \
  -n kube-system ENABLE_PREFIX_DELEGATION=<span class="hljs-literal">true</span>
</code></pre>
<p>Os Pods do <code>aws-node</code> reiniciam, e o cluster passa a operar no modo de prefixo.</p>
<h2 id="heading-conclusao">Conclusão</h2>
<p>No fim, prefix delegation não muda o Kubernetes. Ele só altera como o EKS gerencia IPs. Isso costuma ser suficiente para permitir Nodes menores, com densidade maior, e um cluster mais previsível.</p>
<p>No geral, o benefício real é evitar aquela situação-problema apontado no inicio do texto. Com prefix delegation, a capacidade passa a refletir melhor o que o Node realmente consegue entregar.</p>
]]></content:encoded></item></channel></rss>