Thunderbird Support for Browserpass
Summary
This PR adds Thunderbird email client support to the Browserpass extension. It allows users to store and retrieve email credentials (IMAP, SMTP, POP3) and OAuth tokens (Gmail, Microsoft, Fastmail) from their pass password store instead of Thunderbird's built-in password manager.
I am already running the implementation locally since a few days. I have tried different setups, fixed several issues on the way and also ran into Thunderbird issues. For debugging purposes I have added quite some logging, which should not hurt and probably at least be kept until more users tried the extension.
I am interested in this feature myself and got some time to work on this. It turned out to be much more code then originally anticipated but there were a lot of edge cases to cover and will probably be some more. Any feedback is appreciated.
Features
- Mail Protocol Support: Automatic password retrieval for IMAP, SMTP, and POP3 accounts
- OAuth2 Token Storage: Refresh token storage for Gmail, Microsoft, and Fastmail
- CalDAV/CardDAV: OAuth authentication for calendar and contacts
-
Automatic Migration: Credentials are migrated from Thunderbird's password manager to
pass -
Credential Saving: New credentials entered in Thunderbird are automatically saved to
pass - OAuth Window Autofill: Clipboard-based autofill for OAuth browser windows with keyboard shortcuts
Technical Implementation
Why Separate Builds?
Thunderbird requires WebExtension Experiments to hook into its authentication system, which Firefox doesn't allow for non-privileged add-ons. The experiment API provides access to:
-
MsgAuthPrompt- Intercepts IMAP/SMTP/POP3 password prompts -
OAuth2Module- Intercepts OAuth token requests for CalDAV/CardDAV -
browserRequest- Monitors OAuth browser windows for autofill
Therefore, the extension is built separately:
-
Firefox:
make firefox- Standard browser extension -
Thunderbird:
make thunderbird- Includes experimental credentials API
The core extension code remains shared; only the manifest and experiment files differ.
Architecture
Thunderbird Auth Request
↓
implementation.js (WebExtension Experiment)
- Hooks MsgAuthPrompt (IMAP/SMTP/POP3)
- Hooks OAuth2Module (CalDAV/CardDAV)
- Hooks browserRequest (OAuth windows)
↓
Event Emitters → background.js
↓
thunderbird.js
- Matches credentials from pass
- Stores new credentials to pass
↓
browserpass-native (GPG decryption)
Requirements
- Thunderbird 128.0+: Uses WebExtension Experiments API
-
browserpass-native: Required for GPG decryption - run
make hosts-thunderbird-userto register - pass: Standard Unix password manager with GPG
Testing
- Build extension:
make thunderbird - Package as XPI:
cd thunderbird && zip -r browserpass-thunderbird.xpi * - Install in Thunderbird via Add-ons → Install from File
- Open Thunderbird Error Console with Ctrl+Shift+J
- Test credential retrieval for existing email accounts
- Test OAuth authentication for Google/Microsoft accounts
- Test migration of existing Thunderbird credentials
Password Store Organization
~/.password-store/
├── imap/
│ └── mail.example.com.gpg # IMAP server credentials
├── smtp/
│ └── mail.example.com.gpg # SMTP server credentials
├── pop3/
│ └── pop.example.com.gpg # POP3 server credentials
├── https/
│ └── sso.example.com.gpg # OAuth identity provider credentials
└── oauth/
├── mail/
│ └── [email protected] # OAuth mail tokens
├── caldav/
│ └── [email protected] # Calendar OAuth tokens
└── carddav/
└── [email protected] # Contacts OAuth tokens
The https/ directory is for OAuth identity provider login pages (e.g., Google, Okta) that appear in the OAuth browser window during account setup.
Design Decisions
1. Offline Startup Control
Thunderbird is forced to start offline to prevent auth requests before the extension is ready (This seems to be a Thunderbird issue). Once hooks are registered, Thunderbird goes online automatically. User's "Always offline" preference is respected.
2. OAuth Token Caching
Tokens retrieved from pass are cached for 8 hours to reduce GPG decryption overhead. Cache is cleared on token update or after the timeout expires.
3. Credential Migration
Credentials are migrated from Thunderbird's password manager to pass. Existing pass entries are not overwritten.
4. Service-Specific OAuth Storage
OAuth tokens are stored in service-specific directories (oauth/mail/, oauth/caldav/, oauth/carddav/) because different services may request tokens with different scopes. A calendar app might request a token with calendar-only permissions, while mail needs separate permissions. Sharing a single token would break services that require permissions the new token doesn't have.
Known Limitations
- CalDAV Startup OAuth Windows: CalDAV calendars without offline cache may trigger OAuth windows at startup before the extension hooks are ready (This seems to be a Thunderbird issue). The extension automatically closes these windows and retries once initialization is complete
- OAuth Autofill Method: OAuth browser window autofill uses clipboard-based injection with keyboard shortcuts rather than direct DOM manipulation, due to security restrictions in browser windows.
Breaking Changes
None - this is additive functionality that is mainly added to the Thunderbird extension.
Related PRs
A companion PR to browserpass-native is required to register the native host for Thunderbird:
- Adds
hosts-thunderbird-userandhosts-thunderbirdMakefile targets - Registers
firefox-host.jsonnative messaging manifest
References
- pass - Standard Unix password manager
- WebExtension Experiments - Thunderbird API documentation
- keepassxc-mail - Inspired the general architecture approach (offline startup control, WebExtension Experiments, credential event handling)