heroku-cli-command
heroku-cli-command copied to clipboard
fix(W-18094367): remove support for .netrc files
Remove .netrc support in favor of modern encryption and OS-level key stores
This PR modernizes credential storage by removing .netrc file support and implementing secure credential storage using OS-level key stores and encryption.
OS-Specific Keystore Implementation
The CLI now uses the following secure credential storage mechanisms:
- macOS: Keychain Access
- Windows: Windows Credential Manager
- Linux: libsecret (GNOME Keyring/KWallet)
- Requires libsecret library to be installed
- For Debian/Ubuntu:
sudo apt-get install libsecret-1-dev - For Red Hat/Fedora:
sudo yum install libsecret-devel - For Arch Linux:
sudo pacman -S libsecret
Breaking Changes
-
No longer writes or reads token data from
.netrcfiles- Any ancillary uses of the .netrc file will no longer contain Heroku credentials
- Applications depending on Heroku credentials contained in the .netrc will need to be updated
- The
Netrcmachines for 'api.heroku.com' and 'git.heroku.com' are explicitly removed - any existing .netrc files containing Heroku credentials will be permanently removed.
-
Token storage implementation changes
- New dependencies on file encryption and OS keystore. These are OS-level dependencies and are described below.
- Token retrieval now uses
retrieveToken()andgetConfigContents() - Applications directly accessing token storage need to be updated to use new methods
- *Applications using code patterns like
Authorization: bearer ${this.heroku.auth}can safely continue to do so.
System Requirements
-
Linux Users:
- Must have libsecret installed and a running keyring daemon (GNOME Keyring or KWallet)
- Without libsecret, the Heroku CLI will fail to store credentials securely and alternative auth methods such as the
HEROKU_API_KEYenv var must be used - Desktop environments like GNOME and KDE include the above listed utils by default
-
macOS Users:
- No additional requirements
- Uses the built-in Keychain Access
-
Windows Users:
- No additional requirements
- Uses the built-in Windows Credential Manager
Testing Instructions
- Build the package:
npm run build npm pack - install this by file path
- fix above mentioned breaking changes in code and unit tests if applicable
- test your CLI
I think using the credential storage makes sense but there is a minimal change in security posture: A local user who can read the .netrc file will also be able to execute
heroku auth:token.
@tt - Exactly. This was an area of consideration for me as well. I understand the best practice to be:
- Generate a token and display it once and only once
- Regular Auth flows never display the token
- If a token is not securely saved by the user, it is lost and the user must generate a new one.
Thoughts?
- Generate a token and display it once and only once
- Regular Auth flows never display the token
- If a token is not securely saved by the user, it is lost and the user must generate a new one.
Thoughts?
I think we should definitely implement these but it still doesn't change the fact that any user who can invoke the CLI can exfiltrate a token.
We could make heroku auth:token require explicit consent similar to when you sign in but that wouldn't prevent you from getting the token that the CLI itself is using. As long as you can run a plug-in, this.heroku.auth could be read and exposed. Even if we block that by, say, only exposing a way to issue API requests, a plug-in could communicate with the credential store directly because it's running inside the CLI process.
I'm not saying this because we shouldn't more in the direction of adopting better platform primitives. I only want us to recognize that we're making it more complicated to receive the plaintext token but not impossible.
Do the "secure credential storage mechanisms" implemented by this change (Keychain Access, Windows Credential Manager, libsecret) prompt the user for a local password or biometric authentication, before saving or reading a credential?
Do the "secure credential storage mechanisms" implemented by this change (Keychain Access, Windows Credential Manager, libsecret) prompt the user for a local password or biometric authentication, before saving or reading a credential?
Not in any of the tests I performed. AFAIK, these tools are intended to be used in this way and shouldn't need explicit input from the user.