IAM Condition Keys to Distinguish Agent vs Human Actions in AWS Agent Toolkit

Use AWS IAM condition keys like aws:SourceAccount and aws:SourceArn to scope permissions so that automated agents from the MCP Server can perform privileged operations while human users with the same IAM role are implicitly denied.

The AWS Agent Toolkit (aws/agent-toolkit-for-aws) embeds IAM condition keys into its security model to enforce least-privilege boundaries between automated agents and human operators. By injecting keys such as aws:SourceAccount and aws:SourceArn into trust policies and resource-based policies, the toolkit ensures that sensitive actions—like creating S3 buckets or writing logs—can only execute when the request originates from the Model Context Protocol (MCP) server or specific agent skills. This approach prevents confused deputy attacks and creates audit trails that clearly separate agent-initiated events from human activity in Amazon CloudTrail logs.

Why IAM Condition Keys Matter for Agent Security

Least-Privilege Enforcement

Agents often run with elevated privileges to provision infrastructure. By scoping these permissions with condition keys, you prevent the agent's IAM role from being used for unintended human operations, reducing the blast radius of a compromised agent.

Confused-Deputy Protection

Condition keys such as aws:SourceArn ensure that a service assumes a role only when the request originates from the expected agent resource. This blocks other entities that might try to impersonate the agent, addressing the confused deputy problem.

Auditability

Amazon CloudTrail captures condition key values in request contexts, allowing you to filter logs for agent-initiated events versus human-initiated events using specific ARN or account markers.

How the AWS Agent Toolkit Implements Condition Keys

MCP Server Trust Policies

In skills/core-skills/aws-iam/references/aws-iam-role-management.md (line 40), the toolkit adds aws:SourceAccount and aws:SourceArn to trust policies for service roles such as CloudWatch and Lambda microVMs. This ensures only the MCP server can assume these roles, preventing unauthorized cross-service access.

Skill-Level Resource Policies

When skills create resources like S3 buckets for Web Application Firewall (WAF) logs, the generated bucket policy includes these condition keys. The file skills/specialized-skills/networking-and-content-delivery-skills/waf/references/setting-up-logging-and-request-sampling.md (line 65) demonstrates how the toolkit secures logging destinations by restricting write access to the agent's specific ARN.

Documentation and Best Practices

The repository's README.md (lines 164-165) explicitly documents the ability to write policies that apply only to agents. Additionally, rules/aws-agent-rules.md provides operational guidance on preferring the MCP server and using condition keys for secure access patterns.

Essential IAM Condition Keys for Agent Isolation

The following condition keys appear throughout the toolkit's implementation:

  • aws:SourceAccount — Guarantees the request originates from the same AWS account that owns the agent resources. Example: "Condition": {"StringEquals": {"aws:SourceAccount": "123456789012"}}

  • aws:SourceArn — Binds the request to a specific ARN, such as the MCP server's Lambda function. Example: "Condition": {"ArnEquals": {"aws:SourceArn": "arn:aws:lambda:us-east-1:123456789012:function:my-agent-handler"}}

  • aws:SecureTransport — Enforces HTTPS for API calls made by the agent. Example: "Condition": {"Bool": {"aws:SecureTransport": "true"}}

  • kms:ViaService — Limits KMS key usage to specific services like Secrets Manager. As shown in skills/specialized-skills/security-and-identity-skills/creating-secrets-using-best-practices/references/create-secrets-using-best-practices.md (line 62), this ensures encryption operations are tied to the agent's service context. Example: "Condition": {"StringEquals": {"kms:ViaService": "secretsmanager.us-east-1.amazonaws.com"}}

  • aws:ResourceTag/<TagKey> — Restricts access to resources tagged by the agent, such as "aws:ResourceTag/CreatedBy": "agent".

Policy Layering Strategy

The toolkit uses a layered approach to apply these controls:

  1. Base Role — Human users receive a role with broad permissions for development tasks.
  2. Agent Overlay — A second policy attached to the same role (or a separate role the agent assumes) adds condition keys that restrict privileged actions to the agent's identity.
  3. Evaluation — When humans use the AWS CLI, the request lacks aws:SourceAccount/aws:SourceArn, causing the conditions to evaluate to false and denying privileged actions. When the agent runs inside the MCP server, it automatically includes the required keys.

Implementation Examples

Agent-Only S3 Bucket Creation

This YAML policy permits bucket creation only when the request includes the agent's source context:

Version: "2012-10-17"
Statement:
  - Effect: Allow
    Action: s3:CreateBucket
    Resource: arn:aws:s3:::my-agent-bucket-*
    Condition:
      StringEquals:
        aws:SourceAccount: "123456789012"
        aws:SourceArn: "arn:aws:lambda:us-east-1:123456789012:function:my-agent-handler"

Attaching the Overlay Policy via CLI

aws iam put-role-policy \
  --role-name DevTeamRole \
  --policy-name AgentOnlyS3Create \
  --policy-document file://agent-s3-create.json

Resource-Based S3 Bucket Policy

This JSON example from the WAF logging implementation shows how to restrict write access:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AgentWriteAccess",
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::123456789012:role/AgentExecutionRole" },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::my-agent-bucket/*",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "123456789012",
          "aws:SourceArn": "arn:aws:lambda:us-east-1:123456789012:function:my-agent-handler"
        }
      }
    }
  ]
}

Enforcing HTTPS for All Agent Calls

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "BoolIfExists": { "aws:SecureTransport": "false" }
      }
    }
  ]
}

Summary

Frequently Asked Questions

What happens if a human tries to use an IAM role that has agent-specific condition keys?

When a human uses the AWS CLI or SDK, the request does not include aws:SourceArn or aws:SourceAccount context. The condition evaluates to false, and the policy denies the action. Only requests originating from the configured MCP server or Lambda function specified in the condition will satisfy the constraint.

Can I use these condition keys with existing IAM roles, or do I need separate roles?

You can use policy layering. Attach the base policy to your existing role for human operations, then attach a second policy with the condition keys. Alternatively, have the agent assume a separate role that requires the condition keys, while humans use the primary role without them.

How do I audit which actions were performed by agents versus humans?

Amazon CloudTrail logs capture the condition key values present in the request. You can filter CloudTrail events for aws:SourceArn values matching your agent's MCP server or Lambda function ARN to isolate agent activity from human-initiated API calls.

Does the AWS Agent Toolkit automatically inject these condition keys?

The toolkit configures the MCP server and skill templates to include the appropriate context. According to the source code in skills/core-skills/aws-iam/references/aws-iam-role-management.md, the trust policies are structured to require these keys, and the agent execution environment provides the necessary context when calling AWS APIs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →