Files
openclaw/extensions/onepassword/onepassword-op-path.js
Peter Steinberger 481d826ff4 fix(vault): prevent insecure secrets plan writes (#113707)
* fix(vault): harden secrets plan writes

* fix(secrets): avoid env marker collision

* style(secrets): type plan write rejection

* refactor(onepassword): remove obsolete path resolver

* fix(secrets): preserve Windows plan path trust

* refactor(secrets): compact ACL token policy

* fix(secrets): route permission checks through facade
2026-07-25 08:27:33 -07:00

46 lines
1.5 KiB
JavaScript

import path from "node:path";
import { pluginSecretRefSetup } from "openclaw/plugin-sdk/secret-ref-runtime";
function errorCode(error) {
return error && typeof error === "object" && "code" in error ? error.code : undefined;
}
export const resolveTrustedExecutablePath = pluginSecretRefSetup.resolveTrustedExecutablePath;
export const resolveTrustedOnePasswordDirectoryPath =
pluginSecretRefSetup.resolveTrustedDirectoryPath;
export async function resolveTrustedOnePasswordCli(options = {}) {
const configuredPath = options.configuredPath?.trim();
if (configuredPath && !path.isAbsolute(configuredPath)) {
throw new Error(`1Password CLI path must be absolute: ${configuredPath}`);
}
const executable = process.platform === "win32" ? "op.exe" : "op";
const candidates = configuredPath
? [configuredPath]
: (options.pathEnv ?? process.env.PATH ?? "")
.split(path.delimiter)
.filter(Boolean)
.map((directory) => path.resolve(directory, executable));
let unsafeError;
for (const candidate of candidates) {
try {
return await resolveTrustedExecutablePath(candidate);
} catch (error) {
if (errorCode(error) === "ENOENT" || errorCode(error) === "ENOTDIR") {
continue;
}
unsafeError = new Error(
`Refusing unsafe 1Password CLI path "${candidate}": ${error instanceof Error ? error.message : String(error)}`,
{ cause: error },
);
if (configuredPath) {
throw unsafeError;
}
}
}
if (unsafeError) {
throw unsafeError;
}
return undefined;
}