Bypass Checks
Bypass checks determine when RLS should be completely bypassed, allowing access to all data regardless of RLS policies.
For API documentation on bypass check functions, see the API Reference (search for bypass).
Default Behavior
The default bypass check allows superusers to bypass RLS:
from django_rls.resolvers import default_rls_bypass_check
DJANGO_RLS = DjangoRLSSettings(
BYPASS_CHECK_RESOLVER=default_rls_bypass_check,
)
Custom Bypass Checks
Role-Based Bypass
from typing import Any
def role_based_bypass(request: Any) -> bool:
"""
Bypass RLS for users with specific roles.
"""
user = getattr(request, 'user', None)
if not user or not getattr(user, 'is_authenticated', False):
return False
# Bypass for superusers
if getattr(user, 'is_superuser', False):
return True
# Bypass for admin role
if hasattr(user, 'role') and user.role == 'admin':
return True
# Bypass for staff
if getattr(user, 'is_staff', False):
return True
return False
DJANGO_RLS = DjangoRLSSettings(
BYPASS_CHECK_RESOLVER=role_based_bypass,
)
IP-Based Bypass
from typing import Any
def ip_based_bypass(request: Any) -> bool:
"""
Bypass RLS for requests from specific IP addresses.
"""
ip = request.META.get('REMOTE_ADDR')
trusted_ips = ['127.0.0.1', '192.168.1.100', '10.0.0.0/8']
for trusted_ip in trusted_ips:
if ip == trusted_ip or ip.startswith(trusted_ip):
return True
return False
DJANGO_RLS = DjangoRLSSettings(
BYPASS_CHECK_RESOLVER=ip_based_bypass,
)
Path-Based Bypass
from typing import Any
def path_based_bypass(request: Any) -> bool:
"""
Bypass RLS for specific URL paths (e.g., admin interface).
"""
bypass_paths = ['/admin/', '/api/admin/', '/internal/']
for path in bypass_paths:
if request.path.startswith(path):
return True
return False
DJANGO_RLS = DjangoRLSSettings(
BYPASS_CHECK_RESOLVER=path_based_bypass,
)
Combined Bypass
from typing import Any
def combined_bypass(request: Any) -> bool:
"""
Combine multiple bypass conditions.
"""
user = getattr(request, 'user', None)
# Superuser bypass
if user and getattr(user, 'is_superuser', False):
return True
# IP bypass
ip = request.META.get('REMOTE_ADDR')
if ip in ['127.0.0.1', '192.168.1.100']:
return True
# Path bypass
if request.path.startswith('/admin/'):
return True
# Header bypass (for internal services)
if request.META.get('HTTP_X_INTERNAL_SERVICE') == 'true':
return True
return False
DJANGO_RLS = DjangoRLSSettings(
BYPASS_CHECK_RESOLVER=combined_bypass,
)
What Happens When Bypassed?
When BYPASS_CHECK_RESOLVER returns True, all RLS fields are set to RlsWildcard.ALL:
# Normal request
{
"tenant_id": 123,
"user_id": 456,
}
# Bypassed request
{
"tenant_id": RlsWildcard.ALL,
"user_id": RlsWildcard.ALL,
}
PostgreSQL RLS policies should handle this wildcard appropriately, or you can create policies that allow access when the value is the wildcard.
Security Considerations
⚠️ Warning: Bypass checks should be used carefully. Only bypass RLS when absolutely necessary and ensure proper authentication/authorization is in place.
Best practices: - Always verify user authentication - Use specific conditions (don't bypass too broadly) - Log bypass events for auditing - Review bypass logic regularly
Testing Bypass Checks
from django.test import RequestFactory
from myapp.bypass import role_based_bypass
def test_bypass_check():
factory = RequestFactory()
request = factory.get('/')
# Test without user
assert role_based_bypass(request) == False
# Test with superuser
from django.contrib.auth import get_user_model
User = get_user_model()
user = User.objects.create_superuser('admin', 'admin@example.com', 'password')
request.user = user
assert role_based_bypass(request) == True
Next Steps
- Custom Resolvers - Custom resolver patterns
- Configuration - Bypass check configuration