Secure Your AI Agents on AWS (Part 3): State, Communication, and Detection
Part 3 of a three-part series mapping the OWASP Top 10 for Agentic Applications 2026 to AWS security controls. This part covers system-level dynamics: memory and context poisoning (ASI06), insecure inter-agent communication (ASI07), cascading failures (ASI08), and rogue agent detection and containment (ASI10).
This is Part 3 of a three-part series mapping the OWASP Top 10 for Agentic Applications 2026 to AWS security controls. Part 1 covered inputs, identity, and human oversight. Part 2 covered tool execution and runtime safety. This part covers the system's dynamics: memory, inter-agent communication, failure propagation, and detection.
This is a personal post. The views are my own and do not represent AWS. The code samples are illustrative — validate every API shape against the current documentation and Regional availability before you deploy.
In Part 1 I established the framework and secured the agent's boundary with users. In Part 2 I secured what the agent runs. This final part covers the system-level dynamics that emerge once agents persist state, talk to each other, and operate autonomously: ASI06 (memory and context poisoning), ASI07 (insecure inter-agent communication), ASI08 (cascading failures), and ASI10 (rogue agents). These map to the "then expand" tier of the roadmap.
ASI06: Memory and context poisoning
Memory stores, conversation history, or Retrieval Augmented Generation (RAG) knowledge bases can be corrupted with unintended data, causing persistent reasoning corruption that affects your agent's future interactions.
A travel agent might store fabricated flight prices in its memory, leading to incorrect recommendations in future sessions. Separately, a security AI trained on poisoned data could learn to classify harmful activity as normal. Even indirect prompt injection can corrupt an assistant's memory without the user's knowledge.
Mitigation: Amazon Bedrock AgentCore Memory and AWS KMS
Amazon Bedrock AgentCore Memory provides encrypted, access-controlled storage for your agent's persistent state.
To create a secure memory store for your agents:
- Initialize the AgentCore control plane client.
- Create a memory configuration with extraction strategies and expiry policies.
- Configure namespace-based isolation to separate data by actor.
The following code creates a memory store with long-term extraction strategies:
Python
# Create an AgentCore memory store with namespace isolation by actorimport boto3control_client = boto3.client('bedrock-agentcore-control', region_name='us-west-2')data_client = boto3.client('bedrock-agentcore', region_name='us-west-2')memory_response = control_client.create_memory(name='agent-memory-secure',description='Encrypted memory with long-term extraction',eventExpiryDuration=90,memoryStrategies=[{'semanticMemoryStrategy': {'name': 'FactExtractor','namespaceTemplates': ['/facts/{actorId}/']}}])
Python
# Same memory store using the AgentCore Python SDKfrom bedrock_agentcore.memory import MemoryClientclient = MemoryClient(region_name="us-west-2")memory = client.create_memory(name="agent-memory-secure",description="Encrypted memory with long-term extraction",strategies=[{'semanticMemoryStrategy': {'name': 'FactExtractor','namespaceTemplates': ['/facts/{actorId}/']}}])
For RAG authorization, use metadata filtering to enforce access control:
Python
# Enforce role-based access on RAG retrieval with a metadata filterresponse = bedrock_agent_runtime.retrieve(knowledgeBaseId='kb-id',retrievalQuery={'text': query},retrievalConfiguration={'vectorSearchConfiguration': {# authorized_roles is a list attribute on each document, so use# listContains to match when the user's role is one of the allowed# roles. Use `equals` only for single-valued scalar attributes.'filter': {'listContains': {'key': 'authorized_roles','value': user_role}}}})
Validation note: I validated the AWS KMS encryption key, the namespace-isolation design (/facts/{actorId}/separates data by actor), and the RAG metadata-filter API contract in a test account. Amazon Bedrock AgentCore Memory is generally available; thecreate_memorycontrol-plane call uses thebedrock-agentcore-controlclient. Validate the exact request shape (for example,namespaceTemplates) against the current API version and confirm Regional availability before you deploy.
Protecting an individual agent's memory is necessary, but if you're running multiple agents, you also need to secure how they communicate.
ASI07: Insecure inter-agent communication
If your system uses multiple agents, your agents depend on continuous communication. Insecure communication allows interception, spoofing, or manipulation of agent messages and intents.
In practice, an unauthorized party intercepting traffic could inject hidden instructions, replayed messages could trick agents into granting access, or an unintended agent could impersonate a legitimate peer.
Mitigation: AWS PrivateLink, AWS Private CA, and Amazon EventBridge
Secure inter-agent communication relies on encrypted messaging with identity validation. The code below creates an event bus that restricts
PutEvents to authorized agents using a principal-tag condition.A note on the API:
put_permission 's simplified Condition parameter only supports a single organization check ( Key='aws:PrincipalOrgID' , Type='StringEquals' ). To gate on a principal tag, pass a full IAM resource policy through the Policy parameter instead:Python
# Create an event bus and allow PutEvents only from tag-authorized agentsimport boto3import jsonevents = boto3.client('events')events.create_event_bus(Name='agent-communication-bus')policy = {"Version": "2012-10-17","Statement": [{"Sid": "AllowAuthorizedAgents","Effect": "Allow","Principal": {"AWS": "arn:aws:iam::111122223333:root"},"Action": "events:PutEvents","Resource": "arn:aws:events:us-west-2:111122223333:event-bus/agent-communication-bus","Condition": {"StringEquals": {"aws:PrincipalTag/AgentType": "authorized"}}}]}events.put_permission(EventBusName='agent-communication-bus',Policy=json.dumps(policy))
Secure communication controls:
Control | AWS service | Purpose |
|---|---|---|
Private connectivity | AWS PrivateLink | No public internet exposure |
Mutual Transport Layer Security (mTLS) | AWS Private Certificate Authority | Agent-to-agent authentication |
Message encryption | AWS KMS | End-to-end confidentiality |
Message signing | AWS KMS | Integrity verification |
Audit logging | AWS CloudTrail | Communication trail |
Validation note: I validated this end to end in a test account: a custom EventBridge bus with a tag-based resource policy allowedPutEventsfrom an authorized agent and denied it from an unauthorized one. The PrivateLink VPC endpoint and AWS Private CA mTLS layers are described here for completeness; validate those separately, as they carry additional cost and setup.
Even with secure communication, failures in one agent can ripple across your system. The next risk addresses how to contain those failures.
ASI08: Cascading failures
A single fault in one of your agents can propagate across your system, compounding into system-wide harm. Because agents plan, persist, and delegate autonomously, errors can bypass human checks and persist in saved state.
Poisoned market data could cause portfolio agents to recommend the same risky trade, a false positive could trigger automated responses across an entire security operations center, or a remediation agent could suppress alerts and create a feedback loop.
Mitigation: AWS Step Functions and Amazon CloudWatch
AWS Step Functions provides built-in support for circuit breakers and error isolation. The task definition below uses retry logic with exponential backoff and a catch block that routes failures to an isolation state.
Step Functions has an optimized integration for
bedrock:InvokeModel , but agent invocation is reached through the AWS SDK integration ( aws-sdk:bedrockagentruntime:invokeAgent ) rather than an optimized bedrock:invokeAgent resource:JSON
{"Type": "Task","Resource": "arn:aws:states:::aws-sdk:bedrockagentruntime:invokeAgent","Parameters": {"AgentId": "<agent-id>","AgentAliasId": "<agent-alias-id>","SessionId.$": "$.sessionId","InputText.$": "$.inputText"},"Retry": [{"ErrorEquals": ["States.TaskFailed"],"MaxAttempts": 3,"BackoffRate": 2.0}],"Catch": [{"ErrorEquals": ["States.ALL"],"ResultPath": "$.error","Next": "IsolateFailure"}]}
Amazon CloudWatch composite alarms help detect cascading patterns across your agents:
Python
# Composite alarm that fires only when error rate AND latency are both highcloudwatch = boto3.client('cloudwatch')cloudwatch.put_composite_alarm(AlarmName='Agent-CascadingFailure',AlarmRule='ALARM(Agent-ErrorRate-High) AND ALARM(Agent-Latency-High)',ActionsEnabled=True,AlarmActions=['arn:aws:sns:<region>:111122223333:critical-alerts'])
Additional controls:
- Use Amazon API Gateway throttling to enforce per-agent and per-endpoint rate limits, preventing a single agent from overwhelming downstream services
- Enable AWS Shield Advanced for distributed denial of service (DDoS) protection on agent-facing endpoints
- Implement dead-letter queues for failed agent tasks to prevent retry storms
Validation note: I validated this end to end in a test account: the Step Functions circuit breaker retried three times with exponential backoff, then routed the exhausted execution to anIsolateFailurestate via the catch block, and the CloudWatch composite alarm fired only when both the error-rate and latency alarms were in ALARM.
Finally, even with controls for each of the previous risks, you need to detect and respond when an agent itself becomes the threat.
ASI10: Rogue agents
Unintended or tampered-with agents can deviate from their intended function, acting harmfully or deceptively within multi-agent environments. An agent's emergent behavior can become harmful even if individual actions appear legitimate.
An agent might continue exfiltrating data after a harmful source is removed, a fake review agent injected into a workflow might approve fraudulent transactions, or a tampered-with agent might spawn unauthorized replicas.
Mitigation: Amazon GuardDuty and AWS Security Hub
Amazon GuardDuty provides threat detection across your agent infrastructure, including runtime monitoring for containers and Lambda functions:
Python
# Enable GuardDuty with runtime monitoring and malware protection.# The nested DataSources parameter is deprecated in favor of the flat# Features list, so configure everything through Features.import boto3guardduty = boto3.client('guardduty')detector = guardduty.create_detector(Enable=True,FindingPublishingFrequency='FIFTEEN_MINUTES',Features=[{'Name': 'EKS_AUDIT_LOGS', 'Status': 'ENABLED'},{'Name': 'EBS_MALWARE_PROTECTION', 'Status': 'ENABLED'},{'Name': 'RUNTIME_MONITORING', 'Status': 'ENABLED'},{'Name': 'LAMBDA_NETWORK_LOGS', 'Status': 'ENABLED'}])
To automate containment, pair GuardDuty with an AWS Lambda function triggered by AWS Security Hub findings. The function below revokes an agent's credentials and notifies your security team:
Python
# Lambda triggered by a Security Hub finding: deny-all the agent role, then notifyimport jsonimport boto3def contain_rogue_agent(event, context):finding = event['detail']['findings'][0]# A Security Hub finding resource Id is a full ARN# (e.g. arn:aws:iam::111122223333:role/AgentRole-42). IAM APIs take the# bare role name, so extract it from the ARN. Splitting on '/' and taking# the last segment also handles roles created under a path.role_arn = finding['Resources'][0]['Id']role_name = role_arn.split('/')[-1]# Revoke the agent's credentials immediately with a deny-all policyiam = boto3.client('iam')iam.put_role_policy(RoleName=role_name,PolicyName='EmergencyDenyAll',PolicyDocument=json.dumps({"Version": "2012-10-17","Statement": [{"Effect": "Deny", "Action": "*", "Resource": "*"}]}))# Notify the security teamsns = boto3.client('sns')sns.publish(TopicArn='arn:aws:sns:<region>:111122223333:security-critical',Subject=f'Rogue Agent Contained: {role_name}',Message=f'Agent role {role_name} was automatically contained.')
Validation note: I validated the containment chain end to end in a test account: an EventBridge rule matching high-severity Security Hub findings triggered the containment Lambda, which applied theEmergencyDenyAllinline policy and locked the target agent role out of all actions. Match on the severity representation of the source you route from - Security Hub findings (ASFF) exposeSeverity.Label(for example,HIGH/CRITICAL) and a normalized 0-100Severity.Normalized, whereas raw GuardDuty findings use a numeric 1.0-10.0 scale (Low 1.0-3.9 through Critical 9.0-10.0). When adopting this, be careful enabling new GuardDuty features on an existing detector in a production account - a live detector is core security infrastructure for your account.
Series summary: AWS services mapped to the OWASP Agentic AI Top 10
This table is the quick reference for the full series - each issue, the part that covers it, and the primary AWS services for mitigation:
Issue | Part | Primary AWS services | Key controls |
|---|---|---|---|
ASI01: Goal hijack | 1 | Amazon Bedrock Guardrails, Amazon S3 Object Lock | Prompt injection detection, immutable prompts |
ASI02: Tool misuse | 2 | AgentCore Gateway, IAM, AWS WAF | Input validation, injection protection, least-privilege |
ASI03: Identity abuse | 1 | AgentCore Identity, STS, IAM | OAuth flows, temporary credentials |
ASI04: Supply chain | 2 | Amazon Inspector, AWS Signer, AWS CodeArtifact | Security scanning, code signing |
ASI05: Code execution | 2 | AgentCore Code Interpreter, AWS Lambda, Firecracker | Managed sandbox, network isolation, least-privilege execution role |
ASI06: Memory poisoning | 3 | AgentCore Memory, AWS KMS, Amazon OpenSearch Service | Encryption, metadata filtering |
ASI07: Inter-agent comms | 3 | AWS PrivateLink, AWS Private CA, AWS KMS | mTLS, message signing |
ASI08: Cascading failures | 3 | AWS Step Functions, Amazon CloudWatch, Amazon API Gateway | Circuit breakers, rate limiting, anomaly detection |
ASI09: Trust abuse | 1 | AWS Step Functions, Amazon Bedrock Guardrails, Automated Reasoning | Human approval, contextual grounding, factual verification |
ASI10: Rogue agents | 3 | Amazon GuardDuty, AWS Security Hub, AWS Lambda | Threat detection, automated containment |
Conclusion
Across this three-part series, I showed you how to secure your agentic AI systems against each of the 10 OWASP risks using AWS services. You now have a defense-in-depth strategy that protects your agents at every layer - from input validation with Amazon Bedrock Guardrails to threat detection with Amazon GuardDuty - while maintaining their autonomous capabilities.
The key is a layered approach that combines:
- Identity and access management with distinct agent identities and least-privilege permissions ( Part 1 )
- Input validation through Amazon Bedrock Guardrails ( Part 1 )
- Human oversight for high-risk actions through Step Functions approval workflows ( Part 1 )
- Secure tool orchestration through Amazon Bedrock AgentCore Gateway ( Part 2 )
- Runtime isolation for agent-generated code and a verified supply chain ( Part 2 )
- Protected memory and knowledge stores using encryption and metadata-based access control (Part 3)
- Resilient architectures with circuit breakers and error handling (Part 3)
- Continuous monitoring and threat detection through AWS Security Hub and Amazon GuardDuty (Part 3)
As agentic AI continues to evolve, security must remain a foundational consideration - not an afterthought.
Next steps
Not every organization needs to implement all ten mitigations at once. The priority order below - reflected in the "week 1 / weeks 2-3 / then expand" guidance across the series - helps you focus on the controls that provide the broadest protection first.
Start here ( Part 1 - foundational): Amazon Bedrock Guardrails (ASI01, ASI09), AgentCore Identity (ASI03), and logging/observability.
Add next ( Part 2 - tool and infrastructure): AgentCore Gateway (ASI02), AWS Lambda isolation (ASI05), Amazon Inspector and AWS Signer (ASI04).
Then expand (Part 3 - system resilience): Step Functions (ASI08), AgentCore Memory (ASI06), AWS PrivateLink and Private CA (ASI07), Amazon GuardDuty and Security Hub (ASI10).
To begin putting these controls in place:
- Review the OWASP Top 10 for Agentic Applications to understand your specific risk profile
- For threat modeling guidance, see the MAESTRO framework from the Cloud Security Alliance
- Assess your current agent security posture using the AWS Well-Architected Framework
- Deploy the Fullstack AgentCore Solution Template (FAST) as a reference implementation
- Explore the AWS Samples repository for additional reference implementations
Clean up resources
To avoid ongoing charges from resources created while following this series, delete the following:
- Delete the Amazon Bedrock Guardrails you created using the Amazon Bedrock console or the
delete_guardrailAPI.
- Remove AgentCore Gateway instances and their targets using the
delete_gateway_targetanddelete_gatewayAPIs.
- Delete AgentCore Memory stores using the
delete_memoryAPI.
- Remove the AWS Lambda functions created for code execution or containment using the AWS Lambda console or the
delete_functionAPI.
- Delete Amazon EventBridge event buses using the
delete_event_busAPI.
- Disable Amazon GuardDuty detectors only if they were created solely for this walkthrough. Do not disable or reconfigure a pre-existing detector - it is core security infrastructure for your account.
- Remove the IAM roles and policies created specifically for these examples.
- Delete Amazon CloudWatch alarms using the
delete_alarmsAPI. As a tidiness step, delete composite alarms before the metric alarms they reference.
Additional resources
About the author
Bharadwaz Kari is a Technical Account Manager at AWS, where he helps enterprise customers operate and secure their workloads on AWS. He focuses on generative AI, security, and developer tooling. This post reflects his personal views, not those of his employer.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article