Skip to content

feat(auth): Add 1Password keyring backend#894

Open
lox wants to merge 5 commits into
openclaw:mainfrom
lox:lox/onepassword-backend
Open

feat(auth): Add 1Password keyring backend#894
lox wants to merge 5 commits into
openclaw:mainfrom
lox:lox/onepassword-backend

Conversation

@lox

@lox lox commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

gog currently supports OS keychain and encrypted file storage, but local agent workflows that rely on macOS Keychain can hit repeated approval prompts. This adds an opt-in 1Password keyring backend that stores gog secrets as 1Password API Credential items.

The backend supports desktop-app auth in compatible CGO builds and service-account auth for headless use. Non-secret settings are available through gog config; OP_SERVICE_ACCOUNT_TOKEN remains environment-only.

gog auth keyring 1password
gog config set onepassword_auth desktop
gog config set onepassword_account 'Your 1Password account name'
gog config set onepassword_vault <vault-id>
gog auth list --check

This is the backend-only slice from the earlier cache-plus-backend proposal. It deliberately omits the access-token cache. Switching backends also does not migrate existing tokens, default-account state, or client credentials; export/import is required before switching.

Maintainer repairs

  • Rebased onto current main; kept the contributor commits and credit.
  • Moved the maintainer changelog entry into 0.31.2 - Unreleased and thanked @lox.
  • Rejects desktop auth in static macOS/Linux builds with actionable service-account/CGO guidance; release Linux archives are static.
  • Corrected desktop account, platform timeout, migration, and static-build documentation.
  • Fixed an upstream SDK lifecycle trap: Client.Items() does not retain *Client, so GC could release the core client ID and later operations failed with invalid client id. The adapter now retains the parent client and has a forced-GC regression test. Upstream context: Client not able to retrieve secrets after a while 1Password/onepassword-sdk-go#210

Exact-head proof

Candidate: 7d72c8377b4710e9bc445e7c47b5da8539e4e2d9

  • make ci: pass.
  • CGO_ENABLED=0 go test ./internal/secrets ./internal/cmd -count=1: pass.
  • GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ./cmd/gog: pass.
  • Forced-GC ownership regression, 20 runs: pass.
  • Autoreview: clean, no accepted/actionable findings (confidence 0.84).
  • Source-blind service-account behavior validation: 4 PASS, 0 FAIL, 1 not exercised locally (desktop path). Restricted existing service account; isolated --home; synthetic example.invalid token; config/import/list/doctor/remove all passed; exact-title cleanup count zero.
  • Built binary: v0.31.1-13-g7d72c837, SHA-256 b220c03f5b284e32dfbb68ae4193e69fcdeb4588dd2eacf15e16a899c201be2d.
  • Contributor desktop proof remains available at the original exact head: feat(auth): Add 1Password keyring backend #894 (comment)

Owner decision required

The feature works, but the dependency/product tradeoff is material:

  • Adds direct github.com/1password/onepassword-sdk-go@v0.4.1-0.20260605221002-f1117e36ce06; stable v0.4.0 lacks the static-build fix used here, so this pins an unreleased pseudo-version.
  • The SDK embeds about 9.1 MB of WASM and pulls Extism/wazero plus archived wabin. Socket flags the embedded/obfuscated-code shape and archived transitive dependency.
  • The built macOS binary grows from 55,702,818 to 70,929,602 bytes: +15,226,784 bytes (+27.3%).
  • SDK use is governed by 1Password API terms. Desktop mode needs an unlocked app and is unavailable in static macOS/Linux builds; service-account mode remains supported there.
  • One 1Password item is used per gog key, so normal list/read operations may fan out across multiple item calls. No access-token cache is included.

Please explicitly choose one: accept this SDK/core-backend dependency and size/security tradeoff; request a narrower op CLI or other design; or wait for a tagged SDK release/dependency reduction. This PR should remain unmerged until that owner decision.

@lox lox force-pushed the lox/onepassword-backend branch from 6582f40 to 73a3421 Compare July 1, 2026 06:37
@socket-security

