← Back to DevBytes

IAM Security: IAM Policies and Network Security

IAM Security: Understanding IAM Policies and Network Security

IAM (Identity and Access Management) policies define who can access what resources under which conditions. Combined with network security controls, they form a powerful defense-in-depth strategy. This tutorial covers how to write effective IAM policies, enforce network-level restrictions, and avoid common pitfalls that lead to data exposure.

What is an IAM Policy?

An IAM policy is a JSON document that grants or denies permissions to identities (users, groups, roles) or resources. Every policy follows a consistent structure consisting of an Effect, Action, Resource, and optional Condition block.

Here is a minimal policy that allows read-only access to an S3 bucket:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": [
        "arn:aws:s3:::example-bucket",
        "arn:aws:s3:::example-bucket/*"
      ]
    }
  ]
}

Key elements:

Why IAM Policies and Network Security Matter

Without tight IAM policies, a single compromised credential can expose your entire infrastructure. Network security adds another layer: even with valid credentials, access can be blocked unless the request originates from an approved IP range, VPC endpoint, or secure network path. This dual control prevents many common attacks:

IAM policies are not just about "who" – they enforce how access happens. Network-aware conditions transform IAM from a static permission model into a dynamic, context-aware authorization system.

How to Write and Attach IAM Policies

Policies can be attached directly to users, groups, or roles (identity-based), or to resources like S3 buckets, Lambda functions, or KMS keys (resource-based). In a typical cloud environment, you'll work with identity-based policies most often.

Step 1: Start with a minimal, explicit policy

Begin by granting only what is absolutely required. Use the IAM policy simulator or a dry-run API call to validate. For example, a policy allowing a developer to read/write only a specific DynamoDB table:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:UpdateItem",
        "dynamodb:DeleteItem"
      ],
      "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/AppUsers"
    }
  ]
}

Step 2: Add network conditions

To restrict access to only requests originating from a specific VPC or IP range, use the Condition block with condition keys like aws:SourceIp, aws:SourceVpc, or aws:SourceVpce (VPC endpoint). This example requires the caller to be coming from your corporate VPN IP range:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:*"],
      "Resource": ["arn:aws:s3:::confidential-data/*"],
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "203.0.113.0/24"
        }
      }
    }
  ]
}

For VPC-based restrictions, use the StringEquals operator with aws:SourceVpc:

"Condition": {
  "StringEquals": {
    "aws:SourceVpc": "vpc-0abc123def456"
  }
}

Step 3: Combine with other security controls

Network conditions are often paired with MFA requirements and time-based restrictions. Here's a policy that demands both MFA authentication and a specific IP range for sensitive administrative actions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iam:CreateUser",
        "iam:DeleteUser",
        "iam:UpdateAccessKey"
      ],
      "Resource": "*",
      "Condition": {
        "Bool": {
          "aws:MultiFactorAuthPresent": "true"
        },
        "IpAddress": {
          "aws:SourceIp": "10.0.0.0/16"
        }
      }
    }
  ]
}

Network Security Integration Patterns

Beyond IP-based conditions, cloud providers offer deeper network-IAM integration:

Practical Code Examples

1. Restricting Lambda invocation to a VPC-originated request

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:my-private-function",
      "Condition": {
        "StringEquals": {
          "aws:SourceVpc": "vpc-0def456abc789"
        }
      }
    }
  ]
}

2. S3 bucket policy that allows reads only from a specific VPC endpoint

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*",
      "Condition": {
        "StringEquals": {
          "aws:SourceVpce": "vpce-0a1b2c3d4e5f6"
        }
      }
    }
  ]
}

3. Deny all access if the request doesn't come from a trusted corporate network (use as a boundary)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "NotIpAddress": {
          "aws:SourceIp": [
            "192.0.2.0/24",
            "198.51.100.0/24"
          ]
        },
        "Bool": {
          "aws:ViaAWSService": "false"
        }
      }
    }
  ]
}

This "Deny if not in allowed IPs" policy can be attached to an IAM role or user as a permissions boundary, ensuring any access (even through role assumption) is blocked when originating from outside the corporate network. The aws:ViaAWSService exclusion prevents breaking AWS service-linked roles that act on your behalf from internal AWS networks.

Best Practices

Testing and Troubleshooting

When a request is denied due to a network condition, the error message often includes the condition key that failed. To debug:

Conclusion

IAM policies and network security are inseparable parts of a modern access control strategy. A well-crafted policy doesn't just say "this role can read that bucket" – it says "this role can read that bucket, but only when connected from our private subnet and authenticated with multi-factor authentication." By embedding network context into IAM, you drastically reduce the risk of credential misuse and build an authorization model that is both granular and resilient. Start with least privilege, add network conditions as a mandatory gate, and continuously validate with simulation tools to keep your cloud environment secure.

🚀 Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles