Skip to content

[comp] Production Deploy#3045

Merged
tofikwest merged 14 commits into
releasefrom
main
Jun 5, 2026
Merged

[comp] Production Deploy#3045
tofikwest merged 14 commits into
releasefrom
main

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented Jun 5, 2026

This is an automated pull request to release the candidate branch into production, which will trigger a deployment.
It was created by the [Production PR] action.


Summary by cubic

Fixes Cloud Tests to scope findings to the selected account and labels the connection picker. Adds presigned uploads for attachments, knowledge-base documents, and offboarding evidence with a true 100MB limit enforced via shared constants and S3 HEAD checks, and hardens automation publishing with validated input, clear errors, and a default 120s SDK/MCP request timeout.

  • Bug Fixes

    • Scoped findings and project pills strictly to the selected connection via filterFindingsByConnection(...).
    • Rejected oversized presigned uploads via an S3 HEAD check before download; aligned inline base64 validation to the full 100MB using shared upload-limits.
    • Validated automation version payloads with CreateVersionDto, trimmed whitespace-only scriptKey, and mapped duplicate versions to 409 and missing automations to 404.
  • New Features

    • Accepted s3Key from /v1/uploads/presign for attachments, knowledge-base documents, and offboarding evidence (added document purpose); services resolve bytes from fileData or s3Key. The MCP overlay removes fileData for these tools and disables automation-authoring endpoints until script generation is exposed.
    • Labeled the cloud connection selector by provider (AWS “Account”, Azure “Subscription”, others “Connection”).
    • Baked a 120s x-speakeasy-timeout into the public OpenAPI for generated SDK/MCP requests.

Written for commit 987afd9. Summary will update on new commits.

Review in cubic

github-actions Bot and others added 6 commits June 5, 2026 03:19
…/evidence)

Customer-reported: the MCP server times out on uploads. Root cause is the
documented one — these tools take the whole file as base64 inside the tool
argument, so the LLM must emit the entire file token-by-token, which is
impractically slow and hits the client's ~4-min timeout. Questionnaire and
policy-PDF were already migrated to the presigned-upload pattern; the rest
were not.

Migrates the three tools the customer hit to the same pattern: accept an
optional `s3Key` (from POST /v1/uploads/presign) alongside `fileData`. The
service resolves the bytes from whichever is provided via
UploadsService.readUploadAsBase64, which enforces that the key belongs to the
caller's org. The MCP overlay strips `fileData` from these tools so agents
must use create-upload-url -> PUT to S3 -> pass the s3Key; the base spec keeps
fileData for the web UI / direct callers.

- attachments (upload-task-attachment): DTO + service + module
- knowledge-base (upload-document): DTO + service + module; also added the
  missing @ApiProperty decorators so the MCP tool finally has a real schema
- offboarding-checklist (complete-checklist-item, upload-evidence): DTO +
  service; delegates to the now-fixed AttachmentsService
- UploadPurpose: added `document`
- regenerated packages/docs/openapi.json (carries the new s3Key fields; also
  synced some pre-existing drift that was stale in the committed spec)

Tests: new attachments.service.spec (s3Key path + neither->400); extended
knowledge-base.service.spec (s3Key path + neither->400); offboarding specs
still green. typecheck clean; AppModule boots (DI wiring verified). The MCP
generator stays healthy: 0 operations declare more than one security scheme.

Out of scope (separate issues): create-version automation script-generation
also times out, but that is heavy synchronous AI work, not base64 — needs an
async job pattern.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Customers with multiple AWS accounts couldn't filter the findings list down to
one account — selecting a different account in the connection selector did
nothing, the list always showed every account's findings merged.

Root cause: the per-section findings filter used
`f.providerSlug === providerSlug || f.connectionId === connectionId`. The first
clause matches EVERY finding of the provider, so the connection (account) clause
never narrowed anything. The selector switched the active connectionId, but the
filter ignored it.

- Extract `filterFindingsByConnection(findings, connectionId)` and use it for
  both the findings list and the project-name pills in CloudTestsSection, so the
  view is scoped strictly to the selected connection (= selected account).
  Every finding carries a required connectionId and each section renders with
  the selected connection's id, so this is safe (nothing is hidden).
- Test: filterFindingsByConnection scopes to one account and does not leak
  another account of the same provider (regression guard).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Three related hardening fixes for the automation endpoints that customers
hit through the MCP server.

1. create-version no longer 500s on a malformed body. The endpoint used an
   inline, untyped @Body() that the global ValidationPipe could not see, so a
   missing version/scriptKey reached Prisma and threw a non-null violation
   (raw 500). Add a validated, documented CreateVersionDto and map Prisma
   failures to clean responses: duplicate version -> 409, missing -> 404.

