Docs

Condições

Condições de relação no OpenFGA e condições de chamada em CEL no PDP, e por que cada uma mora onde mora.

Existem dois tipos de condição, e o critério para separar é simples: sobre o que a condição fala.

Condição de relação

É uma propriedade da relação, conhecida quando ela é publicada. Hoje existe uma: a expiração. Uma delegação ou uma capacidade podem ter data de fim. O OpenFGA avalia a condição com a hora atual que o PDP envia, como no guia de autorização por tarefa do OpenFGA. Quando vence, a relação deixa de existir para a decisão, sem ninguém precisar apagá-la.

Condição de chamada

É uma expressão CEL que lê os dados da chamada: os argumentos originais, o sujeito, o objeto da chamada e os trusted attributes que o PIP trouxe de uma context source. No Admin ela é uma regra, escrita por aresta, a combinação agente · server · tool. Uma regra como esta, numa tool de reembolso, limita o valor ao limite de reembolso que a API de RH informou para a pessoa que delegou:

context.chokepoint.arguments["amount"] <= subject.properties.chokepoint["<binding>"].values["refund_limit"]

<binding> é o identificador do binding que fornece os trusted attributes; o editor de regras preenche esse valor.

A condição precisa devolver booleano. Ela declara os bindings de que depende, e se um deles falta, a chamada é bloqueada em vez de avaliada sem o trusted attribute. Os números chegam ao CEL como double, então operações inteiras pedem int() explícito.

Presença e binding

Uma condição de chamada também pode ler como o token foi obtido (Contexto confiável). Esta condição, numa tool que apaga dados, permite a chamada só a partir de um harness login, com uma pessoa presente:

context.chokepoint.subject.presence == "interactive"

E esta também exige um token preso à chave do harness com DPoP:

context.chokepoint.subject.presence == "interactive" && context.chokepoint.binding == "dpop"

Nada é negado por presença por padrão: sem condição, os dois modos chamam as mesmas tools.

De onde vem o limite

A condição compara um valor da chamada com um limite. O limite vem de um destes lugares:

FonteExemploVale para
Valor fixo na regra do Adminamount <= 1000Toda chamada do agente nessa tool
Fato da API de confiança do cliente (PIP)o limite de reembolso que a cobrança informouO sujeito ou o recurso consultado
Limite da instância do agentemax_amount = 100 no tokenSó as chamadas dessa instância

Instâncias do mesmo agente rodam ao mesmo tempo, com as mesmas relações. O limite de uma instância vem no token que ela recebe na troca, no parâmetro authorization_details da RFC 9396. O token é assinado, então um limite alterado invalida a assinatura (Limites da instância tem o formato e as regras de validação). A regra lê o limite em context.chokepoint.limits:

double(context.chokepoint.arguments.amount) <= double(context.chokepoint.limits.max_amount)

O Admin não oferece limites de instância por enquanto: o agente define o próprio limite no token, então não é um controle do administrador; um limite é conferido a cada chamada, sem total entre chamadas; e o login pelo harness não envia limites.

O limite da instância só estreita o acesso. Todas as condições da aresta valem juntas, então o valor fixo do Admin continua valendo. Se a regra declara um limite e o token veio sem ele, a chamada é negada com motivo condition.

Por que a condição fica na aresta

Uma condição presa a uma pessoa teria que ser repetida para cada pessoa. Presa a um recurso, valeria para qualquer agente que tocasse nele. Presa à aresta agente · tool, ela descreve o que aquele agente pode fazer com aquela tool, que é a unidade que o administrador configura e que o Admin mostra.

Um limite de quantidade de chamadas não é uma condição de relação no OpenFGA: ele exige contar chamadas com reserva antes da execução e regras para falhas e janelas de tempo, e não faz parte do modelo atual.