Skip to main content

Get Resource Policies

API Endpoint: GET /admin/law-firms/\{lawFirmId\}/users/\{userId\}/resource-policies

Priority: P2

User Story: As an admin, I want to see all resource access policies that apply to a specific user for debugging and auditing purposes.

Overview

Retrieve a comprehensive view of all resource access policies that apply to a user, including grants from direct assignment, role inheritance, case membership, and system policies. This endpoint provides visibility into why a user has access to specific resources.

Scenarios

Scenario 1: Get user's resource policies

Given:

  • Admin is authenticated with scope capabilities:read
  • Law firm firm_abc123 exists
  • User user_12345 exists with:
    • Direct grant: WRITE access to case_001
    • Role-based grant: READ access to all litigation cases
    • Case member grant: ADMIN access to case_002 (assigned attorney)

When:

  • Admin GETs /admin/law-firms/firm_abc123/users/user_12345/resource-policies

Then:

  • Response status is 200 OK
  • Response body contains:
    {
    "data": [
    {
    "resourceType": "case",
    "resourceId": "case_001",
    "accessLevel": "WRITE",
    "source": "MANUAL",
    "grantedBy": "admin_789",
    "grantedAt": "2024-01-15T10:00:00Z"
    },
    {
    "resourceType": "case",
    "resourceId": "case_002",
    "accessLevel": "ADMIN",
    "source": "CASE_MEMBER",
    "reason": "User is assigned attorney on case",
    "grantedAt": "2024-02-01T14:30:00Z"
    },
    {
    "resourceType": "case",
    "resourceId": "*",
    "resourceSubtype": "litigation",
    "accessLevel": "READ",
    "source": "ROLE",
    "role": "LAWYER",
    "reason": "All lawyers have read access to litigation cases"
    }
    ]
    }

Scenario 2: Filter by resource type

Given:

  • Admin is authenticated with scope capabilities:read
  • User has policies on multiple resource types

When:

  • Admin GETs /admin/law-firms/firm_abc123/users/user_12345/resource-policies?resourceType=case

Then:

  • Response status is 200 OK
  • Response contains only policies for "case" resources
  • Other resource types are excluded

Scenario 3: User has no policies

Given:

  • Admin is authenticated with scope capabilities:read
  • User exists but has no resource access policies

When:

  • Admin GETs user's resource policies

Then:

  • Response status is 200 OK
  • Response body contains:
    {
    "data": []
    }

Scenario 4: User not found

Given:

  • Admin is authenticated with scope capabilities:read
  • No user with ID user_nonexistent in law firm

When:

  • Admin GETs /admin/law-firms/firm_abc123/users/user_nonexistent/resource-policies

Then:

  • Response status is 404 Not Found
  • Response body contains:
    {
    "error": "NOT_FOUND",
    "message": "User with ID 'user_nonexistent' not found in law firm 'firm_abc123'"
    }

Scenario 5: Filter by specific resource

Given:

  • Admin is authenticated with scope capabilities:read
  • User has multiple case policies

When:

  • Admin GETs /admin/law-firms/firm_abc123/users/user_12345/resource-policies?resourceType=case&resourceId=case_001

Then:

  • Response status is 200 OK
  • Response contains only policies for case_001
  • Wildcard policies (*) that apply to case_001 are also included

Request Specification

Path Parameters

ParameterTypeRequiredDescription
lawFirmIdstringYesLaw firm identifier
userIdstringYesUser identifier

Query Parameters

ParameterTypeRequiredDefaultDescription
resourceTypestringNo(all)Filter by resource type
resourceIdstringNo(all)Filter by specific resource ID
sourcestringNo(all)Filter by policy source

Policy Sources

SourceDescription
MANUALDirect access grant by admin
ROLEAccess inherited from functional role
CASE_MEMBERAccess from case team membership
SYSTEMSystem-generated access policy

Response Specification

Success Response (200 OK)

{
"data": [
{
"resourceType": "case",
"resourceId": "case_abc123",
"resourceSubtype": "litigation",
"accessLevel": "WRITE",
"source": "MANUAL",
"grantedBy": "admin_789",
"grantedByName": "System Admin",
"grantedAt": "2024-01-15T10:00:00Z",
"expiresAt": null,
"reason": null
},
{
"resourceType": "case",
"resourceId": "*",
"resourceSubtype": "litigation",
"accessLevel": "READ",
"source": "ROLE",
"role": "LAWYER",
"reason": "All lawyers have read access to litigation cases"
}
]
}

Response Fields

FieldTypeDescription
dataarrayArray of resource policy objects
data[].resourceTypestringType of resource
data[].resourceIdstringResource ID or * for wildcard
data[].resourceSubtypestring | nullResource subtype if applicable
data[].accessLevelstringLevel of access (READ, WRITE, ADMIN)
data[].sourcestringHow policy was granted
data[].grantedBystring | nullAdmin who granted (for MANUAL)
data[].grantedByNamestring | nullGranting admin's name
data[].grantedAtstringPolicy creation timestamp
data[].expiresAtstring | nullExpiration timestamp
data[].rolestring | nullFunctional role (for ROLE source)
data[].reasonstring | nullHuman-readable explanation

Error Responses

StatusError CodeDescription
400VALIDATION_ERRORInvalid query parameters
401UNAUTHORIZEDMissing or invalid auth token
403FORBIDDENMissing capabilities:read scope
404NOT_FOUNDUser or law firm not found

Requirements Mapping

  • FR-228: Accept GET with lawFirmId and userId parameters
  • FR-229: Aggregate policies from all sources (MANUAL, ROLE, CASE_MEMBER, SYSTEM)
  • FR-230: Return comprehensive policy list
  • FR-231: Include policy source and reason
  • FR-232: Support filtering by resourceType
  • FR-233: Support filtering by resourceId
  • FR-234: Support filtering by source
  • FR-235: Include wildcard policies that apply to resources
  • FR-236: Return empty array when no policies
  • FR-237: Require capabilities:read scope

Notes

Use Cases

This endpoint is useful for:

  • Debugging access issues ("Why does user have access to X?")
  • Auditing user permissions
  • Compliance reporting
  • Understanding policy inheritance
  • Troubleshooting authorization logic

Policy Aggregation

The response aggregates policies from multiple sources:

  1. MANUAL: Direct grants via access-grants API
  2. ROLE: Policies inherited from functional roles (LAWYER, PARALEGAL, etc.)
  3. CASE_MEMBER: Access from being assigned to cases
  4. SYSTEM: Automatic policies (e.g., users can always access their own profile)

Wildcard Policies

Policies with resourceId: "*" apply to all resources of that type:

  • May be filtered by resourceSubtype
  • Useful for role-based access (e.g., all lawyers can read all cases)
  • Authorization logic must evaluate wildcards correctly

Effective Access Calculation

This endpoint shows policies, not effective access:

  • User may have multiple policies for same resource
  • Highest access level typically wins (ADMIN > WRITE > READ)
  • Use GET .../capabilities to see final effective access

Performance

For users with many policies:

  • Response can be large
  • Consider pagination in future versions
  • Use filters to narrow results
  • May need caching for frequently accessed users

Read-Only

This endpoint is read-only:

  • Does not modify policies
  • Use access-grants endpoints to create/revoke policies
  • Role-based policies managed via user roles
  • Case member policies managed via case assignments