UNPKG

@vigilbase/cli

Version:

Vigilbase CLI — security scanners, agent tools, and Vigilbase One from the terminal.

81 lines (80 loc) • 4.28 kB
/** * The environment every cf child process receives (spec §F3). * * This is the only source file that names the Cloudflare API token variable; * everything else imports `CF_TOKEN_ENV` (enforced by the grep guard test). * The child environment is built from an empty object: a fixed allowlist is * copied by name without inspecting values, then fixed values are forced. * Base-URL overrides (`CLOUDFLARE_API_BASE_URL`, `CF_API_BASE_URL`), other * Cloudflare/Wrangler credentials, `VIGILBASE_*`, `NODE_OPTIONS`, `DEBUG`, * npm config and agent-harness markers are therefore absent by construction. * Scrubbing the base-URL variables is the primary control against redirecting * the token; the dry-run preflight cannot detect it. */ export const CF_TOKEN_ENV = 'CLOUDFLARE_API_TOKEN'; export const CF_ACCOUNT_ENV = 'CLOUDFLARE_ACCOUNT_ID'; const PASSTHROUGH = [ 'PATH', 'HOME', 'USER', 'LOGNAME', 'USERPROFILE', 'APPDATA', 'LOCALAPPDATA', 'SystemRoot', 'WINDIR', 'XDG_CONFIG_HOME', 'XDG_CACHE_HOME', 'XDG_DATA_HOME', 'XDG_STATE_HOME', 'XDG_RUNTIME_DIR', 'TMPDIR', 'TMP', 'TEMP', 'LANG', 'LC_ALL', 'LC_CTYPE', 'TZ', 'HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY', 'http_proxy', 'https_proxy', 'no_proxy', 'NODE_EXTRA_CA_CERTS', 'SSL_CERT_FILE', 'SSL_CERT_DIR', 'DBUS_SESSION_BUS_ADDRESS', 'CLOUDFLARE_AUTH_USE_KEYRING', ]; /** Telemetry off, no update checks or prompts, no project-local delegation. */ const FORCED_TELEMETRY = { CF_SEND_TELEMETRY: 'false', DO_NOT_TRACK: '1', CF_DELEGATION: '1' }; const FORCED_NON_INTERACTIVE = { CI: '1', NO_COLOR: '1', FORCE_COLOR: '0', CF_QUIET: '1' }; function lookup(parent, platform) { if (platform !== 'win32') return (name) => parent[name]; // Windows variable names are case-insensitive (`Path`, `SystemRoot`). const keys = new Map(Object.keys(parent).map((key) => [key.toUpperCase(), key])); return (name) => { const key = keys.get(name.toUpperCase()); return key === undefined ? undefined : parent[key]; }; } /** Presence only: the value is never read, printed or validated by the Vigilbase CLI. */ export function hasEnvToken(parent, platform = process.platform) { const value = lookup(parent, platform)(CF_TOKEN_ENV); return typeof value === 'string' && value.length > 0; } export function buildChildEnv(parent, options) { const platform = options.platform ?? process.platform; const get = lookup(parent, platform); const env = {}; for (const name of PASSTHROUGH) { const value = get(name); if (typeof value === 'string') env[name] = value; } Object.assign(env, FORCED_TELEMETRY); if (options.purpose !== 'login') Object.assign(env, FORCED_NON_INTERACTIVE); if (options.accountId !== undefined) { if (!/^[0-9a-f]{32}$/.test(options.accountId)) throw new Error('Invalid Cloudflare account ID for cf.'); env[CF_ACCOUNT_ENV] = options.accountId; } // Copied by name, only for authenticated reads in --cf-auth env mode. In // profile and default modes it would outrank --profile, so it is stripped. if (options.purpose === 'api' && options.authMode === 'env') { const token = get(CF_TOKEN_ENV); if (typeof token === 'string' && token.length > 0) env[CF_TOKEN_ENV] = token; } return env; } /** Variable names (never values) a cf child would receive, for `--dry-run` output. */ export function childEnvVariableNames(parent, authMode, platform = process.platform) { const names = Object.keys(buildChildEnv(parent, { purpose: 'api', authMode, accountId: '0'.repeat(32), platform })); if (authMode === 'env' && !names.includes(CF_TOKEN_ENV)) names.push(CF_TOKEN_ENV); return names.sort(); } /** Shown in profile and default modes when the token variable is set in the parent shell. */ export function strippedTokenNotice(authMode) { return `${CF_TOKEN_ENV} is set in this shell but is not passed to cf in --cf-auth ${authMode} mode (it would override the profile). Use --cf-auth env to collect with it.`; } export function missingEnvTokenMessage() { return `--cf-auth env requires ${CF_TOKEN_ENV} in this shell. cf reads it itself; the Vigilbase CLI only passes it through by name.`; }