*/ private const SENSITIVE_KEY_PARTS = [ 'access_token', 'authorization', 'assertion', 'bearer', 'certificate', 'client_secret', 'cookie', 'credential', 'id_token', 'password', 'private_key', 'refresh_token', 'secret', 'set-cookie', 'token', ]; public function redact(mixed $value): mixed { if (! is_array($value)) { return $value; } if (array_is_list($value)) { return array_map(fn (mixed $item): mixed => $this->redact($item), $value); } $redacted = []; foreach ($value as $key => $nestedValue) { $key = (string) $key; $redacted[$key] = $this->isSensitiveKey($key) ? '[redacted]' : $this->redact($nestedValue); } return $redacted; } private function isSensitiveKey(string $key): bool { $normalized = strtolower($key); foreach (self::SENSITIVE_KEY_PARTS as $part) { if (str_contains($normalized, $part)) { return true; } } return false; } }