Skip to content

fix(cloud-security): honor finding exceptions in integration task checks#3135

Merged
tofikwest merged 3 commits into
mainfrom
tofik/honor-finding-exceptions
Jun 15, 2026
Merged

fix(cloud-security): honor finding exceptions in integration task checks#3135
tofikwest merged 3 commits into
mainfrom
tofik/honor-finding-exceptions

Conversation

@tofikwest

@tofikwest tofikwest commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Problem

A customer (PRIMER) marked a deliberately-public S3 bucket as an exception (primer-production-reports-bucket, reason "reports deliberately public"), but the "S3 — public access blocked" task check still failed — both the "1 failed" card and the compliance task status — on every run after the exception was created.

Root cause: FindingException was honored only in the Cloud Tests findings view (cloud-security-query.getFindings). The integration task-check path (run paths + display) never consulted exceptions, so an excepted finding was hidden in one surface but kept failing the task in another.

Fix — one source of truth, applied everywhere a finding becomes pass/fail

This is the scalable part: the exception key format + active-filter now live in one place, so a future change can't honor an exception in one surface and miss another.

  • New ActiveExceptionSet / loadActiveExceptionSet (cloud-security/finding-exceptions.ts) — the single definition of "is this finding excepted?" (keyed by connectionId :: checkId :: resourceId, active = not revoked / not expired).
  • Cloud Tests refactored to use it (removes the duplicate private lookup — the two systems are now matched by construction).
  • Manual run-check + scheduled Trigger task: task status excludes excepted findings via shared countEffectiveFailures + decideTaskStatus, so a task whose only failures are excepted goes done — identical logic in both paths.
  • Task-check display (getTaskCheckRuns): excepted results are flagged (excepted: true) and dropped from the run's failedCount/status; the UI renders them as a muted "Exception" row instead of a red issue.

Safety

  • Additive — with no active exceptions the behavior is byte-for-byte identical (existing tests pass unchanged).
  • Fail-safe — if the exception lookup errors, it suppresses nothing (never hides a real finding).
  • Raw data untouchedIntegrationCheckResult.passed and the persisted run counts stay raw (audit intact); exceptions only affect derived status + display.
  • Consistency note: the scheduled path's old "execution error ⇒ task failed" was dropped so it matches the manual path — an execution error is indeterminate (it gates integrationLastRunAt → retry next tick), not a compliance failure.

Verification

  • ✅ 44 tests pass across 10 suites — incl. new specs for the shared helpers and exception scenarios (manual run goes done when the only finding is excepted; getTaskCheckRuns flags excepted + drops it from the failed count).
  • ✅ Changed API + app files type-clean.
  • The PRIMER case: with the existing active exception, the scheduled and manual runs will now mark the task done and the card will stop showing the bucket as failed.

Notes

🤖 Generated with Claude Code


Summary by cubic

Fixes task checks to honor finding exceptions across manual runs, scheduled runs, and the UI. Excepted findings no longer fail tasks, and status/display are consistent while keeping real execution errors visible.

  • Bug Fixes

    • Task status excludes excepted findings; a task with only excepted failures is marked done (even with 0 passing).
    • Run history flags excepted results, removes them from failed counts, and shows a muted “Exception”; failed → success rewrite happens only when failures were excepted, so execution-error runs stay failed.
    • Manual and scheduled paths use the same evaluation; lookup failures suppress nothing, and execution errors don’t drive status.
    • Added tests, including provider-agnostic coverage (AWS, GCP, Azure).
  • Refactors

    • Introduced ActiveExceptionSet/loadActiveExceptionSet as the single source of truth; Cloud Tests now use it too.
    • Added shared countEffectiveFailures and decideTaskStatus used by both run paths.
    • Raw check rows and persisted counts are unchanged; only derived status and display are adjusted.

Written for commit bd1b774. Summary will update on new commits.

Review in cubic

A finding marked as an exception (e.g. a deliberately-public S3 bucket) was
suppressed in the Cloud Tests findings view but still failed the corresponding
integration TASK check — both the compliance task status and the "N failed"
card — because only cloud-security-query applied exceptions.

Centralize the exception logic into one source of truth (ActiveExceptionSet /
loadActiveExceptionSet) and apply it everywhere a check result becomes pass/fail:

- Cloud Tests findings view refactored to use it (removes the duplicate; the two
  systems are now matched by construction).
- Manual run-check + scheduled Trigger task: task status excludes excepted
  findings (shared decideTaskStatus / countEffectiveFailures helpers), so a task
  whose only failures are excepted goes done — identical in both paths.
- Task-check display (getTaskCheckRuns): excepted results are flagged and dropped
  from the run's failed count/status; the UI renders them as "Exception".

Additive + fail-safe: with no exceptions the behavior is byte-for-byte identical,
and if the exception lookup errors it suppresses nothing (never hides a real
finding). Raw check results/counts are left untouched in the DB; exceptions only
affect derived status + display.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
comp-framework-editor Ready Ready Preview, Comment Jun 15, 2026 12:32am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
app Skipped Skipped Jun 15, 2026 12:32am
portal Skipped Skipped Jun 15, 2026 12:32am

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 10 files

Confidence score: 2/5

  • In apps/api/src/integration-platform/controllers/task-integrations.controller.ts, the failed→success rewrite can mark execution-error runs as successful when they have zero findings, which can hide real runtime failures and mislead downstream monitoring/reporting—gate the rewrite on explicit "excepted findings" state (not just zero findings) before merging.
  • In apps/api/src/trigger/integration-platform/run-task-integration-checks.ts, status may remain unchanged when all findings are excepted and there are no passing results, so scheduled runs can miss the intended "excepted-only => done" transition and appear stuck/incomplete—add explicit handling for the all-excepted/no-pass path and verify with a scheduled-run test case before merging.

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread apps/api/src/trigger/integration-platform/run-task-integration-checks.ts Outdated
Comment thread apps/api/src/integration-platform/controllers/task-integrations.controller.ts Outdated
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two P1 issues from cubic:

1. getTaskCheckRuns rewrote a failed run to success whenever the effective
   failed count was 0 — which also matched an execution-error run (status
   failed, failedCount 0 because the error produced no findings), hiding real
   runtime failures. Gate the rewrite on exceptedCount > 0 so only genuinely
   all-excepted runs are downgraded; error runs stay failed.

2. decideTaskStatus returned null (leave unchanged) when all findings were
   excepted AND there were no passing results, so an all-excepted task could
   stay stuck in its prior (failed) status. Add the raw totalFindings signal:
   if the check evaluated any resource and nothing effectively fails, it goes
   done; only a run that evaluated nothing (e.g. all errored) stays unchanged.
   Applied in both the manual and scheduled paths.

Added tests: all-excepted/no-passing -> done (helper + manual run), and an
execution-error run stays failed in the display.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tofikwest

Copy link
Copy Markdown
Contributor Author

@cubic-dev-ai review it

@cubic-dev-ai

cubic-dev-ai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review it

@tofikwest I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 10 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@tofikwest tofikwest merged commit e3a1495 into main Jun 15, 2026
11 checks passed
@tofikwest tofikwest deleted the tofik/honor-finding-exceptions branch June 15, 2026 00:41
@claudfuen

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.82.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants