Skip to content

feat: add 1Password secrets backend#35

Open
khalilgharbaoui wants to merge 14 commits intoiHildy:mainfrom
khalilgharbaoui:main
Open

feat: add 1Password secrets backend#35
khalilgharbaoui wants to merge 14 commits intoiHildy:mainfrom
khalilgharbaoui:main

Conversation

@khalilgharbaoui
Copy link

Summary

  • add a 1Password secrets backend with config validation and backend plumbing
  • integrate secrets pull/push/status commands and hook backend into sync lifecycle
  • exclude auth.json and mcp-auth.json from git sync when using 1Password

Testing

  • Not run (not requested)

Related

Adds tests for extra path defaults and normalized plans.
Clarifies how to keep auth tokens out of git while syncing config.
Mentions optional 1Password secrets backend support.
Lets the sync plan omit auth files when a 1Password backend is configured.
Adds backend pull/push hooks and blocks tracked auth files.
Exposes 1Password pull/push/status via opencode_sync.
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @khalilgharbaoui, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant security and usability enhancement to opencode-synced by providing an optional 1Password secrets backend. This feature allows users to store and manage their opencode authentication credentials and other sensitive configuration files in 1Password, rather than directly within their git repository. The implementation includes new commands for explicit secrets management, integrates secrets operations into the existing pull/push synchronization lifecycle, and enforces strict exclusion of these sensitive files from git commits when the 1Password backend is active. This change aims to improve the security posture for users handling sensitive opencode data.

Highlights

  • 1Password Secrets Backend: Implemented an optional 1Password secrets backend to securely manage opencode authentication tokens and other sensitive files.
  • Git Exclusion for Secrets: Automatically excludes auth.json and mcp-auth.json from git synchronization when the 1Password backend is configured, preventing sensitive data from being committed to repositories.
  • New Secrets Commands: Added dedicated commands (secrets-pull, secrets-push, secrets-status) for direct interaction with the 1Password backend.
  • Integrated Sync Lifecycle: The secrets backend is seamlessly integrated into the existing sync workflow, performing pulls after sync-pull and pushes before sync-push.
  • Robust Configuration & Validation: Implemented new configuration types and validation logic for the 1Password backend, ensuring proper setup and error handling.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a 1Password secrets backend, a significant and well-implemented feature. While the code is well-structured and considers security aspects, a medium-severity race condition was identified in how secret files are moved to their final destination, potentially exposing them to other users on the system briefly. This should be addressed by ensuring restricted permissions are applied before the files are moved to a publicly accessible directory. Additionally, there are suggestions for improving code clarity, consistency, and maintainability, such as simplifying a complex type definition, making type signatures more accurate, and refactoring duplicated logic.

@jules-relay
Copy link

jules-relay bot commented Feb 1, 2026

🤖 Review Jules Relay

I found 1 Gemini suggestion so far.

Type /relay batch to send all suggestions to Jules.

Include opencode-synced.jsonc in the core plan and avoid duplicate extra paths.
@iHildy
Copy link
Owner

iHildy commented Feb 4, 2026

@khalilgharbaoui Appreciate the PR and think this idea is great. Though I'd like to request some improvements before merging.

Main Issues

  1. Missing Import Bug (config.ts:88)
    normalizeSecretsBackend() is a hoisted function declaration. Could you follow the pattern from mcp-secrets.ts
  2. Race Condition in Push Flow (service.ts)
    Secrets are pushed before git sync. If git fails, secrets are updated but config isn't - inconsistent state.
  3. Silent Failures on Pull (service.ts:136)
    Secrets pull failures are just logged, not thrown. User thinks sync succeeded but has no auth files.
  4. Dead Config (secrets-backend.ts:18-20)
    envFile is in the config schema but is never used in the implementation.

Design Issues

  1. Not Generic
    SecretsBackend interface claims to be generic but is hardcoded to 1Password. Adding another backend (e.g., AWS Secrets Manager) would require refactoring. Not asking you to build one for every password manager, but designing it in a way that's extendible would be much preferred.
  2. No Change Detection
    Design doc mentions SHA256 hashing to avoid unnecessary 1P calls I couldn't find that implemented. Every sync hits 1Password.
  3. Fragile Error Detection (secrets-backend.ts:243)
    Uses regex /not found/i on error text. Will break if 1Password CLI changes error messages or localizes. Could we detect the type of response? Not super familiar with the 1Password CLI.

Testing Gaps

  • No tests for secrets-backend.ts
  • No tests for normalizeSecretsBackend()
  • No integration tests for the op CLI calls

Other Issues

  • Hardcoded path (~/.local/share/opencode/) won't work on Windows - Though resolveXdgPaths() might handle this, double check
  • 0600 permissions are set after copy, not atomically
  • Missing validation that document names are unique

(drafted with AI - reviewed and edited manually)

@iHildy iHildy self-assigned this Feb 4, 2026
@iHildy iHildy added the enhancement New feature or request label Feb 4, 2026
@iHildy iHildy linked an issue Feb 4, 2026 that may be closed by this pull request
@khalilgharbaoui
Copy link
Author

Updated per review:

  • Removed envFile support from config + docs; require unique auth/mcp document names.
  • Secrets backend now resolves generically, validates via op document list (no regex), and prevents duplicate names; added change detection via stored SHA256 and state merge updates.
  • Sync flow pushes secrets only after successful git push (or when no repo changes) and surfaces secrets pull failures; auth files are excluded for any configured secrets backend.
  • Permission handling keeps 0600 before rename, and secrets commands share backend resolution.
  • Added tests for normalizeSecretsBackend, backend validation/uniqueness, and secrets hash.

Tests: bun run check, bun run test.

@iHildy
Copy link
Owner

iHildy commented Feb 6, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant new feature: a 1Password secrets backend. The implementation is comprehensive, covering configuration, validation, new commands, and deep integration into the existing sync lifecycle. The code is well-structured, with a clear separation of concerns and strong attention to security best practices, such as preventing secrets from being committed to Git, using atomic file operations, and setting restrictive file permissions. The addition of new tests for the backend logic is also a great step towards ensuring robustness. I have a couple of suggestions to simplify the error handling logic within the new secrets backend for improved clarity and maintainability, but overall, this is a high-quality and well-executed feature addition.

@iHildy
Copy link
Owner

iHildy commented Feb 6, 2026

@khalilgharbaoui I made some additional adjustments, let me know if you approve.

  • Unknown secrets backend types are kept through normalization so validation can surface a clear error; new type aliases for known vs arbitrary backend types: src/sync/config.ts.
  • Validation now runs before startup/status and before config use, preventing later failures; push flow now reports secrets push errors instead of silently ignoring them: src/sync/service.ts.
  • Pull/update retry logic for 1Password now rethrows the original error after retry checks; update failures are wrapped at the opDocumentEdit layer for consistent SyncCommandError typing: src/sync/secrets-backend.ts.
  • Tests updated to cover unknown backend retention and invalid backend rejection: src/sync/config.test.ts, src/sync/secrets-backend.test.ts.
  • Minor config/doc tweaks: removed branch policy section from AGENTS.md, added schema to opencode.json, and formatting cleanup in package.json.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add secretsBackend option (e.g. 1Password)

2 participants