socket-security Bot commented Jul 1, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedgolang/​github.com/​1password/​onepassword-sdk-go@​v0.4.1-0.20260605221002-f1117e36ce0688100100100100

View full report

@socket-security

socket-security Bot commented Jul 1, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: golang github.com/1password/onepassword-sdk-go is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: go.modgolang/github.com/1password/onepassword-sdk-go@v0.4.1-0.20260605221002-f1117e36ce06

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore golang/github.com/1password/onepassword-sdk-go@v0.4.1-0.20260605221002-f1117e36ce06. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: golang github.com/tetratelabs/wazero is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ?golang/github.com/1password/onepassword-sdk-go@v0.4.1-0.20260605221002-f1117e36ce06golang/github.com/tetratelabs/wazero@v1.11.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore golang/github.com/tetratelabs/wazero@v1.11.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Medium
Deprecated by its maintainer: golang github.com/tetratelabs/wabin

Reason: Repository has been archived by the owner.

From: ?golang/github.com/1password/onepassword-sdk-go@v0.4.1-0.20260605221002-f1117e36ce06golang/github.com/tetratelabs/wabin@v0.0.0-20230304001439-f6f874872834

ℹ Read more on: This package | This alert | What is a deprecated package?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Research the state of the package and determine if there are non-deprecated versions that can be used, or if it should be replaced with a new, supported solution.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore golang/github.com/tetratelabs/wabin@v0.0.0-20230304001439-f6f874872834. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@clawsweeper

clawsweeper Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 1, 2026, 10:37 PM ET / 02:37 UTC.

Summary
The PR adds an opt-in 1Password-backed keyring backend with config/env settings, auth-doctor checks, docs, tests, and a new 1Password SDK dependency chain.

Reproducibility: not applicable. this is a feature PR rather than a bug report. The relevant proof is after-fix runtime validation, which the PR body and contributor comment provide for the new backend paths.

Review metrics: 3 noteworthy metrics.

  • Dependency surface: 1 direct dependency, 7 new indirect dependencies. The feature adds a new SDK stack directly in the credential-storage path.
  • Patch size: 23 files, +2054/-49. The branch spans backend code, config, docs, tests, linter policy, and module metadata, so owner review should include upgrade and dependency scope.
  • Reported binary growth: +15,226,784 bytes (+27.3%) on macOS. The PR body reports a material packaged binary-size increase that maintainers should explicitly accept or reject.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Maintainer should choose whether to accept the SDK dependency tradeoff, request a narrower op CLI design, or wait for an upstream tagged SDK/dependency reduction.

Risk before merge

  • [P1] Merging would add a direct 1Password SDK pseudo-version plus Extism/wazero/wabin transitives to the OAuth refresh-token, default-account, and client-secret storage path.
  • [P1] Socket flagged the added SDK chain for obfuscated/embedded-code shape and an archived transitive dependency, so green tests do not settle the supply-chain acceptance decision.
  • [P1] The new backend is opt-in but switching backends does not migrate tokens, defaults, or client credentials, so users must export/import or re-authorize before relying on it.
  • [P1] The PR body reports a 15,226,784-byte macOS binary increase and a one-1Password-item-per-key design, both of which need maintainer product and operational acceptance.

Maintainer options:

  1. Accept the SDK-backed backend deliberately
    A maintainer can approve the pseudo-version SDK, dependency-chain alerts, binary growth, terms boundary, and no-migration behavior as an intentional opt-in auth backend tradeoff.
  2. Request a narrower credential bridge
    Ask for an op CLI or alternate integration that reduces embedded code and dependency footprint before adding 1Password support to core.
  3. Wait for upstream dependency stabilization
    Pause the PR until 1Password ships a tagged SDK release or dependency reduction that removes the current pseudo-version and supply-chain concern.

Next step before merge

  • [P2] The remaining action is an owner/product/security decision about the SDK-backed backend and dependency tradeoff, not a narrow repair ClawSweeper should make automatically.

Security
Needs attention: The diff adds a security-sensitive 1Password SDK dependency chain to credential storage, and Socket flagged supply-chain concerns that require maintainer acceptance before merge.

