Skip to content

fix(cloud-security): run task evidence checks against all connected accounts#3067

Merged
tofikwest merged 4 commits into
mainfrom
tofik/aws-checks-run-all-accounts
Jun 9, 2026
Merged

fix(cloud-security): run task evidence checks against all connected accounts#3067
tofikwest merged 4 commits into
mainfrom
tofik/aws-checks-run-all-accounts

Conversation

@tofikwest

@tofikwest tofikwest commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Problem

A task's evidence check (e.g. AWS S3 — default encryption enabled) only ran against the customer's first connected account. The run-check endpoint ran the single referenced connectionId, and the task card displayed only the latest single run. Customers with multiple AWS accounts (e.g. Dustin) saw results for just one account.

Fix

Manual Run → all accounts. runCheckForTask now resolves the provider from the referenced connection, then runs the check against every active account of that provider (extracted into a resilient per-connection helper runCheckForConnection). Each account keeps its own IntegrationCheckRun — required because reconciliation diffs findingKeys per connectionId. Task status is aggregated across all accounts (any finding → failed; else any pass → done), removing the previous last-writer race. A bad account is recorded as a failed run and the batch continues.

Scheduler → already runs every account (run-integration-checks-schedule.ts loops all active connections, one run per account/task). No run-level change needed — the same display fix below surfaces all accounts for scheduled runs, identical to manual.

