Skip to content

feat(aws): expand SES/STS/Secrets Manager tool coverage, fix API alignment gaps#5450

Open
waleedlatif1 wants to merge 4 commits into
stagingfrom
validate/aws-ses-sts-secretsmanager
Open

feat(aws): expand SES/STS/Secrets Manager tool coverage, fix API alignment gaps#5450
waleedlatif1 wants to merge 4 commits into
stagingfrom
validate/aws-ses-sts-secretsmanager

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Ran a full /validate-integration audit on the SES, STS, and Secrets Manager integrations against live AWS API docs
  • Closed all high-value coverage gaps found: 10 new SES tools (suppression list management, email identity CRUD, template update, configuration set creation, custom verification email), 2 new STS tools (AssumeRoleWithWebIdentity, AssumeRoleWithSAML) plus session-tag/policy-ARN support on assume_role, 5 new Secrets Manager tools (describe_secret, tag_resource, untag_resource, restore_secret, rotate_secret)
  • Fixed a real defect in secrets_manager_list_secrets that silently dropped rotation/version metadata the block's own bundled templates relied on
  • A second independent validation pass caught two SES bugs before shipping: create_configuration_set was silently dropping httpsPolicy when no customRedirectDomain was set (now validated with a clear 400), and list_suppressed_destinations wasn't validating the reasons filter against AWS's BOUNCE/COMPLAINT enum (now rejects invalid values instead of surfacing a generic 500)
  • Normalized tool versions to 1.0.0 and alphabetized the Secrets Manager registry section
  • All 31 tools (original + new) verified param-by-param and field-by-field against live AWS API docs; confirmed fully backwards compatible — no existing param, response field, or tool ID was renamed or removed

Type of Change

  • New feature (tool coverage expansion)
  • Bug fix (SES config-set/suppression validation gaps, Secrets Manager list_secrets missing fields)

Testing

  • Two independent rounds of live-AWS-doc validation via parallel subagents, plus manual re-verification of the two bugs found in round two
  • bunx tsc --noEmit, bun run lint, bun run check:api-validation all pass

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…nment gaps

- SES: add suppression list management, email identity CRUD, template
  update, configuration set creation, custom verification email (10
  new tools); fix silent httpsPolicy drop in create_configuration_set
  and unvalidated suppression reason enum in list_suppressed_destinations
- STS: add AssumeRoleWithWebIdentity and AssumeRoleWithSAML (unsigned,
  no static credentials required); extend assume_role with
  policyArns/tags/transitiveTagKeys session params
- Secrets Manager: add describe_secret, tag_resource, untag_resource,
  restore_secret, rotate_secret; fix list_secrets dropping
  rotation/version metadata fields; normalize tool versions to 1.0.0
  and alphabetize registry entries

All 31 tools verified param-by-param against live AWS API docs across
two independent audit passes.
@vercel

vercel Bot commented Jul 6, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 6, 2026 11:27pm

Request Review

@cursor

cursor Bot commented Jul 6, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Large additive surface in auth (federated STS, temporary credentials), secret rotation/deletion restore, and SES sending identity/suppression controls; mistakes in workflows could affect access or deliverability despite existing internal auth on routes.

Overview
Expands AWS Secrets Manager, SES v2, and STS workflow integrations with many new operations, matching API routes, Zod contracts, block UI wiring, docs, and integrations.json metadata.

Secrets Manager gains describe, tag/untag, restore, and rotate actions; list secrets responses now include rotation rules, version stages, and related dates so list output matches what governance templates expect.

SES adds template updates, account suppression list CRUD/list, email identity create/get/delete, configuration set creation, and custom verification email sends, with stricter validation (e.g. suppression reasons enum, configuration set httpsPolicy requiring a redirect domain).

STS adds assume role with web identity and assume role with SAML (no static keys on those paths via an unauthenticated regional client), and extends classic assume role with managed policyArns, session tags, and transitiveTagKeys.

