Skip to content

feat: 1Password Rust SDK — initial implementation#1

Merged
lightcap merged 27 commits into
mainfrom
feat/initial-design
May 13, 2026
Merged

feat: 1Password Rust SDK — initial implementation#1
lightcap merged 27 commits into
mainfrom
feat/initial-design

Conversation

@lightcap
Copy link
Copy Markdown
Collaborator

@lightcap lightcap commented Mar 31, 2026

Summary

Port of the 1Password Go SDK to idiomatic Rust with full API parity.

  • Typed wrapper around the same core.wasm binary used by Go/Python/JS SDKs
  • Two core backends: ExtismCore (WASM, default) and SharedLibCore (desktop app integration via libloading, feature-gated)
  • Full API surface: Secrets, Items (with Files and Shares sub-APIs), Vaults, Groups, Environments
  • Builder pattern for client construction with mutual exclusivity validation
  • All domain types ported with native serde tagged enums (replacing Go's manual marshal/unmarshal)

Security hardening (post-initial review)

  • Error handling: unmarshal_core_error handles both Plugin (WASM) and SharedLib (desktop) error payloads; transport-only guard prevents non-core errors from being misidentified
  • Concurrency: Acquire/Release atomic ordering on client_id; retry_lock mutex serializes session re-initialization with stale-ID check to prevent race conditions and client ID leaks
  • Input validation: random_fill WASM host function rejects negative lengths; UTF-8 strictness on core responses (no silent lossy conversion)
  • Serialization safety: account_name unconditionally skipped from core config; sa_token omitted when empty; SharedLib response payload correctly base64-decoded (matching Go wire format)
  • Memory safety: FFI output buffer freed on error paths; old client ID released before storing new one in retry
  • CI/tooling: deny.toml v2 compat with documented advisory ignores, rustls-webpki upgraded to 0.103.13, Dependabot + upstream Extism watch workflow, explicit permissions: contents: read on CI, CodeQL enabled
  • Examples: no secret values logged (print length only), generic vault references

Not at parity (flagged)

  1. Types are hand-ported (Go SDK auto-generates via typeshare) — manual reconciliation needed on core WASM updates
  2. No automated core WASM update pipeline
  3. Host function ABI validated only via desktop path; service account path needs a token to test

Test plan

  • cargo fmt --check — clean
  • cargo clippy --all-features -- -D warnings — clean
  • cargo test — 25 tests passing
  • cargo deny check — advisories ok, bans ok, licenses ok, sources ok
  • cargo build --all-features compiles
  • Deep code review (Claude Opus) — approved
  • Second opinion (Codex gpt-5.3-codex) — patch correct, 86% confidence
  • Cursor Bugbot — all findings addressed across 8 review iterations
  • CodeQL — all alerts resolved
  • Service account token test (requires business plan)

Note

High Risk
Large initial drop that introduces new runtime backends (Extism WASM + unsafe desktop shared-library FFI), core invocation/retry logic, and a full set of typed API bindings; failures could impact security-sensitive secret handling and session management. Also adds dependency/CI automation and advisory ignores that affect supply-chain posture.

Overview
Adds an initial onepassword-sdk Rust crate (edition 2024) that wraps the 1Password core.wasm via an Extism-based Core backend (feature wasm, default) and a feature-gated desktop backend via unsafe libloading FFI.

Implements the public client surface (ClientBuilder, client_invoke with retry on DesktopSessionExpired) and typed APIs for Secrets/Items (incl. Files & Shares)/Vaults/Groups/Environments, backed by a large set of serde domain types and improved core error unmarshalling/UTF-8 handling.

Adds repo automation and guardrails: CI workflow (fmt/clippy/tests + cargo-deny), Dependabot config, an upstream Extism watch workflow, deny.toml advisory/license/source policy (with temporary Wasmtime ignores), and scaffolding/docs/examples.

Reviewed by Cursor Bugbot for commit 61e3eae. Bugbot is set up for automated code reviews on this repo. Configure here.

lightcap added 14 commits March 30, 2026 18:11
Port of the Go SDK (v0.4.1-beta.1) to idiomatic Rust with WASM core
and desktop app integration support.
13 tasks covering project scaffolding, types, core abstraction,
WASM runtime, client builder, all 7 API surfaces, desktop app
integration, examples, and CI.
Implements the Core trait using the Extism SDK with the embedded 9MB
WASM binary. Registers required host functions (random_fill,
unix_time_milliseconds, utc_offset_seconds) in their respective
namespaces and configures allowed 1Password hosts.
- Use op_sdk_ipc_send_message/op_sdk_ipc_free_response symbols (not init_client/invoke)
- Send payload as base64 string matching Go's json.Marshal([]byte) behavior
- Receive response payload as byte array matching Rust serde serialization
- Use 7-digit build version format (0040101) matching Go SDK's version-build
…handling

- Handle mutex poisoning in ExtismCore instead of unwrap() panics
- Fix memory leak in SharedLibCore when out_buf is non-null but out_len is 0
- Fix error double-processing in client_invoke (preserve error type info)
- Redact sa_token in ClientConfig Debug impl
- Validate that at least one auth method is configured in builder
… Debug

- Cache shared ExtismCore via LazyLock for standalone Secrets operations
  (avoids recompiling 9.5MB WASM on every call)
- Add DesktopSessionExpired retry in client_invoke (re-inits client, retries once)
- Use AtomicU64 for InnerClient.id to support retry without &mut self
- Redact sensitive fields in Debug impls for ItemField, ResolvedReference,
  and GeneratePasswordResponse to prevent secret leakage via logging
…ries

cargo-deny v2 changed the advisories config format — `unmaintained`
now takes a scope value, not a severity. Also adds missing license
entries (LLVM-exception, MPL-2.0, CDLA-Permissive-2.0), upgrades
rustls-webpki to 0.103.13, and ignores wasmtime advisories pinned
by extism.
fix: harden core invocation boundaries and error handling
Daily Cargo dependency checks to catch advisories early, grouped
minor/patch version bumps to reduce noise, and GitHub Actions
ecosystem monitoring to mitigate CI supply-chain risk.
Harden Dependabot config for security product
@codezero-io codezero-io deleted a comment from cursor Bot May 12, 2026
@codezero-io codezero-io deleted a comment from cursor Bot May 12, 2026
@lightcap
Copy link
Copy Markdown
Collaborator Author

@BugBot review

Comment thread src/core_shared_lib.rs Outdated
Comment thread src/core.rs
… lookup

Address Bugbot findings:
- AtomicU64 for client_id now uses Release/Acquire ordering so concurrent
  threads observe the updated id after session retry re-initialization.
- Windows library path lookup uses USERPROFILE instead of HOME via
  compile-time cfg, fixing broken path resolution on Windows.
Comment thread src/core_shared_lib.rs
Comment thread src/core_extism.rs Outdated
…size check

The Go shared library encodes response payloads as base64 strings
(Go's json.Marshal of []byte), not JSON integer arrays. Add a custom
serde deserializer using base64::STANDARD to match the wire format.

Remove redundant MESSAGE_LIMIT check in ExtismCore::invoke() since
CoreWrapper::invoke() already validates payload size for all backends.
Comment thread src/client.rs
Comment thread src/core.rs
@github-advanced-security
Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Comment thread .github/workflows/ci.yml Fixed
Comment thread .github/workflows/ci.yml Fixed
Comment thread examples/desktop_app.rs Fixed
Comment thread examples/service_account.rs Fixed
… permissions

Examples now print secret length instead of the secret value itself.
CI workflow gets explicit `contents: read` permissions block.
Comment thread src/client.rs
Concurrent threads hitting DesktopSessionExpired could each call
init_client independently, racing on set_client_id and orphaning
the loser's client ID. A retry_lock mutex now serializes the
re-initialization path. Also removes the unnecessary params.clone()
on every invoke — params are moved into the config and only consumed
on retry.
Comment thread src/client.rs Outdated
…nfig

The double map_err chain first typed transport errors via
unmarshal_core_error then immediately wrapped them into a generic
Config string, destroying the type information callers need for
error-specific handling like rate limit backoff.
Only used within core.rs — no need for pub(crate) export.
Comment thread src/client.rs
Comment thread deny.toml Outdated
Prevents leaking the old client ID in the WASM core when
re-initializing after DesktopSessionExpired. Also changes
deny.toml unmaintained scope from "workspace" to "all" for
clarity in a single-crate project.
Comment thread src/client.rs
Comment thread src/core_shared_lib.rs Outdated
…r on error

Retry now compares stale_id to current_id under the lock — if another
thread already refreshed, reuse the new ID instead of releasing it.

SharedLibCore now frees the library-allocated output buffer before
returning early on FFI error codes, preventing a memory leak.
Comment thread src/client.rs
Pre-core errors (Serialization, Config) now bypass unmarshal_core_error
entirely via a match guard, ensuring they're never misidentified as
core errors or passed through unnecessary JSON parsing.
Comment thread examples/desktop_app.rs Outdated
Comment thread Cargo.toml
error_from_return_code returns Result<(), _> — use ? to propagate
the error instead of returning it directly from a Result<Vec<u8>, _>
function.
Comment thread Cargo.toml Outdated
Desktop-only consumers can now compile with --no-default-features
--features desktop, skipping the entire extism/wasmtime dependency
tree. CI updated to clippy-check the desktop-only path.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8ee1880. Configure here.

Comment thread Cargo.toml Outdated
Only used in core_extism.rs host functions which are gated on the
wasm feature. Desktop-only builds no longer pull in chrono.
@lightcap lightcap merged commit 8eeb45d into main May 13, 2026
10 checks passed
@lightcap lightcap deleted the feat/initial-design branch May 13, 2026 01:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants