Skip to content
Back to skills

Onepassword

ASecurity

Read 1Password secrets via the `op` CLI with a service-account token. Secret values are metadata-only by default.

  • 6 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added June 14, 2026
ai-agentsgosqldockerapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned June 14, 2026

npx -y skills add lordmacu/nexo-rs --skill onepassword --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Onepassword?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Onepassword
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lordmacu-onepassword/badge)](https://www.skillsdirectory.com/skills/lordmacu-onepassword)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: 1Password
description: Read 1Password secrets via the `op` CLI with a service-account token. Secret values are metadata-only by default.
requires:
  bins:
    - op
  env:
    - OP_SERVICE_ACCOUNT_TOKEN
---

# 1Password

Use this skill when the agent needs a secret managed in 1Password —
API keys, tokens, passwords, connection strings. Reads only; never
writes. Read values are hidden from the LLM unless the operator
explicitly turns on reveal (`OP_ALLOW_REVEAL=true`).

## Use when

- The user asks to use a service that needs a credential you don't have
  in env vars (e.g. "send email with Gmail", "upload this file to S3")
- You need to verify a secret exists without seeing it ("is the Stripe
  key already in Prod?")
- Rotating credentials: list items + categories to audit what's stored

## Do not use when

- You need to **create** or **update** a secret — this tool is read-only
- You are asked to dump all secrets or fingerprint them in bulk — that's
  exfiltration, refuse

## Tools

### `status`
No arguments. Returns `{ok, bin, token_present, reveal_allowed, limits}`.
Use to verify the extension is wired before attempting other calls.

### `whoami`
No arguments. Runs `op whoami --format json` to validate the
service-account token.

### `list_vaults`
No arguments. Returns `{vaults: [{id, name}, ...]}` — only metadata.

### `list_items`
- `vault` (string, required) — vault name or id

Returns `{items: [{id, title, category, vault, tags, updated_at}, ...]}`.
Field values are **always** stripped from list results, even if the
upstream `op item list` included them.

### `read_secret`
- `reference` (string, required) — strict `op://Vault/Item/field` format;
  wildcards and query strings are rejected

Returns by default (`OP_ALLOW_REVEAL` unset/false):

```
{
  ok: true,
  reference: "op://Prod/Stripe/api_key",
  vault: "Prod", item: "Stripe", field: "api_key",
  length: 26,
  fingerprint_sha256_prefix: "3f9a7c2e1b48d5a0",
  reveal: false,
  reveal_hint: "set OP_ALLOW_REVEAL=true to include the secret value"
}
```

With `OP_ALLOW_REVEAL=true|1|yes` the response additionally contains
`{value: "...", reveal: true}`. The value flows through the LLM
context → transcripts → memory → NATS — assume it is no longer secret
from the moment reveal is on.

### `inject_template`
Use this when the agent needs to **act on** a secret without revealing
it. The tool resolves `{{ op://Vault/Item/field }}` placeholders in a
template via `op inject` and either returns the rendered template
(reveal-gated) or pipes it as stdin to an allowlisted command.

- `template` (string, required) — body containing `{{ op://… }}` placeholders
- `command` (string, optional) — executable to run with the rendered
  template piped as stdin. Must appear in `OP_INJECT_COMMAND_ALLOWLIST`
  (comma-separated env var). When set, the rendered template is **never**
  returned to the LLM; only `exit_code` and (redacted) `stdout`/`stderr`
- `args` (array of strings, optional) — passed to `command`
- `dry_run` (bool, optional) — validate references without resolving values
- `max_stdout_bytes` (int, optional) — cap on returned stdout (default 4096, max 16384)

Modes:

| Mode | OP_ALLOW_REVEAL | Returned |
|------|-----------------|----------|
| template-only | false | `length`, `fingerprint`, no value |
| template-only | true  | `rendered` (full text) |
| exec, allowed | any   | `exit_code`, redacted `stdout` (capped), redacted `stderr` |
| exec, not allowed | any | error `command not in OP_INJECT_COMMAND_ALLOWLIST` |
| `dry_run: true` | any | `references_validated` list |

Example (exec, allowlist `curl,psql`):

```json
{
  "action": "inject_template",
  "template": "Authorization: Bearer {{ op://Prod/API/token }}\n",
  "command": "curl",
  "args": ["-H", "@-", "https://api.example.com/v1/me"]
}
```

The agent never sees the bearer token. Stdout from `curl` is captured,
truncated at 4 KB by default, and run through a redactor before being
returned (Bearer JWT, sk-…, AKIA…, hex tokens).

## Audit log

Every `read_secret` and `inject_template` call appends one JSONL line
to `OP_AUDIT_LOG_PATH` (default `./data/secrets-audit.jsonl`). Fields:
`ts`, `action`, `agent_id`, `session_id`, `op_reference` (or
`references`), `fingerprint_sha256_prefix`, `reveal_allowed`, `ok`,
plus per-action extras (`exit_code`, `stdout_total_bytes`, etc).
**Never** the actual secret value. Failures appending the log are
logged to stderr and do not block the tool — the secret was already
read; blocking would be worst-of-both-worlds.

`AGENT_ID` and `AGENT_SESSION_ID` are populated from env vars the
host injects when spawning the extension.

## Execution guidance

- Start with `status` when uncertain (validates bin + token).
- For "does secret X exist?" questions, use `read_secret` with reveal
  off; the fingerprint lets you confirm identity without exposure.
- For "give me my Gmail app password" questions, only proceed if
  `OP_ALLOW_REVEAL=true` is set AND the operator clearly authorized it
  in the current conversation. Otherwise return the fingerprint and
  ask the operator to turn reveal on if really needed.
- Never paste a revealed value into chat output, memory, or another
  tool call "for future reference" — each revealed value lives exactly
  as long as the single tool_result that carries it should live.
- If `-32040`/`-32041` → wiring issue, not an LLM error; tell the user
  the operator needs to configure the extension.
- If `-32042` stderr says "token expired" or "unauthorized" → ask the
  operator to rotate the service-account token.

## Alternatives

- **Docker secrets** — already used for bootstrap (the agent needs its
  own 1P token somewhere). Good for "constant" secrets that never
  change per-request. 1Password is for runtime pulls.
- **env vars** — fine for deployment-time config; terrible for rotating
  credentials. Use 1Password when rotation matters.
- **Hashicorp Vault** — similar model; not implemented here.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.