{"record":{"id":"e5f0b9e2a12225d4","repo":"neondatabase/neon","slug":"audit-logging-endpoint-and-audit-logging-tls-endpo","errorCode":null,"errorMessage":"AUDIT_LOGGING_ENDPOINT and AUDIT_LOGGING_TLS_ENDPOINT are both empty","messagePattern":"AUDIT_LOGGING_ENDPOINT and AUDIT_LOGGING_TLS_ENDPOINT are both empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compute_tools/src/compute.rs","lineNumber":958,"sourceCode":"\n            let _handle = tokio::spawn(async move {\n                if let Err(err) = local_proxy::configure(&local_proxy) {\n                    error!(\"error while configuring local_proxy: {err:?}\");\n                    // Continue with the startup anyway\n                }\n            });\n        }\n\n        // Configure and start rsyslog for compliance audit logging\n        match pspec.spec.audit_log_level {\n            ComputeAudit::Hipaa | ComputeAudit::Extended | ComputeAudit::Full => {\n                let remote_tls_endpoint =\n                    std::env::var(\"AUDIT_LOGGING_TLS_ENDPOINT\").unwrap_or(\"\".to_string());\n                let remote_plain_endpoint =\n                    std::env::var(\"AUDIT_LOGGING_ENDPOINT\").unwrap_or(\"\".to_string());\n\n                if remote_plain_endpoint.is_empty() && remote_tls_endpoint.is_empty() {\n                    anyhow::bail!(\n                        \"AUDIT_LOGGING_ENDPOINT and AUDIT_LOGGING_TLS_ENDPOINT are both empty\"\n                    );\n                }\n\n                let log_directory_path = Path::new(&self.params.pgdata).join(\"log\");\n                let log_directory_path = log_directory_path.to_string_lossy().to_string();\n\n                // Add project_id,endpoint_id to identify the logs.\n                //\n                // These ids are passed from cplane,\n                let endpoint_id = pspec.spec.endpoint_id.as_deref().unwrap_or(\"\");\n                let project_id = pspec.spec.project_id.as_deref().unwrap_or(\"\");\n\n                configure_audit_rsyslog(\n                    log_directory_path.clone(),\n                    endpoint_id,\n                    project_id,\n                    &remote_plain_endpoint,","sourceCodeStart":940,"sourceCodeEnd":976,"githubUrl":"https://github.com/neondatabase/neon/blob/8f60b04da47ffefe0e52bda2440134b42874eb75/compute_tools/src/compute.rs#L940-L976","documentation":"compute_ctl only sets up remote compliance audit logging when a spec demands it (audit_log_level Hipaa/Extended/Full). It reads the destination from the AUDIT_LOGGING_ENDPOINT or AUDIT_LOGGING_TLS_ENDPOINT environment variables; if both are empty/absent it bails because there is nowhere to ship the audit trail. Deployment env and spec must agree.","triggerScenarios":"A ComputeSpec with spec.audit_log_level in {Hipaa, Extended, Full} reaches start_compute while the compute_ctl process environment has neither AUDIT_LOGGING_ENDPOINT nor AUDIT_LOGGING_TLS_ENDPOINT set (both default to \"\").","commonSituations":"Enabling HIPAA/audit levels on a project whose compute pods lack the env vars; local/dev runs of compute_ctl with an audit spec; infra migration where the env vars were dropped from the pod template; misnamed variable (e.g. AUDIT_LOG_ENDPOINT).","solutions":["Set AUDIT_LOGGING_ENDPOINT (plaintext) or AUDIT_LOGGING_TLS_ENDPOINT (TLS) in the compute_ctl container environment and restart the endpoint","If audit logging is not actually required, lower spec.audit_log_level so the rsyslog path is not taken","Add a deployment-time assertion: audit levels imply at least one endpoint variable"],"exampleFix":"# before: spec.audit_log_level = \"Hipaa\", env empty -> bail\n# after\nAUDIT_LOGGING_TLS_ENDPOINT=audit.example.com:6514 compute_ctl run ...","handlingStrategy":"validation","validationCode":"// Before launching a compute with an audit spec, verify its env\nfn audit_env_ok(level: ComputeAudit) -> bool {\n    let needs_remote = matches!(level, ComputeAudit::Hipaa | ComputeAudit::Extended | ComputeAudit::Full);\n    !needs_remote\n        || !std::env::var(\"AUDIT_LOGGING_ENDPOINT\").unwrap_or_default().is_empty()\n        || !std::env::var(\"AUDIT_LOGGING_TLS_ENDPOINT\").unwrap_or_default().is_empty()\n}","typeGuard":null,"tryCatchPattern":"// Fail with an actionable message at deploy time rather than at compute start\nif !audit_env_ok(spec.audit_log_level) {\n    anyhow::bail!(\"audit level {:?} requires AUDIT_LOGGING_ENDPOINT or AUDIT_LOGGING_TLS_ENDPOINT\", spec.audit_log_level);\n}","preventionTips":["Encode the rule in deployment manifests: any pod that may run Hipaa/Extended/Full specs gets both env vars","Add a preflight check script in the image entrypoint for audit env vars","Include a smoke test that boots a Full-audit compute in CI with the env vars set"],"tags":["rust","compute-ctl","audit-logging","env-var","compliance","rsyslog","startup"],"backgroundTag":"missing-env-var","analyzedSha":"8f60b04da47ffefe0e52bda2440134b42874eb75","analyzedAt":"2026-08-16T23:39:28.135Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}