-
Notifications
You must be signed in to change notification settings - Fork 157
feat(marketplace): add audit command to flag deps that bypass marketplace pinning #881
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
edenfunf
wants to merge
6
commits into
microsoft:main
Choose a base branch
from
edenfunf:feat/marketplace-doctor-847
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,458
−15
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
e7b603d
feat(marketplace): add audit command to flag deps that bypass marketp…
edenfunf ba9f3b8
Merge branch 'main' into feat/marketplace-doctor-847
edenfunf 5233944
Merge branch 'main' into feat/marketplace-doctor-847
edenfunf 596f31d
Merge branch 'main' into feat/marketplace-doctor-847
danielmeppiel 07c51b2
test(marketplace): use _quoted_hosts helper for fetch_raw host assertion
edenfunf eba1833
Merge branch 'main' into feat/marketplace-doctor-847
edenfunf File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| """``apm marketplace audit`` command.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import sys | ||
| import traceback | ||
|
|
||
| import click | ||
|
|
||
| from ...core.command_logger import CommandLogger | ||
| from ...marketplace.audit import FetchStatus, run_audit | ||
| from ...marketplace.client import fetch_marketplace | ||
| from ...marketplace.registry import get_marketplace_by_name | ||
| from . import marketplace | ||
|
|
||
|
|
||
| @marketplace.command( | ||
| help="Audit plugin transitive deps for marketplace-bypass risk" | ||
| ) | ||
| @click.argument("name", required=True) | ||
| @click.option( | ||
| "--strict", | ||
| is_flag=True, | ||
| help="Exit non-zero when any plugin has bypass dependencies or fetch errors", | ||
| ) | ||
| @click.option("--verbose", "-v", is_flag=True, help="Show detailed output") | ||
| def audit(name, strict, verbose): | ||
| """Audit a registered marketplace's supply-chain pinning. | ||
|
|
||
| For each plugin in ``NAME``'s manifest, fetch the plugin's own | ||
| ``apm.yml`` (at its pinned ref) and warn when ``dependencies.apm`` | ||
| entries use direct repo paths, which bypass the marketplace's | ||
| version pinning and make transitive deps track HEAD. | ||
| """ | ||
| logger = CommandLogger("marketplace-audit", verbose=verbose) | ||
| try: | ||
| source = get_marketplace_by_name(name) | ||
| logger.start(f"Auditing marketplace '{name}'...", symbol="gear") | ||
|
|
||
| manifest = fetch_marketplace(source, force_refresh=True) | ||
| n = len(manifest.plugins) | ||
| logger.progress( | ||
| f"Checking {n} plugin{'' if n == 1 else 's'}...", symbol="info" | ||
| ) | ||
|
|
||
| reports = run_audit(manifest, source) | ||
|
|
||
| ok_count = 0 | ||
| bypass_total = 0 | ||
| fetch_error_count = 0 | ||
| skipped_count = 0 | ||
|
|
||
| # Suppress the per-plugin section header when there is nothing to | ||
| # report and the user did not opt into verbose: in the all-clean | ||
| # default run the header would otherwise hang above an empty body. | ||
| has_findings = any( | ||
| rep.fetch_status != FetchStatus.OK or rep.issues | ||
| for rep in reports | ||
| ) | ||
|
|
||
| click.echo() | ||
| if has_findings or verbose: | ||
| click.echo("Audit Results:") | ||
| for rep in reports: | ||
| if rep.fetch_status == FetchStatus.OK: | ||
| if not rep.issues: | ||
| ok_count += 1 | ||
| if verbose: | ||
| logger.success( | ||
| f" {rep.plugin_name}: deps are marketplace-resolved", | ||
| symbol="check", | ||
| ) | ||
| continue | ||
| bypass_total += len(rep.issues) | ||
| if len(rep.issues) == 1: | ||
| verb_phrase = "1 dependency bypasses" | ||
| else: | ||
| verb_phrase = f"{len(rep.issues)} dependencies bypass" | ||
| logger.warning( | ||
| f" {rep.plugin_name}: {verb_phrase} the marketplace", | ||
| symbol="warning", | ||
| ) | ||
| for issue in rep.issues: | ||
| click.echo(f" - '{issue.dep}'") | ||
| click.echo(f" hint: {issue.suggestion}") | ||
| elif rep.fetch_status in ( | ||
| FetchStatus.NO_MANIFEST, | ||
| FetchStatus.UNSUPPORTED_SOURCE, | ||
| ): | ||
| skipped_count += 1 | ||
| if verbose: | ||
| logger.verbose_detail( | ||
| f" {rep.plugin_name}: skipped ({rep.fetch_status.value}" | ||
| f"{' - ' + rep.detail if rep.detail else ''})" | ||
| ) | ||
| else: | ||
| fetch_error_count += 1 | ||
| logger.warning( | ||
| f" {rep.plugin_name}: could not verify " | ||
| f"({rep.fetch_status.value}: {rep.detail})", | ||
| symbol="warning", | ||
| ) | ||
|
|
||
| click.echo() | ||
| warn_noun = "warning" if bypass_total == 1 else "warnings" | ||
| err_noun = "error" if fetch_error_count == 1 else "errors" | ||
| click.echo( | ||
| f"Summary: {ok_count} clean, {bypass_total} bypass {warn_noun}, " | ||
| f"{skipped_count} skipped, " | ||
| f"{fetch_error_count} unverifiable {err_noun}" | ||
| ) | ||
| if bypass_total: | ||
| click.echo() | ||
| click.echo( | ||
| "Marketplace refs (name@marketplace) pin transitive deps " | ||
| "through the catalogue so consumers get the same versions " | ||
| "you tested. See: " | ||
| "https://microsoft.github.io/apm/guides/marketplaces/" | ||
| ) | ||
|
|
||
| if strict and (bypass_total or fetch_error_count): | ||
| sys.exit(1) | ||
|
|
||
| except Exception as e: | ||
| logger.error(f"Failed to audit marketplace: {e}") | ||
| logger.verbose_detail(traceback.format_exc()) | ||
| sys.exit(1) |
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.