AI Security

AI agents + cloud functions: the minimum IAM posture to enforce

An agent invoking Lambdas, Cloud Run, Azure Functions inherits attached IAM. The minimum scoping to apply.

Aroua Biri

Many 2026 AI agents are implemented as cloud function chains: the agent receives a request, invokes a Lambda to query a database, another to send an email, another to generate a PDF. Practical architecture, scalable, fragile on one specific point: each function runs with an IAM role whose permissions are inherited by the agent. An over-broad IAM scope turns a compromised agent into broad cloud access.

The minimum IAM posture is one of the most effective — and most neglected — levers in AI agent security.

The common pattern and its flaw

Typical architecture:

`` user → agent (orchestrator, EC2 or Lambda) → Lambda A (reads customer DB) → Lambda B (sends email via SES) → Lambda C (generates PDF in S3) ``

Common pattern: each Lambda has an IAM role, those roles often hold too-broad permissions ("AmazonSESFullAccess", "AmazonS3FullAccess") because that passes tests fastest and you need to ship.

Consequence: if the agent is compromised and invokes Lambda B with hijacked parameters, it could send email to anyone (not just the requested customer). C hijacked, the agent writes anywhere in S3.

5 IAM principles for an AI agent

1. One IAM role per function, never shared

Each cloud function has its own role. No "generic agent" role shared across functions. If function A is compromised, its role gets revoked without breaking B and C.

2. Resource-level permissions, not service-level

Bad: ``json {"Effect": "Allow", "Action": "s3:", "Resource": ""} ``

Good: ``json { "Effect": "Allow", "Action": ["s3:PutObject"], "Resource": "arn:aws:s3:::weesec-pdfs/clients/${aws:PrincipalTag/UserId}/*" } ``

Limited to exact action (s3:PutObject, not s3:*) and to a bucket sub-perimeter. If compromised, the attacker writes only into the current user's folder.

3. IAM conditions for context

IAM supports conditions: only from VPC X, only during business hours, only on objects matching a pattern.

``json { "Condition": { "StringEquals": {"aws:SourceVpc": "vpc-internal-prod"} } } ``

Very useful to limit a permission to its intended context. An external attacker can't activate the permission.

4. Tagging and ABAC (attribute-based access control)

For multi-tenant agents, ABAC scopes permissions per tenant via tags. The role holds a generic permission, principal and resource tags do the matching.

``json { "Effect": "Allow", "Action": "dynamodb:Query", "Resource": "*", "Condition": { "StringEquals": { "dynamodb:LeadingKeys": "${aws:PrincipalTag/TenantId}" } } } ``

The agent queries the DB but only records matching its tenant. Cross-tenant isolation guaranteed at IAM level, not just code level.

5. No long-lived credentials in agent runtime

The agent never stores long-lived AWS_ACCESS_KEY_ID. It uses:

  • Instance role on EC2.
  • Task role on ECS / Fargate.
  • Function role on Lambda.
  • OIDC federation elsewhere (GitHub Actions, on-prem, other cloud).

Ephemeral token, fetched on demand, no persistent credentials.

Agent-specific mistakes

"Read-all so the agent can 'understand context'"

Classic temptation: give the agent broad read access "so it can find what it needs". Antipattern. An agent needing to read 30 tables is probably mis-scoped on UX — it should have more specific tools.

Agent writing to the same DB as human services

If the agent writes to the prod DB with a broad role, a bug or manipulation can corrupt critical data. Defensive pattern: write to an intermediate table or outbox the agent can freely fill, with a separate process validating before integration.

Agent that assumes a role above its perimeter

With AssumeRole, an agent can temporarily take a stronger role. Strictly control this:

  • Explicit allowlist of assumable roles.
  • AssumeRole audit trail.
  • No AssumeRole letting elevation to admin.

Periodic IAM review

Every 3 months, per role used by an agent:

  1. List actions actually used over the period (CloudTrail / GCP Audit Logs / Azure Monitor).
  2. Compare with actions allowed by policy.
  3. Remove allowed but unused actions.

Partially automatable. AWS offers IAM Access Analyzer to suggest policies based on real usage. Good baseline, complete with human review.

Special case: MCP servers running as cloud functions

If you expose an MCP tool running via Lambda, that Lambda's permissions indirectly become the calling agent's permissions. Treat with same care.

Good practice: dedicated IAM role per MCP tool, never reused. If "send_email" is compromised, "delete_file" keeps its own role.

Validation checklist

Before agent go-live invoking cloud:

  • [ ] Each cloud function has its own IAM role.
  • [ ] No role has : (no Action: , no unscoped Resource: ).
  • [ ] Resources named precisely or matched via restrictive patterns.
  • [ ] No long-lived credentials in agent runtime.
  • [ ] Audit log enabled on all sensitive functions.
  • [ ] Quarterly IAM review scheduled.

5 of 6 yes = top 10% of deployments. 3 yes = good start. 0-2 yes = don't ship on a sensitive scope.

A related topic on your side?

20 minutes to scope it together. No commercial pitch.

Book a Calendly call