1Password Plugin: SecretRefs and Agent Access

Learn how the 1Password plugin resolves SecretRefs and provides curated, audited agent access. This is for administrators setting up secure credential management.

Read this when

  • You want agents to request curated 1Password secrets
  • You want OpenClaw config credentials to resolve from 1Password
  • You need per-secret approval policy and audit history
  • You are configuring a 1Password service account for OpenClaw

1Password

The onepassword plugin that ships with the product offers two separate, optional integration points:

  • a managed exec provider that handles configured SecretRefs during Gateway startup, reload, audit, and apply preflight
  • a policy-controlled agent tool that accesses a defined subset of 1Password fields

Both rely on the official op CLI and share the same service-account token file. Activating the plugin by itself does not enable the agent tool; that feature additionally requires a populated item registry.

Security model

  • Authentication is limited to service accounts. The token lives in a local credentials file and is never accepted through openclaw.json.
  • The agent registry is curated. Agents can list configured slugs, but the plugin does not enumerate any 1Password vault. SecretRef reads are restricted to references stored explicitly on registered OpenClaw credential targets.
  • Policy applies per slug using auto, approve, or deny.
  • Approval grants have a time limit. A cached value does not override current policy.
  • Every access attempt gets logged in OpenClaw's shared SQLite state. Audit entries contain the reason you supply; keep reasons free of sensitive data. The broker never places a fetched value or the service token into an audit entry.
  • After the current tool execution finishes, OpenClaw-owned transcript persistence swaps a successful get value for redacted metadata.
  • The value remains visible to the model during that execution. If the model copies it into a later tool call or response, that separate record falls outside this plugin's persistence hook. Keep policies tight and avoid asking the model to repeat a value.
  • The plugin calls op once for each cache miss. It does not retry rate limits or other errors.
  • Every op call runs with a stripped-down environment that turns off 1Password desktop-app integration (OP_LOAD_DESKTOP_APP_SETTINGS=false, OP_BIOMETRIC_UNLOCK_ENABLED=false), so a 1Password app on the Gateway host never triggers biometric or macOS permission dialogs.

Grant the service account read access only to the vaults and items that registered SecretRefs and agent-tool slugs actually use.

Before you begin

You will need:

  • the 1Password CLI (op) installed on the Gateway host
  • a 1Password service account with access to the chosen items
  • a dedicated service-account token file

Activate the bundled plugin:

openclaw plugins enable onepassword

Set up the token directory and file inside the OpenClaw state directory:

mkdir -p ~/.openclaw/credentials/onepassword
chmod 700 ~/.openclaw/credentials/onepassword
printf '%s' "$OP_SERVICE_ACCOUNT_TOKEN" > \
  ~/.openclaw/credentials/onepassword/service-account-token
chmod 600 ~/.openclaw/credentials/onepassword/service-account-token
unset OP_SERVICE_ACCOUNT_TOKEN

When OPENCLAW_STATE_DIR is configured, swap ~/.openclaw for that directory. The plugin issues a single warning if the token file is readable or writable by group or other users.

Configure SecretRefs

Build a secrets apply plan for common model provider keys:

openclaw onepassword secretref setup \
  --anthropic-id op://Automation/Anthropic/credential \
  --openrouter-id op://Automation/OpenRouter/credential \
  --plan-out ./openclaw-1password-secrets-plan.json

For a different model provider, use --provider-key <provider=id>, or use --target <path=id> for any registered SecretRef credential target. The command needs at least one target and produces a plan. Review it, verify the local op and token-file prerequisites, then apply and reload:

openclaw onepassword secretref status
openclaw secrets apply --from ./openclaw-1password-secrets-plan.json --dry-run --allow-exec
openclaw secrets apply --from ./openclaw-1password-secrets-plan.json --allow-exec
openclaw secrets audit --check --allow-exec
openclaw secrets reload

Before applying, status may show that the provider is not yet configured; prerequisites ready: yes verifies that the trusted op executable and an accepted non-empty token file are in place. After applying, ready: yes verifies both the provider wiring and prerequisites. Missing or unsafe prerequisites produce actionable next steps without revealing the token or raw resolver errors.

Manual provider setup uses the existing plugin id:

{
  plugins: {
    entries: {
      onepassword: { enabled: true },
    },
  },
  secrets: {
    providers: {
      onepassword: {
        source: "exec",
        pluginIntegration: {
          pluginId: "onepassword",
          integrationId: "onepassword",
        },
      },
    },
  },
  models: {
    providers: {
      openai: {
        apiKey: {
          source: "exec",
          provider: "onepassword",
          id: "op://Automation/OpenAI/credential",
        },
      },
    },
  },
}

References use op://<vault>/<item>/<field> or op://<vault>/<item>/<section>/<field>. Vault, item, section, and field names can contain spaces. The setup command stores references that do not fit OpenClaw's shared exec-id grammar in a plugin-local opaque form and decodes them only inside the resolver. For very long references, prefer stable 1Password IDs; they are shorter and cut down on 1Password API requests.

The SecretRef resolver runs at most four op read processes concurrently, disables the 1Password CLI cache so reloads see rotated values, never uses desktop-app integration, and does not expose an agent tool for arbitrary reads. Before passing the service-account token, both plugin surfaces resolve the executable and reject paths that another local account could replace; Windows ACL verification must also pass. Check provider wiring and local readiness with:

