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
searchrule but the request was aread) - 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 Miss | What It Means | Fix |
|---|---|---|
Operation mismatch: rule has search, request has read | You have a search rule but no read rule | Add a read rule for the same role and resource |
Operation mismatch: rule has read, request has graphql-read | You have a REST rule but the client uses GraphQL | Add a graphql-read rule |
| Role mismatch | The client's resolved identity type doesn't match the rule | Check that identity resolution maps to the expected resource type |
| Identity filter returned false | The rule exists but the client's identity resource didn't pass the FHIRPath filter | Review the identity filter expression |
Example Workflow
- A request fails with
403:
curl -H "Authorization: Bearer $TOKEN" \
-H "X-Fire-Arrow-Debug: true" \
http://localhost:8080/fhir/Patient/123
-
The response reveals: "Rule [Practitioner, Patient, search, PractitionerCompartment]: SKIPPED - operation mismatch (rule has 'search', request has 'read')"
-
You realize you have a
searchrule but forgot thereadrule, and add it:
- client-role: Practitioner
resource: Patient
operation: read
validator: PractitionerCompartment
- Retry the request -- it succeeds.
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.