Repository navigation
feat(cli): publish standalone Azure scanner package - #394
ritiksah141 wants to merge 9 commits into
Conversation
Signed-off-by: ritiksah141 <ritiksah141@gmail.com>
Signed-off-by: ritiksah141 <ritiksah141@gmail.com>
Signed-off-by: ritiksah141 <ritiksah141@gmail.com>
Signed-off-by: ritiksah141 <ritiksah141@gmail.com>
Signed-off-by: ritiksah141 <ritiksah141@gmail.com>
Signed-off-by: ritiksah141 <ritiksah141@gmail.com>
Signed-off-by: ritiksah141 <ritiksah141@gmail.com>
Signed-off-by: ritiksah141 <ritiksah141@gmail.com>
Signed-off-by: ritiksah141 <ritiksah141@gmail.com>
parthrohit22
left a comment
There was a problem hiding this comment.
Reviewed 2d1be5b. The packaging is solid:
Hosted-only modules are kept out of the wheel.
A missing rule makes the result “incomplete” and the exit code nonzero.
The CLI checks credentials before scanning and doesn’t print raw SDK errors.
PyPI publishing stays disabled until the protected environment exists.
Approving. Mark it ready after a rebase. Non-blocking:
The manifest.txt check in scanner/engine.py also runs in the hosted worker. A rule that’s in the manifest but missing turns every hosted scan into incomplete. Please mention that in the PR description.
New rules now need a manifest.txt entry, and only the package CI checks this. Please add that to the rule-author docs. OWASP/openshield#280’s AZ-CI rules will need entries.
logging.disable(CRITICAL) with no --verbose flag will make debugging on users’ machines hard.
Drop the multidict/Werkzeug lock edits once OWASP/openshield#401 merges.
OWASP/openshield#397 describes an openshield ask command. It should become a subcommand here rather than a second root-level cli.py.
Summary
Closes #393. Packages the standalone Azure scanner as
owasp-openshieldwith anopenshield scancommand. The distribution includes 144 rules, the severity contract, and referenced playbooks. CLI results support readable and JSON output, and failed rules produce an incomplete, nonzero result. Hosted API and worker behavior remain on their existing deployment path.Safety and release design
DefaultAzureCredential, checks subscription access before scanning, redacts raw SDK errors, and never executes packaged playbooks.mainbuilds and verifies Python artifacts, attaches them and checksums to the GitHub Release, then publishes from the protectedpypienvironment with Trusted Publishing. PR builds have no publication path.pypienvironment does not currently exist. The PyPI job is now skipped until a repository administrator creates it with required reviewers, the PyPI owner registers the Trusted Publisher, andPYPI_TRUSTED_PUBLISHING_READY=trueis set. This prevents a tag from auto-creating an unprotected publishing environment.multidict6.9.1 andWerkzeug3.1.9 releases found by the PR dependency audit. No audit exceptions were added.openshieldpackage is not this project.Verification completed locally
ruff check .,ruff format --check .,git diff --check, andactionlintpassed.pip check, CLI help/version, 144-rule inventory and playbook checks, isolated imports, readable and JSON synthetic output, incomplete rule handling, authentication failure, and invalid configuration.2d1be5bpassed the backend test suite, CI summary, SCA, Semgrep workflow and code-scanning check, CodeQL, and isolated wheel/sdist installs on Linux, macOS, and Windows.The actual terminal recording from a clean Python 3.11 wheel install captures
python -m pip check(No broken requirements found),openshield --version(0.3.1.dev216+g443be0c),openshield scan --help, andopenshield scan --subscription-id invalid --format json(invalid_configuration, exit 2). Download the.castfile and play it withasciinema play cli-installed-wheel.cast. It contains no Azure credentials, subscription ID, or findings. The version is a PR development build, not a PyPI release.I installed the current PR wheel in another clean Python 3.11 environment and attempted a read-only live preflight against a non-production subscription. It returned JSON
authentication_failedwith exit 2 and empty stderr. The local Azure CLI refresh token had expired, so no live rule execution or finding output occurred. The subscription ID and Azure error details are withheld from this PR.Remaining gates
Human review, merge/promotion to
main, a signed release, GitHub Release assets, PyPI publication, and installation from the public PyPI index are separate pending gates. The live subscription scan awaits refreshed Azure credentials; no subscription ID or findings are included here.Documentation