Troubleshooting Guide¶
Common issues and solutions when working with fastapi-topaz.
Connection Issues¶
"Connection refused" to Topaz¶
Symptoms:
Solutions:
-
Check Topaz is running:
-
Verify URL in config:
-
Check network/firewall:
TLS handshake failures against a plaintext Topaz¶
Symptoms: the client hangs or fails with SSL errors when Topaz runs without TLS (e.g. topaz start --no-tls or a plaintext docker-compose setup).
Solution: the client uses a TLS gRPC channel by default. For a local, non-TLS Topaz, enable the insecure channel:
Never enable insecure=True against a production Topaz. If Topaz runs with TLS and a self-signed certificate, keep the default and point AuthorizerOptions(cert_file_path=...) at the CA certificate instead.
"Deadline exceeded" / Timeout¶
Symptoms:
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.DEADLINE_EXCEEDED
Solutions:
-
Increase timeout:
-
Enable circuit breaker:
-
Check Topaz health:
Authorization Issues¶
Always Getting 403 Forbidden¶
Symptoms: Every request returns 403, even for admins.
Debug steps:
-
Enable debug logging:
-
Check identity extraction:
-
Verify policy path:
-
Test policy directly:
Seeing Which Policy Denied a Request¶
For development and debugging, expose_deny_reason=True makes 403 responses include the evaluated policy path and check source instead of a bare "Forbidden":
Denied responses then carry a structured body — {"detail": "Forbidden", "policy": "myapp.GET.documents", "source": "middleware"} from the middleware or dependency paths, with object_type and relation added for ReBAC denials. A custom middleware on_denied callback still takes precedence.
Warning: this leaks your policy structure to API clients. Never enable it in production.
Policy Not Found¶
Symptoms:
Solutions:
-
Check policy_instance_name matches:
-
Verify policy is loaded:
-
Check Rego package name:
Hyphens in Policy Path (Invalid Rego Identifier)¶
Symptoms:
Topaz returns errors about invalid policy paths, or policies don't match,
when your API routes contain hyphens (e.g., /aircraft-programs).
Cause:
Rego identifiers cannot contain hyphens. The - character is parsed as
the minus operator. Route /aircraft-programs generates policy path
myapp.GET.aircraft-programs, which is invalid Rego.
Solution:
Use policy_path_normalizer to replace hyphens with underscores:
from fastapi_topaz import TopazConfig, normalize_hyphens
config = TopazConfig(
...
policy_path_normalizer=normalize_hyphens,
)
# Verify:
config.policy_path_for("GET", "/aircraft-programs")
# → "myapp.GET.aircraft_programs"
ReBAC Always Denied¶
Symptoms: ReBAC checks always return false, even for owners.
Debug steps:
-
Check resource context:
-
Verify object_id resolution:
-
Check directory relations:
Caching Issues¶
Changes Not Taking Effect¶
Symptoms: Updated permissions in Topaz aren't reflected immediately.
Solutions:
-
Clear cache:
-
Reduce TTL for development:
-
Bypass the cache for specific checks: use a second
TopazConfigwithoutdecision_cachefor those calls:
Cache Not Working¶
Symptoms: Cache hit rate is 0%, every request hits Topaz.
Debug steps:
-
Verify cache is configured:
-
Check cache keys are consistent:
-
Enable metrics:
Circuit Breaker Issues¶
Circuit Opens Too Quickly¶
Symptoms: Circuit breaker opens after minor network blips.
Solutions:
circuit_breaker=CircuitBreaker(
failure_threshold=10, # Increase from default 5
recovery_timeout=60, # Longer recovery time
success_threshold=3, # More successes needed to close
)
Fallback Not Working¶
Symptoms: When circuit is open, requests fail instead of using fallback.
Debug steps:
-
Check fallback strategy:
-
Verify stale cache is enabled:
-
Check circuit status:
Middleware Issues¶
Middleware Not Applied¶
Symptoms: Routes aren't being protected by TopazMiddleware.
Solutions:
-
Check middleware order:
-
Check exclusion patterns:
-
Check route is matched:
Routes Excluded Unexpectedly¶
Symptoms: Some routes aren't being protected.
Debug steps:
-
Check @skip_middleware decorator:
-
Check router dependencies:
Integration Environment¶
Start with make int-doctor. It prints what the Makefile detected and fails with a fix-it message for each missing prerequisite.
Every Authenticated Call Returns 401¶
Cause: The webapp container started without OIDC credentials. Compose reads env_file (integration-tests/.env.oidc) only when it creates a container. docker-compose restart keeps the old environment.
Solution: make int-tf-apply recreates the webapp for you. If you ran Terraform or compose by hand, recreate it:
Login Redirect Fails / Cannot Resolve authentik-server¶
Cause: The OIDC issuer is http://authentik-server:9000. The e2e client and your browser follow redirects to that name from the host.
Solution:
Podman: "Cannot connect to the Docker daemon"¶
Cause: docker-compose is looking for /var/run/docker.sock.
Solution: The Makefile sets DOCKER_HOST to the Podman machine socket when DOCKER_HOST is unset. Check that the machine is running (podman machine start). For compose commands run outside make, export it yourself:
export DOCKER_HOST="unix://$(podman machine inspect --format '{{.ConnectionInfo.PodmanSocket.Path}}')"
To pin a different socket, compose command, or Terraform binary, copy local.mk.example to local.mk.
Common Error Messages¶
| Error | Cause | Solution |
|---|---|---|
Identity has no value |
identity_provider returned None/empty | Check header extraction, authentication |
policy_path must not be empty |
Empty policy path | Check policy_path_root configuration |
Semaphore released too many times |
Bug in custom code | Check async context managers |
Unexpected 403, or 503 Authorization service unavailable |
Authorizer call failed with no circuit-breaker fallback (e.g. INVALID_ARGUMENT for a missing policy); the status follows on_error |
Check the ERROR log "Authorization check failed in ... for policy ..."; add the policy or configure a CircuitBreaker |
Getting Help¶
If you're still stuck:
-
Enable full debug logging:
-
Check Topaz logs:
-
Simplify to minimal example:
-
Report issues: GitHub Issues
See Also¶
- Testing - Mock authorization in tests
- Circuit Breaker - Resilience configuration
- Observability - Monitoring and debugging