---
name: 1password-secrets
description: Read secrets from 1Password vaults using a service account. Use when an agent needs credentials (passwords, API keys, tokens, TOTP codes) stored in 1Password — without interactive sign-in.
homepage: https://developer.1password.com/docs/service-accounts/
metadata:
  {
    "minion":
      {
        "emoji": "🔑",
        "primaryEnv": "OP_SERVICE_ACCOUNT_TOKEN",
        "requires": { "bins": ["op"], "env": ["OP_SERVICE_ACCOUNT_TOKEN"] },
        "install":
          [
            {
              "id": "brew",
              "kind": "brew",
              "formula": "1password-cli",
              "bins": ["op"],
              "label": "Install 1Password CLI (brew)",
            },
          ],
      },
  }
---

# 1Password Secrets (Service Account)

Read secrets from 1Password vaults on headless servers using a **service account token**.
No desktop app, no biometric auth, no interactive sign-in required.

> **This skill vs `1password`**: The `1password` skill requires the desktop app and
> interactive authentication (Touch ID / PolKit). This skill uses a **service account
> token** (`OP_SERVICE_ACCOUNT_TOKEN`) and works on headless servers with zero
> interaction. Use this skill when running on remote servers or in automated pipelines.

## References

- `references/service-accounts.md` — setup, limitations, and token management

## Prerequisites

1. The `op` CLI must be installed on the host.
2. `OP_SERVICE_ACCOUNT_TOKEN` must be set in the environment (gateway `.env` or system env).
3. The service account must have **read access** to the vault(s) containing the needed secrets.

## Helper Scripts

| Script                             | Purpose                                                        |
| ---------------------------------- | -------------------------------------------------------------- |
| `scripts/op-check.sh`              | Verify service account connectivity and list accessible vaults |
| `scripts/op-read.sh <ref>`         | Read a single secret by its `op://` reference                  |
| `scripts/op-list-items.sh [vault]` | List items in a vault for discovery                            |

**Always run `op-check.sh` first** to confirm the service account can authenticate
before attempting to read secrets.

## Reading Secrets

Secrets are addressed using **secret references** with this format:

```
op://vault-name/item-name/field-name
```

### Common patterns

```bash
# Read a password
op read "op://Private/my-service/password"

# Read a username
op read "op://Private/my-service/username"

# Read a TOTP code (one-time password)
op read "op://Private/my-service/one-time password?attribute=otp"

# Read an API key
op read "op://Automation/stripe/secret-key"

# Read a file attachment (e.g. SSH key, certificate)
op read --out-file /tmp/key.pem "op://Private/server/ssh/private-key"
```

### Using the helper script

```bash
# Preferred: use the helper script for validation + error handling
./scripts/op-read.sh "op://Private/my-service/password"
```

## Injecting Secrets into Commands

Use `op run` to inject secrets as environment variables into a command without
writing them to disk:

```bash
# Set env vars using op:// references, then run a command
export DB_PASSWORD="op://Production/database/password"
export API_KEY="op://Production/api/key"
op run -- my-command --flag

# Or inline
op run --env-file=".env.tpl" -- my-command
```

## Discovery

When you don't know the exact secret reference, discover it step by step:

```bash
# 1. List accessible vaults
op vault list --format=json

# 2. List items in a vault
op item list --vault="Private" --format=json

# 3. Get full item details (reveals field names)
op item get "my-service" --vault="Private" --format=json

# Or use the helper:
./scripts/op-list-items.sh Private
```

## Security Guardrails

- **NEVER** log, print, or echo secret values to chat, logs, or files.
- **NEVER** write secrets to disk. Use `op run` to inject into env, or hold in
  memory only for the duration of the operation.
- **NEVER** include secrets in commit messages, code, or configuration files.
- **NEVER** pass secrets as CLI arguments (visible in process lists). Use env vars
  or stdin instead.
- Prefer `op run` over `op read` when possible — it handles cleanup automatically.
- If a secret must be used in a browser login, type it directly into the password
  field; do not store it in a variable longer than needed.

## Troubleshooting

| Symptom                 | Cause                        | Fix                                                                 |
| ----------------------- | ---------------------------- | ------------------------------------------------------------------- |
| `not signed in`         | Token not set or expired     | Check `OP_SERVICE_ACCOUNT_TOKEN` is set                             |
| `vault not found`       | Service account lacks access | Grant vault access in 1Password admin console                       |
| `item not found`        | Wrong vault or item name     | Use `op item list --vault=X` to find exact name                     |
| `op: command not found` | CLI not installed            | Install with `brew install 1password-cli` or system package manager |
| `permission denied`     | Service account is read-only | Service accounts are always read-only; this is expected             |
| `TOTP not available`    | Item has no TOTP field       | Check item in 1Password — TOTP must be configured on the item       |
