record('outbound api call', [ 'authorization' => 'Bearer irdb_svc_ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', ]); $out = $processor($record); self::assertSame('***', $out->context['authorization']); } public function testFormattedOutputDoesNotLeakBearerToken(): void { $processor = new SecretScrubbingProcessor(); $record = $this->record('outbound', [ 'headers' => ['Authorization' => 'Bearer irdb_svc_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'], ]); $out = $processor($record); $line = (new JsonFormatter())->format($out); self::assertStringNotContainsString('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', $line); self::assertStringContainsString('***', $line); } public function testLocalAdminPasswordHashKeyScrubbed(): void { $processor = new SecretScrubbingProcessor(); $record = $this->record('config', [ 'LOCAL_ADMIN_PASSWORD_HASH' => '$argon2id$v=19$abc$def', 'OIDC_CLIENT_SECRET' => 'oidc-secret', ]); $out = $processor($record); self::assertSame('***', $out->context['LOCAL_ADMIN_PASSWORD_HASH']); self::assertSame('***', $out->context['OIDC_CLIENT_SECRET']); } public function testNonSensitiveLeftAlone(): void { $processor = new SecretScrubbingProcessor(); $record = $this->record('search ok', ['count' => 42, 'q' => '203.0.113.42']); $out = $processor($record); self::assertSame(42, $out->context['count']); self::assertSame('203.0.113.42', $out->context['q']); } /** * @param array $context */ private function record(string $message, array $context): LogRecord { return new LogRecord( datetime: new \DateTimeImmutable(), channel: 'test', level: Level::Info, message: $message, context: $context, ); } }