Generated banner for Amazon Ses
Generated logo for Amazon Ses

Amazon Ses

AWSOfficialPublished by AWS

  • Skill
  • Workflow
  • Cloud and DevOps
  • Apache-2.0
  • No issues found

From the author

Guides Amazon SES onboarding for domain-based email sending. Covers identity configuration, production access, an optional first test send, and troubleshooting setup, authentication, or sending failures. Use when setting up SES, resuming incomplete onboarding, or leaving the sandbox. Does not cover inbound email or Mail Manager, SMS/voice, WhatsApp, SNS, Pinpoint, or WorkMail.
— the description by AWS

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured workflow for setting up Amazon SES for domain-based email sending. It assists users in configuring email identities, managing DKIM and custom MAIL FROM settings, and navigating the process of requesting production access from the SES sandbox. The skill ensures that all necessary AWS CLI operations are performed using the v2 API, validates inputs according to strict security rules, and helps troubleshoot common setup or authentication failures.

What it does

  • Configures domain identities for email sending in Amazon SES.
  • Manages DKIM and custom MAIL FROM domain authentication.
  • Guides users through the process of requesting production access.
  • Facilitates optional test email sends to verify configuration.
  • Troubleshoots common setup, authentication, and sending errors.
  • Validates all user-supplied inputs to ensure secure CLI execution.

When to use it

  • When setting up a new domain for email sending in Amazon SES.
  • When resuming an incomplete SES onboarding process.
  • When transitioning an account out of the SES sandbox.
  • When diagnosing issues like MessageRejected errors or failed identity verification.

Advantages

  • Automates complex multi-step AWS CLI configurations.
  • Ensures adherence to security best practices through input validation.
  • Provides clear guidance on state-based configuration to avoid redundant operations.
  • Maintains strict adherence to AWS v2 API requirements.

Usage examples

“Help me set up my domain example.com for Amazon SES.”
The agent will read the current account state, identify missing identity or DNS configurations, and guide you through the necessary steps to verify the domain.
“I am getting a MessageRejected error when trying to send email.”
The agent will check your current SES identity status and sandbox constraints to determine if the issue is due to an unverified sender or a restricted recipient.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/aws/amazon-ses/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip amazon-ses.zip -d .agents/skills

Documentation by AWS

Amazon SES

Overview

Recommended: Use the AWS MCP Server with SES permissions for sandboxed execution and CloudTrail audit logging. Without MCP: All operations use standard AWS CLI syntax (aws sesv2 ...).

Takes a developer who is not an email authentication expert from an empty AWS account to a real, authenticated email in their inbox, and on to production sending if AWS approves the request.

Read the account and identity state before touching anything, and complete only the parts of domain setup that are actually missing. Request production access only after domain setup is complete and the user has given explicit consent. A test send is optional: run it when the user asks for one, to a recipient the account's current state permits.

Routing

If the user wants to...Read
Get started with SES, set up email sending, send a first or test email, move out of the sandbox, or diagnose MessageRejected: Email address is not verifiedSES onboarding: zero to first delivered email
Set up a domain for sending, configure email authentication, or troubleshoot DKIMSetting up SES domain identity

Guardrail — where this skill's own files live (MCP vs local install)

This skill can be loaded two ways, and they resolve its own bundled files from different places. Determine how the skill was loaded before reading a reference:

  • Loaded through the AWS MCP retrieve_skill tool: the skill is not on the local filesystem. You MUST fetch each reference via retrieve_skill with the file parameter (e.g. file="references/onboarding.md"). Do NOT file_read these paths locally — they do not exist on disk.

  • Installed locally (e.g. ~/.kiro/skills/amazon-ses/, .kiro/skills/amazon-ses/, or ~/.claude/skills/amazon-ses/): read files from the local skill directory using the relative paths above.

This distinction applies only to the skill's own packaged files. User data and session artifacts are always read from and written to the user's working directory — never fetch or write customer data through retrieve_skill.

