Portal Community

What Are Resource Policies?

Role permissions define broad capability grants — "managers can execute workflows". Resource policies narrow this to specific resources — "this manager can only execute the payroll workflow, not the HR onboarding workflow".

Resource policies are restrictive only — they cannot grant permissions that the user's role does not already have. They only add constraints on top of existing role grants.

Policy Model

// Resource policy definition
public class ResourcePolicy
{
    public required string PolicyId    { get; init; }
    public required string ResourceType{ get; init; }  // "workflow", "form", "agent", "report"
    public required string ResourceId  { get; init; }  // the specific resource GUID
    public required string TenantId    { get; init; }
    public required PolicyEffect Effect{ get; init; }  // Allow or Deny
    public required string Permission  { get; init; }  // permission being scoped
    public required string[] SubjectIds{ get; init; }  // user IDs or group IDs this applies to
    public string? Condition           { get; init; }  // optional CEL expression
    public DateTimeOffset? ExpiresAt   { get; init; }
}

public enum PolicyEffect { Allow, Deny }

Creating Resource Policies

// Restrict a specific workflow to specific users
POST /passport/admin/resource-policies
Authorization: Bearer {admin-token}
Content-Type: application/json

{
  "resourceType": "workflow",
  "resourceId":   "payroll-monthly-run-workflow-guid",
  "tenantId":     "tenant-abc",
  "effect":       "Allow",
  "permission":   "workflow.initiate",
  "subjectIds":   ["user-guid-1", "user-guid-2", "group-guid-finance"],
  "description":  "Only finance team can initiate the monthly payroll workflow"
}

// Deny access for a specific user even though their role would allow it
POST /passport/admin/resource-policies
Authorization: Bearer {admin-token}
Content-Type: application/json

{
  "resourceType": "form",
  "resourceId":   "salary-adjustment-form-guid",
  "tenantId":     "tenant-abc",
  "effect":       "Deny",
  "permission":   "form.submit",
  "subjectIds":   ["user-guid-contractor"],
  "description":  "Contractors cannot submit salary adjustment forms"
}

Use Cases

Resource TypeExample PolicyRationale
WorkflowAllow only Finance group to initiate the payroll workflowSensitive workflows should be restricted even within the manager role
FormDeny contractors from submitting salary formsRole says "users can submit forms" but this specific form requires employee status
AgentAllow only IT admins to interact with the infrastructure agentInfrastructure automation should be restricted to IT administrators
ReportAllow Finance role to view the P&L reportFinancial reports require explicit access beyond the general viewer permission

Conditional Policies (CEL Expressions)

Resource policies support optional CEL (Common Expression Language) conditions for time-based or attribute-based restrictions:

// Time-based restriction — only allow access during business hours
{
  "resourceType": "workflow",
  "resourceId":   "live-payment-workflow-guid",
  "effect":       "Allow",
  "permission":   "workflow.initiate",
  "subjectIds":   ["group-guid-payment-team"],
  "condition":    "timestamp.hours() >= 9 && timestamp.hours() < 17 && timestamp.dayOfWeek() >= 1 && timestamp.dayOfWeek() <= 5"
}

// Attribute-based — only users from a specific department
{
  "resourceType": "form",
  "resourceId":   "payroll-correction-form-guid",
  "effect":       "Allow",
  "permission":   "form.submit",
  "subjectIds":   ["role:manager"],
  "condition":    "subject.department == 'Finance'"
}

Policy Precedence

When multiple resource policies match a check, the evaluation follows these precedence rules:

  1. Explicit DENY wins — any matching Deny policy immediately denies the request
  2. Explicit ALLOW required — if the resource has any Allow policies defined, the subject must match at least one
  3. No policy = role decision — if no resource policy applies, the role-based decision stands
Resource Policies Do Not Grant New Permissions

A resource Allow policy on workflow.initiate for a user with the viewer role does NOT grant them workflow initiation. The user must also have the workflow.initiate permission from their role. Resource policies only restrict — they never expand — what roles already allow.