$payload */ public function record( Tenant $tenant, string $taskType, string $status, ?string $reasonCode = null, ?string $message = null, array $payload = [], ?OnboardingSession $session = null, ?ProviderConnection $providerConnection = null, ?OperationRun $operationRun = null, ?User $recordedBy = null, ): OnboardingEvidence { $reasonCode = $reasonCode === null ? null : RunFailureSanitizer::normalizeReasonCode($reasonCode); $message = $message === null ? null : RunFailureSanitizer::sanitizeMessage($message); /** @var array $payload */ $payload = $this->sanitizePayload($payload); return OnboardingEvidence::query()->create([ 'tenant_id' => $tenant->getKey(), 'onboarding_session_id' => $session?->getKey(), 'provider_connection_id' => $providerConnection?->getKey(), 'task_type' => $taskType, 'status' => $status, 'reason_code' => $reasonCode, 'message' => $message, 'payload' => $payload, 'operation_run_id' => $operationRun?->getKey(), 'recorded_at' => now(), 'recorded_by_user_id' => $recordedBy?->getKey(), ]); } /** * @param array $payload * @return array */ private function sanitizePayload(array $payload): array { $redactedKeys = ['access_token', 'refresh_token', 'client_secret', 'password', 'authorization', 'bearer']; $sanitize = function (mixed $value) use (&$sanitize, $redactedKeys): mixed { if (is_array($value)) { $out = []; foreach ($value as $k => $v) { $key = is_string($k) ? strtolower($k) : null; if ($key !== null) { foreach ($redactedKeys as $needle) { if (str_contains($key, $needle)) { $out[$k] = '[REDACTED]'; continue 2; } } } $out[$k] = $sanitize($v); } return $out; } if (is_string($value)) { return RunFailureSanitizer::sanitizeMessage($value); } return $value; }; /** @var array $sanitized */ $sanitized = $sanitize($payload); return $sanitized; } }