Skip to content

Security: soma-intelligence/onepass

SECURITY.md

Security policy

OnePass is a password manager. A flaw in it directly affects the people who use it, so we would much rather hear about one through a private report than read about it in public.

Reporting a vulnerability

Don't open a public issue, pull request or discussion for a security problem. Report it privately instead:

Please include:

  • the version or commit, the platform and the OS version;
  • what the flaw is and what it lets an attacker do (which data, which attacker, which conditions);
  • steps to reproduce, ideally with synthetic data, never a real vault;
  • a proof of concept if you have one, and any ideas for a fix;
  • the name to credit, if you want credit.

Timelines

  • Acknowledgement within 72 hours.
  • First assessment (confirmed or not, estimated severity) within 7 days.
  • A fix released, or a dated fix plan shared with you, within 90 days.

If a flaw is already being exploited, we ship a fix or a mitigation as soon as we can, without waiting for the end of that window.

Coordinated disclosure

Please don't publish anything before a fix is available or 90 days have passed, whichever comes first. If we can't meet that window, we'll tell you and agree on a date together. Reporters are credited in the security advisory unless they ask otherwise.

Safe harbor for good faith research

We won't take legal action against, or ask for prosecution of, anyone who looks for and reports a flaw in good faith and follows these rules:

  • test only your own accounts, devices and data, or synthetic data;
  • don't access, change or destroy other people's data;
  • don't degrade a shared service (no denial of service, no load testing against CloudKit or third party infrastructure);
  • no social engineering and no physical attacks against people;
  • give us the window above before publishing.

In scope

  • The Rust core (core/): cryptography, vault format, sync, restore epochs, import and export, archives.
  • The Apple apps (apple/): iPhone, iPad, Mac, Apple Watch and Vision Pro, the AutoFill provider, widgets.
  • The browser extension (extension/) and the native messaging host (core/onepass-native-host, core/onepass-bridge).
  • The command line and the local interfaces (core/onepass-cli, core/onepass-ffi, core/onepass-mcp, core/onepass-ssh-agent).
  • The build chain: GitHub Actions workflows, dependencies, signatures.

The threat model and the guarantees we aim for are described in docs/security/README.md.

Out of scope

  • Attacks that need a device already compromised at the system level (root, kernel, the owner debugging the app), or physical access to an unlocked device.
  • A weak or reused master password chosen by the user.
  • Platform flaws (iOS, macOS, browsers, CloudKit) unrelated to our code: report those to the vendor.
  • Reports from automated tools without a demonstrated impact, and headers or settings without a demonstrated consequence.
  • Phishing and social engineering.
  • Limits already documented in docs/security/README.md and in the design specs under docs/specs/, such as the CLI keeping its Secret Key in clear in device.bin when run with --insecure-file-secret-key (machines without a system secret store).

Agents on the Mac: iPhone approval and remote unlock

The Mac app's MCP server can ask the owner's iPhone to approve a request, and the iPhone can unlock a locked Mac for agents only. Design: docs/superpowers/specs/2026-10-28-agent-ready-design.md, section 9. Attackers A1 to A4 of the MCP and SSH hardening spec still apply. These are added:

Attacker Capability Defense
A5. Hostile CloudKit Replays, delays, deletes, reorders or forges records Every message is sealed to the recipient's key and signed by a device of the signed approver list; request id, 60 s expiry, 24 h replay memory on the phone, device list and approver list seqs that may not go back; an answer counts only for a request the Mac sent and still waits on. Worst case: denial of service, the Mac panel still works.
A6. Stolen or lost iPhone Holds the phone, not the owner's face K_r sits behind .biometryCurrentSet; every answer needs Face ID through a .biometryCurrentSet check; K_r and the phone's approver keys stay on this device only, never synced. Revoking the phone in the device list makes the Mac erase C and refuse its answers.
A7. Stolen Mac, or a session left open The disk, or physical access during an agent window C alone opens nothing. The agent window is agents only (the app, AutoFill, the extension and widgets see a locked vault), bounded, and ends when the Mac sleeps or its user session goes inactive, on lock, or on "Lock now" on the phone; the display going to sleep does not end it. While a window is open, an approval clicked on the Mac panel counts only after Touch ID (MCP and SSH).
A8. An agent that spams unlock requests Triggers requests in a loop Only the first tool call of a paired client asks the phone (the locked app answers the MCP handshake itself, and an unpaired client is told to pair at the Mac); at most one unlock request per 10 minutes per Mac; 3 refusals (an unanswered request counts as one) block remote unlock for 1 hour; the existing per-client limits.
A9. A fake notification Shows the owner a notification that looks like OnePass Nothing can be answered from the notification itself; the app shows the decrypted, signature-checked request before Face ID; for approvals, the same 4-letter code is shown to the agent and on the phone. Unlock requests carry no code: they show the agent's identity and the window length, and the agent's request then goes through an approval with its code.

Residual risks, known and accepted for now:

  • CloudKit and Apple see when and how many requests are made, and which device receives them (the recipient's device id is in clear for the subscription).
  • A malicious process of the same user, signed by a paired team, during an agent window, is the "compromised system" case, out of scope.
  • The unlock throttle is stored on disk, but the lock around its check is held in one process: two processes racing on one Mac could each pass the check once.
  • The throttle trusts the wall clock. A clock stepped back by more than a whole throttle window lifts the limit (a monotonic clock would be needed).
  • For strong actions (reveal_secret, totp_code), the Mac trusts the phone's Face ID and does not ask for Touch ID again. The phone refuses to answer a strong request without a .biometryCurrentSet check.
  • The Mac's approver accepts the origin string the app returns (mac or phone:<device_id>). Recording the ids of accepted responses in the core would close this.
  • Reading the approver list while the Mac is locked does not persist the chain state: a rollback seen there is caught only at the next full unlock.
  • Audit logs that contain the approved_on field cannot be verified by older builds (forward-only change).
  • While locked, the app reads its client registry without checking the signature (nothing can verify it then), only to decide whether to ask the phone at all. A process that can write the data folder can make the phone be asked for an unpaired client (the server still refuses its calls) or keep a paired one from asking.
  • An unlock request that a full unlock of the Mac cut short still counts as a refusal in the throttle.

Supported versions

OnePass has no 1.0 release yet. Only main receives security fixes. After 1.0, this section will list the maintained versions.

OnePass has not had an external audit yet. One is planned before the first stable release.

Supply chain

Dependencies are checked with cargo deny, cargo vet, cargo audit and npm audit, and GitHub Actions are pinned by commit SHA. Releases are built on GitHub's runners by .github/workflows/release.yml, which signs and notarizes the Mac app, writes SHA256SUMS and attests the provenance of every file; verify a download with gh attestation verify as described in docs/security/release-pipeline.md. What can be rebuilt bit for bit, and what cannot, is in docs/security/reproducible-builds.md.

Learn more about advisories related to soma-intelligence/onepass in the GitHub Advisory Database