Skip to main content

Authorization Debug Mode

When developing or troubleshooting authorization rules, it can be difficult to understand why a request is being denied. Fire Arrow Server includes a debug mode that provides detailed information about rule evaluation on failed requests.

Enabling Debug Mode

Debug mode has two requirements:

1. Enable in Configuration

fire-arrow:
authorization:
debug-enabled: true

2. Send the Debug Header

Include the X-Fire-Arrow-Debug header with your request:

GET /fhir/Patient/123 HTTP/1.1
Authorization: Bearer eyJhbG...
X-Fire-Arrow-Debug: true

Both the configuration flag and the header must be present. This two-step requirement prevents accidental exposure of rule details in production.

What Debug Mode Returns

When a request results in a 403 Forbidden response and debug mode is active, Fire Arrow replaces the generic error with a detailed OperationOutcome that traces the rule evaluation:

{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "error",
"code": "forbidden",
"diagnostics": "Authorization denied for operation 'read' on resource 'Patient/123'",
"details": {
"text": "Rule evaluation trace"
}
},
{
"severity": "information",
"code": "informational",
"diagnostics": "Client role: Practitioner (Practitioner/456)",
"details": {
"text": "Resolved identity"
}
},
{
"severity": "information",
"code": "informational",
"diagnostics": "Rule [Practitioner, Patient, search, PatientCompartment]: SKIPPED - operation mismatch (rule has 'search', request has 'read')",
"details": {
"text": "Near miss: consider adding a rule for 'read'"
}
},
{
"severity": "information",
"code": "informational",
"diagnostics": "Rule [Practitioner, Observation, read, Allowed]: SKIPPED - resource mismatch (rule has 'Observation', request has 'Patient')",
"details": {
"text": "Rule evaluation"
}
},
{
"severity": "information",
"code": "informational",
"diagnostics": "Rule [Patient, Patient, read, PatientCompartment]: SKIPPED - role mismatch (rule has 'Patient', client has 'Practitioner')",
"details": {
"text": "Rule evaluation"
}
},
{
"severity": "information",
"code": "informational",
"diagnostics": "No matching rule found. Default validator 'Forbidden' applied.",
"details": {
"text": "Final result"
}
}
]
}

The trace includes:

  • Client identity -- The resolved role and FHIR resource reference
  • Rule evaluation -- Each rule that was considered, and why it matched or didn't
  • Near-miss hints -- Suggestions when a rule almost matched (e.g., you have a search rule but the request was a read)
  • Final result -- Which validator ultimately decided the outcome

Reading the Debug Output

The most useful part of the debug response is the near-miss hints. Common near-miss patterns include:

Near MissWhat It MeansFix
Operation mismatch: rule has search, request has readYou have a search rule but no read ruleAdd a read rule for the same role and resource
Operation mismatch: rule has read, request has graphql-readYou have a REST rule but the client uses GraphQLAdd a graphql-read rule
Role mismatchThe client's resolved identity type doesn't match the ruleCheck that identity resolution maps to the expected resource type
Identity filter returned falseThe rule exists but the client's identity resource didn't pass the FHIRPath filterReview the identity filter expression

Example Workflow

  1. A request fails with 403:
curl -H "Authorization: Bearer $TOKEN" \
-H "X-Fire-Arrow-Debug: true" \
http://localhost:8080/fhir/Patient/123
  1. The response reveals: "Rule [Practitioner, Patient, search, PractitionerCompartment]: SKIPPED - operation mismatch (rule has 'search', request has 'read')"

  2. You realize you have a search rule but forgot the read rule, and add it:

- client-role: Practitioner
resource: Patient
operation: read
validator: PractitionerCompartment
  1. Retry the request -- it succeeds.
Production Warning

Do not enable debug mode in production. The debug output exposes your complete authorization rule configuration, including identity filters, validators, and resource types. This information could help an attacker understand and circumvent your access control.

Use debug mode only in development and staging environments. If you need to troubleshoot production authorization issues, enable it temporarily and disable it immediately after.