Potential fix for code scanning alert no. 1: Workflow does not contain permissions#5
Merged
Merged
Conversation
…n permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
m1ngshum
added a commit
that referenced
this pull request
Jun 1, 2026
…-disable Applies review findings #1–#5 from the multi-perspective review: - #1/#5: extract the secret→placeholder swap into a single `applyKeychainSecrets()` in keychain.ts (also now the home of `SecretsMode`). install.ts and up.ts both delegate to it, so the "no plaintext secret in config" invariant lives in one place and can't diverge. Drops the duplicated loop + the `storedSecretKeys` array (now a returned count). - #2: guard disable's placeholder warning is now a static import, never throws (advisory scan can't break a successful disable), and surfaces non-ENOENT config-read errors instead of swallowing them. - #3: `up --secrets keychain` only prints the "run mcpm guard enable" notice when a secret was actually stored (threaded via storedCount). - #4: add tests for applyKeychainSecrets, the slash-name keychain-id round-trip, and placeholderEnvKeys (the disable-warning detector). 1088 tests pass; typecheck + build clean.
m1ngshum
added a commit
that referenced
this pull request
Jun 1, 2026
* feat: add `--secrets keychain` to install/up + guard-disable safety Phase 2 of encrypted secrets. Opt-in, default unchanged (plaintext), so no existing flow regresses. - install/up `--secrets keychain`: secret-flagged env vars are stored AES-GCM-encrypted in ~/.mcpm and written into client configs as `mcpm:keychain:server/KEY` placeholders instead of plaintext. Non-secret vars stay inline. mcpm guard resolves the placeholders at launch (Phase 1). Both commands print a "run `mcpm guard enable`" note. - `up --secrets keychain` is rejected under `--ci` (never persist secrets to a CI runner's keychain). - keychain.ts: add deriveKeychainId() — maps slash-containing registry ids (io.github.owner/repo) to a placeholder-safe keychain id. - guard disable: read-only post-disable scan warns when an unwrapped config still references `mcpm:keychain:` placeholders (they only resolve under guard). Never silently rewrites plaintext (security-first). Tests: 9 new (deriveKeychainId, install/up keychain placeholder writes, plaintext no-regression, missing-dep + --ci guards). 1082 pass; coverage 80.85% lines / 87.57% branches. typecheck + build clean. * refactor: address PR review — consolidate keychain swap, harden guard-disable Applies review findings #1–#5 from the multi-perspective review: - #1/#5: extract the secret→placeholder swap into a single `applyKeychainSecrets()` in keychain.ts (also now the home of `SecretsMode`). install.ts and up.ts both delegate to it, so the "no plaintext secret in config" invariant lives in one place and can't diverge. Drops the duplicated loop + the `storedSecretKeys` array (now a returned count). - #2: guard disable's placeholder warning is now a static import, never throws (advisory scan can't break a successful disable), and surfaces non-ENOENT config-read errors instead of swallowing them. - #3: `up --secrets keychain` only prints the "run mcpm guard enable" notice when a secret was actually stored (threaded via storedCount). - #4: add tests for applyKeychainSecrets, the slash-name keychain-id round-trip, and placeholderEnvKeys (the disable-warning detector). 1088 tests pass; typecheck + build clean. * fix(security): injective keychain id + atomic secret store + honest messaging Addresses the dedicated security audit of the secrets feature: - CRIT-1: deriveKeychainId is now injective — sanitized prefix + a sha256 suffix — so names differing only in unsafe chars ("owner/repo" vs "owner_repo") can no longer collide into one secret namespace (cross-server secret confusion/exposure). - MED-1: applyKeychainSecrets persists all of a server's secrets in a single atomic batch (new keychain.setSecrets) BEFORE returning the env written to config — no orphaned half-written secrets if one fails. install/up deps switch from setSecret to setSecrets accordingly. - MED-4: install/up notices no longer overclaim — they state secrets are "encrypted at rest (protects against other-user/offline access, not same-user processes)", matching keychain.ts's documented posture. Tests updated to the batch API + an explicit collision-injectivity test. 1088 pass; typecheck + build clean. Pre-existing guard/keychain findings (full-env forward, event-log sanitization, store write lock, log rotation) are out of scope here and tracked separately.
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.
Potential fix for https://github.com/getmcpm/cli/security/code-scanning/1
Add an explicit
permissionsblock in.github/workflows/ci.ymlat the workflow root (recommended here since there is one job and all steps are read-only). Use least privilege:contents: readThis preserves existing functionality (checkout and CI commands continue to work) while preventing accidental write-capable token use if defaults change.
Suggested fixes powered by Copilot Autofix. Review carefully before merging.