Repository navigation
Conversation
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
CodeRabbit Verify
|
serhalp
force-pushed
the
serhalp/feat/native-token-keychain-storage
branch
2 times, most recently
from
November 3, 2026 20:40
cecfff3 to
bf10059
Compare
commit: |
serhalp
commented
Nov 3, 2026
| "@netlify/config": "^25.5.1", | ||
| "@netlify/dev": "^5.1.12", | ||
| "@netlify/dev-utils": "^6.0.4", | ||
| "@netlify/dev-utils": "https://pkg.pr.new/@netlify/dev-utils@2b6145e", |
Member
Author
There was a problem hiding this comment.
serhalp
commented
Nov 3, 2026
Comment on lines
+216
to
+218
| "overrides": { | ||
| "@netlify/dev-utils": "$@netlify/dev-utils" | ||
| }, |
serhalp
force-pushed
the
serhalp/feat/native-token-keychain-storage
branch
2 times, most recently
from
November 3, 2026 21:03
43852c8 to
714fc86
Compare
Currently, Netlify login tokens are stored in plain text in a json file on disk. This can be read and exfiltrated by malicious actors with disk read access to a user's machine. Avoiding this may limit the blast radius of a breach or agent prompt injection attack. This PR adds support for reading and writing them to the OS's native secure keychain storage. This works on macOS (Keychain), Windows (Credential Manager, built-in), and Linux (Secret Service, built-in to GNOME/KDE, installable elsewhere). The exact user-facing behaviour (prompting for a password/fingerprint/etc.) varies by platform and configuration; it doesn't affect us. Here's the new behaviour: - By default, logging in stores the new token in the OS keychain. - Once a token is in the OS keychain, that's what will be read. - If a plain text token is present, it continues to work the same before. - Whenever the opportunity arises (a user running an interactive command requiring auth, no `--json`, no `--silent`, not in CI, in a TTY, etc.) we prompt the user asking them if we may migrate their plaintext token to keychain storage. If approved, we initiate a fresh login, which stores the new token in the OS keychain, then we delete the plain text token. - When OS keychain storage is not available, we quietly fall through to plain text storage. We never prompt to migrate in this case. - If writing to the OS keychain fails, we faill through to plain text. - Edge case: In the event that a user somehow ends up with both a plaintext token and a keychain token, the plaintext token takes precedence. - As an escape hatch, `NETLIFY_USE_LEGACY_AUTH_STORAGE=1` may be set to disable OS keychain storage entirely. Most of the above is transparent. I tried to add helpful information to `--debug` mode. The migration copy: ``` Your Netlify auth token is currently stored in plaintext at /Users/…/Library/Preferences/netlify/config.json. The CLI can move it to your OS keychain (more secure). Your operating system may prompt you to allow access. ? Move the token to the keychain now? (Y/n) ``` "Yes" migrates and clears the plaintext entry. "No" is persisted (`auth.keychainMigrationDeclined`) so we don't nag again, with a hint to run `netlify logout && netlify login` to revisit at a later time. `NETLIFY_USE_LEGACY_AUTH_STORAGE=1` skips the keychain entirely on both read and write. The token storage type is printed in the output of `netlify status` for convenience. Plain text storage _may_ be removed in a future major, but we have no current such plans. See netlify/primitives#830, which added the core capability. So we can track relative usage of the two token storage mechanisms, the `cli:command` telemetry event now has an `authTokenSource` attribute, and new events `user_authTokenStored` and `user_authTokenMigrationDeclined` are emitted.
serhalp
force-pushed
the
serhalp/feat/native-token-keychain-storage
branch
from
November 3, 2026 21:10
714fc86 to
e79d2f3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
Currently, Netlify login tokens are stored in plain text in a json file on disk. This can be read and exfiltrated by malicious actors with disk read access to a user's machine. Avoiding this may limit the blast radius of a breach or agent prompt injection attack.
Summary
This PR adds support for reading and writing them to the OS's native secure keychain storage.
This works on macOS (Keychain), Windows (Credential Manager, built-in), and Linux (Secret Service, built-in to GNOME/KDE, installable elsewhere). The exact user-facing behaviour (prompting for a password/fingerprint/etc.) varies by platform and configuration; it doesn't affect us.
Details
Here's the new behaviour:
--json, no--silent, not in CI, in a TTY, etc.) we prompt the user asking them if we maymigrate their plaintext token to keychain storage. If approved, we initiate a fresh login, which
stores the new token in the OS keychain, then we delete the plain text token.
prompt to migrate in this case.
plaintext token takes precedence.
NETLIFY_USE_LEGACY_AUTH_STORAGE=1may be set to disable OS keychain storageentirely.
Most of the above is transparent. I tried to add helpful information to
--debugmode.The migration copy:
"Yes" migrates and clears the plaintext entry. "No" is persisted (
auth.keychainMigrationDeclined) so we don't nag again, with a hint to runnetlify logout && netlify loginto revisit at a later time.NETLIFY_USE_LEGACY_AUTH_STORAGE=1skips the keychain entirely on both read and write.The token storage type is printed in the output of
netlify statusfor convenience.Plain text storage may be removed in a future major, but we have no current such plans.
So we can track relative usage of the two token storage mechanisms, the
cli:commandtelemetry event now has anauthTokenSourceattribute, and new eventsuser_authTokenStoredanduser_authTokenMigrationDeclinedare emitted.Notes
See netlify/primitives#830, which added the core capability.
Supersedes #8273