Adding LINE Messenger to your AWS omnichannel fallback solution

Post Syndicated from Rommel Sunga original https://aws.amazon.com/blogs/messaging-and-targeting/adding-line-messenger-to-your-aws-omnichannel-fallback-solution/

In this post, you will learn how to extend an existing omnichannel fallback solution by integrating LINE Messenger, including architecture updates, deployment steps, and testing procedures. The original solution, built with Amazon API Gateway, AWS Lambda, Amazon Simple Email Service (Amazon SES), and AWS End User Messaging, delivers messages across SMS, WhatsApp, and email with automatic fallback capabilities.

For more information about the original omnichannel fallback solution that this aims to extend to LINE, see the Enhancing Message Reach: An Omnichannel Approach Using WhatsApp, SMS, and Email with AWS.

Why LINE Messenger?

LINE is a popular messaging platform in Japan, Taiwan, and Thailand, with 181 million monthly active users across its primary markets, including 100 million in Japan alone (LY Corporation FY2025 Q3 earnings data). With an 84 percent DAU/MAU ratio (88 percent in Japan), LINE sees high daily engagement, making it a reliable channel for time-sensitive communications such as appointment reminders in healthcare, order and shipping notifications in ecommerce, and promotional campaigns in retail.

While other messaging platforms are popular in specific APAC markets (KakaoTalk in South Korea, WeChat in China, Zalo in Vietnam, Viber in the Philippines), LINE holds a strong position across Japan, Taiwan, and Thailand simultaneously, making it a high-impact addition to a multi-channel messaging strategy for those countries. By adding LINE to the omnichannel fallback solution, you can reach your audience on their preferred messaging channel in these key markets. You can use LINE as either a primary or fallback channel while maintaining the same fallback and broadcast patterns already available for other channels.

Cost note: LINE Messaging API pricing varies by country and plan. See the pricing pages for LINE Messaging API, Amazon Simple Email Service (Amazon SES), and Amazon End User Messaging for details on each channel.

Architecture overview

Adding LINE to your fallback solution means you can now cover four major messaging channels from a single API endpoint, giving you broader reach without added operational complexity. The LINE integration follows the same event-driven serverless pattern as the existing channels. The following diagram shows the key additions to the architecture.

Figure 1: Updated omnichannel architecture with LINE Messenger (new components highlighted)

You can now reach LINE users with two straightforward additions to the existing architecture:

LINE Messaging API Integration – The Primary and Secondary Handler Lambda functions now include a send_line module that calls the LINE Messaging API to deliver messages using the Push Message endpoint.

AWS Secrets Manager Integration – LINE channel credentials (access token and channel secret) are stored securely in AWS Secrets Manager and retrieved by Lambda functions with caching for performance.

How LINE integration works

The LINE Messenger integration extends the existing message processing pipeline, so you get the same reliable fallback behavior that you already have for email, SMS, and WhatsApp. The following sections describe how the system handles LINE messages and fallback scenarios.

Sending a LINE message

When you send a message with LINE as the primary or fallback channel, the flow follows the same pattern as other channels with LINE-specific handling:

  1. API Gateway receives the request and places it in the Primary Amazon Simple Queue Service (Amazon SQS) Queue.
  2. The Primary Handler Lambda detects the channel as “line” and invokes the send_line module.
  3. The send_line module retrieves LINE credentials from Secrets Manager (cached for performance) and sends a request to the LINE Messaging API Push Message endpoint. The Push Message API sends messages to LINE users without requiring the user to message first. The request body contains a to field with the recipient’s LINE User ID (a unique identifier assigned when a user follows your LINE Official Account) and a messages array with the message objects to deliver. The module validates the recipient LINE User ID against the expected format (a capital ‘U’ followed by 32 lowercase hexadecimal characters) before invoking the LINE API. Requests with malformed recipient IDs are rejected early and don’t reach the external API.
  4. The Lambda function records the message status in the Amazon DynamoDB table.
  5. If fallback is configured, the Lambda function enqueues the message to the Fallback Queue. This happens regardless of whether the LINE API call succeeds (HTTP 200) or fails (non-200 response, timeout, or exception). DynamoDB records the message status as delivered on success or failed on failure. The Secondary Handler checks DynamoDB and sends through the fallback channel if the status isn’t delivered.
  6. The Secondary Handler updates the DynamoDB status to sent_fallback.

How LINE differs from other channels

Aspect Email SMS WhatsApp LINE
API Amazon SES SendEmail API AWS End User Messaging SendTextMessage API AWS End User Messaging Social SendWhatsAppMessage API LINE Messaging API Push Message API
Authentication IAM roles IAM roles IAM roles Channel access token via Secrets Manager
External Message ID Mapping Not required. SES returns the same message ID in delivery callbacks Not required. SMS returns the same message ID in delivery callbacks. Required. WhatsApp returns a different platform message ID in delivery webhooks that must be mapped back to the internal AWS message ID. Not required. No delivery callbacks exist, so no message ID correlation is needed.
Credential Storage IAM (automatic) IAM (automatic) IAM (automatic) Secrets Manager (manual)
Delivery Tracking Async via SES delivery events (SNS callback updates DynamoDB) Async via End User Messaging events (SNS callback updates DynamoDB) Async via End User Messaging events (SNS callback updates DynamoDB) None. Status set to delivered immediately on 200 response from LINE API. No delivery webhook available for LINE Messaging API.

LINE uses an external API with its own authentication rather than AWS-native IAM authentication. This means you must manage credentials through AWS Secrets Manager rather than relying on AWS Identity and Access Management (IAM)-managed authentication. For more information, see the LINE Messaging API documentation.

LINE offers two distinct messaging products for businesses, LINE Messaging API, and LINE Official Notification.

  • The LINE Messaging API, which is the focus of this guide, supports two-way conversational messaging and is widely adopted across industries for use cases such as mobile ordering, loyalty programs, and customer engagement. LINE also offers LINE Official Notification (also known as LINE Notification Messages), a separate service designed for one-way transactional notifications such as shipping updates and appointment reminders, which requires business verification.
  • LINE Official Notification provides per-message delivery completion events, but the LINE Messaging API doesn’t. With the Messaging API, an HTTP 200 response confirms LINE accepted the message for delivery, and this is the most granular delivery signal available.

Creating a LINE Messaging API Channel

You need a LINE Messaging API Channel to authenticate and send messages through the LINE integration. The following steps walk you through creating one:

  1. Sign in to the LINE Developers Console. Create a personal LINE account if you don’t have one already and download the corresponding iOS/Android/PC application. This is required to test receiving LINE messages.
  2. Create a Provider (your company/org name).
  3. Create a new Messaging API channel under that provider.
  4. After you create the channel, enable the Messaging API from the LINE Official Account Manager page.
  5. From the channel settings, note the following:
    1. Channel access token (Messaging API tab, then select Issue)

    2. Channel secret (Basic settings tab)
  6. Disable Auto-reply and Greeting messages under Messaging API settings.

Deploying and testing

The repository includes a complete deployment guide with step-by-step instructions for deploying the CDK stack, configuring LINE credentials in AWS Secrets Manager, obtaining personal LINE user IDs, and running the integration test suite. The test suite automatically detects which channels are configured and runs the applicable tests. For full deployment and testing instructions, see the Deployment Guide in the repository.

Security considerations

Before deploying this solution to production, review the following considerations and adjust for your workload and compliance obligations.

Least-privilege IAM

The Lambda execution roles in the sample scope DynamoDB, Amazon SQS, and AWS Secrets Manager permissions to specific resource ARNs. The send actions for Amazon SES (ses:SendEmail, ses:SendTemplatedEmail), SMS (sms-voice:SendTextMessage), and WhatsApp (social-messaging:SendWhatsAppMessage) are granted on resources: [“*”] in this sample for simplicity, because the specific sending identities, phone pools, and WhatsApp business accounts are left configurable. For production, scope these further where the API supports it: SES allows identity-level ARNs (for example, arn:aws:ses:region:account:identity/example.com), and End User Messaging SMS supports pool and phone-number ARNs. When adapting this code, keep resource-level scoping for everything that supports it and review the AWS Well-Architected Security Pillar and Lambda execution role guidance for production deployments.

Rotating LINE credentials

LINE channel access tokens are long-lived and are issued and rotated manually through the LINE Developers Console; there’s no programmatic rotation API. Rotate the token periodically in line with your organization’s key-rotation policy (for example, every 90 days), update the Secrets Manager secret with the new value, and force a Lambda cold start (by redeploying the stack or updating a Lambda environment variable) so the cached credentials are refreshed.

Data protection and PII retention

The solution stores message metadata and recipient identifiers (including LINE User IDs, phone numbers, and email addresses) in Amazon DynamoDB. DynamoDB uses AWS-managed encryption at rest, Secrets Manager uses AWS Key Management Service (AWS KMS), and all outbound calls to the LINE API are made over HTTPS. Point-in-time recovery is enabled on the message table.

The sample doesn’t configure a DynamoDB Time-to-Live (TTL) attribute, so records persist indefinitely. For production, add a TTL attribute (for example, expiresAt) that matches your retention policy, and review whether the RemovalPolicy.RETAIN setting on the tables is appropriate for your environment. LINE User IDs, phone numbers, and email addresses are personally identifiable information under regulations including Japan’s APPI, the EU’s GDPR, and similar laws. Assess your retention obligations, data residency requirements, and processes for handling subject access and deletion requests for the regions you serve.

Conclusion

By adding LINE Messenger to the omnichannel fallback solution, you can now reach your customers across the four messaging channels that matter most: email, SMS, WhatsApp, and LINE. The integration follows the same serverless, event-driven patterns as the existing channels, making it straightforward to deploy and maintain. LINE can serve as either a primary or fallback channel, giving you the flexibility to tailor your messaging strategy to regional preferences. As a next step, consider adding other regional messaging services to further expand your reach. You can also explore advanced LINE features such as rich messages, quick replies, and Flex Messages to create more engaging customer interactions.

Resources


About the authors

Send WhatsApp Business messages with AWS End User Messaging Social

Post Syndicated from Rommel Sunga original https://aws.amazon.com/blogs/messaging-and-targeting/send-whatsapp-business-messages-with-aws-end-user-messaging-social/

WhatsApp reaches over 3 billion monthly active users worldwide — with more than 2 billion using it every day — making it the single most direct channel for customer communication at global scale. AWS End User Messaging Social gives you a managed API to send WhatsApp Business messages without building or maintaining your own WhatsApp Business API integration.

Whether you’re building appointment reminders, order notifications, or interactive customer support flows, with WhatsApp Business messaging, you can meet customers where they already communicate.

This post is for developers and solutions architects looking to integrate WhatsApp messaging into their customer engagement workflows using AWS. By the end, you will know how to send every supported message type—from straightforward text and media to templates, interactive menus, and WhatsApp Flows—using Python and the AWS End User Messaging Social API.

Solution overview

This solution uses AWS End User Messaging Social to connect your WhatsApp Business Account (WABA) with your AWS workloads, enabling automated, two-way messaging with your customers. When a customer sends a WhatsApp message to your WABA phone number, AWS End User Messaging Social receives the message and publishes an event to an Amazon Simple Notification Service (Amazon SNS) topic. Amazon SNS then invokes an AWS Lambda function. You configure this Lambda function to process the incoming message and send a contextual WhatsApp reply to the customer. The following diagram illustrates this architecture:

Figure A: Shows the architecture flow “Customer WhatsApp → End User Messaging Social → SNS → Lambda → End User Messaging Social → Response”

IMPORTANT: Note that any WhatsApp user can send a message to your WABA number and trigger the workflow. To avoid incurring ongoing charges, complete the steps in the “Clean up” section.

The solution is deployed using the AWS Serverless Application Model (AWS SAM) and includes a sample Lambda function that demonstrates how to handle common message types, send interactive list messages, and respond with templated replies. You can extend this foundation to build more sophisticated workflows, such as invoking AWS Step Functions for multi-step processes or routing messages to container-based workloads running on AWS. AWS End User Messaging Social also provides unified billing within AWS, streamlining cost management for your WhatsApp messaging workloads.

Prerequisites

Before you run any of the examples in this post, complete the following prerequisites:

  • A phone number to link a WABA.
  • Connect a verified WhatsApp Business Account (WABA) to AWS End User Messaging Social.
  • Install the AWS SDK for Python (Boto3).
  • Optionally, install the AWS Command Line Interface (AWS CLI) for template creation (otherwise the templates must be created within the AWS Console UI or Meta’s WhatsApp Manager).
  • A phone with WhatsApp Messenger app installed to test the solution. Note that the mobile app uses a different phone number than the one that is associated with your WABA.

This walkthrough typically takes 30–45 minutes, though actual time might vary based on your familiarity with AWS services and WhatsApp Business configuration.

If you’re new to AWS End User Messaging Social, see the Getting Started with WhatsApp guide before proceeding.

IAM permissions

To configure AWS End User Messaging Social, you will need several types of permissions depending on what you’re setting up. Here are the key permissions required:

Core AWS End User Messaging social permissions

For basic configuration and management, you will need permissions for the following actions:

  • social-messaging:AssociateWhatsAppBusinessAccount — to associate a WhatsApp Business Account with your AWS account
  • social-messaging:CreateWhatsAppMessageTemplate — to create WhatsApp message templates
  • social-messaging:ListLinkedWhatsAppBusinessAccounts — to list linked WhatsApp Business Accounts
  • social-messaging:GetWhatsAppMessageTemplate — to retrieve message template details
  • social-messaging:ListWhatsAppMessageTemplates — to list message templates

For event destinations (SNS integration)

If you’re configuring event destinations with Amazon SNS, your SNS topic must have a resource policy allowing the sms-voice.amazonaws.com service principal to publish to it, and you will need an AWS Identity and Access Management (IAM) role with a trust policy allowing social-messaging.amazonaws.com to assume it. For detailed setup instructions, see Configuring Event Destinations in the AWS End User Messaging Social User Guide.

For Amazon Connect integration

If integrating with Amazon Connect, the service-linked role (SLR) includes the following permissions:

  • social-messaging:SendWhatsAppMessage
  • social-messaging:PostWhatsAppMessageMedia
  • social-messaging:GetWhatsAppMessageMedia
  • social-messaging:GetLinkedWhatsAppBusinessAccountPhoneNumber

For more information, see Amazon Connect Service-Linked Role in the Amazon Connect Administrator Guide.