2. Bake a finite default request timeout (x-speakeasy-timeout = 120s) into the
   generated SDK and MCP server. Without it the generated request functions
   resolve their timeout to -1 ("no timeout"), so a hung upstream call leaves
   the MCP fetch dangling forever and the client marks the whole connection
   unhealthy. 120s covers our slowest endpoints while staying under the ALB's
   300s idle timeout.

3. Hide the two automation-authoring tools (create-automation, create-version)
   from the MCP surface. A working automation needs its evidence script
   generated, and that step lives only in the enterprise-api browser chat, so
   over MCP these POSTs only ever create an empty shell plus a version row
   pointing at a script that was never generated. Disable them via the
   generation overlay until script generation is a first-class endpoint; the
   HTTP endpoints stay live for the web UI.

openapi.json is edited surgically (root key only) to avoid clobbering the open
uploads PR (#3042); the full create-version body appears on the next regen.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The connection selector doubles as the account filter, but it had no label, so
it wasn't obvious that picking an item scopes the findings to that account.
Add a provider-aware label next to it — "Account" for AWS, "Subscription" for
Azure, "Connection" for GCP — and use the same term in the placeholder.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
fix(cloud-security): scope Cloud Tests findings to the selected account
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 5, 2026

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

Project Deployment Actions Updated (UTC)
app (staging) Ready Ready Preview, Comment Jun 5, 2026 3:40pm
comp-framework-editor (staging) Ready Ready Preview, Comment Jun 5, 2026 3:40pm
portal (staging) Ready Ready Preview, Comment Jun 5, 2026 3:40pm

Request Review

Addresses the cubic review on PR #3042.

A presigned S3 PUT cannot enforce a size limit, so an authenticated client
could upload an arbitrarily large file and then call a feature endpoint that
reads it back via readUploadAsBase64 -> getObjectAsBuffer, loading the whole
object into memory (plus ~1.33x for base64) before any size check ran. That is
an avoidable OOM/DoS vector shared by attachment, knowledge-base, and
questionnaire uploads.

- Add getObjectContentLength (a HEAD request) and check the object size BEFORE
  downloading in readUploadAsBase64; reject anything over a configurable
  ceiling (default 100MB, matching the feature services' decoded-buffer limit).
- Add the missing @maxlength(134_217_728) + @IsBase64() to UploadDocumentDto's
  fileData, matching the other migrated upload DTOs (caps the inline base64
  path at the validation layer).
- Cover both with unit tests: oversized rejected before download, caller
  maxBytes honored, unknown content-length still proceeds, HEAD failure gives a
  clear error.

Issues identified by cubic.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

No issues found across 4 files

Confidence score: 5/5

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

Re-trigger cubic

tofikwest and others added 3 commits June 5, 2026 11:10
The base64 max-length on the inline fileData fields was 134_217_728, which is
the encoded length of only 96 MiB of data — but the web UI dropzones and the
feature services both allow 100 MiB. So a 96-100 MiB file a user can pick in
the UI would be rejected with a 400 at validation. Adding that same cap to
UploadDocumentDto (the cubic fix) would have introduced this break for
knowledge-base uploads, whose dropzone allows 100 MiB.

- Add upload-limits.ts as the single source of truth: MAX_UPLOAD_BYTES
  (100 MiB) and MAX_UPLOAD_BASE64_LENGTH (its base64 length, 139,810,136).
- Point all three inline upload DTOs (attachment, knowledge-base document,
  offboarding evidence) and the presigned-read ceiling at it. Loosening a cap
  only accepts more (still <= the 100 MiB the services enforce on decode), so
  no currently-valid upload is newly rejected.
- Verified the web UI sends raw, prefix-stripped base64, so the @IsBase64()
  check accepts existing UI uploads unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
fix(api): accept presigned s3Key for MCP uploads (attachment/document/evidence)
tofikwest and others added 2 commits June 5, 2026 11:24
@isnotempty() treats a whitespace-only string ("   ", "\t\n") as valid, so a
blank scriptKey could pass validation and persist a version row whose script
can never be fetched at runtime. Trim the value first (type-guarded so
non-strings still hit @IsString) so a blank collapses to "" and @isnotempty
rejects it; legitimate keys are normalized.

Issue identified by cubic on PR #3044.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…rdening

# Conflicts:
#	apps/mcp-server/.speakeasy/mcp-uploads-overlay.yaml
fix(api): harden task automations for MCP/API clients
@tofikwest tofikwest merged commit 7ccf6ea into release Jun 5, 2026
14 checks passed
@claudfuen
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.72.0 🎉

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants