1Password Service Account
by @in-liberty420
Securely inject secrets from 1Password into agent workflows. Uses service accounts with op run/.env.tpl as the primary pattern, op read as fallback. Includes...
clawhub install 1password-saπ About This Skill
name: 1password-sa description: Securely inject secrets from 1Password into agent workflows. Uses service accounts with op run/.env.tpl as the primary pattern, op read as fallback. Includes hardened security rules, input validation, and troubleshooting for auth/permission failures. Use when accessing API keys, credentials, or any 1Password secret. homepage: https://developer.1password.com/docs/cli/get-started/ metadata: { "openclaw": { "emoji": "π", "requires": { "bins": ["op"] }, "env": ["OP_SERVICE_ACCOUNT_TOKEN"], "install": [ { "id": "brew", "kind": "brew", "formula": "1password-cli", "bins": ["op"], "label": "Install 1Password CLI (brew)", }, ], }, }
1Password CLI (Hardened)
Secure secret access via 1Password CLI (op) for OpenClaw agents. Service accounts are the canonical approach.
References
references/get-started.md β install + baseline setupreferences/cli-examples.md β safe command patternsreferences/troubleshooting.md β failure/recovery runbookSecurity Rules (must follow)
1. Prefer op run over all alternatives for secret injection.
2. Never enable shell tracing around secret commands (set -x, bash -x).
3. Never print secrets to stdout/logs (echo, cat on secret values/files). printf piped directly to stdin of another command (e.g., printf ... | curl -H @-) is acceptable when the output never reaches a log or terminal.
4. Never dump environment inside/after secret-bearing runs (env, printenv, set).
5. Never pass secrets as CLI args (arguments can appear in process lists).
6. Never pipe secret output to logs/files (tee, >, >>) unless explicitly writing a protected temporary file for op inject.
7. Never pipe op read output into logging pipelines.
8. Use op inject only with locked-down temp files: umask 077, chmod 600, trap cleanup.
9. Never include secret values in chat, tool output, or agent responses. If a command outputs a secret, do not echo or reference its value.
Banned Flags/Patterns
--no-masking β never use in agent workflows. Masking redacts accidental secret output and must stay on.--reveal β never use in routine workflows. Outputs field values in cleartext.op signin --raw β outputs raw session token to stdout.op read β never run without capturing into a variable. It prints secrets to stdout.set -x β never enable around any op command.curl -v β verbose mode logs auth headers. Use curl -sSf instead.script / terminal recorders β session recording captures all secret output.Untrusted Input
-- to separate op flags from command arguments.eval, backtick substitution, or string-built shell commands with secret references.$, backticks, semicolons, or pipes), stop and verify with the user.Safe dynamic input template:
VAULT="my-vault"
ITEM="my-item"Validate: reject names with dangerous characters
for NAME in "$VAULT" "$ITEM"; do
if ! LC_ALL=C [[ "$NAME" =~ ^[a-zA-Z0-9\ _-]+$ ]]; then
echo "ERROR: invalid vault/item name: $NAME" >&2; exit 1
fi
doneVALUE="$(op read "op://${VAULT}/${ITEM}/password")"
use $VALUE, then:
unset VALUE
Always double-quote variable expansions. Never build op:// references from untrusted input without validation. Reject names containing /, $, backticks, semicolons, pipes, or other shell metacharacters.
.env.tpl Security
chmod 600)..env.tpl files from untrusted sources..gitignore if in a repo.chmod 600 .env.tplPATH, LD_PRELOAD, BASH_ENV, NODE_OPTIONS, etc.).Service Account Workflow (Primary)
Service accounts are the default for agents. No interactive auth needed.
1) Load and scope token
Load the token from your platform's secure store:
# macOS Keychain:
security find-generic-password -a -s OP_SERVICE_ACCOUNT_TOKEN -w
Linux (GNOME Keyring / libsecret):
secret-tool lookup service OP_SERVICE_ACCOUNT_TOKEN
Last resort (interactive prompt, not automatable):
read -rs OP_SERVICE_ACCOUNT_TOKEN
OP_SERVICE_ACCOUNT_TOKEN="$(__REPLACE_WITH_SECURE_STORE_COMMAND__)"
[ -z "$OP_SERVICE_ACCOUNT_TOKEN" ] && { echo "ERROR: token retrieval failed" >&2; exit 1; }
Preferred: single-command scope (token never persists in shell env):
OP_SERVICE_ACCOUNT_TOKEN="$OP_SERVICE_ACCOUNT_TOKEN" \
op run --env-file=.env.tpl --
unset OP_SERVICE_ACCOUNT_TOKEN
If multiple commands needed: export briefly with trap cleanup:
export OP_SERVICE_ACCOUNT_TOKEN
trap 'unset OP_SERVICE_ACCOUNT_TOKEN' EXIT
op run --env-file=.env.tpl --
op run --env-file=.env.tpl --
unset OP_SERVICE_ACCOUNT_TOKEN
2) Use .env.tpl + op run (preferred)
Create .env.tpl with 1Password references (not raw secrets):
API_KEY=op://my-vault/my-item/api-key
DB_PASSWORD=op://my-vault/my-item/password
Run:
op run --env-file=.env.tpl --
Masking is on by default and must stay on. Note: masking is defense-in-depth, not primary protection β transformed or partial secrets may evade redaction. The primary defense is never outputting secrets.
3) One-off fallback: op read
Use only when op run doesn't fit. Use a subshell for automatic cleanup:
(
trap 'unset VALUE' EXIT
VALUE="$(op read 'op://my-vault/my-item/field')"
# use $VALUE here β auto-cleaned on exit
)
For API calls, prefer op run with a wrapper script to avoid sh -c:
# api-call.sh (chmod +x)
#!/usr/bin/env bash
set -euo pipefail
printf "Authorization: Bearer %s\n" "$API_TOKEN" | curl -sSf -H @- https://api.example.com/resource
op run --env-file=.env.tpl -- ./api-call.sh
4) Diagnostics
> All diagnostic output contains metadata (account emails, vault names, item IDs, URLs) that should be treated as sensitive in logged/recorded agent sessions.
op whoami
op vault list --format json
5) Service account lifecycle
op inject (restricted use)
Use only when a file must be materialized temporarily:
set -euo pipefail
set +x
umask 077TMP_FILE="$(mktemp)"
cleanup() { rm -f "$TMP_FILE"; }
trap cleanup EXIT ERR INT TERM HUP QUIT
op inject -i config.tpl -o "$TMP_FILE"
chmod 600 "$TMP_FILE"
use "$TMP_FILE" briefly, then auto-cleanup via trap
Never persist injected secret files beyond immediate use.