Comprehensive guide to troubleshooting and debugging pgauthz.
This guide covers common issues, debugging techniques, and error resolution strategies for pgauthz.
-- Verify extension is installed
SELECT extname, extversion FROM pg_extension WHERE extname = 'pgauthz';
-- Test basic functionality
SELECT pgauthz_define_policy('type user {}');SET authz.tracing_level = 'debug';SELECT name, setting FROM pg_settings WHERE name LIKE 'authz.%';Symptom: pgauthz_check() returns false when you expect true (or vice versa).
Diagnosis:
Use pgauthz_expand() to see how the permission is computed:
SELECT pgauthz_expand('document', 'doc1', 'viewer');Common Causes:
- Missing Relation:
-- Check if relation exists
SELECT * FROM pgauthz_read_relationships('document', 'doc1', 'viewer', 'user', 'alice');- Wrong Relation Name:
-- List all relations for the object
SELECT * FROM pgauthz_read_relationships('document', 'doc1', NULL, NULL, NULL);- Policy Mismatch:
-- View current policy
SELECT * FROM pgauthz_read_latest_policy();- Condition Not Met:
-- Check with context
SELECT pgauthz_check_with_context(
'document', 'doc1', 'viewer', 'user', 'alice',
'{"hour": 14}'::jsonb
);Solution:
Add missing relation or fix policy definition:
-- Add the relation
SELECT pgauthz_add_relation('document', 'doc1', 'viewer', 'user', 'alice');
-- Or update the policy
SELECT pgauthz_define_policy('...');Symptom: ERROR: policy parse error or ERROR: policy validation error
Error Codes:
22000- Syntax error in policy23514- Validation error (undefined types, cycles, etc.)
Common Causes:
- Syntax Error:
-- Missing bracket
SELECT pgauthz_define_policy('
type document {
relations
define viewer: [user
}
');
-- ERROR: policy parse error at line 4- Undefined Type:
-- Referencing undefined type
SELECT pgauthz_define_policy('
type document {
relations
define viewer: [group#member]
}
');
-- ERROR: undefined type: group- Circular Dependency:
-- Cycle in relations
SELECT pgauthz_define_policy('
type document {
relations
define viewer: editor
define editor: viewer
}
');
-- ERROR: cycle detectedSolution:
Fix the policy syntax:
-- Define all types
SELECT pgauthz_define_policy('
type user {}
type group {
relations
define member: [user]
}
type document {
relations
define viewer: [user | group#member]
}
');Symptom: Checks take longer than expected (>100ms).
Diagnosis:
- Enable timing:
\timing on
SELECT pgauthz_check('document', 'doc1', 'viewer', 'user', 'alice');- Check cache hit rate:
SET authz.tracing_level = 'debug';
SELECT pgauthz_check('document', 'doc1', 'viewer', 'user', 'alice');
-- Look for "cache_hit" or "cache_miss" in output- Check resolution depth:
SELECT pgauthz_expand('document', 'doc1', 'viewer');
-- Count the depth of the treeCommon Causes:
- Caching Disabled:
SHOW authz.model_cache_ttl_secs; -- Should be > 0
SHOW authz.result_cache_ttl_secs; -- Should be > 0-
Complex Policy: Deep permission hierarchies cause many database queries.
-
Large Tuple Set: Many relations for a single object slow down resolution.
Solution:
Enable caching:
SET authz.model_cache_ttl_secs = 300;
SET authz.result_cache_ttl_secs = 60;
SET authz.tuple_cache_ttl_secs = 60;Simplify policy if possible, or use batch operations:
-- Instead of multiple checks
SELECT * FROM pgauthz_list_objects('user', 'alice', 'viewer', 'document');Symptom: PostgreSQL memory usage grows over time.
Diagnosis:
Check cache capacity:
SHOW authz.cache_max_capacity;Solution:
Reduce cache capacity:
SET authz.cache_max_capacity = 5000;Or reduce cache TTLs to expire entries faster:
SET authz.model_cache_ttl_secs = 60;
SET authz.result_cache_ttl_secs = 30;Symptom: Permission checks return outdated results after changes.
Cause: Cache TTL is too long.
Solution:
Reduce cache TTLs:
SET authz.result_cache_ttl_secs = 10;
SET authz.tuple_cache_ttl_secs = 10;Or disable caching:
SET authz.result_cache_ttl_secs = 0;
SET authz.tuple_cache_ttl_secs = 0;Symptom: ERROR: could not open extension control file
Diagnosis:
Check extension files:
# Check control file
ls -l $(pg_config --sharedir)/extension/pgauthz.control
# Check shared library
ls -l $(pg_config --pkglibdir)/pgauthz.soSolution:
Reinstall the extension package. See Installation Guide.
Symptom: ERROR: extension "pgauthz" has no update path
Diagnosis:
Check available versions:
SELECT * FROM pg_available_extension_versions WHERE name = 'pgauthz';Solution:
Update to compatible version or reinstall.
| Code | Error Type | Description | Solution |
|---|---|---|---|
22023 |
Invalid Parameter | Empty or invalid input | Check parameter values |
22000 |
Data Exception | Policy parsing error | Fix policy syntax |
23514 |
Check Violation | Validation failure | Fix policy or tuple data |
02000 |
No Data Found | Policy not found | Define a policy first |
42704 |
Undefined Object | Relation not in policy | Update policy definition |
54000 |
Program Limit | Max depth exceeded | Simplify policy hierarchy |
38000 |
External Routine | Datastore error | Check database connectivity |
XX000 |
Internal Error | Unexpected error | Report bug |
-- PL/pgSQL example
DO $$
BEGIN
PERFORM pgauthz_check('document', 'doc1', 'viewer', 'user', 'alice');
EXCEPTION
WHEN SQLSTATE '22023' THEN
RAISE NOTICE 'Invalid parameter: %', SQLERRM;
WHEN SQLSTATE '02000' THEN
RAISE NOTICE 'Policy not found - define policy first';
WHEN SQLSTATE '54000' THEN
RAISE NOTICE 'Max depth exceeded - policy too complex';
WHEN OTHERS THEN
RAISE NOTICE 'Unexpected error: % (SQLSTATE: %)', SQLERRM, SQLSTATE;
END $$;Visualize permission resolution:
SELECT pgauthz_expand('document', 'doc1', 'viewer');Output shows the permission tree:
union(
direct(user:alice),
computed(editor) -> union(
direct(user:bob)
)
)
Inspect stored relations:
-- All relations for an object
SELECT * FROM pgauthz_read_relationships('document', 'doc1', NULL, NULL, NULL);
-- All relations for a subject
SELECT * FROM pgauthz_read_relationships(NULL, NULL, NULL, 'user', 'alice');
-- Specific relation
SELECT * FROM pgauthz_read_relationships('document', 'doc1', 'viewer', NULL, NULL);SET authz.tracing_level = 'debug';
SELECT pgauthz_check('document', 'doc1', 'viewer', 'user', 'alice');Look for log messages about:
- Cache hits/misses
- Database queries
- Resolution steps
Create a minimal policy to isolate issues:
-- Minimal test policy
SELECT pgauthz_define_policy('
type user {}
type document {
relations
define viewer: [user]
}
');
-- Add test relation
SELECT pgauthz_add_relation('document', 'test', 'viewer', 'user', 'alice');
-- Test check
SELECT pgauthz_check('document', 'test', 'viewer', 'user', 'alice');
-- Should return trueEnsure you're using the latest policy:
-- List all policies
SELECT id, LEFT(definition, 100) FROM pgauthz_list_policies(10, NULL);
-- Get latest
SELECT * FROM pgauthz_read_latest_policy();For conditional permissions:
-- Check without context (should fail if condition required)
SELECT pgauthz_check('document', 'doc1', 'editor', 'user', 'bob');
-- Check with context
SELECT pgauthz_check_with_context(
'document', 'doc1', 'editor', 'user', 'bob',
'{"allowed_ips": ["10.0.0.1"], "current_ip": "10.0.0.1"}'::jsonb
);-- Enable timing
\timing on
-- Run check multiple times
SELECT pgauthz_check('document', 'doc1', 'viewer', 'user', 'alice');
SELECT pgauthz_check('document', 'doc1', 'viewer', 'user', 'alice');
SELECT pgauthz_check('document', 'doc1', 'viewer', 'user', 'alice');
-- First call: cache miss (slower)
-- Subsequent calls: cache hit (faster)Enable PostgreSQL query logging:
SET log_statement = 'all';
SET log_min_duration_statement = 0;Then check PostgreSQL logs for queries executed by pgauthz.
EXPLAIN ANALYZE
SELECT pgauthz_check('document', 'doc1', 'viewer', 'user', 'alice');SELECT * FROM pg_locks WHERE relation::regclass::text LIKE '%authz%';With OpenTelemetry enabled:
SET authz.otel_enabled = true;
-- Check metrics for cache hit ratesWhen debugging an issue:
- Check extension is installed and loaded
- Verify policy is defined
- Confirm relations exist
- Use
pgauthz_expand()to visualize resolution - Enable debug logging
- Check cache configuration
- Verify context variables (for conditions)
- Test with simplified policy
- Check error codes and messages
- Review PostgreSQL logs
- Monitor performance metrics
If you're still stuck:
-
Check Documentation:
-
Search Issues:
-
Ask for Help:
-
Report a Bug: Include:
- pgauthz version
- PostgreSQL version
- Policy definition
- Steps to reproduce
- Error messages
- Debug logs
- API Reference - Function documentation
- Configuration Guide - Tuning parameters
- Performance Guide - Optimization strategies
- Observability Guide - Monitoring and metrics