Skip to content

Flag security groups open to the internet on Insights - #85

Merged
JetSquirrel merged 4 commits into
mainfrom
feat/security-findings
Nov 3, 2026
Merged

JetSquirrel merged 4 commits into
mainfrom
feat/security-findings

Conversation

@JetSquirrel

@JetSquirrel JetSquirrel commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

Closes #80

Adds a read-only Security configuration section to Insights. It flags AWS security groups that open SSH or RDP to the whole internet (0.0.0.0/0 or ::/0), and says plainly what it could not evaluate. It changes nothing in the cloud, and it is not a compliance check or a security score.

What it does

  • Rules: aws-sg-public-ssh and aws-sg-public-rdp, covering TCP ranges that include the port and all-traffic rules.
  • Row states: Finding, Not evaluated, and Evaluated with no finding. A status filter narrows the list, and a row opens onto the observed rule, why it matters, a manual check and the scan's details.
  • Coverage is explicit: the card counts groups evaluated and not evaluated. No inventory, a partial scan and a scan listing no groups each get their own notice, so none reads as clean.
  • Never a pass by default: a group with no configuration, no inbound rule data or an unreadable rule is Not evaluated.
  • Separate from cost: findings carry no amount and are in their own card. Cost Insights, script rules and resource matching are untouched.

The evaluator is pure, in src/analytics/security.rs, and needs no new credentials or feeds.

Please confirm against a real scan

The issue asks which scan paths actually expose ingress rules. I answered that by reading the pinned fork's code, not from a real scan, because I have no AWS scan to run.

On cloudbridge-dist, AWS::EC2::SecurityGroup is a curated type, its Cloud Control identifier is derived from the ARN, and the GetResource properties are stored raw. CloudFormation's schema for that type includes SecurityGroupIngress, and that is the only input these rules read. Test fixtures follow that schema's shape.

If real properties differ, or Cloud Control leaves the key out of its response, groups will show as Not evaluated rather than give a false result. Before relying on this, check what real security groups show after a scan.

Worth a look in review

  • A group with no inbound rules may read as Not evaluated. An absent SecurityGroupIngress is Not evaluated, as the issue requires, and I don't know whether Cloud Control omits the key for an empty list. An explicit [] reads as evaluated.
  • "Optional" means separate, not switched off. The issue calls this an optional extension. The card always shows and only reads the inventory, so there is no setting to turn it off. Tell me if you want one.
  • No separate Scan failed state. The inventory records "complete" or "partial" and nothing per service, so a failed service shows through the partial-scan notice. The Insights page reports a scan that fails outright, as it already did, and the card then shows the previous inventory's results or Not scanned.
  • Filtering but no column sorting. Rows are ordered findings first, then Not evaluated, then passes, with a status filter.
  • Only TCP counts for RDP. RDP can also use UDP 3389, but a UDP-only rule doesn't trigger this finding.
  • A public rule isn't proof of exposure. The check doesn't look at whether the group is attached to anything, and the manual check says to confirm that.
  • Merging: this branch has main merged in, including Freeze a billing period as an immutable month-end snapshot #82. CHANGELOG.md and src/analytics.rs may conflict again with Export a monthly cloud cost review #84 and Land invoice reconciliation on main #86; both are adjacent additions, so keep both sides.

Testing

Run locally on Windows against this branch:

  • cargo test: 594 passed, 2 ignored, after merging main. New tests cover public SSH and RDP, IPv6, ranges, all traffic, restricted ingress, absent and undecodable configuration, partial scans and deterministic output. The existing Insights tests pass unchanged.
  • cargo clippy --all-targets -- -D warnings and cargo fmt --check: clean.
  • cargo +nightly-2026-07-28 check --lib --target wasm32-unknown-unknown: passes. This is a type-check, not the full build-web.sh.

Not tested in a real window. Nothing here has been clicked. Please check on desktop, using demo data:

  • Insights shows the card below the cost findings, with one finding, one Not evaluated and one pass.
  • The cost findings and their totals match what they were before.
  • A row opens with its evidence, and the filter keeps working around it.
  • Keyboard: Tab reaches a row, and Enter or Space opens it.
  • The card fits at minimum window width and in 简体中文.

🤖 Generated with Claude Code

JetSquirrel and others added 4 commits November 3, 2026 13:00
Closes #80

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	CHANGELOG.md
#	src/analytics.rs
@JetSquirrel
JetSquirrel merged commit ef99048 into main Nov 3, 2026
4 checks passed
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.

feat(insights): optional security configuration findings [P2]

1 participant