Reviewed by Cursor Bugbot for commit b94cf1d. Configure here.

Comment thread apps/sim/app/api/tools/ses/create-configuration-set/route.ts
Comment thread apps/sim/lib/api/contracts/tools/aws/secrets-manager-rotate-secret.ts Outdated
Comment thread apps/sim/lib/api/contracts/tools/aws/ses-create-configuration-set.ts Outdated
Comment thread apps/sim/lib/api/contracts/tools/aws/ses-create-email-identity.ts Outdated
@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR expands AWS tool coverage across SES (10 new tools), STS (2 new tools + session-tag/policy-ARN support on assume_role), and Secrets Manager (5 new tools), and fixes two SES validation defects found during the audit: create_configuration_set silently dropped httpsPolicy and list_suppressed_destinations passed unsanitised suppression reasons straight to AWS.

  • SES: adds suppression-list CRUD, email-identity CRUD, template update, configuration-set creation, and custom-verification-email; the httpsPolicy/customRedirectDomain co-dependency is now enforced by a contract-level superRefine, and suppressedReasons is validated against the BOUNCE/COMPLAINT enum before the AWS call.
  • STS: AssumeRoleWithWebIdentity and AssumeRoleWithSAML use a credential-free STSClient (correct for unsigned requests); assume_role gains policyArns, session tags (validated as a JSON object in the contract), and transitiveTagKeys.
  • Secrets Manager: list_secrets now returns rotationRules, lastRotatedDate, nextRotationDate, deletedDate, and secretVersionsToStages; five new operations cover describe_secret, tag_resource, untag_resource, restore_secret, and rotate_secret with mutex enforcement for automaticallyAfterDays/scheduleExpression.

Confidence Score: 5/5

The change is additive — all new routes, tools, and contracts. No existing tool IDs, params, or response fields were removed or renamed. Both validation defects called out in the PR description are fixed.

All 17 new routes use Zod contracts for input validation; critical invariants (BOUNCE/COMPLAINT enum, httpsPolicy co-dependency, JSON-object tags, mutually-exclusive rotation fields) are enforced before any AWS call. Client lifecycle is consistently managed with try/finally. The only findings are minor defensive-coding and documentation nits that do not affect correctness in the current call paths.

apps/sim/app/api/tools/sts/utils.ts — parseTags lacks a defensive try/catch around JSON.parse (safe in current paths due to contract validation, but worth hardening).

Important Files Changed

Filename Overview
apps/sim/app/api/tools/ses/utils.ts Adds 9 new SES utility functions. Correct SDK usage and safe null-coalescing throughout.
apps/sim/app/api/tools/sts/utils.ts Adds createUnauthenticatedSTSClient and new assumeRoleWithWebIdentity/assumeRoleWithSAML functions. parseTags calls JSON.parse without try/catch, relying on upstream contract validation for safety.
apps/sim/lib/api/contracts/tools/aws/ses-create-configuration-set.ts New contract with correct enum validation for suppressedReasons and a superRefine ensuring httpsPolicy requires customRedirectDomain.
apps/sim/lib/api/contracts/tools/aws/ses-list-suppressed-destinations.ts reasons field is z.string().nullish() with no enum validation at the contract layer; the route handler performs the BOUNCE/COMPLAINT check. Works correctly but inconsistent with ses-create-configuration-set.
apps/sim/lib/api/contracts/tools/aws/secrets-manager-rotate-secret.ts New rotate-secret contract with superRefine rejecting concurrent use of automaticallyAfterDays and scheduleExpression.
apps/sim/app/api/tools/secrets_manager/utils.ts Adds describeSecret, tagResource, untagResource, restoreSecret, rotateSecret utilities; enriches listSecrets response with rotation and version metadata.
apps/sim/tools/registry.ts Registers 17 new tools (10 SES, 5 Secrets Manager, 2 STS). Consistent with existing registry patterns.
scripts/check-api-validation-contracts.ts Baseline updated from 887 to 904 routes; nonZodRoutes stays at 0.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Client as Tool / Block
    participant Route as Next.js Route Handler
    participant Contract as Zod Contract
    participant Util as AWS Utility fn
    participant AWS as AWS API

    Client->>Route: "POST /api/tools/{service}/{operation}"
    Route->>Route: checkInternalAuth()
    Route->>Contract: parseToolRequest(contract, request)
    Contract-->>Route: 400 if validation fails
    Route->>Util: call utility fn
    Util->>AWS: SDK Command
    AWS-->>Util: response
    Util-->>Route: mapped response object
    Route-->>Client: 200 NextResponse.json(result)
    Note over Route,Util: client.destroy() in finally block
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Client as Tool / Block
    participant Route as Next.js Route Handler
    participant Contract as Zod Contract
    participant Util as AWS Utility fn
    participant AWS as AWS API

    Client->>Route: "POST /api/tools/{service}/{operation}"
    Route->>Route: checkInternalAuth()
    Route->>Contract: parseToolRequest(contract, request)
    Contract-->>Route: 400 if validation fails
    Route->>Util: call utility fn
    Util->>AWS: SDK Command
    AWS-->>Util: response
    Util-->>Route: mapped response object
    Route-->>Client: 200 NextResponse.json(result)
    Note over Route,Util: client.destroy() in finally block
