feat(cloud-security): cloud tests v2 — services, remediation, multi-provider adapters#2493
feat(cloud-security): cloud tests v2 — services, remediation, multi-provider adapters#2493
Conversation
…ti-provider adapters Major upgrade to cloud security scanning and remediation across AWS, Azure, and GCP: - Add 45 AWS service-specific adapters (S3, IAM, RDS, Lambda, ECS, etc.) - Add 13 Azure service adapters (AKS, Key Vault, Entra ID, Cosmos DB, etc.) - Add GCP remediation service with AI-driven fix generation - Add remediation controller with preview/execute/rollback flow - Add batch remediation support with Trigger.dev task - Add services grid UI for grouping findings by cloud service - Add integration provider detail pages with connection management - Add scheduled scan popover and activity tracking - Extend integration platform with services metadata support Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryHigh Risk Overview Expands cloud-security API capabilities with new endpoints for Updates auth for service tokens: Reviewed by Cursor Bugbot for commit aef367b. Bugbot is set up for automated code reviews on this repo. Configure here. |
- Fix Azure remediation always recording 'success' regardless of verification outcome (was `verified ? 'success' : 'success'`) - Remove InvalidInputException from idempotent success list in AWS executor — it indicates real validation errors, not duplicates - Re-check blocked commands after fuzzy match resolution to prevent bypass via AI-generated command name variants - Remove dead code ensureProvidersRegistered (superseded by azure-command-executor's auto-registration) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Azure validator: parse URLs with new URL() and check hostname against
allowlist instead of using .includes() substring match (CodeQL fix)
- GCP validator: same — parse hostname properly, check against
*.googleapis.com instead of substring match (CodeQL fix)
- Azure detectNeededRole: return null when no specific role matches
instead of always falling back to Contributor (privilege escalation fix)
- Pre-flight ensureWriteAccess now passes a matching keyword to
explicitly trigger the Contributor role condition
The GCP security service errorText.includes('securitycenter.googleapis.com')
is a CodeQL false positive — it checks error message content, not URLs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove redundant securitycenter.googleapis.com substring check in GCP error detection — already covered by 'Security Command Center API' and 'has not been used' conditions (CodeQL fix) - Allow rollback of 'unverified' remediation actions across all three providers (AWS, Azure, GCP) — the previous fix introduced 'unverified' status but rollback only accepted 'success', making unverified actions that changed infrastructure impossible to undo - Clone step.params before passing to executeAwsCommand to prevent normaliseInputParams from mutating the original plan objects, which corrupts the plan cache and stored appliedState Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Service tokens now verify that the x-user-id header references a real member of the target organization before accepting it. Previously, any arbitrary user ID was trusted without validation, which could create misleading audit trails. Also removes accidentally committed generated Prisma schema files (apps/*/prisma/schema.prisma) that are build artifacts from generate-prisma-client-js.js. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The two patterns got merged into one nonsensical line during rebase. Restore the original .superpowers/* coverage and add .claude/worktrees/ as a separate entry. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…gner Root package.json pinned @aws-sdk/client-s3 to 3.1013.0 which hoisted over the app's ^3.859.0, making it incompatible with @aws-sdk/s3-request-presigner (getSignedUrl type error). AWS SDK deps belong in apps/api/package.json only. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The app had @aws-sdk/client-s3@^3.859.0 while the api added 30+ AWS SDK clients at ^3.948.0. Bun hoisted the newer @smithy/types which was incompatible with the app's older s3-request-presigner, causing a type error on getSignedUrl. Bumped all app AWS SDK deps to ^3.948.0 to match. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BASELINE_SERVICES had 'iam' but the IAM adapter's serviceId is 'iam-analyzer'. When service filtering was active, IAM security checks were silently skipped from baseline scans. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both apps now use the exact same version, eliminating the duplicate nested @smithy/types that caused the getSignedUrl type error on Vercel. The ^3.948.0 range wasn't enough — bun resolved presigner to 3.957.0 which bundled @smithy/types@4.11.0 while client-s3@3.1013.0 used @smithy/types@4.13.1. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The auto-rollback path in executePlanSteps passed rbStep.params directly to executeAwsCommand, unlike the normal path which uses structuredClone. normaliseInputParams mutates in place, corrupting the stored rollback steps. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bun on Vercel resolves duplicate @smithy/types copies for client-s3 and s3-request-presigner even when pinned to the same version. This causes a private property 'handlers' type conflict on S3Client. Added root-level pins to force hoisting and a typed wrapper for getSignedUrl that uses the client-s3 types directly, bypassing the class identity check while keeping full type safety. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TypeScript requires the intermediate 'unknown' cast when the source and target types have incompatible private properties (separate declarations of 'handlers' from duplicate @smithy packages). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
serverApi.post returns typed {} by default. Added generic type param
for the batch create response in both cloud-tests and integrations
batch-fix actions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The STATUS_CONFIG map included needs_permissions but the FindingStatus union type didn't, causing a Vercel build type error. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…hProgress phase The component compared progress.phase against 'retrying' and 'waiting_for_permissions' but the type only included 'running', 'scanning', 'done', 'cancelled'. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… types Added permChecksLeft to BatchProgress, and key + severity to FindingProgress to match all runtime property accesses in the component. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
findingsResponse?.mutate?.() was never declared or imported. Replaced with the existing onComplete prop callback which triggers the parent to refresh findings data. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PROVIDER_FIELDS was typed as Record<'aws', ...> but accessed with 'gcp' | 'azure' | 'aws'. Changed to Partial<Record<...>> with guards for undefined (GCP/Azure use OAuth, not credential fields). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Created shared @/lib/s3-presigner.ts wrapper that handles the @smithy/types duplicate class identity issue. Updated all 6 files that import getSignedUrl to use the shared wrapper instead of importing directly from @aws-sdk/s3-request-presigner. Also fixed EmptyState PROVIDER_FIELDS type for multi-provider support. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The app uses @db/server for Prisma client, not @db directly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 827ca8d. Configure here.
| logger.warn(`Rollback step ${r} failed: ${err instanceof Error ? err.message : String(err)}`); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Auto-rollback skips first completed step on Azure failure
Medium Severity
When a fix step fails, auto-rollback only triggers when i > 0, which means if step index 1 (the second step) fails, only step 0 is rolled back. However, the failed step's result is pushed to results before the success check, so results includes the failed entry. This is inconsistent with the AWS executor pattern where failed steps are not pushed. More critically, the convention states rollbackSteps[i] undoes fixSteps[i], but the rollback loop starts at Math.min(i, autoRollbackSteps.length) - 1, which skips the rollback for step i itself if step i partially executed before failing.
Reviewed by Cursor Bugbot for commit 827ca8d. Configure here.
…y else branch TypeScript narrowing already excludes 'needs_permissions' from retry.status in the final else block (handled by prior else-if). The guard was always true, causing a build error on Vercel. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>


Summary
Major upgrade to cloud security scanning and remediation across AWS, Azure, and GCP:
servicesmetadata on manifests, services controller, scheduled scan popoverKey files
apps/api/src/cloud-security/providers/aws/*.adapter.ts(45 files)apps/api/src/cloud-security/providers/azure/*.adapter.ts(13 files)remediation.controller.ts,remediation.service.ts,*-remediation.service.tsapps/app/src/trigger/tasks/cloud-security/remediate-batch.tscloud-tests/components/,integrations/[slug]/components/remediation-action.prisma,remediation-batch.prismaConflict resolution notes (rebased onto main)
syncDefinitionsupport with ourservicessupport across all layers (Prisma, types, repo, controller, manifest loader)Test plan
npx jest src/cloud-security --passWithNoTestsfor API testsnpx turbo run typecheck🤖 Generated with Claude Code