openclaw-plugin-onepassword 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,180 @@
1
+ /**
2
+ * openclaw-plugin-onepassword
3
+ *
4
+ * Native OpenClaw plugin that resolves 1Password secrets *in-process* (inside
5
+ * the Gateway, not as a sandboxed child) and writes them into OpenClaw's shared
6
+ * secret store, plus optional agent tools for vault/item operations.
7
+ *
8
+ * Why in-process: OpenClaw v2026.8.1 sandboxes exec secret providers, blocking
9
+ * filesystem writes and network access — which breaks `op read` and any other
10
+ * network-dependent exec resolver. Running inside the Gateway process avoids the
11
+ * sandbox entirely, so the official `@1password/sdk` can reach the 1Password API
12
+ * over HTTPS normally.
13
+ */
14
+ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
15
+ import { parsePluginConfig, readServiceAccountToken, } from "./config.js";
16
+ import { createOnePasswordClient } from "./op-client.js";
17
+ import { syncSecrets, syncResultIsClean, } from "./secret-sync.js";
18
+ import { createTools } from "./tools.js";
19
+ import { PLUGIN_ID, PLUGIN_VERSION } from "./version.js";
20
+ const SERVICE_ID = "onepassword-secret-sync";
21
+ const STORE_SET_METHOD = "secrets.store.set";
22
+ /**
23
+ * StoreWriter backed by the `secrets.store.set` Gateway RPC dispatched through
24
+ * the trusted plugin runtime. Retries briefly while the Gateway request context
25
+ * is still coming up during cold start.
26
+ */
27
+ function createStoreWriter(api) {
28
+ return {
29
+ async write(name, value) {
30
+ const gateway = api.runtime?.gateway;
31
+ if (!gateway) {
32
+ throw new Error("plugin runtime gateway is unavailable; cannot write to the secret store");
33
+ }
34
+ const deadline = Date.now() + 10_000;
35
+ let lastError;
36
+ // The gateway request context may not be ready the instant a startup
37
+ // service runs; retry with backoff until it is (or we give up).
38
+ for (let attempt = 0;; attempt++) {
39
+ try {
40
+ if (await gateway.isAvailable()) {
41
+ await gateway.request(STORE_SET_METHOD, { name, value });
42
+ return;
43
+ }
44
+ lastError = new Error("gateway request context not yet available");
45
+ }
46
+ catch (err) {
47
+ lastError = err;
48
+ }
49
+ if (Date.now() >= deadline)
50
+ break;
51
+ await delay(Math.min(1000, 100 * 2 ** attempt));
52
+ }
53
+ throw lastError instanceof Error ? lastError : new Error(String(lastError));
54
+ },
55
+ };
56
+ }
57
+ function delay(ms) {
58
+ return new Promise((resolve) => setTimeout(resolve, ms));
59
+ }
60
+ /** Lazily create and memoize a 1Password client from the configured token. */
61
+ function createClientFactory(config) {
62
+ let cached;
63
+ return () => {
64
+ if (!cached) {
65
+ const token = readServiceAccountToken(config);
66
+ if (!token) {
67
+ return Promise.reject(new Error(`1Password service account token not found. Set the ${config.serviceAccountTokenEnvVar} environment variable on the Gateway process.`));
68
+ }
69
+ cached = createOnePasswordClient({
70
+ token,
71
+ integrationName: config.integrationName,
72
+ integrationVersion: PLUGIN_VERSION,
73
+ requestTimeoutMs: config.requestTimeoutMs,
74
+ }).catch((err) => {
75
+ cached = undefined; // allow retry on next call
76
+ throw err;
77
+ });
78
+ }
79
+ return cached;
80
+ };
81
+ }
82
+ export default definePluginEntry({
83
+ id: PLUGIN_ID,
84
+ name: "1Password",
85
+ description: "Resolve 1Password secrets in-process into the OpenClaw store, and expose 1Password vault/item tools to agents.",
86
+ register(api) {
87
+ const logger = api.logger;
88
+ let config;
89
+ try {
90
+ config = parsePluginConfig(api.pluginConfig);
91
+ }
92
+ catch (err) {
93
+ // Surface config errors loudly; do not register anything with bad config.
94
+ logger?.error?.(`onepassword: invalid plugin config: ${err instanceof Error ? err.message : String(err)}`);
95
+ throw err;
96
+ }
97
+ const getClient = createClientFactory(config);
98
+ const store = createStoreWriter(api);
99
+ const runSync = async () => {
100
+ const client = await getClient();
101
+ return syncSecrets({ client, store, secrets: config.secrets, logger });
102
+ };
103
+ // --- Startup / reload sync service -----------------------------------
104
+ api.registerService({
105
+ id: SERVICE_ID,
106
+ async start() {
107
+ if (!config.syncOnStartup) {
108
+ logger?.debug?.("onepassword: syncOnStartup disabled; skipping startup sync");
109
+ return;
110
+ }
111
+ if (Object.keys(config.secrets).length === 0) {
112
+ logger?.debug?.("onepassword: no secrets configured; nothing to sync at startup");
113
+ return;
114
+ }
115
+ if (!readServiceAccountToken(config)) {
116
+ const message = `onepassword: ${config.serviceAccountTokenEnvVar} is not set; cannot sync secrets at startup`;
117
+ if (config.failFastOnStartup)
118
+ throw new Error(message);
119
+ logger?.warn?.(message);
120
+ return;
121
+ }
122
+ try {
123
+ const result = await runSync();
124
+ if (config.failFastOnStartup && !syncResultIsClean(result)) {
125
+ throw new Error(`onepassword: startup sync failed for ${result.total - result.written.length} of ${result.total} secret(s)`);
126
+ }
127
+ }
128
+ catch (err) {
129
+ if (config.failFastOnStartup)
130
+ throw err;
131
+ logger?.error?.(`onepassword: startup sync error: ${err instanceof Error ? err.message : String(err)}`);
132
+ }
133
+ },
134
+ });
135
+ // --- Gateway methods --------------------------------------------------
136
+ // onepassword.sync — re-fetch every configured secret from 1Password and
137
+ // write it into the store. This is what makes fresh values available at
138
+ // runtime (analogous to, and composable with, `openclaw secrets reload`).
139
+ api.registerGatewayMethod("onepassword.sync", async ({ respond }) => {
140
+ try {
141
+ const result = await runSync();
142
+ respond(true, {
143
+ written: result.written,
144
+ total: result.total,
145
+ resolveErrors: result.resolveErrors,
146
+ storeErrors: result.storeErrors,
147
+ });
148
+ }
149
+ catch (err) {
150
+ respond(false, undefined, {
151
+ code: "ONEPASSWORD_SYNC_FAILED",
152
+ message: err instanceof Error ? err.message : String(err),
153
+ });
154
+ }
155
+ }, { scope: "operator.admin" });
156
+ // onepassword.status — cheap health/config summary (no secret values).
157
+ api.registerGatewayMethod("onepassword.status", ({ respond }) => {
158
+ respond(true, {
159
+ version: PLUGIN_VERSION,
160
+ serviceAccountTokenEnvVar: config.serviceAccountTokenEnvVar,
161
+ tokenPresent: readServiceAccountToken(config) !== undefined,
162
+ syncOnStartup: config.syncOnStartup,
163
+ managedStoreKeys: Object.keys(config.secrets),
164
+ toolsEnabled: config.tools.enabled,
165
+ toolsWriteEnabled: config.tools.allowWrite,
166
+ });
167
+ }, { scope: "operator.admin" });
168
+ // --- Agent tools (optional) ------------------------------------------
169
+ if (config.tools.enabled) {
170
+ const tools = createTools({ getClient, allowWrite: config.tools.allowWrite });
171
+ for (const tool of tools) {
172
+ // Boundary cast: PluginTool is a structural subset of the SDK's tool type.
173
+ api.registerTool(tool, { optional: true });
174
+ }
175
+ logger?.debug?.(`onepassword: registered ${tools.length} agent tool(s) (write=${config.tools.allowWrite})`);
176
+ }
177
+ logger?.info?.(`onepassword plugin v${PLUGIN_VERSION} registered`);
178
+ },
179
+ });
180
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Thin, testable wrapper over the official `@1password/sdk`.
3
+ *
4
+ * The wrapper exists so the rest of the plugin depends on a small, stable
5
+ * interface ({@link OnePasswordClient}) rather than the SDK surface directly,
6
+ * which keeps unit tests fast (no network, no real SDK) and isolates us from
7
+ * SDK churn.
8
+ */
9
+ import type { Item, ItemCreateParams, ItemOverview, VaultOverview } from "@1password/sdk";
10
+ export interface ResolveResult {
11
+ /** Resolved values keyed by the original reference. */
12
+ values: Record<string, string>;
13
+ /** References that failed, keyed by reference -> error message. */
14
+ errors: Record<string, string>;
15
+ }
16
+ /** The stable surface the rest of the plugin relies on. */
17
+ export interface OnePasswordClient {
18
+ resolve(reference: string): Promise<string>;
19
+ resolveAll(references: string[]): Promise<ResolveResult>;
20
+ listVaults(): Promise<VaultOverview[]>;
21
+ listItems(vaultId: string): Promise<ItemOverview[]>;
22
+ getItem(vaultId: string, itemId: string): Promise<Item>;
23
+ createItem(params: ItemCreateParams): Promise<Item>;
24
+ updateItem(item: Item): Promise<Item>;
25
+ deleteItem(vaultId: string, itemId: string): Promise<void>;
26
+ }
27
+ export interface CreateClientOptions {
28
+ token: string;
29
+ integrationName: string;
30
+ integrationVersion?: string;
31
+ /** Per-operation timeout in milliseconds. */
32
+ requestTimeoutMs?: number;
33
+ }
34
+ /**
35
+ * Create an authenticated {@link OnePasswordClient}. The `@1password/sdk`
36
+ * package is imported dynamically so it is only loaded when 1Password access is
37
+ * actually used, keeping gateway startup cheap for operators who install but do
38
+ * not configure the plugin.
39
+ */
40
+ export declare function createOnePasswordClient(options: CreateClientOptions): Promise<OnePasswordClient>;
41
+ //# sourceMappingURL=op-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"op-client.d.ts","sourceRoot":"","sources":["../src/op-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAU,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIlG,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACzD,UAAU,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACvC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,6CAA6C;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA4GD;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAW5B"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Thin, testable wrapper over the official `@1password/sdk`.
3
+ *
4
+ * The wrapper exists so the rest of the plugin depends on a small, stable
5
+ * interface ({@link OnePasswordClient}) rather than the SDK surface directly,
6
+ * which keeps unit tests fast (no network, no real SDK) and isolates us from
7
+ * SDK churn.
8
+ */
9
+ import { PLUGIN_VERSION } from "./version.js";
10
+ /** Reject a promise that does not settle within `ms`. */
11
+ async function withTimeout(promise, ms, label) {
12
+ if (!ms || ms <= 0)
13
+ return promise;
14
+ let timer;
15
+ const timeout = new Promise((_resolve, reject) => {
16
+ timer = setTimeout(() => {
17
+ reject(new Error(`1Password operation "${label}" timed out after ${ms}ms`));
18
+ }, ms);
19
+ // Do not keep the event loop alive solely for this timer.
20
+ timer.unref?.();
21
+ });
22
+ try {
23
+ return await Promise.race([promise, timeout]);
24
+ }
25
+ finally {
26
+ if (timer)
27
+ clearTimeout(timer);
28
+ }
29
+ }
30
+ function resolveAllUnsupported(err) {
31
+ // Older SDKs may not implement resolveAll; fall back to per-ref resolve.
32
+ return (err instanceof TypeError ||
33
+ (err instanceof Error && /resolveAll is not a function/i.test(err.message)));
34
+ }
35
+ class SdkOnePasswordClient {
36
+ client;
37
+ timeoutMs;
38
+ constructor(client, timeoutMs) {
39
+ this.client = client;
40
+ this.timeoutMs = timeoutMs;
41
+ }
42
+ resolve(reference) {
43
+ return withTimeout(this.client.secrets.resolve(reference), this.timeoutMs, "secrets.resolve");
44
+ }
45
+ async resolveAll(references) {
46
+ const values = {};
47
+ const errors = {};
48
+ if (references.length === 0)
49
+ return { values, errors };
50
+ // Prefer the batched SDK call when available.
51
+ try {
52
+ const response = await withTimeout(this.client.secrets.resolveAll(references), this.timeoutMs, "secrets.resolveAll");
53
+ for (const [reference, entry] of Object.entries(response.individualResponses ?? {})) {
54
+ if (entry?.content?.secret !== undefined) {
55
+ values[reference] = entry.content.secret;
56
+ }
57
+ else if (entry?.error) {
58
+ errors[reference] = entry.error.message ?? String(entry.error.type ?? "unknown error");
59
+ }
60
+ }
61
+ // Any reference the batch response omitted is treated as an error below.
62
+ for (const reference of references) {
63
+ if (!(reference in values) && !(reference in errors)) {
64
+ errors[reference] = "1Password returned no response for this reference";
65
+ }
66
+ }
67
+ return { values, errors };
68
+ }
69
+ catch (err) {
70
+ if (!resolveAllUnsupported(err)) {
71
+ // Batch call failed wholesale (e.g. auth/timeout). Fall through to
72
+ // per-reference resolution so a single bad ref does not sink the rest.
73
+ }
74
+ }
75
+ await Promise.all(references.map(async (reference) => {
76
+ try {
77
+ values[reference] = await this.resolve(reference);
78
+ }
79
+ catch (err) {
80
+ errors[reference] = err instanceof Error ? err.message : String(err);
81
+ }
82
+ }));
83
+ return { values, errors };
84
+ }
85
+ listVaults() {
86
+ return withTimeout(this.client.vaults.list(), this.timeoutMs, "vaults.list");
87
+ }
88
+ listItems(vaultId) {
89
+ return withTimeout(this.client.items.list(vaultId), this.timeoutMs, "items.list");
90
+ }
91
+ getItem(vaultId, itemId) {
92
+ return withTimeout(this.client.items.get(vaultId, itemId), this.timeoutMs, "items.get");
93
+ }
94
+ createItem(params) {
95
+ return withTimeout(this.client.items.create(params), this.timeoutMs, "items.create");
96
+ }
97
+ updateItem(item) {
98
+ return withTimeout(this.client.items.put(item), this.timeoutMs, "items.put");
99
+ }
100
+ deleteItem(vaultId, itemId) {
101
+ return withTimeout(this.client.items.delete(vaultId, itemId), this.timeoutMs, "items.delete");
102
+ }
103
+ }
104
+ /**
105
+ * Create an authenticated {@link OnePasswordClient}. The `@1password/sdk`
106
+ * package is imported dynamically so it is only loaded when 1Password access is
107
+ * actually used, keeping gateway startup cheap for operators who install but do
108
+ * not configure the plugin.
109
+ */
110
+ export async function createOnePasswordClient(options) {
111
+ if (!options.token || options.token.trim().length === 0) {
112
+ throw new Error("A 1Password service account token is required to create a client.");
113
+ }
114
+ const { createClient } = await import("@1password/sdk");
115
+ const client = await createClient({
116
+ auth: options.token,
117
+ integrationName: options.integrationName,
118
+ integrationVersion: options.integrationVersion ?? PLUGIN_VERSION,
119
+ });
120
+ return new SdkOnePasswordClient(client, options.requestTimeoutMs ?? 0);
121
+ }
122
+ //# sourceMappingURL=op-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"op-client.js","sourceRoot":"","sources":["../src/op-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Standalone exec secret resolver (OPTIONAL / ADVANCED).
3
+ *
4
+ * OpenClaw's `secretProviderIntegrations` feature runs this file as
5
+ * `node dist/resolver.js` (a child process) and speaks a small JSON protocol
6
+ * over stdin/stdout:
7
+ *
8
+ * request: { "protocolVersion": 1, "provider": "op", "ids": ["op://Vault/Item/field"] }
9
+ * response: { "protocolVersion": 1, "values": { "op://Vault/Item/field": "<secret>" } }
10
+ *
11
+ * IMPORTANT: because this runs as an *exec* secret provider, it is subject to
12
+ * the v2026.8.1 exec sandbox that blocks filesystem writes and network access.
13
+ * It therefore only works when the operator has allowlisted the 1Password API
14
+ * host for secret egress (see README → "Exec resolver mode"). For most setups,
15
+ * prefer the in-process store sync, which is not sandboxed.
16
+ *
17
+ * This module intentionally imports nothing from `openclaw` so it stays a
18
+ * lightweight, independently testable leaf.
19
+ */
20
+ interface ResolverRequest {
21
+ protocolVersion?: number;
22
+ provider?: string;
23
+ ids?: string[];
24
+ }
25
+ interface ResolverResponse {
26
+ protocolVersion: 1;
27
+ values: Record<string, string>;
28
+ errors?: Record<string, {
29
+ code: string;
30
+ message?: string;
31
+ }>;
32
+ }
33
+ export declare function resolveRequest(request: ResolverRequest, env?: NodeJS.ProcessEnv): Promise<ResolverResponse>;
34
+ /** CLI entrypoint: read a request from stdin, print a response to stdout. */
35
+ export declare function main(): Promise<void>;
36
+ export {};
37
+ //# sourceMappingURL=resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AASH,UAAU,eAAe;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,UAAU,gBAAgB;IACxB,eAAe,EAAE,CAAC,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D;AA2BD,wBAAsB,cAAc,CAClC,OAAO,EAAE,eAAe,EACxB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,gBAAgB,CAAC,CAmC3B;AAED,6EAA6E;AAC7E,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAa1C"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Standalone exec secret resolver (OPTIONAL / ADVANCED).
3
+ *
4
+ * OpenClaw's `secretProviderIntegrations` feature runs this file as
5
+ * `node dist/resolver.js` (a child process) and speaks a small JSON protocol
6
+ * over stdin/stdout:
7
+ *
8
+ * request: { "protocolVersion": 1, "provider": "op", "ids": ["op://Vault/Item/field"] }
9
+ * response: { "protocolVersion": 1, "values": { "op://Vault/Item/field": "<secret>" } }
10
+ *
11
+ * IMPORTANT: because this runs as an *exec* secret provider, it is subject to
12
+ * the v2026.8.1 exec sandbox that blocks filesystem writes and network access.
13
+ * It therefore only works when the operator has allowlisted the 1Password API
14
+ * host for secret egress (see README → "Exec resolver mode"). For most setups,
15
+ * prefer the in-process store sync, which is not sandboxed.
16
+ *
17
+ * This module intentionally imports nothing from `openclaw` so it stays a
18
+ * lightweight, independently testable leaf.
19
+ */
20
+ import { createOnePasswordClient } from "./op-client.js";
21
+ import { DEFAULT_INTEGRATION_NAME, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_TOKEN_ENV_VAR, } from "./config.js";
22
+ const NOT_FOUND = "NOT_FOUND";
23
+ const UNAVAILABLE = "UNAVAILABLE";
24
+ function readStdin() {
25
+ return new Promise((resolve, reject) => {
26
+ let data = "";
27
+ process.stdin.setEncoding("utf8");
28
+ process.stdin.on("data", (chunk) => {
29
+ data += chunk;
30
+ });
31
+ process.stdin.on("end", () => resolve(data));
32
+ process.stdin.on("error", reject);
33
+ });
34
+ }
35
+ function parseRequest(input) {
36
+ const trimmed = input.trim();
37
+ if (trimmed.length === 0)
38
+ return {};
39
+ const parsed = JSON.parse(trimmed);
40
+ if (typeof parsed !== "object" || parsed === null) {
41
+ throw new Error("resolver request must be a JSON object");
42
+ }
43
+ return parsed;
44
+ }
45
+ export async function resolveRequest(request, env = process.env) {
46
+ const ids = Array.isArray(request.ids) ? request.ids.filter((id) => typeof id === "string") : [];
47
+ const response = { protocolVersion: 1, values: {} };
48
+ if (ids.length === 0)
49
+ return response;
50
+ const tokenEnvVar = env.OP_RESOLVER_TOKEN_ENV_VAR?.trim() || DEFAULT_TOKEN_ENV_VAR;
51
+ const token = env[tokenEnvVar]?.trim();
52
+ if (!token) {
53
+ response.errors = {};
54
+ for (const id of ids) {
55
+ response.errors[id] = {
56
+ code: UNAVAILABLE,
57
+ message: `service account token env var ${tokenEnvVar} is not set`,
58
+ };
59
+ }
60
+ return response;
61
+ }
62
+ const client = await createOnePasswordClient({
63
+ token,
64
+ integrationName: env.OP_INTEGRATION_NAME?.trim() || DEFAULT_INTEGRATION_NAME,
65
+ requestTimeoutMs: DEFAULT_REQUEST_TIMEOUT_MS,
66
+ });
67
+ const { values, errors } = await client.resolveAll(ids);
68
+ response.values = values;
69
+ const errorEntries = Object.entries(errors);
70
+ if (errorEntries.length > 0) {
71
+ response.errors = {};
72
+ for (const [id, message] of errorEntries) {
73
+ const code = /not\s*found|no item|no vault/i.test(message) ? NOT_FOUND : UNAVAILABLE;
74
+ response.errors[id] = { code, message };
75
+ }
76
+ }
77
+ return response;
78
+ }
79
+ /** CLI entrypoint: read a request from stdin, print a response to stdout. */
80
+ export async function main() {
81
+ try {
82
+ const request = parseRequest(await readStdin());
83
+ const response = await resolveRequest(request);
84
+ process.stdout.write(JSON.stringify(response));
85
+ }
86
+ catch (err) {
87
+ // Never leak error internals to stdout (may contain credential material).
88
+ process.stderr.write(`onepassword resolver error: ${err instanceof Error ? err.message : String(err)}\n`);
89
+ process.stdout.write(JSON.stringify({ protocolVersion: 1, values: {} }));
90
+ process.exitCode = 1;
91
+ }
92
+ }
93
+ // Run only when executed directly (node dist/resolver.js), not when imported by tests.
94
+ const invokedPath = process.argv[1] ? process.argv[1].replace(/\\/g, "/") : "";
95
+ if (invokedPath.endsWith("/resolver.js") || invokedPath.endsWith("/resolver.ts")) {
96
+ void main();
97
+ }
98
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * In-process secret synchronization.
3
+ *
4
+ * This is the mechanism that bypasses the OpenClaw exec secret sandbox: instead
5
+ * of running `op` (or any resolver) as a sandboxed child process, the plugin
6
+ * runs inside the Gateway process, fetches values from 1Password over HTTPS
7
+ * using the official SDK, and writes them into OpenClaw's shared secret store.
8
+ * Operators then reference those values with `source: "store"`.
9
+ */
10
+ import type { OnePasswordClient } from "./op-client.js";
11
+ /** Minimal logger surface (compatible with OpenClaw's PluginLogger). */
12
+ export interface SyncLogger {
13
+ info?: (message: string) => void;
14
+ warn?: (message: string) => void;
15
+ error?: (message: string) => void;
16
+ debug?: (message: string) => void;
17
+ }
18
+ /**
19
+ * Writes a resolved secret into OpenClaw's shared store.
20
+ *
21
+ * Implemented in {@link file://./index.ts} by dispatching the
22
+ * `secrets.store.set` Gateway method through `api.runtime.gateway.request`,
23
+ * which persists the value (team scope) and triggers a live runtime refresh so
24
+ * dependent channels/providers pick it up without a restart.
25
+ */
26
+ export interface StoreWriter {
27
+ write(name: string, value: string): Promise<void>;
28
+ }
29
+ export interface SyncOptions {
30
+ client: OnePasswordClient;
31
+ store: StoreWriter;
32
+ /** Map of store key -> op:// reference. */
33
+ secrets: Record<string, string>;
34
+ logger?: SyncLogger;
35
+ }
36
+ export interface SyncResult {
37
+ /** Store keys successfully fetched and written. */
38
+ written: string[];
39
+ /** Store key -> error message for references that failed to resolve. */
40
+ resolveErrors: Record<string, string>;
41
+ /** Store key -> error message for values that resolved but failed to store. */
42
+ storeErrors: Record<string, string>;
43
+ /** Total number of configured references. */
44
+ total: number;
45
+ }
46
+ export declare function syncResultIsClean(result: SyncResult): boolean;
47
+ /**
48
+ * Resolve every configured reference from 1Password and write it into the
49
+ * store. Individual failures are collected rather than thrown so one bad
50
+ * reference cannot prevent the rest of the secrets from loading. The caller
51
+ * decides whether a partial failure is fatal (see `failFastOnStartup`).
52
+ */
53
+ export declare function syncSecrets(options: SyncOptions): Promise<SyncResult>;
54
+ //# sourceMappingURL=secret-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-sync.d.ts","sourceRoot":"","sources":["../src/secret-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,wEAAwE;AACxE,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,+EAA+E;IAC/E,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAI7D;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAgD3E"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * In-process secret synchronization.
3
+ *
4
+ * This is the mechanism that bypasses the OpenClaw exec secret sandbox: instead
5
+ * of running `op` (or any resolver) as a sandboxed child process, the plugin
6
+ * runs inside the Gateway process, fetches values from 1Password over HTTPS
7
+ * using the official SDK, and writes them into OpenClaw's shared secret store.
8
+ * Operators then reference those values with `source: "store"`.
9
+ */
10
+ export function syncResultIsClean(result) {
11
+ return (Object.keys(result.resolveErrors).length === 0 && Object.keys(result.storeErrors).length === 0);
12
+ }
13
+ /**
14
+ * Resolve every configured reference from 1Password and write it into the
15
+ * store. Individual failures are collected rather than thrown so one bad
16
+ * reference cannot prevent the rest of the secrets from loading. The caller
17
+ * decides whether a partial failure is fatal (see `failFastOnStartup`).
18
+ */
19
+ export async function syncSecrets(options) {
20
+ const { client, store, secrets, logger } = options;
21
+ const entries = Object.entries(secrets);
22
+ const result = {
23
+ written: [],
24
+ resolveErrors: {},
25
+ storeErrors: {},
26
+ total: entries.length,
27
+ };
28
+ if (entries.length === 0) {
29
+ logger?.debug?.("onepassword: no secrets configured to sync");
30
+ return result;
31
+ }
32
+ // Resolve references in a single batch. Map references back to store keys;
33
+ // note two store keys may point at the same reference.
34
+ const references = [...new Set(entries.map(([, ref]) => ref))];
35
+ const { values, errors } = await client.resolveAll(references);
36
+ for (const [key, reference] of entries) {
37
+ const value = values[reference];
38
+ if (value === undefined) {
39
+ const message = errors[reference] ?? "reference did not resolve";
40
+ result.resolveErrors[key] = message;
41
+ logger?.warn?.(`onepassword: failed to resolve ${key} (${reference}): ${message}`);
42
+ continue;
43
+ }
44
+ try {
45
+ await store.write(key, value);
46
+ result.written.push(key);
47
+ logger?.debug?.(`onepassword: stored ${key} from ${reference}`);
48
+ }
49
+ catch (err) {
50
+ const message = err instanceof Error ? err.message : String(err);
51
+ result.storeErrors[key] = message;
52
+ logger?.error?.(`onepassword: failed to store ${key}: ${message}`);
53
+ }
54
+ }
55
+ const failed = Object.keys(result.resolveErrors).length + Object.keys(result.storeErrors).length;
56
+ if (failed === 0) {
57
+ logger?.info?.(`onepassword: synced ${result.written.length} secret(s) into the store`);
58
+ }
59
+ else {
60
+ logger?.warn?.(`onepassword: synced ${result.written.length}/${result.total} secret(s); ${failed} failed`);
61
+ }
62
+ return result;
63
+ }
64
+ //# sourceMappingURL=secret-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-sync.js","sourceRoot":"","sources":["../src/secret-sync.ts"],"names":[],"mappings":"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"}