openclaw onepassword secretref status --json

Configure registered secrets

Add plugin config to openclaw.json:

{
  "plugins": {
    "entries": {
      "onepassword": {
        "enabled": true,
        "config": {
          "vault": "Automation",
          "defaultPolicy": "approve",
          "cacheTtlSeconds": 300,
          "grantTtlHours": 720,
          "opTimeoutMs": 15000,
          "items": {
            "repository-token": {
              "item": "Repository automation token",
              "field": "credential",
              "policy": "approve",
              "description": "Token for repository automation",
            },
            "model-key": {
              "item": "Model provider key",
              "vault": "Agent credentials",
              "policy": "auto",
            },
          },
        },
      },
    },
  },
}

Slugs use lowercase letters, numbers, and hyphens, start with a letter or number, and are at most 64 characters long. A registry holds up to 32 slugs; descriptions are limited to 200 characters. field accepts one field label or ID, must not contain a comma, and defaults to credential. An item-level vault overrides the default vault. opBin can set an absolute path to the op executable; otherwise the plugin resolves op from PATH. Item titles must not start with a hyphen.

Use the agent tool

The tool name is onepassword.

List registered slugs:

{ "action": "list" }

The result shows only the slug, description, policy, and whether a standing grant is active. It never contains a secret value and does not query 1Password.

Request one secret:

{
  "action": "get",
  "slug": "repository-token",
  "reason": "Authenticate the requested repository operation"
}

reason is required, must be non-empty, and is capped at 300 characters. A successful get returns the value plus the configured slug, item title, and field label.

The tool schema also declares an internal authorizationNonce parameter. The policy layer injects it after evaluating the request to pass the authorization to the executing tool call. Never set it manually: the policy hook overwrites any supplied value, and an unknown value fails the request.

Policy tiers and approvals

  • auto: fetch immediately and audit the request.
  • deny: block and audit the request.
  • approve: use an unexpired standing grant, or ask a human to allow once, always, or deny.

Allow once authorizes only the current tool call. Allow always writes a standing grant for that agent and slug to SQLite; other agents must get their own approval. OpenClaw offers allow always only when the caller has a concrete agent identity. The grant expires after grantTtlHours, which defaults to 720 hours. An unresolved or timed-out approval denies the request; the maximum approval wait is 600 seconds. The plugin keeps up to 1,024 standing grants; at that limit, the oldest grant is evicted and its agent must approve the next access.

Each evaluated authorization is single-use and is passed to the executing tool call through shared SQLite state, so the handoff works even when multiple plugin instances are active in the gateway process. Unused authorizations expire after the 600-second approval window.

The in-memory cache defaults to 300 seconds and is bounded by the configured slug registry. Set cacheTtlSeconds to 0 to disable it. Policy is evaluated before every cache lookup, and cache hits are audited. Runtime config reloads take effect at each policy and execution boundary; disabling the plugin or removing, denying, or retargeting a slug invalidates pending authorization and cached values.

Inspect status and audit history

Show readiness and registry counts:

openclaw onepassword status

This output indicates whether the token file is present, if op was successfully resolved along with its location, the number of registered items, and breakdowns per policy. No token or secret values are ever accessed or displayed.

Display the 50 most recent audit entries:

openclaw onepassword audit
openclaw onepassword audit --limit 100

Entries appear in reverse chronological order and include the timestamp, agent, slug, result, an errorCode when the attempt failed, and a shortened reason. The reason is recorded exactly as given; the broker never adds the fetched value to the audit trail.

1Password CLI behavior

For every cache miss, op item get runs with the designated item, vault, and precise field selector, JSON output, a limited timeout, and --cache=false. The child process gets only that field, not the whole item. The child environment contains just OP_SERVICE_ACCOUNT_TOKEN and HOME.

A single attempt is made by the plugin. RATE_LIMITED errors should be dealt with by waiting before the next agent request; no automatic retry mechanism is built in.

Error codes

Each failed attempt yields one closed error code in both the tool result and the audit row.

1Password access errors:

CodeMeaning
TOKEN_MISSINGToken file is absent or blank
OP_NOT_FOUNDThe op binary could not be located
ITEM_NOT_FOUNDThe configured item is missing from the vault
FIELD_NOT_FOUNDThe configured field is absent from the item; available labels are shown
RATE_LIMITED1Password service-account rate limit has been hit
AUTH_FAILEDService-account authentication did not succeed
TIMEOUTop went past opTimeoutMs
OP_ERRORAny other op failure or malformed output

Policy and validation errors:

CodeMeaning
INVALID_ACTION, INVALID_REASON, INVALID_SLUGThe request did not pass input validation
UNKNOWN_SLUGSlug is not found in the configured registry
TOOL_CALL_ID_MISSINGCall came in without a tool call id
POLICY_NOT_EVALUATEDNo authorization matches this call; the request was not approved by policy
POLICY_CHANGEDConfig was altered between approval and execution
GRANT_EXPIREDStanding grant expired prior to execution
APPROVAL_CANCELLEDThe run was stopped while the approval was still pending
1,701 words · updated Aug 4, 2026