π A Monolog processor that protects sensitive data from miss logging.
Avoids logging something like {"api_key":"mysupersecretapikey"}
by masking partially or completely sensitive data:
Readme.INFO: Hello, World! {"api_key":"mysu***************"} []
composer require leocavalcante/redact-sensitive
It is a map of key names and how much of it can be displayed, for example:
$sensitive_keys = [
"api_key" => 4,
];
Shows the first 4 characters of the api_key
.
If you want to display the last chars, you can use negative values like ["api_key" => -4]
, then it will display the last 4 characters.
You can now create a new Processor with the given keys:
use RedactSensitive\RedactSensitiveProcessor;
$sensitive_keys = ["api_key" => 4];
$processor = new RedactSensitiveProcessor($sensitive_keys);
use RedactSensitive\RedactSensitiveProcessor;
$sensitive_keys = ["api_key" => 4];
$processor = new RedactSensitiveProcessor($sensitive_keys);
$logger = new \Monolog\Logger("Readme");
$logger->pushProcessor($processor);
use Monolog\Handler\StreamHandler;
use RedactSensitive\RedactSensitiveProcessor;
$sensitive_keys = ["api_key" => 4];
$processor = new RedactSensitiveProcessor($sensitive_keys);
$logger = new \Monolog\Logger("Readme", [new StreamHandler(STDOUT)]);
$logger->pushProcessor($processor);
$logger->info("Hello, World!", ["api_key" => "mysupersecretapikey"]);
Readme.INFO: Hello, World! {"api_key":"mysu***************"} []
Completely hidden
You can hide it completely by passing 0
to the key.
use Monolog\Handler\StreamHandler;
use RedactSensitive\RedactSensitiveProcessor;
$sensitive_keys = ["you_know_nothing" => 0];
$processor = new RedactSensitiveProcessor($sensitive_keys);
$logger = new \Monolog\Logger("Example", [new StreamHandler(STDOUT)]);
$logger->pushProcessor($processor);
$logger->info("Completely hidden", ["you_know_nothing" => "John Snow"]);
Example.INFO: Completely hidden {"you_know_nothing":"*********"} []
Feel free to customize a replacement character *
and/or provide your own template.
use Monolog\Handler\StreamHandler;
use RedactSensitive\RedactSensitiveProcessor;
$sensitive_keys = ["secret" => 2];
$processor = new RedactSensitiveProcessor($sensitive_keys, template: "%s(redacted)");
$logger = new \Monolog\Logger("Example", [new StreamHandler(STDOUT)]);
$logger->pushProcessor($processor);
$logger->info("Sensitive", ["secret" => "my_secret_value"]);
Example.INFO: Sensitive {"secret":"my*************(redacted)"} []
Custom template allows to discard the masked characters altogether:
use Monolog\Handler\StreamHandler;
use RedactSensitive\RedactSensitiveProcessor;
$sensitive_keys = ["secret" => 2];
$processor = new RedactSensitiveProcessor($sensitive_keys, template: "...");
$logger = new \Monolog\Logger("Example", [new StreamHandler(STDOUT)]);
$logger->pushProcessor($processor);
$logger->info("Sensitive", ["secret" => "my_secret_value"]);
Example.INFO: Sensitive {"secret":"my..."} []
Use lengthLimit
to truncate redacted sensitive information, such as lengthy tokens.
use Monolog\Handler\StreamHandler;
use RedactSensitive\RedactSensitiveProcessor;
$sensitive_keys = ["access_token" => 0];
$processor = new RedactSensitiveProcessor($sensitive_keys, lengthLimit: 5);
$logger = new \Monolog\Logger("Example", [new StreamHandler(STDOUT)]);
$logger->pushProcessor($processor);
$logger->info("Truncated secret", ["access_token" => "Very long JWT ..."]);
Example.INFO: Truncated secret {"access_token":"*****"} []
And, as said before, you can mask the value from right to left using negative values.
use Monolog\Handler\StreamHandler;
use RedactSensitive\RedactSensitiveProcessor;
$sensitive_keys = ["credit_card" => -4];
$processor = new RedactSensitiveProcessor($sensitive_keys);
$logger = new \Monolog\Logger("Example", [new StreamHandler(STDOUT)]);
$logger->pushProcessor($processor);
$logger->info("You are not storing credit cards, right?", ["credit_card" => "4111111145551142"]);
Example.INFO: You are not storing credit cards, right? {"credit_card":"************1142"} []
It should work with nested objects and arrays as well.
use Monolog\Handler\StreamHandler;
use RedactSensitive\RedactSensitiveProcessor;
$sensitive_keys = [
"nested" => [
"arr" => [
"value" => 3,
"or_obj" => ["secret" => -3],
],
]
];
$processor = new RedactSensitiveProcessor($sensitive_keys);
$logger = new \Monolog\Logger("Example", [new StreamHandler(STDOUT)]);
$logger->pushProcessor($processor);
$nested_obj = new stdClass();
$nested_obj->secret = "donttellanyone";
$logger->info("Nested", [
"nested" => [
"arr" => [
"value" => "abcdfg",
"or_obj" => $nested_obj,
],
],
]);
Example.INFO: Nested {"nested":{"arr":{"value":"abc***","or_obj":{"stdClass":{"secret":"***********one"}}}}} []
Feel free to open any issues or PRs.
MIT Β© 2021