Additional considerations

  • If using encrypted SNS topics with AWS KMS, you will need additional AWS Key Management Service (AWS KMS) permissions for the service to generate and decrypt data keys.

Configuration

Create a config.json file in your project directory with the following structure to store the destination WhatsApp number and the origination phone number ID (for example, phone-number-id-a1b2c3d4######) that we’re sending messages from and receiving the message:

{
    "originationPhoneNumberId": "your-whatsapp-phone-number-id",
    "destinationPhoneNumber": "+1234567890"
}

Security note: The config.json file is intended for local testing only. In production environments, avoid hardcoding phone numbers and credentials. Instead, use AWS Secrets Manager, AWS Systems Manager Parameter Store, or environment variables to manage sensitive configuration values.

Each example builds a message_data payload and sends it using the following code:

import json
import boto3
import os

config_path = os.path.join(os.path.dirname(__file__), 'config.json')
with open(config_path, 'r') as f:
    config = json.load(f)

client = boto3.client('socialmessaging')
message_data = { ... }

response = client.send_whatsapp_message(
    message=json.dumps(message_data),
    originationPhoneNumberId=config['originationPhoneNumberId'],
    metaApiVersion="v20.0"
)
print(f"Message sent successfully! Response: {response}")

For production use, wrap the send call with error handling to manage throttling and failures gracefully:

try:
    result = client.send_whatsapp_message(
        message=json.dumps(message_data),
        originationPhoneNumberId=config['originationPhoneNumberId'],
        metaApiVersion="v20.0"
    )
    print(f"Message sent. ID: {result['messageId']}")
except client.exceptions.ThrottlingException as e:
    print(f"Rate limited. Retry after backoff: {e}")
except Exception as e:
    print(f"Failed to send message: {e}")

The following sections show only the message_data for each message type. To send any of these messages, use the shared sending code from the previous Configuration section—load config.json, create the Boto3 client, and call client.send_whatsapp_message() with the payload.

Text messages

Text messages are plain text communications sent within the 24-hour conversation window. They don’t require Meta template approval and support basic formatting.

Specifications and requirements

Text messages are the foundation of WhatsApp conversations. You can send up to 4,096 characters per message. Text messages don’t require Meta approval and work within an active 24-hour conversation window that opens when a customer messages your business first, or when you initiate contact using an approved template.

  • Maximum length: 4,096 characters (including spaces and formatting)
  • 24-hour window requirement: Can only be sent within 24 hours of last customer message
  • No WhatsApp template approval required

WhatsApp message example

The following image is a WhatsApp message example.

Code example

The following is a code example for the previous message.

message_data = {
    "messaging_product": "whatsapp",
    "to": config['destinationPhoneNumber'],
    "type": "text",
    "text": {
        "body": "For the Classic T-Shirt, we recommend size Medium based on your measurements. It runs true to size with a regular fit. Size Medium: Chest 38-40 inches, Length 28 inches."
    }
}

Media messages

With Media messages, you can send images, documents, audio, and video files.

Specifications and requirements

  • Images: Maximum 5 MB (JPEG, PNG)
  • Documents: Maximum 100 MB (PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX)
  • Audio: Maximum 16 MB (AAC, MP4, AMR, MP3, OGG)
  • Video: Maximum 16 MB (MP4, 3GPP)

Note: Media uploaded to Meta is retained for 30 days. If you reuse media across messages (such as a company logo), use the external URL method or re-upload before sending. The examples in this post use external URLs.

Media (document) message example

The message is presented as a PDF with the provided message body in the following example.

Code example

The following is a code example for the previous message.

message_data = {
    "messaging_product": "whatsapp",
    "to": config['destinationPhoneNumber'],
    "type": "document",
    "document": {
        "link": "https://docs.aws.amazon.com/pdfs/social-messaging/latest/userguide/social-ug.pdf",
        "caption": "\U0001F4C4 Your invoice #12345 is ready. Payment due: January 31, 2024. Questions? Reply to this message.",
        "filename": "Invoice-12345.pdf"
    }
}

Media (image) message example

This media message includes an image with a message body in the following example to describe the image. In this case it shows a laptop available for purchase with a link included as part of the message body.

Code example

The following is a code example for the previous message.

message_data = {
    "messaging_product": "whatsapp",
    "to": config['destinationPhoneNumber'],
    "type": "image",
    "image": {
            "link": "https://signin.aws.amazon.com/v2/assets/_next/static/media/[email protected]",
            "caption": "Thanks for reaching out to AnyCompany! Here's the product image for the laptop you inquired about. Feel free to reply if you need more details."
    }
}

Template messages

Template messages enable business-initiated conversations outside the 24-hour window. Templates must be created and approved by Meta before use.

Text template message creation with parameters

Template creation using CLI

While it’s possible to create templates directly in the AWS End User Messaging Social console and in WhatsApp Manager’s UI, you can also use AWS End User Messaging Social to programmatically create templates using the AWS CLI.

Step 1 — Create a file named order_confirmation_template.json in your working directory with the following template definition.

{
    "name": "order_confirmation_template",
    "language": "en",
    "category": "UTILITY",
    "parameter_format": "named",
    "components": [
      {
        "type": "HEADER",
        "format": "TEXT",
        "text": "Order {{order_number}}",
        "example": {
          "header_text_named_params": [
            {"param_name": "order_number", "example": "ORD-2025-001"}
          ]
        }
      },
      {
        "type": "BODY",
        "text": "Hi {{customer_name}},\n\nYour order has been confirmed!\n\nItem: {{item_name}}\nTotal: {{total_amount}}\nEstimated Delivery: {{delivery_date}}\n\nThank you for shopping
  with us!",
        "example": {
          "body_text_named_params": [
            {"param_name": "customer_name", "example": "John Smith"},
            {"param_name": "item_name", "example": "Wireless Headphones"},
            {"param_name": "total_amount", "example": "$179.17"},
            {"param_name": "delivery_date", "example": "November 30, 2025"}
          ]
        }
      }
    ]
  }

Step 2 — Run the following CLI command to create the template. Note that the –template-definition parameter points to the local JSON file that contains the template structure:

aws socialmessaging create-whatsapp-message-template \

    --region [AWS_REGION] \
    --cli-binary-format raw-in-base64-out \
    --id [WABA_ID] \
    
--template-definition file://order_confirmation_template.json

Template creation using the console

AWS End User Messaging Social also features a built-in template management UI which you can use to create and manage templates directly within the AWS End User Messaging Social portion of the AWS Console under AWS End User messaging > Social Messaging > Message Templates. To create a new template, choose the Create Template button.

In the first screen, you can set your template name, template language and template type for your respective WhatsApp Business Account.

In the second screen, you can set the message content for the template including variables to dynamically populate when sending the message content.

Approved message templates can be seen under the message template screen along with their approval status.

Sending the template message

After your template is approved, you can send it with parameter values populated at send time.

Important: When sending the template message, you must use the same language and locale that you used when creating the template. For example, a language code of “en” isn’t the same as “en_US”.

message_data = {
    "messaging_product": "whatsapp",
    "to": config['destinationPhoneNumber'],
    "type": "template",
    "template": {
        "name": "order_confirmation_template",
        "language": {"code": "en"},
        "components": [
            {
                "type": "header",
                "parameters": [
                    {"type": "text", "parameter_name": "order_number", "text": "ORD-2025-001"}
                ]
            },
            {
                "type": "body",
                "parameters": [
                    {"type": "text", "parameter_name": "customer_name", "text": "John Smith"},
                    {"type": "text", "parameter_name": "item_name", "text": "Wireless Headphones"},
                    {"type": "text", "parameter_name": "total_amount", "text": "$179.17"},
                    {"type": "text", "parameter_name": "delivery_date", "text": "November 30, 2025"}
                ]
            }
        ]
    }
}

Location messages

Location messages share geographic coordinates with optional name and address information. For example, you can send a location for a store branch to a customer.

Create template message with CLI

Step 1 — Create a file named store_location_template.json in your working directory with the following template definition:

{
    "name": "store_location",
    "language": "en",
    "category": "UTILITY",
    "parameter_format": "named",
    "components": [
      {
        "type": "HEADER",
        "format": "LOCATION"
      },
      {
        "type": "BODY",
        "text": "Visit our {{store_name}} store!\n\nOperating Hours: {{hours}}\n\nSee you soon!",
        "example": {
          "body_text_named_params": [
            {"param_name": "store_name", "example": "Marina Bay Store"},
            {"param_name": "hours", "example": "10 AM - 10 PM"}
          ]
        }
      }
    ]
  }

Step 2 — Run the following CLI command to create the template. The –template-definition parameter references the JSON file that you previously created:

aws socialmessaging create-whatsapp-message-template \
    --region [AWS_REGION] \
    --cli-binary-format raw-in-base64-out \
    --id [WABA_ID] \

--template-definition file://store_location_template.json

Location message example

The following image is an example of a location message.

Code example

The following is a code example of the previous location message example.

message_data = {
    "messaging_product": "whatsapp",
    "to": config['destinationPhoneNumber'],
    "type": "template",
    "template": {
        "name": "store_location",
        "language": {
            "code": "en"
        },
        "components": [
            {
                "type": "header",
                "parameters": [
                    {
                        "type": "location",
                        "location": {
                            "latitude": "1.2838",
                            "longitude": "103.8591",
                            "name": "Marina Bay Sands",
                            "address": "10 Bayfront Ave, Singapore 018956"
                        }
                    }
                ]
            },
            {
                "type": "body",
                "parameters": [
                    {
                        "type": "text",
                        "parameter_name": "store_name",
                        "text": "Marina Bay Store"
                    },
                    {
                        "type": "text",
                        "parameter_name": "hours",
                        "text": "10 AM - 10 PM"
                    }
                ]
            }
        ]
    }
}

Interactive messages

Interactive messages provide pre-defined response options through buttons or lists. These messages must be sent within the 24-hour conversation window.

  • Structured responses – Pre-defined options ensure consistent data collection
  • Enhanced UX – One-tap interactions reduce friction and improve completion rates
  • 24-hour window requirement – Must be sent within active conversation windows

Quick reply buttons message

This example demonstrates collecting guest feedback using quick reply buttons for streamlined response collection.

Technical specifications:

  • Maximum three buttons per message
  • Button text limit: 20 characters
  • Buttons appear in a horizontal row on most devices

Quick reply buttons message example

The following image is an example of the Quick reply buttons message.

Code example

The following is a code example of the previous example image.

message_data = {
    "messaging_product": "whatsapp",
    "recipient_type": "individual",
    "to": config['destinationPhoneNumber'],
    "type": "interactive",
    "interactive": {
        "type": "button",
        "body": {
            "text": "\U0001F3E8 Thank you for staying with us! How would you rate your experience?"
        },
        "action": {
            "buttons": [
                {
                    "type": "reply",
                    "reply": {
                        "id": "excellent",
                        "title": "\u2B50 \u2B50 \u2B50 \u2B50 \u2B50 Excellent"
                    }
                },
                {
                    "type": "reply",
                    "reply": {
                        "id": "good",
                        "title": "\u2B50 \u2B50 \u2B50 \u2B50 Good"
                    }
                },
                {
                    "type": "reply",
                    "reply": {
                        "id": "needs_improvement",
                        "title": "\u2B50 \u2B50 Needs Work"
                    }
                }
            ]
        }
    }
}

List Message

This example shows a restaurant menu using list messages for organized, scrollable content presentation.

Technical specifications:

  • Max Options: Up to 10 rows total, which can be organized into 10 sections.
  • Button Text: Maximum 24 characters to open the menu.
  • Sections: A list can contain multiple sections (e.g., “Starters”, “Mains”).

List message example

The following is an image of a list message example.

When the user expands the list, they can select individual items to add to their cart.

Code example

The following is the code example for the previously mentioned example.

message_data = {
    "messaging_product": "whatsapp",
    "recipient_type": "individual",
    "to": config['destinationPhoneNumber'],
    "type": "interactive",
    "interactive": {
        "type": "list",
        "body": {
            "text": "\U0001F37D\uFE0F Welcome to Bella Vista! Browse our menu categories in the following list:"
        },
        "action": {
            "button": "View Menu",
            "sections": [
                {
                    "title": "Main Courses",
                    "rows": [
                        {
                            "id": "pasta",
                            "title": "\U0001F35D Pasta Dishes",
                            "description": "Fresh pasta with signature sauces"
                        },
                        {
                            "id": "pizza",
                            "title": "\U0001F355 Wood-Fired Pizza",
                            "description": "Authentic Italian pizza"
                        }
                    ]
                },
                {
                    "title": "Beverages",
                    "rows": [
                        {
                            "id": "wine",
                            "title": "\U0001F377 Wine Selection",
                            "description": "Curated Italian wines"
                        },
                        {
                            "id": "cocktails",
                            "title": "\U0001F378 Signature Cocktails",
                            "description": "Handcrafted cocktails"
                        }
                    ]
                }
            ]
        }
    }
}

Contact messages

Contact messages share vCard-formatted contact information, useful for sharing business contact details with customers.

Contact message example

The following is an image of an example contact message.

Customers can choose to directly message the contact, save the contact to their contacts list and view details about the contact in a pop up.

Code example

The following is a code example for the previously mentioned image example.

message_data = {
    "messaging_product": "whatsapp",
    "to": config['destinationPhoneNumber'],
    "type": "contacts",
    "contacts": [
        {
            "name": {
                "formatted_name": "AnyCompany Customer Support",
                "first_name": "Customer",
                "last_name": "Support"
            },
            "org": {
                "company": "AnyCompany Inc."
            },
            "phones": [
                {
                    "phone": "+1-555-0123",
                    "type": "WORK",
                    "wa_id": "15550123"
                }
            ],
            "emails": [
                {
                    "email": "[email protected]",
                    "type": "WORK"
                }
            ],
            "urls": [
                {
                    "url": "https://www.anycompany.com",
                    "type": "WORK"
                }
            ],
            "addresses": [
                {
                    "street": "123 Business Ave",
                    "city": "Seattle",
                    "state": "WA",
                    "zip": "98101",
                    "country": "United States",
                    "country_code": "US",
                    "type": "WORK"
                }
            ]
        }
    ]
}

WhatsApp Flows

WhatsApp Flows can help power interactive experiences. Note that a verified WhatsApp Business Account is required to use WhatsApp Flows. There are two general types of WhatsApp Flows:

  • Without an endpoint — Results are stored and can be viewed directly within WhatsApp Manager. This is the type demonstrated in this post.
  • With an endpoint — Results are sent to an API endpoint that you specify for further processing.

WhatsApp Flow – survey

This is an example of a WhatsApp Flow without an endpoint that sends a product survey to customers. Since this flow doesn’t use an endpoint, the results can be viewed directly within WhatsApp Manager.

Create WhatsApp Flow using Flow Playground

First create a WhatsApp Flow using the Flows Playground on the Meta for Developers website.

You can use the following JSON in the editor to use the example flow that we’re creating.

{"version":"7.2","screens":[{"id":"QUESTION_ONE","title":"Question 1 of 2","data":{},"layout":{"type":"SingleColumnLayout","children":[{"type":"Form","name":"form","children":[{"type":"TextHeading","text":"What product categories interest you?"},{"type":"CheckboxGroup","label":"Choose all that apply:","required":true,"name":"product_categories","data-source":[{"id":"electronics","title":"Electronics"},{"id":"fashion","title":"Fashion"},{"id":"home","title":"Home & Living"},{"id":"beauty","title":"Beauty"}]},{"type":"Footer","label":"Continue","on-click-action":{"name":"navigate","next":{"type":"screen","name":"QUESTION_TWO"},"payload":{"product_categories":"${form.product_categories}"}}}]}]}},{"id":"QUESTION_TWO","title":"Question 2 of 2","data":{"product_categories":{"type":"array","items":{"type":"string"},"__example__":[]}},"terminal":true,"success":true,"layout":{"type":"SingleColumnLayout","children":[{"type":"Form","name":"form","children":[{"type":"TextHeading","text":"What's your typical budget?"},{"type":"RadioButtonsGroup","label":"Choose one:","required":true,"name":"budget_range","data-source":[{"id":"under_50","title":"Under $50"},{"id":"50_150","title":"$50 - $150"},{"id":"over_150","title":"Over $150"}]},{"type":"Footer","label":"Submit","on-click-action":{"name":"complete","payload":{"product_categories":"${data.product_categories}","budget_range":"${form.budget_range}"}}}]}]}}]}

Afterwards you will be prompted to create the template to attach to the flow.

Create WhatsApp template using AWS CLI

Step 1 — Create a file named anycompany_survey_template.json in your working directory with the following template definition. Notice that the Flow JSON is embedded directly in the flow_json field of the button component:

{ "name": "anycompany_survey", "language": "en_US", "category": "MARKETING", "components": [ { "type": "BODY", "text": "Hi! We're AnyCompany and we'd love to personalize your shopping experience. Take our quick 2-question survey!" }, { "type": "BUTTONS", "buttons": [ { "type": "FLOW", "text": "Start Survey", "flow_json": "{"version":"7.2","screens":[{"id":"QUESTION_ONE","title":"Question 1 of 2","data":{},"layout":{"type":"SingleColumnLayout","children":[{"type":"Form","name":"form","children":[{"type":"TextHeading","text":"What product categories interest you?"},{"type":"CheckboxGroup","label":"Choose all that apply:","required":true,"name":"product_categories","data-source":[{"id":"electronics","title":"Electronics"},{"id":"fashion","title":"Fashion"},{"id":"home", "title":"Home & Living"},{"id":"beauty","title":"Beauty"}]},{"type":"Footer","label":"Continue","on-click-action":{"name":"navigate","next":{"type":"screen","name":"QUESTI ON_TWO"},"payload":{"product_categories":"${form.product_categories}"}}}]}]}},{"id":"QUESTION_TWO","title":"Question 2 of 2","data":{"product_categories":{"type":"array","items":{"type":"string"},"__example__":[]}},"terminal":true,"success":true,"layout":{"type":"SingleColumnLayout
 ","children":[{"type":"Form","name":"form","children":[{"type":"TextHeading","text":"What's your typical budget?"},{"type":"RadioButtonsGroup","label":"Choose one:","required":true,"name":"budget_range","data-source":[{"id":"under_50","title":"Under $50"},{"id":"50_150","title":"$50 - $150"},{"id":"over_150","title":"Over $150"}]},{"type":"Footer","label":"Submit","on-click-action":{"name":"complete","payload":{"product_categories":"${data.product_categories}","budget_range":"${form .budget_range}"}}}]}]}}]}", "flow_action": "navigate" } ] } ] }

Step 2 — Run the following CLI command to create the template. The –template-definition parameter references the JSON file that you previously created:

aws socialmessaging create-whatsapp-message-template \
--region [AWS_REGION] \
--cli-binary-format raw-in-base64-out \
--id [WABA_ID] \
--template-definition file://anycompany_survey_template.json

Sending the WhatsApp Flow

After the Template and Flow are approved, a message can be sent with the following code.

message_data = {
    "messaging_product": "whatsapp",
    "to": config['destinationPhoneNumber'],
    "type": "template",
    "template": {
        "name": "anycompany_survey",
        "language": {
            "code": "en_US"
        },
        "components": [
            {
                "type": "button",
                "sub_type": "flow",
                "index": "0",
                "parameters": [
                    {
                        "type": "action",
                        "action": {
                            "flow_token": "survey-12345",
                            "flow_action_data": {
                                "screen": "QUESTION_ONE"
                            }
                        }
                    }
                ]
            }
        ]
    }
}

WhatsApp Flow survey example

The Flow will appear with the message body specified and a link to start the survey.

The recipient can provide their answers on each page of the Flow which can be submitted at the end.

After providing inputs, the Flow will show a completed message.

Clean up

To avoid incurring future charges, delete the resources that you created during this walkthrough:

  1. In the AWS End User Messaging Social console, disassociate (unlink) the WhatsApp Business Account.
  2. Navigate to Message Templates and delete any test templates that you created.
  3. Delete any WhatsApp Flows you created in the Flow Playground on the Meta for Developers website.
  4. Review your Amazon CloudWatch Logs for any log groups created by the service and delete them if no longer needed.
  5. Optionally, if you provisioned a phone number in End User Messaging SMS just for WhatsApp release the phone number in End User Messaging SMS.

For templates created in WhatsApp Manager, you can also delete them directly from the WhatsApp Business Manager interface on the Meta for Developers website.

Conclusion

In this post, you learned how to send various WhatsApp Business message types using AWS End User Messaging Social, including text messages, media messages, template messages, location messages, interactive messages, contact messages, and WhatsApp Flows.

AWS End User Messaging Social provides a managed API that removes the complexity of maintaining your own WhatsApp Business API integration, so you can focus on building engaging customer experiences. The service handles the heavy lifting of managing WhatsApp Business API connections, template approvals, and message delivery, while providing you with a unified, consistent API interface.

Next steps

  • Explore advanced template features with dynamic content and media headers
  • Implement webhook handlers for incoming messages and delivery receipts
  • Set up automated message flows for common customer inquiries using Amazon EventBridge
  • Integrate with Amazon Connect for omnichannel customer support experiences

We’d love to hear about your experience! Share your use cases and implementation approaches in the comments.

Additional resources


About the authors

[$] Moving beyond fork() + exec()

Post Syndicated from corbet original https://lwn.net/Articles/1076018/

Since the earliest days of Unix, two of the core process-oriented system
calls have been fork(), which creates a child process as a copy of
the parent, and exec(), which runs a new program in the place of
the current one. In Linux kernels, those system calls are better known as
clone()
and execve(),
but the core functionality remains the same. While there is elegance to
this process-creation model, there are shortcomings as well. A recent proposal from
Li Chen to add “spawn templates” to the kernel will not be accepted in its
current form, but it may point the way toward a new process-creation
primitive in the future.

Your AI bill is out of control. Cloudflare can fix it now. 

Post Syndicated from Ming Lu original https://blog.cloudflare.com/ai-gateway-spend-limits/

There isn’t a CIO on the planet not worried about AI spend right now. CFOs are increasingly nervous, too.

For fear of falling behind, many companies have pushed their employees to use AI as aggressively as possible. The edict was clear: “Move fast, we’ll figure out the bill later.” And for the most part, it worked: AI has been genuinely transformational for the teams that leaned in.

But the costs are real: we’ve heard countless horror stories of huge bills and painful overages on token spend.

Today, we’re announcing spend controls in Cloudflare AI Gateway, and a closed beta for identity-driven budgets and routing using Cloudflare Access and your existing identity provider.

As we’ve spoken with hundreds of companies about their AI strategy, we’ve seen a common story:  The company gives every engineer access to frontier models through a shared API key. Usage takes off. At the end of the month, finance pulls the invoice and nobody can explain where the money went. Was it the machine learning team training a new pipeline? Was it an intern running Claude Opus on email triage? Was it a runaway continuous integration job that burned through 50 million tokens in a weekend? Nobody knows, because the API key doesn’t tell you who used it.

Without guidelines, staff will generally reach for the biggest model available. And why wouldn’t they? If there’s no budget, no visibility, and no routing logic, the rational move is to use the most powerful model for everything. The problem is that most tasks don’t need a frontier model. A code review summary doesn’t need the same model as a complex architecture refactor. A log parser doesn’t need the same model as a customer-facing content generator. It should be easy to select the right tool for the job, rather than defaulting to the most powerful and expensive one. And it should be simple to see where the spend is going.

You can’t calculate ROI on your AI spend without visibility on what you’re spending, and you can’t protect that ROI without controls. Every other line item in a business has a budget and per-team attribution and AI spend should be no different. 

What AI Gateway is 

AI Gateway sits between your applications and AI providers. Instead of calling OpenAI, Anthropic, Google, or any other provider directly, your requests route through AI Gateway first. 

This immediately gives you several useful tools: 

However, AI Gateway didn’t have an easy way to answer who is spending what or how you might set limits on AI spend. 

You could see aggregate usage across your account. But you couldn’t see that Jane from engineering burned through \$2,000 on Claude this month while the entire data science team only used \$400. You couldn’t set a budget that said “engineering gets \$5,000/month on frontier models, interns get \$200/month on Kimi K2.6.”

That changes today.

Spend limits: budgets for AI usage

AI Gateway now supports spend limits as a core feature. These are true cost control measures in the form of budgets set in dollars, not tokens, that track cumulative spend across all requests, operating independently of traditional rate limiting.

You can scope limits to any combination of dimensions: model, provider, or admin-defined custom attributes like user, team, or application. Windows can be fixed (resets on the first of the month, Monday, or midnight) or rolling, and set to daily, weekly, or monthly.


AI Gateway calculates cost per request based on the model’s pricing, and tracks cumulative spend against your limit in real time. You can easily track your model spend on our analytics dashboard and filter by model, provider, or any custom attribute. 

You have options for what happens when the budget limit is reached. AI Gateway will block further requests by default. Or you can set up rules through Dynamic Routes to route requests to a fallback model after you’ve hit a spend limit, so that a hard spending cap won’t kill your engineers’ workflow. We’re working to add the capability for you to also send alerts when a limit is reached. 

Spend limits are available in open beta today for all AI Gateway users across all plans. Configure them in your gateway settings in the dashboard or via the API.

We use this ourselves

We’re tracking token costs inside Cloudflare already. Every Cloudflare employee uses AI tools daily, routing millions of requests and billions of tokens per month through AI Gateway. We faced the same question every company faces at this scale: who’s using what, and how do we budget for it?

We solved this by enabling AI Gateway to add identity to every request. When an employee authenticates via Cloudflare Access, we extract their identity from the JSON Web Token (JWT) and attach it as metadata on the AI Gateway request. This makes per-user token consumption, team-level usage breakdowns, and cost attribution across the organization all visible in one place.

Identity-driven budgets and policies (closed beta)

In addition to spend limits, today we’re also announcing identity-driven budgets and policies as a closed beta. 

Spend limits in AI Gateway let you set budgets by model, provider, or custom attributes. But your application has to pass that metadata, and AI Gateway trusts whatever it receives. For verified, automatic attribution, you need identity.

When combined with Cloudflare Access, AI Gateway can see who is making each request — not just which account, but which employee, which identity provider (IdP) group, which service, etc.

Here’s what that looks like in practice.



You can set per-user budgets, say \$500/month for individual contributors and \$2,000 for senior engineers. When a user hits their limit, requests can be downgraded to a cheaper model or blocked.

You can set per-team model policies. For instance, your ML team gets Claude Opus and GPT-4o. The brand design team can access generative image and video models. Interns use open-source models on Workers AI. These policies map directly to your existing IdP groups, the same identity provider groups you already manage.

For CI/CD pipelines and autonomous agents, Access service tokens allow you to give each agent a named identity. You can see that your code review bot used 5 million tokens this week while your documentation generator used 500,000. If one agent is running out of control, apply a budget policy without affecting any others.

Every AI Gateway log entry will include the authenticated identity: email, IdP group, service token name. Export these to your analytics platform, and you’ve got a cost-by-user-by-team breakdown without building anything custom.

Under the hood, you create a Cloudflare Access application for your AI Gateway endpoint and configure policies based on your IdP groups. When a developer or agent makes a request, they authenticate via OAuth, using the typical CLI device-code flow. AI Gateway validates the token and extracts the identity. You don’t need to write a custom Worker, parse JWTs yourself, or rely on honor-system metadata headers.

We recently wrote about how we built our internal AI engineering stack. This is what we are making available today — so you can use it, too, and you don’t have to build it yourself.

If you would like access to the closed beta, sign up here

What’s next: from cost control to cost optimization

Setting a budget is necessary. But once you’ve got a budget, how do you make the most of it? 

The reality is that not every request needs a frontier model: a summarization task can run on a smaller, cheaper model without meaningful quality loss, while a large-scale code refactor might require the bleeding edge. But without controls, people will almost always opt for the most advanced model.

A solution for that is coming next: We’re building intelligent, task-based routing in AI Gateway. For each request, we can analyze and automatically route it to the model that will give you the best result at the lowest cost. This is in active development, so follow our developer docs and changelog

Get started

It’s free to get started with AI Gateway. Spend limits are available now for all users.

If you haven’t already, create a gateway and point your applications at it. From there, set up spend limits in the dashboard or via API. Start with a high limit in monitoring mode to understand your current usage patterns before you start enforcing.

If you want per-user attribution and team-based policies, sign up for the identity-driven budgets closed beta, and we’ll get you set up with the Access integration.

We want to hear how you’re managing AI costs today. Join the conversation on Cloudflare Community or reach out to discuss your broader AI security strategy.

Ruby’s Bundler adds a cooldown feature

Post Syndicated from jzb original https://lwn.net/Articles/1076526/

Version
4.0.13
of Ruby’s Bundler
package-manager has added
dependency cooldowns
in order to help mitigate the effect of
supply-chain attacks:

Most supply-chain attacks against RubyGems exploit a narrow window:
an account is compromised, a malicious version ships, and any
bundle install in the minutes that follow resolves
straight to it. Bundler 4.0.13 introduces cooldown, a time-based
filter that refuses to resolve to a version until it has been public
for at least N days. Releases too new to have been scrutinized are
passed over in favor of ones that have aged past the window.

The feature was designed in
the open
, drawing on how
other ecosystems approach the same problem
. It is opt-in, and
complements rather than replaces existing defenses like mandatory 2FA
and trusted publishing.

LWN covered
dependency cooldowns in April, and the takeover of RubyGems and
Bundler
in October 2025.

Security updates for Friday

Post Syndicated from jzb original https://lwn.net/Articles/1076605/

Security updates have been issued by AlmaLinux (kernel), Debian (dovecot, exim4, frr, and haveged), Fedora (cockpit, freeipa, jpegxl, libre, nextcloud, perl-Cpanel-JSON-XS, perl-Crypt-Argon2, perl-Dist-Build, perl-ExtUtils-Builder, perl-ExtUtils-Builder-Compiler, perl-HTTP-Tiny, perl-libwww-perl, python-starlette, rubygem-yard, rust-sequoia-cert-store, rust-sequoia-chameleon-gnupg, rust-sequoia-octopus-librnp, rust-sequoia-sop, rust-sequoia-sq, rust-sequoia-wot, samba, and transmission), Red Hat (image-builder), Slackware (dnsmasq and libinput), SUSE (evince, glibc, google-guest-agent, hplip, ignition, LibVNCServer, libzypp, libsolv, python-Pillow, salt, thunderbird, and vim), and Ubuntu (apache2, linux, linux-aws, linux-aws-5.15, linux-aws-fips, linux-fips, linux-gcp,
linux-gcp-5.15, linux-gcp-fips, linux-gke, linux-gkeop, linux-hwe-5.15,
linux-ibm, linux-ibm-5.15, linux-intel-iot-realtime, linux-intel-iotg,
linux-kvm, linux-nvidia, linux-nvidia-tegra, linux-nvidia-tegra-5.15,
linux-nvidia-tegra-igx, linux-oracle, linux-raspi, linux-realtime, linux, linux-aws, linux-aws-fips, linux-azure, linux-azure-5.4,
linux-azure-fips, linux-bluefield, linux-fips, linux-gcp, linux-gcp-5.4,
linux-gcp-fips, linux-iot, linux-kvm, linux-oracle, linux-oracle-5.4,
linux-xilinx-zynqmp, linux, linux-azure, linux-azure-4.15, linux-azure-fips, linux-fips,
linux-gcp-4.15, linux-gcp-fips, linux-kvm, linux-oracle, linux-aws-5.4, linux-hwe-5.4, linux-azure-fips, linux-fips, linux-raspi, linux-raspi-5.4, nano, postfix, robocode, tomcat6, tomcat7, and yard).

Good night, and good luck, motherf*ckers

Post Syndicated from Дарина Сарелска original https://www.toest.bg/good-night-and-good-luck-motherf-ckers/

Good night, and good luck, motherf*ckers

С думите „Мълчанието е краят на свободата“ един белокос американски журналист закрива централната емисия новини на CBS на 9 януари 2015 г. Часове по-рано двама въоръжени терористи са нахлули в редакцията на френското сатиричното издание Charlie Hebdo в Париж, за да убият 12 души, включително някои от най-известните френски карикатуристи. Не харесвали карикатурите им. 

„Врагът знае къде сме уязвими“, казва Скот Пели във финала на онази емисия. 

Силата на един народ зависи от качеството на информацията, която получава. А когато журналистите бъдат принудени да мълчат, свободата започва да изчезва. Мълчанието е краят на свободата.

Пауза, общ план, светлините угасват, преливка към черно, музика, финална шапка. 

Единайсет години по-късно същият този американски журналист е уволнен дисциплинарно. На Доналд Тръмп не му харесва предаването, в което той работи. А новинарят ветеран вече трябва да защитава мисията на журналистиката не от терористи в чужда държава, а доста по-близо до дома. „Вие убивате „60 минути“, казва той на собствените си началници, обвинявайки ги публично в некомпетентност, задкулисни сделки и политически натиск. 

Бунтът на кореспондентите 

В понеделник сутринта екипът на „60 минути“ се събира на планьорка да се запознае с новия изпълнителен продуцент на предаването, избран лично от наскоро инсталираната шефка на новините Бари Уайс – консервативна коментаторка без телевизионен опит, промотирана официално с идеята да направи новините „по-балансирани“ и съобразени с вкуса на „по-голяма част от Америка“. Неофициално – да ги калибрира по вкуса на Доналд Тръмп, който открито е заявявал своята неприязън конкретно към „60 минути“ и изобщо към журналистите като „враговете на народа“

Срещата е дни след Черния четвъртък – така журналистите в екипа наричат серията уволнения няколко дни по-рано, когато Уайс е опразнила столчетата на двама от дългогодишните продуценти на шоуто заедно с две от най-опитните кореспондентки – Шарън Алфонси и Сесилия Вега. Малко преди тях по свое желание си е тръгнал Андерсън Купър, а година по-рано и легендарният изпълнителен продуцент на предаването Бил Оуенс, който обяснява решението си с корпоративни промени, пречещи му да си върши работата. 

Напуснатите вече говорят открито за цензура, натиск за смекчаване на тона и масажиране на фактите. Най-често в полза на Израел и Белия дом. 

„Нямате необходимата квалификация. Доведени сте, за да унищожите „60 минути“ и точно това правите“, казва в прав текст Пели на ръководството под аплодисментите на своите колеги. И настоява да знае защо колегите му са уволнени. Вместо отговор получава упреци от ръководството, че е „груб“. 

Но Пели не отстъпва: 

Знаете ли кое беше грубо? Черният четвъртък беше груб. Да кажеш на Таня Саймън, че трябва да си тръгне до пет часа̀. Да изпратиш Драган Михайлович в отдел „Човешки ресурси“, за да бъде уволнен, защото никой не е могъл да го погледне в очите. Да не обсъдиш договорите на Шарън Алфонси и Сесилия Вега. Просто да ги извикаш и да им кажеш, че са уволнени. Това е грубост. Това тук е разговор. Онова беше грубост. И вие участвахте в нея.

Черен бланк. Тишина. Няма музика. А финалната шапка идва на следващия ден, когато Пели е поредният уволнен. 

Тo speak truth to power („да говориш истината в очите на властта“) – един от фундаменталните принципи на американската журналистика не издържа собствения си вътрешноведомствен стрес тест. След над половин век в професията един журналист си тръгва заради въпроси и заради „лошо поведение“. Защото е казал истината в лицето на властта. Защото мълчанието, както разбрахме, е краят на свободата. 

Няма повече въпроси

Ден по-късно в онлайн среща Бари Уайс застава пред екипа и обяснява уволнението с „нарушено доверие“ и липса на „взаимно уважение“. Изказва и благодарности за дългогодишната работа на ветерана Пели. Този път няма допълнителни въпроси от екипа. Смразяващият ефект на поголовната сеч на най-големите имена в редакцията тепърва ще дава своите плодове – и вътре в екипа, и в гилдията, и в обществото. А доволен, разбира се, ще е основно Тръмп. И Дейвид Елисън – медийният магнат, собственик на Skydance, който, след като придоби Paramount и CBS, сега чака държавно ОК за поредната си мегахапка – този път пакетът е CNN, HBO и редица филмови студиа. Залогът е 110 млрд. долара, а на пътя отново стоят само няколко подписа на държавни служители, назначено от Тръмп. 

Познато ли ви звучи? Неизбежно е – след като отвъд океана вече се прилагат тактиките на Виктор Орбан и балканските олигарси за превземане на медии, няма как да не ни се стори мила и родна тази картинка. 

С уговорката, че да сравняваме Америка с България, CBS с Нова телевизия и „60 минути“ с който и да е нашенски сутрешен блок е като да сравняваме терористите от Charlie Hebdo с орките на ПИК и „Блиц“, но все пак накрая ще стигнем до някои неизбежни паралели. С признателност и благодарност, че и тук, и там – в Америка, все още властта не убива журналисти. Само ги умълчава. И това изглежда съвсем достатъчно. 

Историята на една предизвестена смърт 

За американската публика „60 минути“ е институция. Повече от половин век предаването задава стандарта за телевизионна журналистика, разследвания и дълбочинни интервюта. Всяка неделя вечер в 19:00 започва познатото тиктакане на часовника, превърнало се в една от най-разпознаваемите емблеми на американските медии. 

Последващите 60 минути често опаковат историите, които задават тона както на политическия разговор във Вашингтон, така и на разговорите около масата за вечеря в милиони американски домове. Дори и днес, във време, когато телевизионната аудитория намалява, а онлайн платформите променят начина, по който хората консумират новини, и въпреки дългогодишните пропагандни атаки на Тръмп и на влиятелни консервативни подкастъри срещу „либералния уклон на старите медии“, „60 минути“ си остава най-гледаното новинарско предаване в Съединените щати.

Най-близката аналогия за българската публика вероятно би била комбинация между най-силните години на „Всяка неделя“ и „Панорама“. Минус Държавна сигурност. Плюс много пари. Докато ролята на комунистическите служби дълбоко опорочават българския златен век на телевизията, тук става дума за поколения журналисти, изграждани въпреки комерсиализма в професионалната култура и традициите на политическа автономност и с огромно влияние над културното ДНК на нацията. 

Корените на тази култура водят към легендарния журналист Едуард Р. Мъроу. Именно неговото леко дръзко, леко високомерно Good night, and good luck се превръща в запазена марка и символ на гръбнака, характера и дори дозата „лошо възпитание“, необходими на един журналист, за да се изправи срещу властта в най-мрачните години на маккартизма, когато Америка преследва различните по убеждения и идеология. Днес същата институция, която превърна тези думи в свое знаме, изглежда, не е готова да плати цената на това наследство. 

Предизвестената смърт на легендарното американско предаване започва почти веднага след изборите, които връщат Доналд Тръмп в Белия дом за втори мандат.

Поводът е интервю на Камала Харис за „60 минути“ по време на предизборната кампания. Тръмп обвинява CBS, че е манипулирала монтажа на разговора, и завежда дело срещу телевизията за намеса в изборите. По това време почти всички медийни и правни експерти са единодушни, че подобен иск няма никакви шансове за успех в американски съд. Но точно тогава Paramount чака извънредно важно регулаторно одобрение за многомилиардната сделка по придобиването ѝ от Skydance. И избира да сключи извънсъдебно споразумение и да плати 16 млн. долара на кампанията на Тръмп, макар и без да признава вина. 

Именно тук започват първите сериозни съмнения. Дали това е просто бизнес, или червен флаг, че една от най-големите медийни компании в Америка е готова да прави редакционни компромиси в името на по-големи корпоративни интереси?

Дългогодишният продуцент на „60 минути“ Бил Оуенс напуска в разгара на тази криза и разсейва съмненията. В продължение на десетилетия Оуенс е един от пазителите на редакционните стандарти на предаването. При напускането си заявява, че вече не може да гарантира независимостта, необходима за работата му, тъй като корпорацията има други приоритети.

Следващият курбан, даден на олтара на това необходимо приятелство между династията Елисън и президента Тръмп, е Стивън Колбер. Само дни след като назовава в ефир споразумението между Paramount и Тръмп „огромен подкуп“, CBS обявява края на неговото The Late Show. Малко по-късно държавното одобрение за придобиването в крайна сметка е получено, а Тръмп дори приема да даде интервю за „60 минути“. 

Предаването обаче си остава следваща мишена за отстрел от Тръмп. С десетки постове в своята социална мрежа Truth Social президентът атакува журналистите на програмата, наричайки ги „измамници“ и „политически функционери“, като заплашва открито с отнемане на лицензи. Резултатът не закъснява – точно когато на тезгяха е нова огромна бизнес хапка: фамилията Елисън е на път да придобие и CNN заедно с апетитен пакет развлекателни медийни брандове. И пак се чака един подпис, който няма как да дойде без кимане от Белия дом. 

Когато президентът едва ли не казва „Ще използвам силата на държавата, за да си осигуря медии, каквито си харесвам“ и когато се заобиколи с приятели олигарси, които получават лъвския пай от бизнес сделки срещу политически услуги, ние в Източна Европа нямаме никакво съмнение какво се случва. Хронологията е ясна и тенденцията за политическо quid pro quo, макар и юридически недоказуема, е видима с просто око.

Как се стига до Черния четвъртък

Хронология на сделките, натиска и редакционните отстъпки


Skydance обявява сделка за придобиване на Paramount, собственик на CBS, за 8 млрд. долара. Необходимо е одобрение от Федералната комисия по комуникации.


Доналд Тръмп печели президентските избори. Малко преди това завежда дело срещу CBS заради интервюто на Камала Харис в „60 минути“.


Тръмп встъпва в длъжност. Paramount още чака одобрение на сделката със Skydance.


След 22 години начело на „60 минути“ Бил Оуенс подава оставка. Заявява, че вече не може да взема независими редакционни решения.


Paramount плаща 16 млн. долара по извънсъдебно споразумение с Тръмп, без да признава вина.


В ефира на CBS Стивън Колбер нарича споразумението с Тръмп „огромен подкуп“.


CBS обявява, че прекратява шоуто на Стивън Колбер, считано от май 2026 г.


Федералната комисия одобрява сделката между Paramount и Skydance.


Бари Уайс е назначена за главна редакторка на CBS News. Решението е спорно заради липсата на телевизионен новинарски опит.


Шарън Алфонси обвинява ръководството, че е спряло неин репортаж за депортирането на мигранти към затвора CECOT в Ел Салвадор по политически причини.


Paramount Skydance обявява споразумение за придобиване на Warner Bros. Discovery в сделка за около 110 млрд. долара.

Масови уволнения в „60 минути“. Решението за сливането на Paramount Skydance и Warner Bros. Discovery се очаква до два месеца.

Парадоксът е, че като цяло телевизията, която е най-пострадала в борбата с рейтингите (в последните години CBS традиционно изостава зад ABC и NBC), в крайна сметка решава да убие двете си най-рейтингови програми. Шоуто на Стивън Колбер беше лидер сред късните вечерни програми в Америка до спирането му миналия месец. „60 минути“ остава най-гледаното новинарско предаване в страната повече от половин век след създаването му. Това са двете марки, които продължават да носят престиж, влияние и публика на CBS, и то не само по телевизора. И Колбер, и „60 минути“ продължават да събират милиони гледания и споделяния онлайн. На теория това са програмите, които една телевизия би трябвало да пази най-много.

Само че рейтингите вече не са това, което бяха, а телевизионният бизнес – такъв, какъвто го познаваме, е на доизживяване. 

Така за семейство Елисън залогът не са няколко рейтинг точки повече, а многомилиардните сливания, придобивания и корпоративни сделки, които зависят от благоволението на регулатори и политици. Както казваше Ахмед Доган, „поне едно кимане от нас трябва“. Доказателства за пряка сделка няма. Но няма и друг възможен отговор на въпроса защо една телевизия би жертвала най-ценното си.

Може би защото, докато телевизията престава да бъде апетитен бизнес сама по себе си, все още има някакво влияние, което ѝ позволява да бъде инструмент за бизнес. Валута за разкешване. Ефирът става фасада, а журналистиката – разменна монета в една много по-голяма игра. Място, на което се изграждат отношения, печели се достъп и се договарят решения, струващи много повече от рекламното време между две новинарски емисии. Този завой в бизнес модела е далеч по-видим на малки пазари като нашия, където парите просто свършват по-бързо. 

Големите търговски оператори у нас, като част от мултинационални компании с разнородни бизнес интереси, отдавна практикуват този модел. В него телевизията е само рекламна витрина, през която се отварят (или затварят) врати към далеч по-доходоносни сделки и индустрии.

За семейство Елисън това може да означава филмови студиа, стрийминг платформи и развлекателни империи. За далеч по-скромния български пазар – телекомуникации, обществени поръчки, инфраструктурни проекти, влакове, мотриси – всичко зависи от политическата благосклонност. А тя се договаря на мегдана на телевизора. 

Същото, ама различно

С това паралелите между Америка и България като че ли се поизчерпват.

Ние нямаме нито „60 минути“, нито Стивън Колбер. Имаме Слави Трифонов. Нямаме Бил Оуенс, имаме Антон Хекимян. Нямаме Скот Пели, имаме Бареков. Българската Бари Уайс е жена с много имена, но среща като тази с екипа на „60 минути“ не мисля, че някога ѝ се е случвала.

Иначе, и в Нова телевизия чакаха одобрение за придобиване от братята Кирил и Георги Домусчиеви през 2019 г. И го дочакаха. След серия от черни четвъртъци, макар и не само в четвъртък, прочистили десетки знакови лица на медията. Тогава покойният вече чешки бизнесмен Петр Келнер не успя да получи кимване от когото трябва. Компенсираха го малко по-късно с bTV, където също в годините последваха санитарна сеч и уволнения с благодарности – за лошо поведение и неподходящи чаши. По своя път минаха и БНТ, и БНР, макар и не толкова успешно. 

И у нас политическите чистки в медиите обикновено се обясняват с купешки клишета за нарушени стандарти за обективност, плурализъм и баланс. Fair and balanced („честно и балансирано“), между другото, е мотото на всички бариуайски по света и у нас.

Схемата може и да е същата. Но съпротивата не е. С изключение на БНР, където гилдията се надигна и предотврати уволнението на Силвия Великова. 

Съществена е и друга разлика. Битова е, но не е незначителна и обяснява тишината, с която се убиват медии у нас. Повечето от споменатите американски журналисти излизат извън ефир вече милионери. Пазарът е огромен, а публика дебне отвсякъде. 

У нас малкото независими гласове, отстранени и изтъргувани срещу някой подпис или кимане за милиони, живеят от заплата до заплата, не могат да си платят нито сигурността, нито адвокатите, докато се изправят срещу лицата на одържавената българска мафия, борят се за миниатюрна аудитория и често плащат много по-висока лична цена. 

Но да, журналистиката, дори опакована в бизнес модел, все пак си остава кауза. И мисия. В услуга на обществото. Иначе от нея няма смисъл.

Неслучайно през последните седмици социалните мрежи зад океана започнаха да преработват емблематичното сбогуване на Мъроу в далеч по-мрачен и гневен вариант:

Good night, and good luck, motherfuckers.

В наши дни фразата заживя собствен живот като бунтарска и саркастична версия на оригинала. След кризата около CBS тя се превърна в нещо средно между хаштаг и среден пръст към институцията, пре/продала собствените си принципи. За мнозина тя е и символично сбогуване с американската илюзия за непробиваемата защита на Първата поправка.

Най-добре го каза един американски студент, получил в пика на скандала стипендия именно от CBS, за да следва журналистика. Застанал до Скот Пели по време на раздаването на наградите „Еми“ за журналистика („60 минути“ печели две статуетки, между другото, ако искате да видите как животът имитира началото на „Дяволът носи Прада“ 2), 18-годишния Сантяго Кампос казва тези думи и изправя на крака целия журналистически елит в залата: 

Искам да благодаря на CBS News за тази щедра подкрепа за образованието ми. Но искам също да отбележа, че докато корпоративните елити все по-силно овладяват каналите, по които достига информацията до обществото, журналистиката в служба на хората става все по-трудна за намиране, но и все по-необходима. А това, което хората искат, е истината. Затова, ако някога се поколебаете да произнесете думата „геноцид“ или предпочетете да замълчите пред очевидни лъжи, запитайте се: „За кого го правя?“ Надявам се да изберете нас.

Това е. 

А алтернативата:

Good night, and good luck, motherfuckers.

Прогресът на Радев тръгва с остеритет

Post Syndicated from Емилия Милчева original https://www.toest.bg/progresut-na-radev-trugva-s-osteritet/

Прогресът на Радев тръгва с остеритет

Съдебната реформа е поставена на стендбай, а правителството на Румен Радев спешно търси пари – от пенсионерските ковид добавки до административните разходи. Налага се да прави и инвентаризация на скелетите в гардероба, за да оправдае обещанията за борба с корупцията. Така приключва първият месец на новото мнозинство, получило твърде много политически капитал и твърде малко финансова свобода за действие. 

Каквито и наследени договори, съмнителни (и) неразплатени разходи или неизгодни решения да открива новата власт, ще трябва да намери трудното решение как да финансира собствените си политики, като се побере в лимита за дефицит от 3% от БВП. 

Европейската комисия препоръча да започне процедура за прекомерен дефицит спрямо България, очаквайки превишение на разходите над приходите от 4,1% за 2026 г. и 4,3% за 2027 г. Последната дума има Съветът на ЕС. Ако предложението бъде прието, публичните финанси на България ще бъдат под надзора на Европейската комисия през следващите няколко години. Ще се наложи кабинетът да представи план с коригиращи мерки, който да договори с Европейската комисия, и до 6 месеца да започне да го изпълнява.

Амбициите на вицепремиера и финансов министър Гълъб Донев са да бъде свита дупката в бюджета до края на 2026 г. и чрез орязване на разходите да се измъкне от процедурата, за да избегне властта на надзора от Брюксел. 

Правителството тепърва ще внася бюджета за 2026-та през юли, което означава, че в последните пет месеца на годината държавата ще работи с ограничен ресурс. Причината е, че Министерството на финансите (МФ) настоява да получи заявки за бюджет, който е 90% от миналогодишния, макар че през изминалите месеци структурите на бюджетна издръжка са харчили без такъв лимит.

Междувременно управляващите разкриват наследените задължения. Към май 2026 г. общият размер на неразплатените разходи от 2024, 2025 и началото на 2026 г. е бил 2,2 млрд. евро. Те включват фактурирани, но неплатени проекти на Агенция „Пътна инфраструктура“ и на общините, като тези разходи са заложени в закона за бюджета, но без да бъдат осигурени необходимите средства. 

Допълнителен риск за бюджета идва от проектите по Плана за възстановяване и устойчивост (ПВУ). По тях МФ първо плаща на изпълнителите с бюджетни средства, а едва след това подава искане за възстановяване към Европейската комисия при изпълнение на съответните етапи и цели. Това означава, че всяко забавяне на реформите или на плащанията от Брюксел временно прехвърля тежестта върху българския бюджет. Така МФ се оказва принудено да финансира проекти, за които формално има европейски ресурс, но реално парите може да пристигнат много по-късно. Или да не дойдат, ако някоя от целите в Плана не е изпълнена от българските власти. 

Все още не е обявено публично каква е сумата на декларираните по ПВУ за разплащане проекти. 

България има и задължения по „президентския“ договор с турската компания „Боташ“, по който до май 2025 г. са платени 600 млн. лева (306,8 млн. евро), макар да е бил използван капацитет за 15 пъти по-малка сума. Ежедневно задължението на българската страна е за 1,05 млн. лв. (536 900 евро).

Темата за „Боташ“ се появява и изчезва от обществения интерес с променлива интензивност, но се зашумя отново, когато бившият енергиен министър, участвал в сключването на договора, беше назначен в Държавната консолидационна компания. Постът му стана причина лидерът на „Продължаваме промяната“ Асен Василев да обяви, че възнаграждението на Росен Христов ще е 11 160 евро, или 18 минимални работни заплати, какъвто е таванът по закон. 

По-късно председателят на парламентарната група на „Прогресивна България“ Петър Витанов съобщи по bTV, че заплатата ще е 1878 евро, а Христов заплаши със съд лидера на ПП.

Проблемът за новото правителство е, че сега ще търси средства не за да реализира своите политики, а за да плаща за решения, взети от предишните управления и превърнали се в задължения на държавата. 

Неизбежното: съкращения и реформи

Парадоксално, но факт. Натовареното с най-големи очаквания правителство след години на политически кризи ще трябва да ореже публични разходи, да извърши съкращения, да намали дела на сивата икономика и корупцията, ако иска да си осигури някакво финансовото благополучие и обществен престиж. Процедурата за прекомерен дефицит му развързва ръцете да предприеме непопулярни мерки, например дългоочакваната административна реформа. Абсолютното мнозинство, с което разполага, пък му осигурява необходимата подкрепа без напрежение от коалиционни партньори. 

Проблемът е, че икономическата и политическата логика рядко съвпадат. 

В следващите месеци кабинетът ще трябва едновременно да съкращава разходи и да убеждава избирателите, че управлява успешно. И това в навечерието на президентски избори и година преди местния вот, когато всяко евро за инвестиции в общински проекти има и политическа стойност. 

Кметовете, които се канят да се присъединят към „Прогресивна България“, ще очакват финансиране на инвестиционните си проекти.

Гласувалите за Румен Радев близо 1 445 000 български граждани, които очакваха от него „да оправи държавата“, „да сложи ред“, не са очаквали остеритет. 

Според Радев „тежкото наследство, което получаваме, е резултат на безхаберие, некомпетентност, волунтаризъм, популизъм и грабеж“. 

Всички българи ще плащаме вересиите на олигархията и на предишните управления.

Това обяснение вероятно ще e убедително за някои избиратели. Проблемът е, че част от решенията, които днес натоварват бюджета, бяха вземани и от служебни кабинети, назначавани именно от президента Радев. 

От ковид пандемията насам почти всяко управление добавяше нови постоянни разходи, без да осигурява устойчив източник за финансирането им. Временните антикризисни мерки, като интегрираните в пенсиите добавки и енергийните помощи за бизнеса, постепенно се превърнаха в трайни ангажименти. Социалните плащания и заплатите в публичния сектор растяха с темпове, които изпреварваха реалния икономически растеж. 

Автоматичният механизъм за МВР и Министерството на отбраната се превърна в голям бюджетен проблем през миналата и тази година, когато започна да генерира двуцифрени годишни увеличения на възнагражденията, независимо от общото състояние на бюджета. 

Тези политики на правителствата в последните пет години, които се изпълняваха и от назначените от президента Румен Радев служебни кабинети, дебалансираха бюджета. Върху тях тежат и безпринципните назначения в държавната администрация. Новата власт ще обяви огромните заплати, от порядъка на 20–25 000 евро, раздавани в държавни дружества и предприятия, които при това са на загуба.

Инвентаризацията на наследството включва и твърдения за злоупотреби при големи инфраструктурни проекти. Регионалният министър Иван Шишков вече обяви, че има подадени сигнали до прокуратурата за строителството на автомагистрала „Хемус“ и за обществени поръчки по европейски програми, поставили под риск около 127 млн. евро европейско финансиране. 

Като президент обаче Радев не е критикувал обвързаните с минималната и средната работна заплата увеличения в силовия сектор. Нещо повече, във втория си мандат като държавен глава беше критикувал по-високите повишения в МВР, а не в Министерството на отбраната.

Засега е ясно, че ще отпаднат автоматичните увеличения на заплатите в съдебната система и висшето образование. Дали правителството ще посмее да отреже МВР и Министерството на отбраната, които по закон трябва да получат със задна дата увеличените си отново от 1 януари 2026 г. възнаграждения? 

Във Вътрешното министерство има и друг проблем – работещите пенсионери. Според отговор на министър Демерджиев на парламентарен въпрос от Мартин Димитров от „Демократична България“ към 30 април техният брой е 1098.

Засега управляващите говорят основно за съкращаване на разходи. Правителството се отказа да купува ракети за F-16 за 957 млн. долара заради липсата на средства.

Първите, които ще усетят остеритета, са пенсионерите – социалната група с най-ниски доходи. В действителност от 1 юли пенсиите им ще се увеличат с по-малко от 7,8%, защото от сегашните суми ще бъде извадена ковид добавката от 30,68 евро, а в отпуснатите нови пенсии изобщо ще липсва. Няма всички пенсионери да умрат заради 2 евро, каза Константин Проданов от „Прогресивна България“ в спор с лидера на „Продължаваме промяната“ Асен Василев.

За хората с най-ниски доходи обаче 2 евро тежат много повече от 1,09 евро по-малка субсидия за партиите, които занапред ще получават по 3 евро за всеки действителен глас. 

Депутатите все още не са премахнали автоматичното увеличение на заплатите им на всеки три месеца. Тяхното основно възнаграждение се равнява на три средни в обществения сектор и в момента е 4326 евро, като към него се получават добавки за комисии и безотчетните ⅔ от тази сума за сътрудници, наем на офиси и др.

Изглежда невъзможно България да се върне към правилата от времето на валутния борд, когато държавата не си позволяваше да харчи повече, отколкото получаваше. Как ще бъдат съкратени разходите и кои социални групи ще понесат тази тежест, ще проличи още при съставянето на бюджета за тази година.

Някои икономисти вече предупреждават, че ако бюджетната консолидация не даде резултат, процедурата по свръхдефицит може да доведе не само до ограничения на разходите, но и до натиск за повишаване на данъци.

Първият месец от управлението не даде отговор дали Румен Радев ще успее да изпълни обещанията за по-малко корупция и по-ефективна държава. 

Ако мнозинството обаче успее да превърне бюджетната криза в повод за реформи, може да излезе по-силно от нея. Ако се ограничи до счетоводни икономии и търсене на виновни, ще остане поредното управление, което е управлявало дефицита, вместо да се занимава с причините за него. След бюджета следва тестът със съдебната реформа.

Въпросът е дали избирателите могат да бъдат убедени, че остеритетът е промяна. 

Dave Airlie on Linux Kernel Maintenance (SE Radio)

Post Syndicated from corbet original https://lwn.net/Articles/1076478/

The Software Engineering Radio podcast has put up an
interview with graphics maintainer Dave Airlie
. Much of what is in
there will not be news to LWN readers, but it is an interesting overview of
the life of a large-subsystem maintainer.

I was talking to a few of the Rust people, and I thought: these are
very young people, these are a group of people in their 20s, maybe
30s, they are a younger cohort of developers than the people I am
normally used to dealing with. I thought there was maybe a good
way we could bring these groups together. I think that having
young people coming into the kernel using Rust is valuable… So I
thought that I should be supportive of bringing Rust into the
kernel.

Query Amazon Redshift using natural language with Kiro

Post Syndicated from Hitesh Dodiya original https://aws.amazon.com/blogs/big-data/query-amazon-redshift-using-natural-language-with-kiro/

It’s Monday morning and your VP pings you: “Revenue dropped 15 percent over the weekend. What happened?” The clock starts. You open the AWS Management Console, find the right Amazon Redshift cluster, open the query editor, and start hunting. Which database has the revenue data, analytics_db or reporting_db? Is the table called orders, transactions, or sales_events? You find it, but now you need the schema. Is the amount column total_amount, revenue, or order_value? 20 minutes in, you haven’t answered the question. You’ve been navigating infrastructure.

This scenario plays out daily across data teams, and it’s why the landscape is shifting. With AI agents entering the analytics workflow, a growing number of business users can now perform complex data analysis. They no longer need to file a ticket with the data engineering team and wait days for a response. The bottleneck is no longer SQL expertise. It’s the friction between having a question and getting an answer.

The Amazon Redshift MCP server paired with Kiro removes that friction. Instead of memorizing cluster endpoints, reverse-engineering schemas, and hand-writing SQL, you describe what you need in plain text and get results. That Monday morning question becomes a single sentence: “Show me daily revenue for the past two weeks, broken down by region.” Kiro finds the cluster, discovers the schema, writes the query, and returns the answer in seconds, not minutes.

In this post, you learn how to:

  1. Install and configure Kiro with the Amazon Redshift MCP server.
  2. Discover clusters, databases, and schemas using natural language.
  3. Run analytical queries and cross-cluster comparisons conversationally.
  4. Implement security best practices for production Amazon Redshift environments.

You can use Kiro in two forms: Kiro integrated development environment (IDE), a full desktop development environment, and Kiro command line interface (CLI), which brings the same AI capabilities directly to your terminal. The Redshift MCP server works with both. The CLI experience is particularly well suited for the conversational analytics workflow this post describes, because you can start querying your data warehouse from a terminal session without opening an IDE.

Important: Before using this integration with production Amazon Redshift environments, read the Security tips section. This section covers critical considerations around AWS Identity and Access Management (IAM) permissions and Kiro autonomy modes.

What is the Amazon Redshift MCP server?

The Model Context Protocol (MCP) is an open standard that provides AI agents with secure connections to external data sources and tools. The Amazon Redshift MCP server is an open source implementation that bridges the Kiro AI agent with your Amazon Redshift infrastructure.

With the Redshift MCP server, you can:

  • Automatically find both provisioned clusters and serverless workgroups with cluster discovery.
  • Browse databases, schemas, tables, and columns with metadata exploration.
  • Run SQL in READ ONLY mode with built-in safety protections with safe query execution.
  • Work with multiple clusters and workgroups simultaneously with multi-cluster support.

The server translates your natural language requests into the appropriate Amazon Redshift Data API calls and SQL queries. No manual endpoint configuration or SQL writing is required.

How the Redshift MCP server relates to the AWS MCP server

You might have noticed that AWS also offers the AWS MCP server (part of the Agent Toolkit for AWS), which provides broad access to AWS services, including the Redshift Data API. A common question is: if the AWS MCP server can already reach Redshift, why add a dedicated Redshift MCP server?

The two are complementary, not competing. The AWS MCP server gives Kiro general AWS capabilities (service decision guides, SDK usage guidance, troubleshooting skills, and access to AWS APIs). The Redshift MCP server adds a purpose-built analytics layer on top. It provides single-call query execution (compared to a minimum of three API calls for submit, poll, and fetch), read-only safety by default, transparent provisioned and serverless cluster handling, and dedicated metadata navigation tools. Upcoming features like query plan explanation, native identity propagation, cluster analysis, and UDF discovery will further extend this specialized layer.

You can use both together, or use the Amazon Redshift MCP server on its own. There’s no either-or requirement.

Setting it up

The following sections walk you through the installation and configuration process.

Prerequisites

Before you begin, make sure that you have:

On your machine:

  • Kiro IDE or Kiro CLI installed.
  • Python 3.10 or newer.
  • The uv package manager from Astral.

On AWS:

  • AWS credentials configured through the AWS Command Line Interface (AWS CLI), environment variables, or IAM roles.
  • At least one Amazon Redshift provisioned cluster or serverless workgroup.
  • IAM permissions for Amazon Redshift access (see the following section).

Step 1: Install the uv package manager

If you don’t have uv installed, run one of the following commands.

For macOS or Linux:

curl -LsSf https://astral.sh/uv/install.sh | sh

For Windows PowerShell:

powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Then install Python 3.10 or newer if needed:

uv python install 3.10

Step 2: Configure IAM permissions

Your AWS identity needs the following permissions. Attach this policy to your IAM user or role:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "redshift:DescribeClusters",
        "redshift:GetClusterCredentialsWithIAM",
        "redshift:GetClusterCredentials",
        "redshift-serverless:ListWorkgroups",
        "redshift-serverless:GetWorkgroup",
        "redshift-serverless:GetCredentials",
        "redshift-data:ExecuteStatement",
        "redshift-data:DescribeStatement",
        "redshift-data:GetStatementResult"
      ],
      "Resource": "*"
    }
  ]
}

You also need database-level permissions: SELECT on tables you want to query, USAGE on schemas you want to explore, and connection access to the target databases.

Step 3: Configure the MCP server in Kiro

Open (or create) your Kiro MCP configuration file and add the Amazon Redshift server.

For Kiro IDE:

  1. User-level configuration (applies globally): ~/.kiro/settings/mcp.json.
  2. Workspace-level configuration (applies to a specific project): .kiro/settings/mcp.json.

For Kiro CLI:

  1. User-level configuration: ~/.kiro/settings/mcp.json.
  2. Workspace-level configuration: .kiro/settings/mcp.json in your project directory.

The configuration format is the same for both. Add the following:

{
  "mcpServers": {
    "awslabs.redshift-mcp-server": {
      "command": "uvx",
      "args": ["awslabs.redshift-mcp-server@latest"],
      "env": {
        "AWS_PROFILE": "default",
        "AWS_DEFAULT_REGION": "us-east-1",
        "FASTMCP_LOG_LEVEL": "ERROR"
      },
      "disabled": false,
      "autoApprove": []
    }
  }
}

Tip: Replace AWS_PROFILE and AWS_DEFAULT_REGION with values matching your environment. If you use AWS_REGION instead of AWS_DEFAULT_REGION, AWS_REGION takes higher precedence.

Note: Windows users: use uv instead of uvx with additional args. See the Amazon Redshift MCP server documentation for the Windows-specific configuration.

Step 4: Verify the connection

In Kiro IDE, restart Kiro (or reconnect MCP servers from the MCP Server view in the Kiro feature panel). Then open the Kiro chat and enter the following prompt:

List my available Redshift clusters

If everything is configured correctly, Kiro discovers your clusters and lists them with details like cluster identifiers, status, node types, and endpoints.

Practical examples

The following scenarios show how Kiro and the Amazon Redshift MCP server work together in real-world workflows.

Tip: If you want Kiro to show the SQL that it executes alongside every result, tell it at the beginning of your session:

For every query you run against Amazon Redshift, show me the exact SQL you executed along with the results.

Kiro follows this instruction for the rest of the conversation. For a permanent setup, add this rule to a steering file (see the Tips section that follows) so you don’t need to repeat it. The following examples reflect this behavior.

Example 1: Discover and explore your infrastructure

Without Kiro: Log in to the AWS Management Console, navigate to Amazon Redshift, choose clusters, open the query editor, sign in to each database, and manually browse schemas.

With Kiro:

What Amazon Redshift clusters and serverless workgroups do I have?

Kiro responds with a structured overview:

Found two provisioned clusters and one serverless workgroup:

  • analytics-cluster (provisioned, 2x ra3.xlplus nodes, available)
  • reporting-cluster (provisioned, 4x ra3.4xlarge nodes, available)
  • etl-workgroup (serverless, available)

Then drill deeper:

What databases and schemas exist in analytics-cluster?

Kiro uses the MCP metadata tools to explore the cluster. No SQL is needed for discovery:

Database: analytics_db (local)

  • information_schema — system schema
  • pg_catalog — system schema
  • public — default schema
  • sales — user-created schema

Database: dev (local)

  • information_schema — system schema
  • pg_catalog — system schema
  • public — default schema

The only user-created schema is sales in the analytics_db database.

Show me the tables in the sales schema of the analytics database

There are five base tables in analytics_db.sales:

  1. customers
  2. order_items
  3. orders
  4. products
  5. returns
Describe the columns in the orders table
Column Type Nullable
order_id INTEGER NO
customer_id INTEGER NO
order_date TIMESTAMP NO
total_amount numeric(12,2) NO
status VARCHAR(20) YES

Each request builds on the previous context. Kiro remembers which cluster you’re exploring and navigates the hierarchy for you.

Example 2: On-demand data analysis in plain English

Without Kiro: Write SQL from scratch, guess at column names, run the query, fix syntax errors, iterate.

With Kiro:

Show me the top 10 customers by total purchase amount from the analytics-cluster,
including how many orders each customer placed

Kiro does the following:

  1. Identifies the relevant cluster and database.
  2. Explores the schema to find customer and order tables.
  3. Understands the table relationships.
  4. Generates and runs the appropriate SQL, showing you the query first.
  5. Presents the results in a readable format.

The response includes the query and results:

Query executed:

SELECT
    c.customer_id,
    c.customer_name,
    COUNT(o.order_id) AS total_orders,
    SUM(o.total_amount) AS total_spent
FROM sales.customers c
JOIN sales.orders o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.customer_name
ORDER BY total_spent DESC
LIMIT 10;
customer_id customer_name total_orders total_spent
4821 Acme Corp 347 $1,284,500.00
1190 Globex Inc 289 $1,102,340.00
7734 Initech LLC 256 $987,210.00

You didn’t need to remember table names, column names, or join conditions. Kiro figured it out by exploring the metadata first. You can see exactly what it ran, copy the SQL, and reuse it.

Example 3: Cross-cluster data comparison

Without Kiro: Open two SQL clients, sign in to different clusters, run similar queries, manually compare results in a spreadsheet.

With Kiro:

Compare the total sales revenue and transaction counts between
analytics-cluster and etl-workgroup for the last quarter.
Are there any discrepancies?

Kiro queries both environments, aligns the results, and provides a comparison, showing every query it runs along the way.

Query executed on analytics-cluster:

SELECT
    COUNT(*) AS total_records,
    SUM(total_amount) AS total_revenue,
    COUNT(CASE WHEN order_date >= DATE_TRUNC('quarter', CURRENT_DATE - INTERVAL '3 months')
        THEN 1 END) AS q4_transactions
FROM sales.orders;

Query executed on etl-workgroup:

SELECT
    COUNT(*) AS total_records,
    SUM(total_amount) AS total_revenue,
    COUNT(CASE WHEN order_date >= DATE_TRUNC('quarter', CURRENT_DATE - INTERVAL '3 months')
        THEN 1 END) AS q4_transactions
FROM sales.orders;

Sales data comparison: Analytics vs ETL.

Metric Analytics Cluster ETL Workgroup Status
Total Records 172,456 172,456 Match
Total Revenue $110,765,431 $110,765,431 Match
Q4 Transactions 38,061 38,061 Match

Because both queries are visible, you can verify that Kiro compared the same metrics on both sides, with no hidden assumptions.

Example 4: Schema documentation on demand

Without Kiro: Manually document table structures in a wiki or spreadsheet. Documentation frequently falls out of date.

With Kiro:

Generate documentation for the tables in the sales schema of analytics-cluster.
Include column names, data types, and notable relationships.

Kiro explores every table using the discovery tools and produces structured documentation.

Table: sales.customers

Column Type Nullable Description
customer_id INTEGER NO Primary key
customer_name VARCHAR(255) NO
email VARCHAR(255) YES
created_at TIMESTAMP NO

Table: sales.orders

Column Type Nullable Description
order_id INTEGER NO Primary key
customer_id INTEGER NO FK to customers
order_date TIMESTAMP NO
total_amount numeric(12,2) NO
status VARCHAR(20) YES

(continues for all tables in the schema…)

You can paste this directly into your team wiki or README, and anyone can rerun the same discovery flow to refresh the docs later.

Example 5: Troubleshooting data quality

Check the orders table in analytics-cluster for any NULL values
in the customer_id or total_amount columns.
How many records are affected?

Query executed:

SELECT
    COUNT(*) FILTER (WHERE customer_id IS NULL) AS null_customer_ids,
    COUNT(*) FILTER (WHERE total_amount IS NULL) AS null_total_amounts,
    COUNT(*) AS total_rows
FROM sales.orders;

Out of 172,456 rows: 0 NULL customer_ids, 3 NULL total_amounts.

Find duplicate order_ids in the sales.orders table and show me
a few examples with their timestamps

Query executed:

SELECT order_id, COUNT(*) AS occurrences, MIN(order_date) AS first_seen, MAX(order_date) AS last_seen
FROM sales.orders
GROUP BY order_id
HAVING COUNT(*) > 1
ORDER BY occurrences DESC
LIMIT 5;

Found two duplicate order_ids: order 88412 (two occurrences), order 91003 (two occurrences).

What's the date range of data in the events table?
Are there any gaps in the daily record counts?

Query executed:

WITH daily_counts AS (
    SELECT DATE(event_date) AS day, COUNT(*) AS record_count
    FROM sales.events
    GROUP BY DATE(event_date)
),
date_range AS (
    SELECT MIN(day) AS start_date, MAX(day) AS end_date FROM daily_counts
),
all_dates AS (
    SELECT (start_date + (n || ' days')::INTERVAL)::DATE AS day
    FROM date_range, generate_series(0, (end_date - start_date)) AS n
)
SELECT a.day AS missing_date
FROM all_dates a
LEFT JOIN daily_counts d ON a.day = d.day
WHERE d.day IS NULL
ORDER BY a.day;

Date range: 2024-01-01 to 2025-04-20. Found three missing dates: 2024-03-15, 2024-07-04, 2024-12-25 (likely holidays).

Every query is right there in the response. You can copy them into your own SQL client, modify them, or save them as reusable scripts.

Tips for getting the most out of Kiro and Redshift

  1. Start with discovery. Begin each session by asking Kiro to list your clusters and explore the database structure. This gives the agent context for subsequent queries.
  2. Be specific about which cluster. If you have multiple clusters, mention the cluster name in your request to avoid ambiguity.
  3. Iterate gradually. Start with simple questions and build complexity. Ask for a count before asking for a full breakdown.
  4. Use steering files for team conventions. Create a .kiro/steering/redshift.md file in your project with details about your cluster naming conventions, important schemas, and common query patterns. This gives Kiro persistent context about your environment.

Example steering file:

---
inclusion: auto
---

# Redshift Environment Context

## Clusters

- **analytics-cluster**: Primary analytics warehouse. Use database `analytics_db`.
- **etl-workgroup**: Serverless workgroup for ETL pipelines. Use database `staging_db`.

## Key Schemas

- `sales`: Customer transactions, orders, and revenue data
- `marketing`: Campaign performance and attribution data

## Conventions

- Always filter by `is_deleted = false` on soft-delete tables
- Date columns use `TIMESTAMP WITHOUT TIME ZONE` in UTC

## Query Transparency

- Always show the exact SQL query text being executed before or alongside the results.
  Users should be able to see, verify, and reuse every query that Kiro runs against Redshift.

That last Query Transparency rule is a small addition with a big impact. By default, Kiro might summarize results without showing the underlying SQL. Adding this steering instruction makes every query visible, which helps maintain consistent behavior across your data team and supports auditing, learning, and trust.

  1. Use hooks for automation. Set up agent hooks to run common validation queries automatically. For example, trigger a data quality check whenever you edit a specific SQL file.
  2. Verify important results. Always cross-check critical business findings with stakeholders before acting on them.

Security tips

When configured with least privilege IAM policies and Supervised mode, the Redshift MCP server provides multiple layers of protection. Under the AWS shared responsibility model, you are responsible for configuring access controls appropriately.

Safety layers at a glance

  • Data stays in your account. The MCP server runs locally, queries run inside your Amazon Redshift cluster, and no data is sent to third-party services.
  • Content not used for training. Enterprise users are excluded from service improvement usage. Free or individual tier users can opt out in Kiro settings.
  • Read-only by default. Every query is wrapped in a read-only transaction, preventing accidental writes.
  • Standard IAM controls. Kiro only gets permissions you’ve explicitly granted.
  • Supervised mode. Review each agent action before it’s applied in production environments.

Important caveat: The read-only enforcement only applies to queries routed through the MCP server’s execute_query tool. Kiro also has shell access. If your IAM credentials have write permissions, direct CLI calls (aws redshift-data execute-statement) bypass this guardrail entirely.

Takeaway: Use least privilege IAM policies (scoped to read and describe operations only) as your primary defense. Avoid broad policies like AdministratorAccess or AmazonRedshiftFullAccess. When IAM is properly scoped, even a direct CLI call cannot perform writes.

Verify Kiro’s output

Kiro is a powerful assistant, but it’s not infallible. Like any AI tool, it can misinterpret your intent, generate incorrect SQL, or present results that look plausible but are wrong. Examples include a misplaced join, a wrong filter, or an aggregation that silently excludes rows. This is especially important when working with production data where decisions have real business impact.

Treat Kiro’s output as a strong starting point, not a final answer. Review the SQL it generates before acting on the results. Use the Query Transparency steering rule (described in the Tips section) so you can see the exact query behind every result. When findings inform business decisions, validate them independently by running the query yourself, cross-checking with a colleague, or comparing against a known baseline.

Summary

Layer What it protects against
MCP server read-only mode Accidental writes through the MCP execute_query tool
Least privilege IAM policy Write operations via any path, including direct CLI calls
Kiro Supervised mode Unreviewed autonomous actions by the agent

Defense in depth: use these layers together for production environments.

What you can achieve with Kiro and Amazon Redshift

Before Now you can
Switch between the console, SQL clients, and documentation Use one interface for discovery, querying, and analysis
Memorize cluster endpoints, database names, and schemas Ask in plain text and let Kiro discover the structure
Write SQL from scratch for every query Describe what you want and get results
Manually compare data across clusters Run single-sentence cross-cluster analysis
Schema documentation is frequently stale Generate fresh docs on demand
Onboarding new analysts takes days New team members can explore immediately

Every minute you spend hunting for a table name or debugging a SQL syntax error is a minute that you’re not spending on actual analysis. You can reduce that overhead by letting Kiro handle the mechanical parts (discovery, navigation, and query construction) so you can focus on the questions that matter to your business.

Cleaning up

If you created Amazon Redshift resources specifically for this walkthrough, or if you no longer need the MCP server integration, follow these steps. They help you avoid ongoing charges and remove the configuration.

  • Remove the MCP server configuration.
  • Detach the IAM policy.
  • Delete test Amazon Redshift resources (if applicable).
  • Uninstall uv (optional).

Conclusion

In this post, you learned how to set up Kiro with the Amazon Redshift MCP server to query your data warehouse using natural language. You explored cluster discovery, schema browsing, analytical queries, cross-cluster comparisons, and data quality checks, all without writing SQL from scratch or switching between tools.

To go further:

  1. New to Amazon Redshift? Get started with Amazon Redshift to create your first cluster or serverless workgroup.
  2. Read the MCP protocol specification to understand how AI agents work with external tools.
  3. Visit kiro.dev for Kiro’s full capabilities, including specs, hooks, and steering files.

As you get comfortable with the basics, try combining steering files with agent hooks to automate recurring workflows like daily data quality checks or weekly schema documentation refreshes.


About the author

Hitesh Dodiya

Hitesh Dodiya

Hitesh is a Database Engineer at Amazon Redshift with over a decade of experience in databases, data warehousing, and analytics. He is passionate about leveraging Gen AI to deliver innovative solutions that solve real customer problems.

Amazon Cognito unlocks advanced capabilities with next-generation infrastructure

Post Syndicated from Howie Li original https://aws.amazon.com/blogs/security/amazon-cognito-unlocks-advanced-capabilities-with-next-generation-infrastructure/

Amazon Cognito recently introduced high-throughput performance for demanding workloads, customer-managed keys for full control over data encryption at rest, and multi- Region replication for business continuity improvement. These capabilities were made possible through a next-generation storage infrastructure designed for extensibility and scale. To deliver this, we migrated hundreds of millions of user profiles, and you probably didn’t even notice. In this post, we walk through what’s new, the architecture behind it, and how we got here with a zero-downtime migration that kept your applications running.

New capabilities now available on Cognito

The migration to the new infrastructure wasn’t just about maintaining existing functionality—it created the foundation for delivering capabilities that solve customer challenges while positioning Amazon Cognito for continuous improvements.

High-throughput performance: The new architecture supports the higher request volumes and scale requirements of modern applications while maintaining the low latency performance that your applications depend on—able to support tens of millions of users per user pool and thousands of transactions per second (TPS).

Customer-managed keys: Customers can now use their own encryption keys stored in AWS Key Management Service (AWS KMS) for encrypting data at rest. This provides enhanced security control and capabilities, giving customers full ownership over their encryption key lifecycle.

Multi-Region replication: Customers can now synchronize their entire user pool data, including user passwords, attributes, and configurations to another user pool in another Region of their choice. This means that customers can implement business continuity strategies and maintain authentication availability in case of a Regional failover, helping their applications remain accessible to users even during unexpected disruptions.

An architecture for innovation

The new architecture uses a purpose-built storage layer designed for extensibility and scale of identity operations. We anchored the new architecture around a set of design tenets:

  • Identity-first design: The storage layer understands user identities. There’s no client-specific business logic and no generalizations beyond identity management; keeping the system focused, portable, and optimized.
  • Avoid one-way doors: Deliver value incrementally while keeping architectural choices reversible, so we can evolve as new needs arise.
  • Backward compatible: Changes to the underlying infrastructure should never break customers’ applications.

These tenets shaped every architectural decision. The architecture separates into independently deployable domains. Previously, while using Amazon Cloud Directory, the service architecture relied on a single data store to persist all customer information. This provided straightforward data traversal mechanisms but required multi-service coordination to adjust database schema when new features were required. The new architecture uses different datasets, allowing them to evolve independently for faster feature iterations.

Migration with zero-downtime

Migrating users requires extreme precautions and a strategy designed to maintain zero downtime and ensure data integrity at every step. Our approach prioritizes both immediate stability and long-term flexibility through the following measures:

  1. Shadow mode validation: We ran customer API requests through both old and new infrastructures simultaneously, comparing response structures, status codes, and behavioral characteristics. The validation was designed so that sensitive information was never exposed in plaintext during comparison. We accounted for known variances—for example, timestamps could differ slightly between systems—so that only meaningful discrepancies surfaced as actionable alerts.
  2. Data backfill: Before switching a user pool to the new infrastructure, we performed a bulk backfill of all existing user records from the legacy system into the new storage. The backfill ran alongside live traffic with dual-write capturing any changes made during the backfill window, ensuring no data loss or stale data. Shadow mode served as the validation layer for the backfill; as we addressed more edge cases in data syncing, shadow mode match rates increased, confirming data completeness before we proceeded to the switchover.
  3. Dual-write architecture: We implemented a system where all identity operations were simultaneously written to both legacy and new services, with comprehensive validation to ensure consistency. Even when a dual-write to the new infrastructure failed, the operation still succeeded in the legacy system, preserving all customer-initiated requests. This means any dual-write failure was contained as an internal consistency issue and not customer-impacting.
  4. Antientropy validation: We implemented a data validation and correction system that continuously compared records across old and new infrastructures, detecting and resolving any data divergence. Anti-entropy scans compared user attributes, credential hashes, group memberships, and configurations, among other records. When true discrepancies were found, the system automatically reconciled them using the legacy system as the source of truth. This layer was able to catch edge cases that shadow mode and dual writes alone could not cover.
  5. Incremental rollout with rollback capability: We established controlled deployment phases with immediate rollback capabilities. After switching a user pool to the new infrastructure, we continued replicating all writes back to the legacy system, ensuring we can revert any user pool to the legacy infrastructure at any point without data loss. If a rollback was needed during migration, an orchestrator replayed entries in timestamp order, syncing user profiles back to the legacy system.

Lessons learned for infrastructure modernization

This modernization taught us valuable principles that apply to any large-scale infrastructure project, therefore we choose to share these learnings to help you perform similar migrations.

  • Customer access patterns drive architecture decisions: Analyzing actual customer access patterns revealed that identity workloads follow predictable patterns, which meant we could adopt a synchronous dual-write approach that balanced completeness with operational simplicity. This principle applies to any domain-specific migration: understand your workload’s actual access patterns before reaching for general-purpose solutions.
  • Behavioral preservation requires techniques beyond traditional testing: Ensuring equivalent functionality across old and new systems was straightforward. Preserving identical API behavior was not. Functional tests validate intended behaviors, but we identified scenarios where customers had built applications around specific API behaviors such that a change could have silently broken their applications. For example, concurrent writes to the same user could resolve to different final states between old and new systems where writes all succeed but outcome diverges slightly. Similarly, customers who write an attribute and immediately read it are affected by the consistency window. Subtle timing differences in when updates become visible could cause stale reads. These aren’t functional failures, but behavior under real traffic patterns can vary. Shadow mode verification surfaced edge cases that automated tests alone would have missed. Invest in these techniques early.
  • Gradual validation builds confidence that testing alone cannot: Layer multiple independent validation techniques, such as shadow mode, dual writes, and anti-entropy scans—each covering a different access pattern. No single approach will catch everything, and the gaps between them are where production issues hide. Incremental rollout with immediate rollback capability lets you validate each step while maintaining the ability to revert quickly.
  • Key principles for your own modernization projects: Invest in purpose-built solutions, design for extensibility, and implement gradual validation. Or use managed services so your infrastructure improves without effort on your part while your applications keep running; helping you focus on your business needs.

Conclusion

In this post, we shared the high-level approach and learnings from the Amazon Cognito infrastructure modernization that create a foundation for modern identity management capabilities. The new Cognito infrastructure is live, delivering capabilities such as customer-managed keys and multi-Region replication. As the migration continues, all Cognito customers will gain access to these capabilities on the same service they rely on today, with no action required.

Ready to modernize your authentication infrastructure? Visit Amazon Cognito to learn more.

If you have feedback about this post, submit comments in the Comments section below.

Howie Li

Howie Li

Howie is a Product Manager at Amazon Web Services, where he strives to make auth easy by default. Outside of work, Howie enjoys exploring cultures and food through travels and making new ice cream flavors inspired by them.

Georgi Baghdasaryan

Georgi Baghdasaryan

Georgi is a Principal Engineer at Amazon Web Services, where he builds identity systems that help organizations securely manage access and authentication at scale. His broader focus is on reliable, high-impact infrastructure that enables customers to operate confidently in the cloud. Outside of work, Georgi enjoys experimenting with new matcha latte recipes and going on long bike rides.

Gain visibility into DDoS attacks with flow logs in AWS Shield Advanced

Post Syndicated from Ken Kitts original https://aws.amazon.com/blogs/security/gain-visibility-into-ddos-attacks-with-flow-logs-in-aws-shield-advanced/

Reconstructing distributed denial of service (DDoS) attack traffic used to mean combining data from multiple sources after the fact. AWS Shield Advanced attack flow logs change that—they capture traffic metadata during attacks so you can pinpoint sources, verify mitigations, and feed your existing analysis pipelines.

Shield publishes logs to Amazon Simple Storage Service (Amazon S3), Amazon CloudWatch Logs, or Amazon Data Firehose using the same CloudWatch Logs delivery infrastructure as other AWS flow logs, so they fit directly into the monitoring and analysis tools you already use.

In this post, you will learn how Shield Advanced attack flow logs capture metadata during DDoS events, what each field in a flow log entry means, and how to enable and configure flow logging for your protected resources.

How DDoS attacks affect your applications

A DDoS attack floods an application with traffic, making it unavailable to users. Infrastructure-layer attacks saturate bandwidth and exhaust connection tables—you see packet loss and timeouts.

Shield Advanced is a managed DDoS protection service that detects and mitigates attacks for Amazon CloudFront distributions, Elastic Load Balancing load balancers, Amazon Route 53 hosted zones, AWS Global Accelerator standard accelerators, and Elastic IP (EIP) addresses. See the AWS Shield Advanced documentation for full coverage details. Initially, Shield Advanced will provide infrastructure-layer attack flow logs for EIP protections, with support for additional resource types to follow.

Key benefits

Flow logs help you understand attacks in several ways:

  • Reconstruct traffic patterns – Query logs after an attack to analyze volume, source distribution, and protocol mix without relying only on aggregate CloudWatch metrics.
  • Identify attack origins – The srccountry and location fields show where traffic originated and which AWS edge location it entered.
  • Verify mitigation behavior – The action field records what Shield did with each flow.

Logs go to Amazon S3, CloudWatch Logs, or Data Firehose. You can then query them with Amazon Athena (a serverless query service for analyzing data in Amazon S3), route them to third-party Security Information and Event Management (SIEM) platforms or build CloudWatch Logs Insights queries (an interactive log analysis feature) without deploying new infrastructure.

What attack flow logs capture

Log records capture source and destination IP addresses and ports, protocol, packet and byte counts, the action Shield Advanced took, and TCP flags. They also include the AWS ingress location where traffic entered and a two-letter country code for the traffic source when available. Logs are written at 5-minute intervals and are available during an active attack and after it concludes.

The maximum file size is 75 MB. If a file reaches that limit within the 5-minute window, the file will be closed, published, and a new file will start. Flow logs support JSON, plain text, W3C, and Parquet output formats and contain the following fields:

Field Description
protection_arn Amazon Resource Name (ARN) of the Shield protection
event_timestamp Timestamp of log generation
version Flow log version number
srcaddr Source IP address
dstaddr Destination IP address
srcport Source port
dstport Destination port
protocol IP protocol number
packets Packet count within the aggregation window
bytes Byte count within the aggregation window
starttime Aggregation window start time
endtime Aggregation window end time
action Action taken by Shield
location AWS ingress location
sampling_rate Sampling rate used during packet processing
tcp_flags TCP flags from the packet
srccountry Two-letter country code for the traffic source

How to configure flow logs for Shield Advanced protected resources

The following steps walk you through creating the CloudWatch Logs delivery resources that connect a Shield Advanced protection to your preferred log destination.

Prerequisites

Before configuring flow logs, make sure you have:

Flow logs incur standard CloudWatch Logs vended log charges, and the destination resources (S3 bucket storage, CloudWatch Logs log group storage, or Firehose data processing) incur separate charges. Review the Vended Logs entry on the CloudWatch pricing page and the pricing for your chosen destination service before enabling flow logs on high-traffic resources.

How it works

Log delivery requires three objects:

  • DeliverySource – Represents the Shield Advanced protection that produces the logs
  • DeliveryDestination – Represents where logs should be sent (Amazon S3, CloudWatch Logs, or Amazon Data Firehose)
  • Delivery – Connects the source to the destination

This three-object model lets you reuse destinations across multiple sources and manage delivery pipelines independently. For example, you can send logs from multiple Shield protections to the same S3 bucket by creating multiple DeliverySource objects that reference the same DeliveryDestination.

Because Shield Advanced attack flow logs use the CloudWatch Logs delivery infrastructure, you can aggregate them across accounts and Regions just like other vended logs. Deliver directly to a centralized S3 bucket with a cross-account policy, replicate CloudWatch Logs log groups using cross-account cross-Region centralization rules, or stream to a shared Firehose stream using cross-account subscriptions. Explore these options to build a unified view of DDoS attack traffic across your multi-account, multi-Region footprint.

Step 1: Create your destination resource

Choose a destination:

Step 2: Configure the destination resource policy (if needed)

The destination resource needs a policy that grants the CloudWatch Logs delivery service write permissions. The policy varies by destination type. For more information, see Logs sent to Amazon S3, Logs sent to CloudWatch Logs, or Logs sent to Firehose.

For Amazon S3 destinations, you have two options:

  • Automatic policy creation: If your bucket has no existing resource policy and you have the s3:GetBucketPolicy and s3:PutBucketPolicy permissions, AWS automatically creates the required policy when you create the delivery in step 6. You can skip to step 3.
  • Manual policy update: If you need to customize the policy or your organization requires pre-approved policies, create the policy manually by following the instructions for Logs sent to Amazon S3.

Step 3: Get your protection ARN

Shield Advanced is a global service and uses the us-east-1 AWS Region for management. Run the following command to list your Shield Advanced protections.

aws shield list-protections \
  --region us-east-1

In the output, copy the ProtectionArn value for the protection you want to log.

Step 4: Create a delivery source

Run the following command to create the delivery source, replace <protection-arn> with the ProtectionArn value from step 3.

aws logs put-delivery-source \
  --name my-shield-delivery-source \
  --resource-arn <protection-arn> \
  --log-type FLOW_LOGS \
  --region us-east-1

The --resource-arn is the ARN of your Shield Advanced protection—not the protected resource itself. Shield Advanced creates a separate protection object that wraps your resource, and flow logs are generated by that protection layer rather than the underlying resource.

Step 5: Create a delivery destination

Run the following command to create the delivery destination, replace <resource-arn> with the ARN of the destination resource you created in step 1.

aws logs put-delivery-destination \
  --name my-shield-delivery-destination \
  --output-format plain \
  --delivery-destination-configuration '{"destinationResourceArn":"<resource-arn>"}' \
  --region us-east-1

The --delivery-destination-configuration parameter takes a JSON object with a destinationResourceArn key whose value is the ARN of your S3 bucket, log group, or Firehose stream.

In the output, copy the value of the top-level ARN field—this is the delivery destination ARN (different from the bucket ARN). You will use this in step 6.

Step 6: Create the delivery

Run the following command to connect the delivery source to the delivery destination, replace <delivery-destination-arn> with the delivery destination ARN from step 5.

aws logs create-delivery \
  --delivery-source-name my-shield-delivery-source \
  --delivery-destination-arn <delivery-destination-arn> \
  --region us-east-1

Step 7: Verify the delivery

Run the following command to confirm the delivery is active.

aws logs describe-deliveries \
  --region us-east-1

After delivery is active, Shield Advanced publishes flow log records to your destination during DDoS events.

Clean up

To avoid ongoing charges, delete the resources you created.

  1. Delete the delivery:
    aws logs delete-delivery \
      --id <delivery-id> \
      --region us-east-1

  2. Delete the delivery source:
    aws logs delete-delivery-source \
      --name my-shield-delivery-source \
      --region us-east-1

  3. Delete the delivery destination:
    aws logs delete-delivery-destination \
      --name my-shield-delivery-destination \
      --region us-east-1

  4. (Optional) Back up flow log data if you need to retain logs for compliance or analysis.
  5. Delete the destination resource. Warning: Deleting the destination resource will permanently delete all flow log data.

    For an S3 bucket:

    aws s3 rb s3://<bucket-name> \
      --force \
      --region <region>

    For a CloudWatch Logs log group:

    aws logs delete-log-group \
      --log-group-name <log-group-name> \
      --region <region>

    For a Firehose stream:

    aws firehose delete-delivery-stream \
      --delivery-stream-name <stream-name> \
      --region <region>

Conclusion

Shield Advanced attack flow logs provide the visibility you need to understand and respond to DDoS attacks effectively. By integrating with your existing observability infrastructure, they deliver actionable insights without requiring new tooling or complex setup. Enable flow logs on your Shield Advanced protections today to gain immediate visibility into attack patterns and strengthen your DDoS defense posture.

Next steps:

For the full reference about flow log configuration, see the AWS Shield Advanced documentation.

If you have feedback about this post, submit comments in the Comments section below.


Ken Kitts

Ken Kitts

Ken is a Technical Account Manager at Amazon Web Services (AWS) with over 20 years of experience in computer networking, including software-defined networking in the financial technology sector. Outside of work, Ken is an avid traveler who enjoys exploring archaeological sites and museums, with Teotihuacan in Mexico as a favorite.

Getting started with Amazon SES Agent Skills for AI-assisted email development

Post Syndicated from Bruno Giorgini original https://aws.amazon.com/blogs/messaging-and-targeting/getting-started-with-amazon-ses-agent-skills-for-ai-assisted-email-development/

Building email infrastructure with Amazon Simple Email Service (SES) involves navigating identity verification, authentication protocols, configuration sets, bounce handling, and deliverability monitoring. Developers often spend time reading documentation and iterating on API calls before getting their first email sent correctly. AI coding agents can accelerate this process, but without domain-specific context, they frequently generate code using the legacy V1 API, skip authentication setup, or miss production requirements like tenant isolation.

Today, we are releasing Amazon SES Agent Skills, an open source set of agent skills that give AI coding agents the context they need to build email integrations correctly from the start. The skills work with Kiro, Claude Code, and any agent that supports the open Agent Skills format.

What are agent skills?

Agent skills are structured context packages that teach AI agents how to use a specific service correctly. Rather than relying on general training data (which may be outdated or incomplete), a skill provides the agent with validated patterns, common mistake avoidance, and step-by-step workflows for a specific domain.

When you install the Amazon SES agent skills, your AI agent gains access to:

  • The correct API version and SDK client to use (SES V2, not V1)
  • The required order of operations (verify identity before sending, create configuration set before going to production)
  • Production-ready patterns including tenant isolation, bounce handling, and email validation
  • Common mistakes and how to avoid them
  • Executable example scripts in Python, Node.js, and Java

Two skills, two use cases

Amazon SES has two distinct capabilities that use different API clients:

Skill Use case SDK client
aws-ses Sending email
(transactional, marketing, notifications)
sesv2
aws-mail-manager Receiving and processing inbound email
(routing, filtering, archiving, SMTP relay)
mailmanager

These are different APIs with different clients. A common mistake agents make without this context is mixing them up or using the legacy ses client for sending.

Installing the skills

Install both skills:

npx skills add amazon-ses/skills

Or install a specific skill:

npx skills add amazon-ses/skills --skill aws-ses
npx skills add amazon-ses/skills --skill aws-mail-manager

Once installed, the skill activates automatically when you ask your agent about email-related tasks.

What the agent experience looks like

After installing the aws-ses skill, ask your agent: “Help me send my first email with Amazon SES.”

Without the skill, an agent might generate code using the deprecated V1 API, skip identity verification, or omit a configuration set. With the skill, the agent follows the correct workflow:

  1. Verifies your identity is set up (domain or email address)
  2. Checks sandbox status and recommends simulator addresses for testing
  3. Creates a configuration set for event tracking
  4. Sets up a tenant for workload isolation
  5. Generates code using the V2 API with proper error handling

Here is an example of what the agent produces for a Python quickstart:

import boto3
from botocore.exceptions import ClientError

client = boto3.client('sesv2', region_name='us-east-1')

try:
    response = client.send_email(
        FromEmailAddress='[email protected]',
        Destination={'ToAddresses': ['[email protected]']},
        Content={
            'Simple': {
                'Subject': {'Data': 'Hello from Amazon SES'},
                'Body': {'Text': {'Data': 'This email was sent using Amazon SES V2 API.'}}
            }
        },
        ConfigurationSetName='my-config-set',
        TenantName='my-tenant'
    )
    print(f"Message sent: {response['MessageId']}")
except ClientError as e:
    print(f"Send failed: {e.response['Error']['Code']} - {e.response['Error']['Message']}")

The agent knows to use sesv2 (not ses), includes a configuration set for observability, uses a tenant for isolation, and sends to a simulator address for safe testing.

What the Mail Manager skill provides

For inbound email processing, the aws-mail-manager skill teaches the agent the core pipeline architecture:

Internet → Ingress Point → Traffic Policy → Rule Set → Action

The skill ensures the agent creates resources in the correct dependency order (traffic policy and rule set before ingress point), uses the correct condition syntax (union types with exactly one key per object), and waits for the ingress point to reach ACTIVE status before recommending DNS changes.

How the skills are structured

Each skill contains:

  • SKILL.md — The entry point that describes capabilities, common mistakes, and when to use the skill
  • references/ — Task-oriented guides for specific workflows (identity verification, configuration sets, tenant setup, troubleshooting)
  • scripts/ or examples/ — Executable code the agent can reference or adapt

The agent loads only the context relevant to your current task. Ask about sending email and it loads the sending guides. Ask about archiving inbound email and it loads the archive reference.

Prerequisites

To use the skills, you need:

  • An AI coding agent that supports the Agent Skills format (Kiro, Claude Code, or compatible tools)
  • An AWS account with Amazon SES access
  • AWS credentials configured (environment variables, shared credentials file, or IAM role)
  • The SDK for your language: Python (boto3), Node.js (@aws-sdk/client-sesv2), or Java (software.amazon.awssdk:sesv2)

Try it today

The Amazon SES Agent Skills are available now on GitHub:

Install the skills, ask your agent to help you send your first email, and see how structured context changes the development experience. If you find issues or want to contribute, open an issue or pull request on the repository.

Additional resources

[$] Splicing out vmsplice()

Post Syndicated from corbet original https://lwn.net/Articles/1075838/

The splice()
and vmsplice()
system calls are meant to improve performance for certain data-movement
tasks by minimizing (or avoiding altogether) system calls and the copying
of data. They also have a long history of security problems. The recent
flood of LLM-discovered vulnerabilities has drawn attention, once again, to
splice() and vmsplice(); as a result, they may end up
being removed altogether.

The collective thoughts of the interwebz