Audit or install maximum-depth 1Password integration in the current project — fetches fresh 1Password developer docs first, detects existing integration, and either reviews/improves it or greenfield-installs (Service Account secret resolution + site-compat autocomplete/well-known). Stack-aware (Laravel, Node/Next, Python, Ruby/Rails, Go). Use when the user says "integrate 1Password", "make this site 1Password-friendly", "audit our 1P integration", or invokes /onepassword-integrate. Use when this capability is needed.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Audit or install maximum-depth 1Password integration in the current project — fetches fresh 1Password developer docs first, detects existing integration, and either reviews/improves it or greenfield-installs (Service Account secret resolution + site-compat autocomplete/well-known). Stack-aware (Laravel, Node/Next, Python, Ruby/Rails, Go). Use when the user says "integrate 1Password", "make this site 1Password-friendly", "audit our 1P integration", or invokes /onepassword-integrate. Use when this capability is needed.
metadata
{"author":"escapeboy"}
1Password Integration & Compatibility Skill
Note on references/: the stack-specific recipes referenced at the bottom are companion files you author per stack (the progressive-disclosure layout from guide.md). The detection and audit phases below are complete without them.
Bring any project to maximum-depth 1Password integration in two layers:
Backend (secret resolution) — let the team store one Service Account token and reference everything else as op://vault/item/field. No more secrets in .env files, CI variables, or code.
Frontend (site compatibility) — make every auth form play perfectly with 1Password autofill, strong-password generation, passkeys, and the W3C /.well-known/change-password URL.
Operating principles
Always refresh docs first. 1Password ships SDK/CLI changes monthly. Never trust training data — pull the current developer portal before recommending anything.
Detect before deciding. Run the detection phase even if the user says "we don't have it yet" — the user's belief is often wrong (a dependency, a CI step, or a colleague may have wired part of it).
Greenfield only when nothing exists. If even partial integration exists, audit + improve rather than rebuild — much cheaper for the user.
Stack matches matter more than depth. A perfect Go install is useless to a Laravel team. Pick the stack first, then the depth.
Defense in depth on the frontend. Adding autocomplete="current-password" is free; not adding it silently breaks autofill. Always ship the full set.
Never write a Service Account token to disk. Tokens live in env vars passed to op (or the SDK). Tokens in .env files committed by accident are a recurring incident pattern.
Phase 1 — Refresh 1Password developer docs (mandatory first step)
Pull the current state of the developer platform via web search/fetch. Always include the current year in the queries.
Required reads — capture these into working memory before doing anything else:
Surface
Why
https://developer.1password.com/
Top-level entry; what's new highlighted here.
https://developer.1password.com/docs/sdks/
SDK matrix (Go / JS / Python). PHP is not on this list — fall back to CLI.
Recovery codes are NOT one-time codes per spec — wrong hint causes SMS autofill on the wrong field.
Third-party API key inputs (BYOK forms)
autocomplete="off" + data-1p-ignore="true"
Without these, 1P tries to save the form itself as a 1P entry.
2.4 Site-compat surface
Check whether these endpoints exist and respond correctly:
Endpoint
Spec
Required behavior
GET /.well-known/change-password
W3C
2xx or 3xx; redirect target should be the change-password UI.
GET /.well-known/passkey-endpoints (optional)
W3C draft
JSON document advertising passkey origins.
Password fields on signup
WHATWG
Should declare passwordrules attribute matching server policy.
Phase 3 — Decide: audit or install
After Phase 2, classify the project:
State
Action
Greenfield — no markers found anywhere.
Full install, stack-specific (§3a).
Partial backend — driver/resolver exists but is broken or shallow.
Audit + improve backend (§3b).
Partial frontend — some autocomplete attrs but not all, or missing well-known.
Frontend hygiene patch (§3c).
Mature — both backend and frontend are correct.
Report A-grade and exit. Suggest only nice-to-haves (passkey login, PRF E2E).
3a — Greenfield install
For the detected stack, implement:
Credential storage — type/enum addition for "1Password Service Account", encrypted at rest, validated against ^ops_.{28,}$.
Resolver — a service shelling out to op read --no-newline (or using the SDK) with the token in env (never argv).
CLI install — Dockerfile or CI step that pins a known op version with checksum.
Env-injection point — wherever the project launches subprocesses or builds env for workers, swap raw env vars for op:// references resolved at launch.
Frontend hygiene — apply §3c patches.
Tests — unit test fakes op CLI to assert: token in env not argv, malformed reference rejected, exit-code-1 surfaces stderr.
For each step, write the change or open a sub-task. Run the test suite afterwards. Never declare done without all green tests + a working op vault list smoke test in the target environment.
3b — Audit + improve existing backend
For each existing surface, check the safety invariants:
Token never in argv (use OP_SERVICE_ACCOUNT_TOKEN env). ps-leak is real.
Token validation: starts with ops_ AND length >= 32.
Reference grammar enforcement: 3 segments, no .., no shell metas ($, `, ;, &, |, <, >, (), whitespace).
Resolver returns trimmed output (rtrim($val, "\r\n")) — --no-newline flag is best-effort across op versions.
op CLI pinned to a specific version (with SHA256 ideally) in the runtime image.
Service Account scope is documented for users — encourage narrow scopes.
No op calls from web request handlers — only from queue workers / async contexts (web has tighter timeouts and loses output buffering).
Logs never include the resolved value.
op:// reference tokens themselves CAN be logged (they're not secrets) — useful for audit trails.
Connect Server, if used, runs as a separate service with its own access token AND 1password-credentials.json mounted read-only.
For each violation, propose a minimal-diff fix and ship it. Do not rewrite the whole driver if only one invariant is broken.
3c — Frontend hygiene patch
Always-safe patches (apply unconditionally — none of them break working autofill):
Login form → add autocomplete="username" + autocomplete="current-password".
Register form → add autocomplete="name", autocomplete="username", autocomplete="new-password" ×2.
Reset-password form → ensure autocomplete="username" + autocomplete="new-password" ×2.
New /.well-known/change-password route → 302 to the actual password-change UI, exempt from auth middleware (so password managers can probe without logging in).
passwordrules attribute on signup password fields (match server policy).
Any third-party-secret input field → autocomplete="off" data-1p-ignore="true".
Always add a regression test (one per stack) asserting autocomplete="..." strings appear in rendered output.
Phase 4 — Report & wrap up
Produce a single-paragraph summary plus a checklist of what was found/changed per layer (backend / frontend / tests / outstanding manual steps).
Always finish with one of:
"Run the project's test suite filtered to the 1Password tests to verify."
"Run op vault list inside the prod container with a real token to smoke-test."
Constraints
Never paste a real Service Account token into chat or logs. Even if the user offers — refuse.
Never check a token into git. Even on branches the user "promises to delete".
Never weaken autocomplete attributes.autocomplete="off" on password fields is almost always wrong (1Password ignores it anyway, but breaks browser autofill).
Never enable Service Account access to Personal/Private vaults. They're not accessible by spec — recommending it leads to confused users.
No PHP SDK exists. If the project is PHP and asks for an SDK, fall back to CLI shell-out — do not invent an SDK.
OAuth Authorization Code does not exist for vault access. Don't propose a "Connect with 1Password" button. Service Account tokens are pasted, not OAuth-redirected.