-
Notifications
You must be signed in to change notification settings - Fork 712
Description
Sorry for my recent streak of nitpicking about the token-related issues — I've been learning about security lately and tried to look at GitButler's secret storage and usage mechanisms from the perspective of a privacy- or security-conscious user doing a bit of reverse-engineering.
And well… that actually led me to a few interesting findings.
From what I can tell with my limited knowledge, GitButler's secret mechanism is already sufficiently secure and properly handled on the backend.
Most of the issues I've noticed are on the frontend (or usage) side (or maybe I'm just not skilled enough to spot backend ones). The way secrets are stored isn't necessarily a best practice — I mean, it's already good, but it could be made even more robust and future-proof instead of leaving potential weak spots behind.
Here are some of my thoughts and takeaways regarding secret handling:
- Keychain or system-level secret storage should only store the secret itself — no extra data structures, and definitely not multiple tokens in a single keychain item.
In the new GitHub multi-account support feature, GitButler stores metadata together with tokens in the keychain for easier data restoration.
While convenient, this might set a precedent that encourages adding more metadata or complex structures later, which is generally not a good design direction. The keychain should focus purely on sensitive data — simple, minimal, and robust.
- (Already fixed — thank you for addressing it!) Secrets should never be stored directly in localStorage. Since they're already safely kept in the keychain, there's no need to add extra exposure risk.
- GitButler account authorization tokens shouldn't rely on a long-lived, never-expiring UUID v4 token. A JWT + refresh token design would be ideal — it's a well-established standard approach.
- (Thanks to @Byron for pointing this out and fixing it!) Tokens entered for GitLab, OpenAI, Anthropic and similar integrations should be masked to some degree in the UI — and in logs as well. Tokens should never be printed or exposed.
- do not log secrets #10781
- Hide sensitive information in the UI #10782
- Hide sensitive information in secret input fields with password masking #10783
- Be careful with cross-project or cross-app (stable, nightly, dev) key sharing.
The GitLab token issue first appeared as unwanted token duplication and reuse across multiple projects.
Similarly, OpenAI and Anthropic API keys in the keychain currently lack namespace prefixes, which allows different GitButler app variants (with distinct bundle IDs) to access them.
I mean, reusing the same keychain item across builds isn't inherently bad, but it does open a backdoor for modified apps to impersonate another and steal tokens.
Sure, a tampered app could always try to request unauthorized secrets — but if GitButler never requests secrets outside its intended scope, users are far more likely to notice if something suspicious happens.