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:
| Fonte | Exemplo | Vale para |
|---|---|---|
| Valor fixo na regra do Admin | amount <= 1000 | Toda chamada do agente nessa tool |
| Fato da API de confiança do cliente (PIP) | o limite de reembolso que a cobrança informou | O sujeito ou o recurso consultado |
| Limite da instância do agente | max_amount = 100 no token | Só 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.