hello guys. I am evaluating <Permit.io> capabiliti...
# permit-saas
a
hello guys. I am evaluating Permit.io capabilities, and I have a bunch of complex policies, involving multiple entities and attributes. I would be abale to express them as XACML or Alpha, but I am a bit unsure how to use the Control Plane to build them (also considering that Permit.io uses Rego as DSL)
a
Hi @antonello, I'm an AI assistant for Permit.io. I'll analyze available sources and get back to you shortly.
For complex, multi-entity, attribute-heavy policies, Permit.io gives you two complementary paths rather than forcing you into one. *Configuration Plane approach (recommended starting point) * Permit's Configuration Plane lets you model Resources, Resource Relationships, Roles (with Role Derivations) , Attributes, and Condition Sets that combine those attributes into match conditions (1) . Policies are the rules that determine allow/deny based on roles, resources, and condition sets . This covers RBAC, ABAC, and ReBAC style logic — so relationships between entities and attribute-based conditions similar to what you'd express in XACML can largely be modeled here without writing policy code directly . You can manage this via UI, Infrastructure as Code (Terraform provider) , or Raw Policy as Code . ​*Custom Policy (Rego) approach for what the UI can't express*​ When your logic goes beyond what's configurable in the UI, Permit.io supports extending policies with custom Rego code via GitOps (2) . Permit's policy repository has two folders,
permit
and
custom
, and you write your custom logic in the
custom
folder :
Copy code
package permit.custom
Copy code
default allow := false
You can then reference Permit's generated evaluation context, e.g.:
Copy code
import data.permit.policies
Copy code
allow {
 not "rbac" in policies.__allow_sources
}
Custom rules can pull in RBAC context too:
Copy code
import permit.rbac
To wire a custom package into the final decision,
root.rego
combines the default policies with your custom logic:
Copy code
allow {
 policies.allow
 custom.allow
}
You aren't limited to one custom file — you can add multiple files/folders under
custom
and either centralize them into one root file or import multiple custom packages into
root.rego
. Note: Permit.io is policy-engine agnostic and also supports AWS Cedar as an alternative to Rego if that fits your modeling style better (3) (4) . If you have specific policies you're trying to port from XACML/ALFA, the Permit.io team explicitly offers to help model them — the documentation states you can set up a meeting with their engineering team for advanced custom policy questions (2) .
To learn more, see the sources I considered: [[1] Modeling and Implementation Components](https://docs.permit.io/how-to/SDLC/modeling-implementation-components) [[2] Write Custom Policies](https://docs.permit.io/integrations/gitops/custom_policy) [[3] How does Permit.io work?](https://docs.permit.io/overview/how-does-it-work) [[4] Top Open-Source Authorization Tools for Enterprises in 2026](https://www.permit.io/blog/top-open-source-authorization-tools-for-enterprises-in-2026)
o
Hi there the AI support agent gave a good answer and links. Let us know if you need further human help, or tag it for follows
I'd further note that most leading agents e.g. Claude, ChatGPT, are well versed in Permit and can easily do most of the policy translation for you
a
@Or Weis I am more or less aware how to write Rego scripts to implement complex policies. Having to handover the Permit.io tool to a team, not necerraily with specific skillset on Rego, I would like to leverage the Control Plane that offers an easy-to-use UI for such design and configurations. Anyway, I found myself a bit lost using the UI for composing such complex ABAC policy sets, and I would like to ask the help of a specialist
o
Did you watch the any of the ABAC videos? e.g.

https://youtu.be/QCsWlsjEE5A?si=v6RG8mEIfyRERZAG▾

If you'd like a more white-glove level of service - please submit this form for Enterprise tier eligibility: https://permit.typeform.com/enterprise-form
a
@Or Weis Thank you for following up with this recommendation. I have watched. Unfortunately it doesn't cover my specific needs of complexity. It is possible that the UI offers the capabilities I am looking for, maybe underneath and not explicitly, but it's not immediately explicit
o
Hi @antonello please ask specific questions and tag the AI, you'd be surprised. Also I recommend these docs for a slightly deepr dive. https://docs.permit.io/how-to/build-policies/abac/patterns/
I'll ask a few example questions here
@Ask Inkeep how to bring in external data into the PDP via input or via OPAL
👍 1
a
Thanks for tagging me @Or Weis. I'll look through relevant sources and get back to you shortly.
OPAL is the mechanism for bringing external data into the PDP in real time. It's an administration layer for Policy Engines that detects changes to both policy and policy data, pushing live updates to your agents (1) (2) . The OPAL Client is deployed alongside the policy engine as part of the PDP, and it keeps the engine up to date by subscribing to topic-based Pub/Sub updates for both data and policy — fetching data from the OPAL Server and "any other relevant sources (e.g., DBs, APIs, 3rd party services) " (2) . The OPAL Server itself is hosted as part of Permit's Cloud Service, tracks a Git repository for policy updates, and pushes those as diffs to clients . On the data side, OPAL "allows tracking a specific policy repository (like GitHub, GitLab, or Bitbucket) for updates" for policy, and separately provides "the ability to track any relevant data source (API, Database, external service) for updates via a REST API, and fetch up-to-date data back into your policy engine" (3) . One important distinction: this OPAL-based external data sourcing (OPAL Scope / custom data sources) is available with the container PDP, but not with the managed Cloud PDP. The Cloud PDP does not let you configure OPAL Scope or custom data sources — instead you load data into Permit as "users, resource instances, tenants, relationship tuples, and role assignments," and the Cloud PDP consumes that managed data (4) . If you need "custom external data sources via OPAL Scope," the documentation says to use the container PDP instead . Regarding bringing data in "via input" at query time — the sources don't have explicit documentation on passing ad hoc external data directly as part of a single check call, so I don't have that detail to share.
To learn more, see the sources I considered: [[1] Concepts / Glossary](https://docs.permit.io/overview/glossary) [[2] How does Permit.io work?](https://docs.permit.io/overview/how-does-it-work) [[3] OPA, Cedar, OpenFGA: Why are Policy Languages Trending Right Now?](https://www.permit.io/blog/opa-cedar-openfga-why-are-policy-languages-trending) [[4] Cloud PDP Capabilities](https://docs.permit.io/concepts/pdp/cloud-pdp-capabilities)
o
@Ask Inkeep how to pass in additional data as input to permit.check attributes or context
a
Thanks for tagging me @Or Weis. I'll look through relevant sources and get back to you shortly.
The Check Function (
permit.check()
) is the core enforcement component, and it considers User, Action, Resource, and Context as elements when making a decision — where Context is defined as "any additional data that might be relevant for evaluating the policy decision" (1) . On the resource/user attribute side, the sources show attributes being passed as part of the user and resource objects rather than as a separate context parameter. For example, additional user attributes and resource attributes can be passed via the CLI's
pdp check
command:
Copy code
$ permit pdp check --user eventHandler --action update --resource Widget:dashboard-1-widget
(2) with optional enrichment arguments: •
--user-attributes
- additional user attributes to enrich the authorization check in the format:
key1=value1,key2=value2
•
-resource-attributes
- additional resource attributes to enrich the authorization check in the format
key1=value1,key2=value2
I don't have explicit documentation showing the exact SDK-level
permit.check()
call signature for passing attributes/context as arguments (e.g., in Python or Node.js) beyond the CLI example above. I do have confirmation that a bug involving inconsistent handling of
userAttributes
and
resourceAttributes
between single (
loadLocalState
) and bulk (
loadLocalStateBulk
) permission checks in the frontend SDK was reported and has since been closed as fixed (3) . If you want, I can look specifically for the SDK method signature for
check()
with attributes/context in a particular language (Python, Node.js, etc.) — let me know which SDK you're using.
To learn more, see the sources I considered: [[1] Modeling and Implementation Components](https://docs.permit.io/how-to/SDLC/modeling-implementation-components) [[2] Policy Decision Point (PDP) Commands](https://docs.permit.io/how-to/permit-cli/permit-cli-pdp) [[3] SDK GET request ignores userAttributes and resourceAttributes, causing inconsistency with bulk POST](https://github.com/permitio/permit-fe-sdk/issues/27)
o
@Ask Inkeep how to reference other variables as part of an ABAC policy set up via the API or UI
a
Thanks for tagging me @Or Weis. I'll look through relevant sources and get back to you shortly.
The available sources cover the building blocks of ABAC (Attributes and Condition sets) but don't include explicit walk-throughs of referencing one attribute against another within a condition set via the UI or API. What the sources do confirm about the Configuration Plane components involved: • ​*Attributes*​: specifications that define the characteristics of resources and users, which can be used to set conditions for access permissions (1) • ​*Condition sets*​: the ability to build conditions to match users or resources in a set, using the attribute configuration to configure
match
conditions • ​*Policy*​: the actual rules that determine whether access is allowed or denied based on roles, resources, and condition sets For the ABAC check itself, attributes are attached to the user and resource objects at check time. From the Node.js SDK:
Copy code
const permitted = permit.check(
 // the user object
 {
 // the user key
 key: "<mailto:check@permit.io|check@permit.io>",
 // just-in-time attributes on the user
 attributes: {
 location: "England",
 department: "Engineering",
 },
 },

 // the action the user is trying to do
 "action",
 // Resource
 {
 // the type of the resource (the resource key)
 type: "resource",
 // just-in-time attributes on the resource
 attributes: {
 hasApproval: "true",
 },
 // the tenant the resource belong to
 tenant: "tenant",
 }
) ;
(2) And the equivalent Python version:
Copy code
permitted = await permit.check(
 ///# User Set
 {
 "userId": "<mailto:check@permit.io|check@permit.io>",
 "attributes": {
 "location": "England",
 "department": "Engineering",
 },
 },
 ///# Action
 "action",

 ///# Resource Set
 {
 "type": "resource",
 "attributes": {
 "hasApproval": "true",
 },
 "tenant": "tenant",
 }
)
I don't have explicit documentation on the specific mechanics of referencing one variable/attribute against another (e.g., comparing a user attribute to a resource attribute) within a condition set's
match
logic, either through the UI or the API. If you want, I can give a general answer based on my broader knowledge instead, or you can point me to a more specific scenario to search for. Check out these potentially useful sources: Modeling and Implementation Components , Concepts / Glossary , Running a demo
To learn more, see the sources I considered: [[1] Modeling and Implementation Components](https://docs.permit.io/how-to/SDLC/modeling-implementation-components) [[2] Running a demo](https://docs.permit.io/overview/connecting-your-app)
a
@Ask Inkeep I want to use the ReBAC model, to determine if a user is in a given relationship with a resource. I want to create a policy that is based on this relationship, using the Policy Editor of the Permit.io Control Plane. Also, I want to create ABAC rules that use attributes of the resource (eg. "status", "type", etc.), and other ABAC rules that check the value of an attribute (eg. "owner") against the input "user key". In the end I would like to compose all these rules in a single policy that I can check
a
Thanks for tagging me @antonello. I'll look through relevant sources and get back to you shortly.
Here's what the sources confirm about each piece, and where the gaps are. *ReBAC (relationships) * ReBAC in Permit is based on Resource Roles and Role Derivations: a resource role is only relevant in the context of a specific resource, commonly denoted as ​*Resource#Role*​ (1) . Role Derivations let you construct a policy such as "a user who is assigned the role of an Owner on a folder will also get the Owner role on every file within that folder" . To model relationships and derivations conceptually, the Configuration Plane includes Resources with Resource Relationships (descriptions of potential connections between resources to facilitate permission derivation) , Roles with Role Derivations (mechanisms to extend permissions from one role to another using relationships) , Attributes, and Condition sets (2) . The sources don't include an explicit UI walkthrough of the Policy Editor screens/buttons for wiring up a relationship-based role derivation. *ABAC on resource attributes (e.g., "status", "type") * Attributes are specifications that define characteristics of resources and users, used to set conditions for access permissions, and Condition sets let you build conditions to match users or resources using that attribute configuration to configure
match
conditions . At check time, resource attributes are passed as part of the resource object, for example in Node.js:
Copy code
const permitted = permit.check(
  // the user object
  {
    // the user key
    key: "<mailto:check@permit.io|check@permit.io>",
    // just-in-time attributes on the user
    attributes: {
      location: "England",
      department: "Engineering",
    },
  },
  // the action the user is trying to do
  "action",
  // Resource
  {
    // the type of the resource (the resource key)
    type: "resource",
    // just-in-time attributes on the resource
    attributes: {
      hasApproval: "true",
    },
    // the tenant the resource belong to
    tenant: "tenant",
  }
) ;
(3) ​*ABAC checking an attribute (e.g., "owner") against the input "user key"*​ The sources don't include explicit documentation on referencing one attribute against another (such as comparing a resource's "owner" attribute to the input user key) within a condition set's
match
logic, either via UI or API. ​*Composing ReBAC + ABAC into a single checkable policy*​ The Policy component itself is described as "the actual rules that determine whether access is allowed or denied based on roles, resources, and condition sets" (2) , and the Enforcement Plane's Check Function (
permit.check()
) evaluates User, Action, Resource, and Context together . Beyond that framing, the sources don't detail the specific Policy Editor mechanics for combining a ReBAC-derived role condition with ABAC attribute conditions into one policy rule. Given these gaps, I don't have enough documented detail to walk you through the exact Policy Editor steps for the attribute-to-user-key comparison or the combined rule composition. I can give a general answer based on broader knowledge if you'd like — otherwise, this looks like a good candidate for the enterprise form or a direct question to the team, since it touches on Policy Editor UI mechanics not covered in these sources. Check out these potentially useful sources: Modeling and Implementation Components , What is Relationship-Based Access Control (ReBAC) ? , Attribute-Based Access Control (ABAC) VS. Relationship-Based Access Control (ReBAC)
To learn more, see the sources I considered: [[1] What is Relationship-Based Access Control (ReBAC)?](https://www.permit.io/blog/what-is-rebac) [[2] Modeling and Implementation Components](https://docs.permit.io/how-to/SDLC/modeling-implementation-components) [[3] Run your First Policy Check (Managed Cloud PDP)](https://docs.permit.io/overview/perform-policy-check-with-cloud-pdp)
o
@Ask Inkeep instead of a UI walkthrough - explain how the concepts connect in the API
a
Thanks for tagging me @Or Weis. I'll look through relevant sources and get back to you shortly.
Based on the Teleco Demo Application source, here's how the API pieces connect for resources, roles, relations, and condition sets. ​*Resources with relations*​ Resources can declare relations to other resources, which is what enables ReBAC-style derivation. For example,
Plan
declares a
parent
relation to `account`:
Copy code
await permit.api.resources.create({  
 key: "plan",  
 name: "Plan",  
 ...  
 relations: {  
 parent: "account",  
 },  
 }) ;
(1) ​*Roles with permissions and derivations*​ A resource-level role (like
editor
on
plan
) can declare
granted_to
logic that derives the role from another resource's role, using the relation declared above:
Copy code
await permit.api.resources.create({  
 key: "plan",  
 name: "Plan",  
 ...  
 roles: {  
 editor: {  
 name: "Editor",  
 permissions: ["view", "change"],  
 granted_to: {  
 users_with_role: [  
 {  
 role: "editor",  
 on_resource: "account",  
 linked_by_relation: "parent",  
 },  
 ],  
 },  
 },  
 },  
 ...  
}) ;
This ties the
parent
relation directly to a role derivation:
Account#Editor
→
Plan#Editor
. *Condition sets for ABAC (user sets and resource sets) * Condition sets are created separately via
conditionSets.create
, specifying
type: "userset"
or
type: "resourceset"
and the attribute-based conditions:
Copy code
await permit.api.conditionSets.create({  
 key: "blocked_users",  
 name: "Blocked Users",  
 type: "userset",  
 conditions: {  
 allOf: [{ allOf: [{ "user.blocked": { equals: true } }] }],  
 },  
}) ;
Copy code
await permit.api.conditionSets.create({  
 key: "owned_plans",  
 name: "Owned Plans",  
 type: "resourceset",  
 resource_id: "plan",  
 conditions: {  
 allOf: [  
 { allOf: [{ "resource.owner": { equals: { ref: "user.key" } } }] },  
 ],  
 },  
}) ;
This resource set shows an attribute-to-input comparison —
resource.owner
matched against
{ ref: "user.key" }
, i.e. referencing the value passed in as the user key at check time . ​*Connecting condition sets into a policy rule*​ The
conditionSetRules.create
call is what ties a user set and a resource set together into an enforceable permission:
Copy code
await permit.api.conditionSetRules.create({  
 user_set: "active_users",  
 resource_set: "owned_plans",  
 permission: "plan:view",  
}) ;  

await permit.api.conditionSetRules.create({  
 user_set: "active_users",  
 resource_set: "owned_plans",  
 permission: "plan:change",  
}) ;
​*Enforcement*​ All of the above (relations, role derivations, condition sets, and condition set rules) feed into the single
permit.check()
call, which takes user, action, and resource and evaluates against everything configured:
Copy code
export const authorize = async (user, action, resource) => {  
 return permit.check(user, action, resource) ;  
};
So in API terms:
resources.create
defines relations → role `granted_to`/`linked_by_relation` derives ReBAC permissions across those relations →
conditionSets.create
defines ABAC user/resource attribute matches (including matching an attribute like
owner
against the input
user.key
) →
conditionSetRules.create
binds a user_set + resource_set to a specific permission →
permit.check()
evaluates it all together . I don't have documentation showing how to combine a role-derivation (ReBAC) condition and a condition-set (ABAC) rule within the ​_same_​ single rule object — the source only shows them as separate constructs (
roles.granted_to
vs
conditionSetRules
) that both ultimately feed the same
permit.check()
call .
To learn more, see the sources I considered: [[1] Teleco Demo Application](https://docs.permit.io/modeling/pink-mobile)