Permissions
[API Docs]
epilot implements flexible role-based access control (RBAC) with attribute-based conditions, inspired by the design of AWS IAM policies. The system supports fine-grained control at the role, resource, and attribute level.
Core Conceptsโ
The permissions model has three building blocks:
- Users are assigned one or more Roles
- Roles are collections of Grants
- Grants define whether a user is allowed (or explicitly denied) to perform an action on a resource
Grant Structureโ
Each grant specifies an action, an optional resource pattern, an effect, and optional conditions:
{
"action": "entity:edit",
"resource": "contract:*",
"effect": "allow",
"conditions": [
{
"attribute": "_tags",
"operation": "equals",
"values": ["active", "pending"]
}
]
}
| Field | Description |
|---|---|
action | The operation being performed (e.g., entity:view, message:send). Supports wildcards (entity:*). |
resource | The target resource pattern (e.g., contact:*, file:*). Defaults to all resources if omitted. |
effect | allow or deny. Defaults to allow. |
conditions | Optional array of attribute-based conditions that must all be satisfied. |
Actionsโ
Actions follow a {domain}:{operation} pattern. Common actions include:
| Action | Description |
|---|---|
entity:view | Read entities |
entity:edit | Update entities |
entity:create | Create entities |
entity:delete | Delete entities |
entity:* | All entity operations |
entity:attribute:view | View specific entity attributes |
entity:attribute:edit | Edit specific entity attributes |
message:view | View messages |
message:send | Send messages |
workflow:* | All workflow operations |
webhook:* | All webhook operations |
user:invite | Invite users to the organization |
role:assign | Assign roles to users |
Resource Patternsโ
Resources support wildcards for flexible scoping:
| Pattern | Matches |
|---|---|
* | All resources |
contact:* | All contacts |
opportunity:123456 | A specific opportunity |
contact:Personal Details:* | All attributes in the "Personal Details" group on contacts |
contact:Personal Details:phone | The phone attribute specifically |
Attribute-level resources follow the format {schema}:{group}:{attribute}, enabling permissions down to individual fields on entity types.
Conditions (Attribute-Based Access Control)โ
Conditions add dynamic, data-driven rules to grants. When conditions are present, the grant only applies if the entity being accessed satisfies all conditions.
{
"action": "entity:view",
"resource": "file:*",
"conditions": [
{
"attribute": "_tags",
"operation": "equals",
"values": ["offer", "contract"]
}
]
}
Conditions support:
- Flat attributes --
"attribute": "_tags"matches a top-level field - Nested paths --
"attribute": "_customer._payment._type"matches deeply nested values - Wildcard paths --
"attribute": "workflows.*.currentTask"matches across dynamic keys - Array matching -- if the attribute is an array, the condition matches if any element equals one of the specified values
tip
Conditions are evaluated at runtime with actual entity data. This enables scenarios like restricting a role to only edit entities in a specific workflow step, or only view files tagged with certain categories.
Condition Examplesโ
Restrict to entities in a specific workflow step:
{
"action": "entity:edit",
"resource": "*",
"conditions": [
{
"attribute": "workflows.*.currentTask",
"operation": "equals",
"values": ["review", "approval"]
}
]
}
Restrict to entities owned by specific organizations (cross-org sharing):
{
"action": "entity:edit",
"resource": "*",
"conditions": [
{
"attribute": "_acl.edit",
"operation": "equals",
"values": ["org_911215"]
}
]
}
Evaluation Rulesโ
Grant evaluation follows AWS IAM conventions:
- Tenant isolation -- Roles only grant access within their own organization.
- Owner role -- The built-in
ownerrole (present in every organization) inherits all organization grants. - Least privilege -- Roles have no grants by default.
- Dual-role matching -- Both the organization root role grant and a user role grant must match for access to be granted.
- Explicit deny -- An explicit
denyin any matched grant overrides allallowgrants. Use deny grants to create exceptions within broad allow rules. - Wildcard matching -- Actions and resources support wildcard expressions (e.g.,
entity:*,contact:*). - Condition evaluation -- When conditions are present, all conditions on a grant must be satisfied (AND logic).
Role Typesโ
| Type | Description |
|---|---|
| User Role | Standard role assigned to specific users. Can inherit from a parent org or share role. |
| Organization Role | Automatically applied to all users in the organization. Defines the maximum permission ceiling. |
| Share Role | Grants cross-organization access for partner sharing scenarios. |
| Partner Role | Assigned to users in partner organizations with configurable user limits. |
| Portal Role | Implicit role for end-customer portal users with restricted permissions. |
Organization Root Roleโ
Every organization has a mandatory root role that defines the maximum permission set any user can receive. The organization's subscription tier determines this role. User roles can only grant permissions up to the ceiling set by the root role.
This two-level model ensures that subscription tiers control feature access at the organization level, while user roles provide fine-grained access within those boundaries.
info
The root role also enables feature flagging via explicit denies. For example, an organization on a lower tier might have "action": "webhook:*", "effect": "deny" on its root role, preventing any user from accessing webhook features regardless of their user roles.
Example Role Definitionโ
{
"id": "66:manager",
"name": "Manager",
"slug": "manager",
"organization_id": "66",
"type": "user_role",
"grants": [
{ "action": "entity:*", "effect": "allow" },
{ "action": "entity:*", "resource": "partner:*", "effect": "deny" },
{ "action": "message:*", "effect": "allow" },
{ "action": "workflow:*", "effect": "allow" }
]
}
This role allows all entity, messaging, and workflow operations, but explicitly denies access to partner-owned entities.
See Alsoโ
- Authorization -- how epilot authorizes API requests
- Token Types -- comparison of all epilot token types
- Security Architecture -- platform security overview