Critical Rules

  • MUST use the SES v2 API: aws sesv2 ..., never the v1 aws ses ... commands. A v1 command reports no error signalling the wrong API was chosen, so the mistake is silent, and the operations this journey needs — production-access requests, and DKIM plus MAIL FROM attributes in a single identity read — exist only in v2. Models trained on published CLI examples tend to default to the v1 syntax.

  • MUST NOT volunteer API version mechanics, internal limit figures, or other plumbing. Explain only what the user has to decide, consent to, pay for, or act on. Surface the rest only when they ask, when their problem turns on it, or when a reference file names the disclosure as required.

  • MUST ask for missing inputs in ONE question set rather than one at a time — and MUST NOT ask for inputs the request does not need. Scope the questions to what the user asked for: a request that already names the domain and MAIL FROM subdomain is a complete domain-setup request, so read state and execute rather than stalling for send-time or production-access inputs. If nothing is missing for the chosen scope, ask nothing.

  • MUST NOT ask which AWS CLI profile or Region to use while either can still be resolved. Honour --profile only if the user names one. Resolve the Region in this order, taking the first that yields a value: a Region the user named; AWS_REGION; AWS_DEFAULT_REGION; aws configure get region, adding --profile '{PROFILE}' when the user named a profile, since a profile can carry its own Region. That last command reads the CLI configuration files only and does not see the environment, which is why the two environment variables are checked separately and ahead of it. State the resolved Region before any mutation, because SES state is per-Region, and report the account and principal from aws sts get-caller-identity. Two cases, and only these two, are where you do ask: nothing in that chain yields a Region, because every aws sesv2 call fails without one; and aws sts get-caller-identity fails on expired or invalid credentials, in which case ask which account (profile) and Region to use once they are refreshed, because the configured defaults are no longer trustworthy. Fold either into the one question set rather than spending an extra turn on it.

  • MUST pass request payloads (change batches and message content) to the CLI as inline JSON strings, never as file:// paths — file:// is AWS-CLI-specific and does not resolve when the CLI is executed through the AWS MCP server.

  • MUST read current state before each step and skip steps already satisfied. In particular: never call create-email-identity for an identity that already exists (it returns AlreadyExistsException), and never re-run put-email-identity-dkim-signing-attributes on an identity whose DkimAttributes.Status is SUCCESS, because re-initialising can change its tokens. Gate that call on status, not on whether the published CNAMEs resolve — on a FAILED identity the records often do resolve and are simply not being honoured, which is what FAILED means, so resolving records are not a reason to withhold the recovery. The status-gated recovery paths, and the BYODKIM check that precedes them, are owned by setting-up-ses-domain-identity.md.

  • For domain setup, create a domain identity. Create an email-address identity only when the user explicitly chooses verification of that individual address.

Invariants

These hold everywhere in this skill. The reference files apply them, and may add workflow-specific detail on top of them — a reference may state how an invariant is checked at a particular step, or narrow it for that step's state. None of them may contradict or relax what is written here.

  • Domain setup complete means all three of these are true in one aws sesv2 get-email-identity response: VerifiedForSendingStatus is true, and DkimAttributes.Status is SUCCESS, and MailFromAttributes.MailFromDomainStatus is SUCCESS. Two of the three is not complete. While MailFromDomainStatus is PENDING, FAILED or TEMPORARY_FAILURE, AWS documents that SES uses the custom MAIL FROM fallback setting: with USE_DEFAULT_VALUE it sends using a subdomain of amazonses.com, so SPF validates but the envelope sender does not align with the From domain and DMARC cannot pass on its SPF leg; with REJECT_MESSAGE SES returns MailFromDomainNotVerified and does not attempt delivery. This is the gate the rest of the skill calls "domain setup complete".

  • Sandbox recipient rule. While ProductionAccessEnabled is false, AWS documents that you can only send to verified email addresses and domains, or to the Amazon SES mailbox simulator. That means, in the order this skill always presents them: (1) an address verified as its own email identity, (2) the Amazon SES mailbox simulator, or (3) any address at any verified domain in the account — not only the domain just set up. The restriction is on the recipient, not the sender: a fully verified sending domain does not lift it, and you must never attempt to work around it. Production access is governed by ProductionAccessEnabled alone — while it is false, these three options apply whatever Details.ReviewDetails.Status says. When you explain the restriction to a user, you MUST name all three recipient options that work right now, in that same numbering, before proposing production access as the remedy, and you MUST NOT describe the restriction as "each recipient must be individually verified": a verified domain covers every address at that domain.

  • The sender must be verified too, in every account state. AWS documents that after an account moves into production "you still have to verify all identities that you use as 'From', 'Source', 'Sender', or 'Return-Path' addresses." So MessageRejected: Email address is not verified has two causes: an unpermitted recipient in the sandbox, and an unverified sending identity in any state. Read the address named in the error before choosing a fix, and check that the From address is at a domain or address verified in this Region.

  • A verified sender is the SES service minimum; this skill's journey asks for more. SES itself will accept a send from an identity that is verified for sending even when DKIM has not reached SUCCESS. This skill deliberately does not stop there: its goal is a delivered, authenticated first email, so it requires DkimAttributes.Status: SUCCESS before it claims domain setup or authentication is complete, and before it sends. That stricter bar is stated once, as the send prerequisite in onboarding.md's domain-verification step, and every send path applies it. The two are not in conflict — one is what the service enforces, the other is what this journey promises the user.

  • Validate every substituted value, then quote it for its context. A value interpolated directly into a shell command is single-quoted; a value placed inside inline JSON is JSON-encoded (double quotes, per JSON rules), and only the whole JSON blob is single-quoted for the shell — never shell-quote an individual value inside JSON. This applies to every user-supplied value this skill substitutes — DOMAIN, the MAIL FROM subdomain, FROM_ADDRESS, TEST_RECIPIENT, CHOSEN_RECIPIENT, MAIL_TYPE, WEBSITE_URL, REGION, PROFILE — not only the DNS names. Reject any value containing a single or double quote, a backtick, $, ;, a backslash, or whitespace, and ask the user to re-provide it; never escape a rejected value into shape. Per-value shapes: DOMAIN and the MAIL FROM subdomain — DNS labels only, letters, digits, hyphens and dots; From address and every recipient value, TEST_RECIPIENT and CHOSEN_RECIPIENT alike — a single address with one @, and reject a comma-separated list (put multiple recipients in the ToAddresses array instead); MAIL_TYPE — exactly TRANSACTIONAL or MARKETING; WEBSITE_URL — an http/https URL of 1–1000 characters, which need not be at the verified domain, since any business site the mail relates to is acceptable to AWS, so the question set may offer https://{DOMAIN} as a suggested default only; REGION — an AWS Region code; PROFILE — a CLI profile name. A CHOSEN_RECIPIENT bound from an option the skill supplies rather than the user — the mailbox simulator address — is validated the same way. JSON-encode any user-supplied subject or body text with a serialiser rather than pasting it between quotes.

