Tools
Plugin Onepassword
Native OpenClaw plugin: resolve 1Password secrets in-process (bypassing the exec sandbox) into the shared store, plus 1Password agent tools.
Install
npm install --ignore-scripts
Configuration Example
{
"plugins": {
"entries": {
"onepassword": {
"enabled": true,
"config": {
"serviceAccountTokenEnvVar": "OP_SERVICE_ACCOUNT_TOKEN",
"secrets": {
"SLACK_BOT_TOKEN": "op://MyVault/SlackBot/bot_token",
"SLACK_APP_TOKEN": "op://MyVault/SlackBot/app_token",
"OPENAI_API_KEY": "op://MyVault/OpenAI/credential"
}
}
}
}
}
}
README
# openclaw-plugin-onepassword
[](https://github.com/ioleksiy/openclaw-plugin-onepassword/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/openclaw-plugin-onepassword)
[](./LICENSE)
A native [OpenClaw](https://openclaw.ai) plugin that resolves **[1Password](https://1password.com) secrets in-process** inside the Gateway — no `op` CLI, no child process, no exec sandbox — and writes them into OpenClaw's shared secret store. It also exposes optional 1Password vault/item **agent tools**.
> **Why this exists.** OpenClaw **v2026.8.1** introduced a security sandbox for `exec` secret providers that blocks **filesystem writes and network access** during provider execution. That breaks the common pattern of using `op read` as an exec provider (you'll see errors like `sh: cannot open /tmp/op_out.txt` and blocked network calls). This plugin runs **inside the Gateway process**, where the sandbox does not apply, and uses the official [`@1password/sdk`](https://github.com/1Password/onepassword-sdk-js) over HTTPS.
---
## Contents
- [How it works](#how-it-works)
- [Requirements](#requirements)
- [Install](#install)
- [Quick start (store sync — recommended)](#quick-start-store-sync--recommended)
- [Configuration reference](#configuration-reference)
- [Agent tools (optional)](#agent-tools-optional)
- [Gateway methods](#gateway-methods)
- [Refreshing secrets at runtime](#refreshing-secrets-at-runtime)
- [Exec resolver mode (advanced)](#exec-resolver-mode-advanced)
- [Security notes](#security-notes)
- [Troubleshooting](#troubleshooting)
- [Development](#development)
- [Publishing](#publishing)
- [License](#license)
---
## How it works
There are two ways a plugin can feed secrets to OpenClaw. This plugin ships both, but **the in-process store sync is the recommended path** because it is the only one that reliably bypasses the exec sandbox.
| Mode | Runs where | Bypasses exec sandbox? | `SecretRef` you write | Vault/item paths live in |
| ---------------------------- | ---------------------- | -------------------------------- | -------------------------------------- | ----------------------------- |
| **Store sync** (default) | In-process (Gateway) | ✅ Yes | `source: "store"` | plugin `config.secrets` map |
| **Exec resolver** (advanced) | Sandboxed child `node` | ⚠️ Only with egress allowlisting | `source: "exec"` + `pluginIntegration` | the `SecretRef.id` (`op://…`) |
**Store sync**, in one picture:
```
Gateway start / onepassword.sync
│
▼
read OP_SERVICE_ACCOUNT_TOKEN (env)
│
▼
@1password/sdk ──HTTPS──▶ 1Password API
│
▼
secrets.store.set { name, value } (in-process Gateway RPC)
│
▼
OpenClaw shared store ◀── resolved by SecretRefs with source:"store"
```
The plugin never writes secrets to `openclaw.json`, environment variables, or disk of its own. Values live only in OpenClaw's store (SQLite, `0600`/`0700` permissions, team scope).
## Requirements
- **OpenClaw** `>= 2026.8.0` (Gateway runs on Node `>= 22.22.3`).
- A **1Password service account** token — see [1Password service accounts](https://developer.1password.com/docs/service-accounts). The service account must have access to the vaults/items you reference.
## Install
From npm (recommended):
```bash
openclaw plugins install openclaw-plugin-onepassword
```
Or from a local checkout:
```bash
openclaw plugins install ./openclaw-plugin-onepassword
```
Then provide the service account token to the **Gateway process** via the environment variable (default `OP_SERVICE_ACCOUNT_TOKEN`). Keep it out of `openclaw.json`, docker-compose files, and shell history — use your process manager's secret mechanism (systemd `LoadCredential`, Docker/Kubernetes secrets, etc.).
```bash
export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
```
## Quick start (store sync — recommended)
1. **Enable the plugin and map store keys to 1Password references** in `openclaw.json`:
```json
{
"plugins": {
"entries": {
"onepassword": {
"enabled": true,
"config": {
"serviceAccountTokenEnvVar": "OP_SERVICE_ACCOUNT_TOKEN",
"secrets": {
"SLACK_BOT_TOKEN": "op://MyVault/SlackBot/bot_token",
"SLACK_APP_TOKEN": "op://MyVault/SlackBot/app_token",
"OPENAI_API_KEY": "op://MyVault/OpenAI/credential"
}
}
}
}
}
}
```
Store keys must match `^[A-Z][A-Z0-9_]{0,127}$` (OpenClaw store-id grammar). Values are standard [1Password secret references](https://developer.1password.com/docs/cli/secret-references/): `op://Vault/Item[/Section]/Field`.
2. **Reference those store keys** anywhere OpenClaw accepts a `SecretRef`, using `source: "store"`:
```json
{
"channels": {
"slack": {
"accounts": {
"myworkspace": {
"botToken": { "source": "store", "id": "SLACK_BOT_TOKEN" },
"appToken": { "source": "store", "id": "SLACK_APP_TOKEN" }
}
}
}
},
"agents": {
"defaults": {
"model": {
"providers": {
"openai": {
"apiKey": { "source": "store", "id": "OPENAI_API_KEY" }
}
}
}
}
}
}
```
3. **Start the Gateway.** On startup the plugin fetches each reference from 1Password and writes it into the store; the referencing channels/providers then initialize with resolved credentials. Because store values persist, subsequent restarts are covered even before the first sync completes.
See [`examples/`](./examples) for complete config files.
## Configuration reference
All keys live under `plugins.entries.onepassword.config`.
| Key | Type | Default | Description |
| --------------------------- | ------- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `serviceAccountTokenEnvVar` | string | `"OP_SERVICE_ACCOUNT_TOKEN"` | Name of the environment variable holding the service account token. |
| `secrets` | object | `{}` | Map of **store key → `op://…` reference**. Store keys must match `^[A-Z][A-Z0-9_]{0,127}$`. |
| `syncOnStartup` | boolean | `true` | Fetch `secrets` from 1Password and write to the store at Gateway startup. |
| `failFastOnStartup` | boolean | `false` | If `true`, a startup sync failure throws and prevents startup. If `false`, log and fall back to last-known-good store values. |
| `integrationName` | string | `"openclaw-plugin-onepassword"` | Integration name reported to 1Password audit logs. |
| `requestTimeoutMs` | number | `15000` | Per-operation timeout for 1Password SDK calls. |
| `tools.enabled` | boolean | `false` | Register the read-only 1Password agent tools. |
| `tools.allowWrite` | boolean | `false` | Also register create/update/delete tools. Requires `tools.enabled`. |
The plugin **hardcodes no vault names, item paths, or field names**. The only 1Password-specific configuration is the env var name and the `secrets` map you provide.
## Agent tools (optional)
Set `tools.enabled: true` to expose in-process tools to the agent. Read tools redact concealed field values by default.
| Tool | Requires `allowWrite` | Description |
| ----------------------- | --------------------- | -------------------------------------------------------------------------- |
| `1password_list_vaults` | | List vaults accessible to the service account. |
| `1password_list_items` | | List item overviews in a vault. |
| `1password_get_item` | | Get a full item (concealed fields redacted unless `includeSecrets: true`). |
| `1password_read_field` | | Resolve a single `op://…` reference to its value. |
| `1password_create_item` | ✅ | Create a new item. |
| `1password_update_item` | ✅ | Update an existing item. |
| `1password_delete_item` | ✅ | Delete an item. |
```json
{
"plugins": {
"entries": {
"onepassword": {
"enabled": true,
"config": { "tools": { "enabled": true, "allowWrite": false } }
}
}
}
}
```
## Gateway methods
Both require the `operator.admin` scope.
- **`onepassword.sync`** — re-fetch every configured secret from 1Password and write it into the store. Returns `{ written, total, resolveErrors, storeErrors }`.
- **`onepassword.status`** — non-secret health/config summary: `{ version, serviceAccountTokenEnvV
... (truncated)
tools
Comments
Sign in to leave a comment