Skip to content

fix: remove plaintext token storage and fix upgrade losing login#160

Merged
rhuanbarreto merged 5 commits into
mainfrom
fix/credential-store-no-plaintext-token
Mar 23, 2026
Merged

fix: remove plaintext token storage and fix upgrade losing login#160
rhuanbarreto merged 5 commits into
mainfrom
fix/credential-store-no-plaintext-token

Conversation

@rhuanbarreto

Copy link
Copy Markdown
Contributor

Summary

  • Removes plaintext token storage: saveCredentials() no longer writes the token field to ~/.archgate/credentials. Only non-sensitive metadata (github_user, created_at) is written to disk. Tokens are stored exclusively in the OS credential manager via git credential approve.
  • Fixes upgrade losing login: loadCredentials() now queries the git credential manager first, before checking the metadata file. Previously it gated on the metadata file existing — if the file was missing or corrupted after an upgrade, credentials were lost even though the token was safely stored in the OS keychain.
  • Adds credential verification: After git credential approve, a verification round-trip (git credential fill) confirms the token was actually persisted. git credential approve exits 0 even with no credential helper configured, silently storing nothing — this is now detected and the user gets a clear warning.
  • Auto-migrates legacy tokens: If a metadata file from a previous version contains a plaintext token, it is automatically migrated to the git credential manager and scrubbed from disk on load.
  • Fixes test isolation on Windows: Git credential tests now set GIT_CONFIG_NOSYSTEM=1 and GIT_CONFIG_GLOBAL=<empty file> to isolate from the Windows Credential Manager (system-level API that ignores HOME).

Test plan

  • bun run validate passes (lint, typecheck, format, 587 tests, 22/22 ADR checks, build)
  • saveCredentials writes metadata file WITHOUT token field
  • loadCredentials returns null when no git credential manager and no legacy token
  • loadCredentials attempts migration of legacy plaintext tokens
  • clearCredentials handles legacy metadata files with plaintext tokens
  • Tests properly isolated from system credential store via GIT_CONFIG_NOSYSTEM

- Stop writing tokens to ~/.archgate/credentials metadata file
- Query git credential manager first in loadCredentials(), independent
  of the metadata file, so credentials survive upgrades
- Add verification round-trip after git credential approve to detect
  misconfigured credential helpers (approve exits 0 even with no helper)
- Auto-migrate legacy plaintext tokens to git credential manager on load
- Make GIT_CREDENTIAL_ENV a function to pick up test-time env overrides
- Isolate credential tests from system credential store on Windows via
  GIT_CONFIG_NOSYSTEM and GIT_CONFIG_GLOBAL
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Mar 23, 2026

Copy link
Copy Markdown

Deploying archgate-cli with  Cloudflare Pages  Cloudflare Pages

Latest commit: b3cf9cb
Status: ✅  Deploy successful!
Preview URL: https://28c0f848.archgate-cli.pages.dev
Branch Preview URL: https://fix-credential-store-no-plai.archgate-cli.pages.dev

View logs

When loadCredentials() finds a legacy metadata file with a plaintext
token, it now deletes the file and returns null — prompting the user
to run `archgate login` again. No migration attempt is made.

Also simplifies clearCredentials() to just delete the file without
parsing it for legacy token fields.
The ~/.archgate/credentials metadata file was the root cause of the
upgrade-loses-login bug and the only place plaintext tokens could exist.

- Remove all metadata file read/write logic (writeMetadata, readMetadata)
- Remove created_at from StoredCredentials interface
- loadCredentials() now only calls git credential fill — no disk I/O
- saveCredentials() now only calls git credential approve — no disk I/O
- Legacy metadata files are deleted on load/save/clear with a re-login prompt
- Update login status to show just the username (from git credential fill)
- No docs changes needed — docs don't reference the credentials file
The validate script called `bun test` directly, bypassing the
--timeout 60000 flag from the test script. This caused the init
idempotency integration test to flake at the default 5s timeout on CI.
@rhuanbarreto rhuanbarreto merged commit 390ef9b into main Mar 23, 2026
9 checks passed
@rhuanbarreto rhuanbarreto deleted the fix/credential-store-no-plaintext-token branch March 23, 2026 22:01
@github-actions github-actions Bot mentioned this pull request Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant