Audit Logging¶
Track every tool invocation for compliance, debugging, and operational visibility.
Enabling Audit Logging¶
Audit logging is disabled by default. Enable it in your policy file:
Or for a more complete configuration:
[audit]
enabled = true
level = "all"
include_args = true
redact_fields = ["password", "db_password", "global_password", "api_key", "api_secret", "access_secret_key", "console_password", "bind_pass", "license_key", "secret", "token"]
Configuration Reference¶
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | false |
Master switch for audit logging |
level |
string | "all" |
Which events to log (see levels below) |
include_args |
bool | false |
Include tool arguments in log entries |
redact_fields |
list | Common password, API credential, key, secret, and token fields | Additional field names to redact when include_args is true |
Audit Levels¶
| Level | Logs |
|---|---|
all |
Every tool call (success, error, and denied) |
writes |
Write and destructive calls, including their errors, plus every policy denial |
destructive |
Destructive calls, including their errors, plus every policy denial |
denied |
Only policy-denied calls |
Policy denials are logged at every level. Other tool errors follow the safety
classification of the tool that was called. The previously documented
"mutations" value remains accepted as an alias for "writes", but new
configuration should use "writes".
Choose based on your needs:
- Production monitoring:
"denied"-- catch policy violations without log noise - Development/debugging:
"all"-- see everything - Compliance:
"writes"or"all"withinclude_args = true-- full mutation audit trail
Log Format¶
Audit events are emitted as structured JSON via the tracing crate with target: "audit". When using JSON log output (--log-level with RUST_LOG filtering), each event includes:
{
"timestamp": "2026-03-05T10:30:00.123Z",
"level": "INFO",
"target": "audit",
"fields": {
"event": "tool_invocation",
"tool": "list_enterprise_databases",
"toolset": "enterprise",
"result": "success",
"duration_ms": 45
}
}
Event Types¶
| Event | Description |
|---|---|
tool_invocation |
Tool was called and completed successfully |
tool_denied |
Tool call was blocked by the router or a handler-time policy guard |
tool_error |
Tool call failed with an error |
With Arguments¶
When include_args = true, an arguments field is added containing the tool's input parameters. Built-in credential fields and the additional fields listed in redact_fields are replaced with [REDACTED]:
{
"fields": {
"event": "tool_invocation",
"tool": "create_enterprise_database",
"toolset": "enterprise",
"result": "success",
"duration_ms": 1200,
"arguments": "{\"name\":\"cache-db\",\"memory_size\":104857600,\"password\":\"[REDACTED]\"}"
}
}
Redaction is recursive and matches common credential-field spellings across
snake_case, kebab-case, and camelCase. Redis credentials embedded in
redis://, rediss://, redis+unix://, and unix:// URLs are always
sanitized. The arbitrary-command tools retain the command name for diagnosis
but always redact every positional operand, since Redis command arguments can
carry credentials or application secrets. These mandatory protections cannot
be disabled by changing redact_fields.
Routing Audit Logs¶
Audit events use target: "audit" so you can route them separately from application logs using RUST_LOG filtering:
# All logs at info, audit at debug
RUST_LOG=info,audit=debug redisctl-mcp --profile my-profile
# Only audit logs
RUST_LOG=warn,audit=info redisctl-mcp --profile my-profile
Log Aggregation¶
To send audit logs to an external system, pipe JSON output to your collector:
# Datadog
redisctl-mcp --profile my-profile 2>&1 | datadog-agent pipe
# Fluentd
redisctl-mcp --profile my-profile 2>&1 | fluent-cat audit.mcp
# File-based (rotate with logrotate)
redisctl-mcp --profile my-profile 2>> /var/log/redisctl-mcp-audit.jsonl
Since the MCP server uses stderr for logs and stdout for MCP protocol messages, redirect stderr (2>) to capture audit output without interfering with the MCP transport.
Practical Examples¶
Compliance: Full Mutation Audit¶
Track all state-changing operations with arguments:
tier = "read-write"
[audit]
enabled = true
level = "writes"
include_args = true
redact_fields = ["password", "api_key", "api_secret", "secret", "token"]
Security: Denied Operations Only¶
Alert on policy violations:
Debugging: Everything¶
Full visibility during development: