mirror of
https://github.com/openclaw/clawhub.git
synced 2026-07-24 13:15:44 -04:00
2deb1b75e9
* fix: redact scan worker artifact errors * fix: harden worker secret logging * fix: keep worker claim failures failing * fix: scan diagnostics as files * fix: pin diagnostics scanner image * fix: narrow worker redaction boundary * fix: avoid custom worker secret patterns * fix: centralize worker transport redaction * fix: redact persisted worker failure secrets * fix: fail security worker on claim outages * fix: redact structured diagnostic secret fields * fix: harden worker failure redaction boundaries * fix: cover bracketed worker secret values * test: enforce worker workflow secret references * fix: redact quoted worker secret values * fix: redact diagnostic artifact path labels * test: cover claim failure redaction * fix: simplify worker redaction boundary * test: prove worker logger emits structured events
61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
import { redactWorkerPublicText as redactSharedWorkerPublicText } from "../../convex/lib/workerTextRedaction";
|
|
|
|
const DEFAULT_MAX_TEXT_CHARS = 20_000;
|
|
|
|
export function redactWorkerPublicText(value: string, maxChars = DEFAULT_MAX_TEXT_CHARS) {
|
|
const redacted = redactSharedWorkerPublicText(value);
|
|
if (redacted.length <= maxChars) return redacted;
|
|
return `${redacted.slice(0, maxChars)}\n...[truncated ${redacted.length - maxChars} chars]`;
|
|
}
|
|
|
|
export function redactWorkerPublicErrorMessage(value: string) {
|
|
return redactWorkerPublicText(value);
|
|
}
|
|
|
|
export function safeWorkerArtifactPathLabel(value: string) {
|
|
const normalized = value.replace(/[\r\n]+/g, " ").trim();
|
|
const parts = normalized.split("/");
|
|
const redacted = redactSharedWorkerPublicText(normalized);
|
|
const isSafe =
|
|
normalized.length > 0 &&
|
|
normalized.length <= 240 &&
|
|
redacted === normalized &&
|
|
!normalized.startsWith("/") &&
|
|
!parts.includes("..") &&
|
|
/^[A-Za-z0-9._/-]+$/.test(normalized);
|
|
return isSafe ? normalized : "[redacted-path]";
|
|
}
|
|
|
|
function escapeGitHubActionsCommandValue(value: string) {
|
|
return value.replace(/%/g, "%25").replace(/\r/g, "%0D").replace(/\n/g, "%0A");
|
|
}
|
|
|
|
export function maskGitHubActionsSecret(
|
|
value: string | null | undefined,
|
|
options?: { env?: NodeJS.ProcessEnv; write?: (line: string) => void },
|
|
) {
|
|
if (!value) return false;
|
|
const env = options?.env ?? process.env;
|
|
if (env.GITHUB_ACTIONS !== "true") return false;
|
|
const write = options?.write ?? ((line: string) => process.stdout.write(line));
|
|
write(`::add-mask::${escapeGitHubActionsCommandValue(value)}\n`);
|
|
return true;
|
|
}
|
|
|
|
export function maskKnownWorkerSecrets(
|
|
env: NodeJS.ProcessEnv = process.env,
|
|
write?: (line: string) => void,
|
|
) {
|
|
const secretKeys = [
|
|
"SECURITY_SCAN_WORKER_TOKEN",
|
|
"OPENAI_API_KEY",
|
|
"GH_TOKEN",
|
|
"GITHUB_TOKEN",
|
|
"CONVEX_DEPLOY_KEY",
|
|
"HOMEBREW_GITHUB_API_TOKEN",
|
|
];
|
|
for (const key of secretKeys) {
|
|
maskGitHubActionsSecret(env[key], { env, write });
|
|
}
|
|
}
|