Feature/security gate - #28
Merged
Merged
Conversation
Port the security gate feature from convisocli to conviso-cli, supporting two evaluation flows: - Platform flow: delegates to the Conviso Platform via the securityGateRun GraphQL query, with full pagination over failingVulnerabilities. - Local YAML flow: validates a user-provided rules file against a JSON Schema and evaluates severity thresholds locally using issuesStats, including max_days_to_fix SLA support with UTC-aware datetime handling. Adds a Rich-based formatter for terminal output, JSON export via --output, and a diagnostic script (tools/check_security_gate_field.py) used to confirm securityGateRun availability on the staging GraphQL schema. - Add jsonschema>=4.0 dependency for rules file validation - Add CONVISO_API_URL env var support to client_graphql.py (defaults to production, allows pointing to staging for manual verification) - Register security-gate command and add it to commands_requiring_auth - Add 46 tests covering YAML parsing, schema validation, rule evaluation, timezone edge cases, formatter output, and both flows via mocked GraphQL calls All 46 tests passing.
The import used 'from src.conviso...' which breaks when the package is installed in editable mode (pip install -e .). The 'src' layout prefix is resolved by setuptools and is not exposed as a Python module name. This was a pre-existing issue on main unrelated to the security-gate feature.
Allows scoping the security gate evaluation to a specific branch.
Vulnerabilities without branch association (legacy/NULL-branch) are
excluded when --branch is used; a warning is printed to inform the user.
Changes:
- New --branch / -b option (envvar: CONVISO_BRANCH)
- Requires --company-id (validated manually, same pattern as --rules-file)
- Case-sensitive match (per API contract)
- Warning emitted before gate result about legacy vuln exclusion
- New BranchLookup GraphQL query (branches(companyId, assetId))
- New _resolve_branch_id() helper
- Distinct exit messages: 'technical error' (network/500) vs
'branch not found' (lists available branches)
- Never silently passes the gate on failure
- Platform flow: passes branchId (ID) resolved via BranchLookup
- Pagination (_fetch_all_failing_pages) propagates branchId
- Restored log_request=True, verbose_only=True on pagination call
(accidentally dropped in prior edit, now restored)
- YAML/local flow: passes branchNames: [branch] directly to issuesStats
(no ID lookup needed — API accepts name directly)
- Output JSON includes 'branch' field in local-rules mode
- 14 new tests covering BRANCH-01 through BRANCH-08
- docs/security_gate_test_plan.md: full test plan with branch cases,
exit criteria, no-credentials policy, and follow-up items
Note: every --branch execution adds one extra GraphQL call for the
branch lookup. Auto-detection from CI env vars is a planned follow-up.
douglaskurotaki
approved these changes
Jul 29, 2026
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.
Summary
This branch adds a new security gate command to the CLI, letting a pipeline check an asset's vulnerabilities against policy thresholds and fail the build if they're exceeded.
conviso security-gate, with two ways to run it:securityGateRunquery). The platform applies its own configured rules and returns which vulnerabilities caused the failure.--rules-file): reads a YAML file with severity thresholds (e.g. "block if more than 0 critical, more than 5 high"), validates it against a JSON Schema, fetches live vulnerability counts (issuesStats), and evaluates the rules locally. Supports an optional grace period per severity (max_days_to_fix) so newly found issues aren't blocked immediately.--branch/-b): scopes the evaluation to a specific branch, in both modes above.BranchLookupquery), then passes it to the gate query.issuesStats.--company-id. Branch names are matched case-sensitively; an unknown branch fails with a clear error listing the available branches.--branchis used — the command warns about this explicitly every time.--output.jsonschemaas a dependency (rules file validation).client_graphql.pynow supports aCONVISO_API_URLoverride (used to test against staging); production remains the default when unset.security-gateas a direct top-level command (not a subcommand group) and added it to the list of commands requiring authentication.f17a07b): corrected a pre-existing broken import intests/test_batch_findings.py(from src.conviso...→from conviso...).Usage
Testing
python -m pytest -v→ 78/78 passingCONVISO_API_URLoverride):--branch.--branch, includingmax_days_to_fix.--branchwithout--company-id→ exit 1, clear error.--outputJSON export produces a complete result file.CONVISO_API_URL) still points to production.conviso security-gate --helpshows options directly, with no subcommand required.Notes
tools/check_security_gate_field.pywas used during discovery to confirmsecurityGateRunand branch-related fields exist on the staging GraphQL schema before implementation started.GITHUB_REF_NAME,CI_COMMIT_REF_NAME) when--branch/CONVISO_BRANCHaren't set.--branchmakes one extra GraphQL call (BranchLookup) before the main gate query — accepted trade-off, not optimized in this PR.docs/security_gate_test_plan.md.Checklist
BranchLookupnetwork/API errors, and missing--company-idall exit 1, with messages that distinguish technical errors from policy failures.