Audit mode¶
RBACX can log authorization decisions for observability without enforcing them.
How it works¶
- Pass a
DecisionLogSink
implementation (e.g.,DecisionLogger
) toGuard
vialogger_sink=...
. - Each decision is emitted to the Python logger
rbacx.audit
. Setas_json=True
to serialize the event as JSON; otherwise a compact text form (decision {...}
) is logged. You can also control the log level via thelevel
parameter. - Optional sampling (
sample_rate
) helps manage log volume in high-traffic environments. - Redactions reuse obligation formats (e.g.
"mask_fields"
,"redact_fields"
) and are applied before the event is logged; if a listed field is missing in the request context, the enforcer will still create it in the loggedenv
with the appropriate placeholder (mask or[REDACTED]
). - It is best practice to log security-relevant events using structured/centralized logs, and to avoid logging sensitive fields.
Example (framework-agnostic)¶
import logging
from rbacx import Guard
from rbacx.logging.decision_logger import DecisionLogger
audit = logging.getLogger("rbacx.audit")
audit.setLevel(logging.INFO)
audit.addHandler(logging.StreamHandler())
decision_logger = DecisionLogger(
sample_rate=0.1,
redactions=[{"type": "mask_fields", "fields": ["subject.email", "resource.attrs.card"]}],
as_json=True, # new: emit JSON
level=logging.INFO, # new: configurable log level
)
policy = {"algorithm":"deny-overrides","rules":[]}
guard = Guard(policy, logger_sink=decision_logger)