Loading

Reviews (4): Last reviewed commit: "fix(ses): stop coercing switch string 'f..." | Re-trigger Greptile

Comment thread apps/sim/app/api/tools/ses/create-configuration-set/route.ts
Comment thread apps/sim/app/api/tools/ses/create-email-identity/route.ts Outdated
Comment thread apps/sim/app/api/tools/sts/utils.ts
…Manager rotation

- ses_create_configuration_set: validate suppressedReasons against
  BOUNCE/COMPLAINT enum before calling AWS (was silently reaching AWS
  as a generic 500 for bad values); tags now a proper Zod array schema
  instead of a string with route-side JSON.parse
- ses_create_email_identity: dkimSigningAttributes and tags now proper
  Zod object/array schemas instead of strings with route-side
  JSON.parse, matching the pattern used elsewhere (e.g. sts_assume_role
  tags, secrets_manager_tag_resource)
- secrets_manager_rotate_secret: reject automaticallyAfterDays and
  scheduleExpression when both are supplied — AWS RotationRules
  accepts only one
- sts createUnauthenticatedSTSClient: corrected a misleading comment
  claiming these calls are fully unsigned; the SDK still falls through
  its default credential provider chain
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile please re-review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/blocks/blocks/ses.ts Outdated
The SES block declared the tags and dkimSigningAttributes block inputs
as 'string' instead of 'json', so the generic block executor never
parsed the JSON code-editor value before forwarding it — workflow runs
sent a raw JSON string where the contract now expects a structured
object/array, failing validation. Also corrected the corresponding
tool param TypeScript types, which were still typed as string | null.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile please re-review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/blocks/blocks/ses.ts Outdated
…guration_set

Boolean('false') evaluates to true, so turning off the
reputationMetricsEnabled or sendingEnabled switch sent the opposite of
the user's choice to SES. Match the established === 'true' string
comparison pattern used elsewhere in the codebase.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile please re-review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b94cf1d. Configure here.

durationSeconds: { type: 'string', description: 'Session duration in seconds' },
policy: { type: 'string', description: 'JSON IAM session policy to restrict permissions' },
policyArns: { type: 'string', description: 'Comma-separated managed policy ARNs' },
tags: { type: 'json', description: 'Session tags (Key/Value pairs) for ABAC' },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

STS session tags schema mismatch

Medium Severity

For assume_role, session tags are serialized to a JSON string for the STS API, but the block marks tags as json, so the generic executor parses that string into an object before the tool request. The route contract expects tags as a string, so valid block runs fail request validation instead of calling AWS.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b94cf1d. Configure here.

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.

1 participant