IAM Permissions

Grant only the actions the workflow being run actually calls, and nothing more — never ses:* or *FullAccess. Each reference file has a Required IAM actions section listing exactly what it calls; use that list, not a wildcard.

Scope per-identity actions to the identity each call actually acts on:

  • arn:aws:ses:{region}:{account-id}:identity/{domain} for domain operations.

  • arn:aws:ses:{region}:{account-id}:identity/{address} for an email-address identity — the identity used for sandbox recipient verification, and equally the From identity when the sender is a separately verified email address rather than an address at the domain. A policy scoped only to the domain denies those calls. Reads are scoped the same way: the ses:GetEmailIdentity statement must carry the ARN of every identity actually read, which includes a recipient address identity and — for sandbox recipient option 3 — the exact identity ARN of the other verified domain the user names. A policy scoped only to the sending domain denies that read, which reads as a broken permission rather than as a missing recipient. A send is authorized by the identity that covers its From address, so scope ses:SendEmail to whichever identity that is; the three cases are listed in onboarding.md's Required IAM actions.

  • Route 53 zone actions (route53:GetHostedZone, route53:ListResourceRecordSets, route53:ChangeResourceRecordSets) to arn:aws:route53:::hostedzone/{hosted_zone_id}, using the bare zone ID — list-hosted-zones-by-name returns /hostedzone/Z123ABC, so strip that prefix before building the ARN or the result is double-prefixed and matches nothing. The zone reads are needed whenever the agent checks whether Route 53 hosts the domain; only route53:ChangeResourceRecordSets is conditional on the user approving a write.

Only genuinely account-level and list actions (sts:GetCallerIdentity, ses:GetAccount, ses:ListEmailIdentities, route53:ListHostedZonesByName, route53:TestDNSAnswer) have no resource-level scoping and must be granted on *. Grant ses:PutAccountDetails deliberately, because it changes account-wide sending posture.

Security Considerations

  • Ephemeral credentials. Use IAM roles with STS — never long-lived access keys.

  • Consent gates. Opening a production-access review and sending a real message both commit the user in ways no API can undo, and a Route 53 change can affect live traffic. Each gate — the production-access consent gate, the send confirmation, and the DNS-write permission — is owned by the reference file that performs the action; never proceed past one because this file summarises it.

  • Delivery TLS is opportunistic by default. AWS documents that SES always attempts a secure connection to the receiving mail server and sends the message unencrypted if it cannot establish one, and that requiring TLS means setting a configuration set's TlsPolicy to REQUIRE — a configuration-set workflow outside this skill's scope.

  • Validate and quote every user-supplied value before it enters a shell command or inline JSON. The rules and character sets are under Invariants above.

  • Never place message bodies or recipient lists in logs.

  • Never hardcode credentials, endpoints, or secrets in examples. Store any application credentials in AWS Secrets Manager or Parameter Store.

  • Enable CloudTrail for SES API call auditing, and alarm on repeated AccessDeniedException and unusual send volume. Encrypt the trail's log files with an AWS KMS key (SSE-KMS) and restrict access to the trail's S3 bucket and CloudWatch Logs group, and encrypt that log group with a KMS key (--kms-key-id on create-log-group) — SES CloudTrail entries carry email addresses, domain names, and account details.

Additional Resources

Files

LICENSE


                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an MCP server

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
AWS
Publisher
AWS (Official)
Source
aws/agent-toolkit-for-aws · skills/specialized-skills/customer-communications-skills/amazon-ses · commit 0a218f8
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • NOTICE (added by AutoGineer from NOTICE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by AWS.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download amazon-ses.zip