Review details

Best possible solution:

Keep the branch open and require an explicit owner decision to accept this SDK-backed core backend as-is, request an op CLI or other narrower design, or wait for a tagged/reduced SDK dependency.

Do we have a high-confidence way to reproduce the issue?

Not applicable; this is a feature PR rather than a bug report. The relevant proof is after-fix runtime validation, which the PR body and contributor comment provide for the new backend paths.

Is this the best way to solve the issue?

Unclear as a product choice: the implementation appears coherent and current main has no equivalent backend, but maintainers still need to decide whether a core SDK-backed integration is preferable to a narrower op CLI design or waiting for a tagged SDK release.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 621757c686ee.

Label changes

Label changes:

  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.

Label justifications:

  • P2: This is a normal-priority opt-in auth backend feature with a limited user-facing blast radius but material review tradeoffs.
  • merge-risk: 🚨 compatibility: Switching to the new backend does not migrate existing stored tokens, defaults, or client credentials, and static Linux builds cannot use desktop auth.
  • merge-risk: 🚨 auth-provider: The PR changes credential-storage backend routing and stores OAuth material, defaults, and client secrets through a new 1Password-backed path.
  • merge-risk: 🚨 security-boundary: The new SDK dependency chain sits on secret storage and has Socket supply-chain warnings that require explicit acceptance.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (terminal): The PR body gives exact-head proof for CI, static Linux build/tests, service-account behavior validation, forced-GC regression, and contributor terminal output showing desktop backend import/list/doctor behavior with private values redacted.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body gives exact-head proof for CI, static Linux build/tests, service-account behavior validation, forced-GC regression, and contributor terminal output showing desktop backend import/list/doctor behavior with private values redacted.
Evidence reviewed

Security concerns:

  • [medium] Accept the new credential-storage SDK chain explicitly — go.mod:8
    go.mod adds github.com/1password/onepassword-sdk-go at an unreleased pseudo-version plus Extism/wazero/wabin transitives in the secrets path; Socket also flagged obfuscated/embedded-code shape and an archived transitive dependency, so this needs owner/security acceptance rather than routine CI approval.
    Confidence: 0.88

What I checked:

  • Repository policy read: AGENTS.md was read fully and its PR-review flow plus auth/secrets guidance apply to this read-only review. (AGENTS.md:34, 621757c686ee)
  • Current main lacks the backend: Current main only allows auto, keychain, and file keyring backends; no 1Password backend symbols were found on main. (internal/secrets/backend.go:113, 621757c686ee)
  • PR routes a new backend: The PR adds KeyringBackendOnePassword constants and routes that backend to openOnePasswordKeyring using the resolved service name. (internal/secrets/backend.go:23, 7d72c8377b47)
  • PR implements 1Password item storage: The new backend stores each keyring entry as 1Password item fields, with the gog key in username and a base64 concealed credential payload. (internal/secrets/onepassword_keyring.go:619, 7d72c8377b47)
  • Credential-path dependency surface: The PR adds github.com/1password/onepassword-sdk-go at an unreleased pseudo-version plus Extism/wazero/wabin-related indirect dependencies. (go.mod:8, 7d72c8377b47)
  • Maintainer proof and owner decision: The PR body and maintainer comment report exact-head CI, static Linux build/tests, service-account validation, forced-GC regression coverage, and an explicit owner decision still required for SDK, size, API-terms, and no-cache tradeoffs. (7d72c8377b47)