Display → shows every account. GET /runs now returns via findLatestPerConnectionAndCheckByTask, which guarantees the latest run of every (connection, check) group (a flat row limit could bury an account behind a busier one's re-runs) plus a bounded history tail, and adds connectionId + a connectionLabel. The task card groups runs per account, labels each, and aggregates the header. Single-account layout is unchanged.

All AWS services for free — the change is account-level, so s3, cloudtrail, ec2, iam, kms, rds all benefit; findings are already account-labelled via #3065.

Notes

  • Extracted CheckRunItem/GroupedCheckRuns into check-run-history.tsx (source was 1610 lines) + pure grouping helpers. DS migration of the moved legacy imports is intentionally out of scope (verbatim move; the parent tree still uses @trycompai/ui/lucide-react, and DS Badge/Button omit className so a naive swap would break the build — belongs in a dedicated PR).
  • Scheduler task-status stays per-connection (only the manual path aggregates) — a separate decision, not bundled here.
  • Sequential manual loop commits each account's run as it completes; fine for a handful of accounts. If customers connect many, move Run to the async Trigger.dev path later.

Tests

  • API (jest): per-account run loop + aggregate status + bad-account resilience (controller); latest-per-account completeness under a re-run burst (repository); account-label branches (util). 15 pass.
  • App (vitest): run grouping + latest-per-account summary. 4 pass.

Verification (post-deploy, impersonated, 3 AWS accounts)

  • Manual: open a task with the S3 check → click Run → all 3 accounts' runs appear, each labelled, header sums all 3.
  • Scheduler: trigger the orchestrator → same card shows all 3, identical to manual.
  • Repeat for a non-S3 AWS check (e.g. IAM).

🤖 Generated with Claude Code


Summary by cubic

Run task evidence checks against all connected accounts for the provider and show per‑account results in the task UI. Hardens the runs API with org scoping, safe history limits, and rejection of inactive manual runs.

  • Bug Fixes

    • Manual “Run” now executes the check for every active account of the provider (one run per connection), aggregates task status across accounts (any finding → failed; else any pass → done), records per‑account errors without stopping, and rejects inactive referenced connections up front.
    • /runs guarantees the latest run per (connection, check) with a bounded history window; clamps ?limit= to 1–50 (default 5); tenant‑scopes the request by verifying the task belongs to the caller’s org (404 otherwise); and returns connectionId plus a human‑readable connection label.
  • UI Improvements

    • Task card groups runs by account, labels each account, and aggregates the header across accounts; single‑account layout is unchanged.

Written for commit 612d624. Summary will update on new commits.

Review in cubic

…ccounts

A task's evidence check (e.g. AWS S3 — default encryption) only ran against
the customer's FIRST connected account: the run-check endpoint ran the single
referenced connectionId, and the task card showed only the latest single run.
Customers with multiple AWS accounts saw results for just one of them.

Manual Run now runs the check against EVERY active account of the provider
(one IntegrationCheckRun per account, preserving reconciliation's per-connection
findingKey diffing) and aggregates task status across all of them. The
scheduler already ran every account per-connection, so it needs no run-level
change — the same display fix surfaces all accounts for scheduled runs too.

Display: /runs now guarantees the latest run per (connection, check) via a
groupBy + completeness query (a flat row limit could bury an account behind a
busier one's re-runs) and returns connectionId + a connection label. The task
card groups runs per account and aggregates the header across accounts;
single-account layout is unchanged. Covers all AWS check services (s3,
cloudtrail, ec2, iam, kms, rds) since the change is account-level, not
per-service.

Extracted CheckRunItem/GroupedCheckRuns into check-run-history.tsx (the source
file was 1610 lines) and added pure grouping helpers. DS migration of the moved
legacy imports is intentionally out of scope (verbatim move; parent tree still
uses them).

Tests: per-account run loop + aggregate status + bad-account resilience
(controller), latest-per-account completeness under a re-run burst (repository),
account label branches (util), and run grouping/summary (app).

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

vercel Bot commented Jun 9, 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 9, 2026 8:57pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
app Skipped Skipped Jun 9, 2026 8:57pm
portal Skipped Skipped Jun 9, 2026 8:57pm

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 12 files

Confidence score: 3/5

  • There is some merge risk because both reported issues are medium severity (6/10) with high confidence, and each can affect runtime behavior in production paths.
  • In apps/api/src/integration-platform/repositories/check-run.repository.ts, unvalidated historyPerGroup is used in take, which can cause 500 errors or unexpectedly heavy database reads from malformed/large query inputs.
  • In apps/api/src/integration-platform/controllers/task-integrations.controller.ts, manual runs may execute checks for non-active connections due to fallback behavior, creating a concrete risk of incorrect check execution.
  • Pay close attention to apps/api/src/integration-platform/repositories/check-run.repository.ts, apps/api/src/integration-platform/controllers/task-integrations.controller.ts - input bounds/status validation gaps can lead to expensive queries and invalid manual-run execution.

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

Fix all with cubic | Re-trigger cubic

Comment thread apps/api/src/integration-platform/repositories/check-run.repository.ts Outdated
…onnections

Addresses two cubic review findings on PR #3067:

- check-run.repository.ts: clamp historyPerGroup (which flows from the
  user-supplied ?limit= query param via parseInt → possibly NaN/negative/huge)
  to [1, 50], defaulting to 5, so it can never produce an invalid Prisma take
  (500) or an unbounded, expensive read.
- task-integrations.controller.ts: restore the active-status guard on the
  referenced connection (dropped during the run-all-accounts refactor) so a
  manual run rejects an inactive connection up front; the empty-active fallback
  can now only ever contain a verified-active connection.

Tests: historyPerGroup clamp (oversized → cap, NaN/negative → default) and
inactive-connection rejection.

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 9, 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.

1 issue found across 12 files

Confidence score: 2/5

  • High merge risk: this is a concrete authorization gap (severity 8/10, confidence 8/10) with likely user-facing security impact, so this should be fixed before merging.
  • In apps/api/src/integration-platform/controllers/task-integrations.controller.ts, the runs endpoint queries by taskId without confirming the task belongs to the caller’s organization, which can expose cross-tenant run data.
  • Pay close attention to apps/api/src/integration-platform/controllers/task-integrations.controller.ts - enforce tenant scoping/ownership checks on taskId lookups in the runs endpoint.

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

Fix all with cubic | Re-trigger cubic

Addresses a cubic finding on PR #3067 (pre-existing on main): GET
:taskId/runs read check runs by taskId with no organization check, so an
arbitrary taskId from another org would leak cross-tenant run data (account
ids, connection labels, logs).

Add @organizationId and validate the task belongs to the caller's org (404
otherwise) before returning runs — mirroring runCheckForTask / getChecksForTask.

Test: rejects a task outside the caller's org and never queries runs.

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 9, 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 12 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 5046926 into main Jun 9, 2026
11 checks passed
@tofikwest tofikwest deleted the tofik/aws-checks-run-all-accounts branch June 9, 2026 21:04
claudfuen pushed a commit that referenced this pull request Jun 9, 2026
## [3.74.2](v3.74.1...v3.74.2) (2026-06-09)

### Bug Fixes

* **cloud-security:** run task evidence checks against all connected accounts ([bdb6b3b](bdb6b3b))
* **cloud-security:** tenant-scope the task check-runs endpoint ([612d624](612d624)), closes [#3067](#3067)
* **cloud-security:** validate run-history limit and reject inactive connections ([c82f9fc](c82f9fc))
* **people:** respect "Send portal invite email" opt-out when adding users ([18144fd](18144fd))
@claudfuen

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.74.2 🎉

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