Likely related people:

  • steipete: Recent current-main history touches keyring backend policy, credential store injection, and auth command plumbing, and the PR discussion records exact-head repair work on this branch. (role: recent area contributor and PR repair author; confidence: high; commits: 716f6c2cf14a, 93d0c7c179df, 92abba72531b; files: internal/secrets/backend.go, internal/secrets/store.go, internal/cmd/auth_keyring.go)
  • lox: Beyond opening this PR, lox authored the merged keyring prompt-storm work and the initial backend-only commits here. (role: prior keyring contributor and feature proposer; confidence: high; commits: c58b381c97ad, f869b66d59f8, c77eabd70a4b; files: internal/secrets/timeout_keyring.go, internal/secrets/token.go, internal/secrets/onepassword_keyring.go)
  • malob: Recent merged keyring timeout work changed the backend timeout surface that this PR extends. (role: adjacent keyring timeout contributor; confidence: medium; commits: b3c285613b74; files: internal/secrets/backend.go, internal/secrets/timeout_keyring.go, docs/spec.md)
  • TurboTheTurtle: Recent merged duplicate token alias repair touched the secrets store write behavior that this PR extends with trusted 1Password writes. (role: adjacent token-store contributor; confidence: medium; commits: ebc8218b609a; files: internal/secrets/store.go, internal/secrets/store_more_test.go)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Jul 1, 2026
@lox

lox commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Fixed the namespace behavior in 335034e: the 1Password backend now receives the existing keyring service name from serviceNameFor(options), derives the default item title from it, and still lets GOG_1PASSWORD_ITEM_TITLE/config onepassword_item_title override that default.\n\nValidated locally with:\n\nbash\ngo test -p=1 ./internal/secrets ./internal/cmd ./internal/config ./internal/googleapi\n

@lox

lox commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Terminal output proof:

$ git rev-parse --short HEAD
335034ec
$ bin/gog auth keyring 1password
NOTE: GOG_KEYRING_BACKEND=1password overrides config.json
written	true
path	/Users/[REDACTED]/Library/Application Support/gogcli/config.json
keyring_backend	1password
$ bin/gog auth doctor --plain --no-input
ok	config.path	/Users/[REDACTED]/Library/Application Support/gogcli/config.json
ok	keyring.backend	1password (source: env)
ok	keyring.1password.vault	GOG_1PASSWORD_VAULT is set
ok	keyring.1password.account	GOG_1PASSWORD_ACCOUNT is set
hint	keyring.1password.account	keep the 1Password app running, unlocked, and configured to integrate with other apps
ok	keyring.1password.timeout	GOG_1PASSWORD_TIMEOUT=60s
ok	keyring.open	opened
ok	tokens	1 readable OAuth token of 1 stored token account
status	ok
$ bin/gog auth tokens export [EMAIL] --client default --out "$tmp/token.json" --overwrite
WARNING: exported file contains OAuth tokens (keep it safe and delete it when done)
exported	true
email	[EMAIL]
client	default
path	/var/folders/z5/[REDACTED]/T/tmp.4pR6FZWiAv/token.json
$ bin/gog auth tokens import "$tmp/token.json"
Imported refresh token into keyring
imported	true
email	[EMAIL]
client	default
$ bin/gog auth list --check
[EMAIL]	default	appscript,calendar,chat,classroom,contacts,docs,drive,forms,gmail,people,sheets,slides,tasks	2026-03-09T20:28:43Z	true		oauth

@lox

lox commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 1, 2026
@steipete steipete force-pushed the lox/onepassword-backend branch from 335034e to 7d72c83 Compare July 1, 2026 11:29
@steipete

steipete commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Maintainer repair is complete at exact head 7d72c8377b4710e9bc445e7c47b5da8539e4e2d9.

The repaired branch passes full local CI, source-blind service-account import/read/doctor/remove/cleanup proof, static Linux build/tests, forced-GC lifecycle regression, and autoreview. It also fixes a real SDK ownership failure found during live proof (invalid client id; upstream 1Password issue #210).

Owner decision still required before merge: accept the unreleased 1Password SDK pseudo-version, embedded WASM/Extism dependency chain and Socket alerts, 15.2 MB (+27.3%) binary growth, API-terms boundary, and one-item-per-key/no-cache design; otherwise request a narrower op CLI/alternative design or wait for a tagged/reduced SDK. Full tradeoffs and proof are now in the PR body. Leaving this unmerged pending that explicit decision.

@clawsweeper clawsweeper Bot added status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 1, 2026
@lox

lox commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

@steipete did I miss a linter somewhere?

@clawsweeper clawsweeper Bot removed the rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. label Jul 2, 2026
@clawsweeper clawsweeper Bot added the rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. label Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants