# API Gateway Policy Examples

![API Gateway Policy Patterns](/files/88ya4FPqCqOxzrRgmlt4)

> **Intro:** API gateways are not the whole security model, but they are an important **outer control layer**. The right gateway policy can reduce exposure before a request even reaches service-level authentication and authorization logic.
>
> **What this page includes**
>
> * policy examples for AWS API Gateway resource policies
> * patterns for public, private, and cross-account access control
> * how gateway policy complements app-layer auth rather than replacing it
>
> **Working assumptions**
>
> * gateway policy should narrow ingress aggressively, then let the application enforce business authorization

## What gateway policy is good at

Gateway policy is strong at constraining:

* **who** can call an API;
* **from where** the call may originate;
* **which stages, methods, or paths** are exposed;
* **which environments** should be reachable from the public internet or only from private entry points.

Gateway policy is **not** where business authorization logic belongs. Object ownership, tenancy checks, entitlement checks, and workflow-level controls still belong in the application.

## Example 1: allow specific cross-account roles

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::111122223333:role/developer",
          "arn:aws:iam::111122223333:role/Admin"
        ]
      },
      "Action": "execute-api:Invoke",
      "Resource": [
        "execute-api:/prod/GET/orders",
        "execute-api:/prod/POST/orders"
      ]
    }
  ]
}
```

Use this when a partner account or central automation account needs narrowly scoped invoke rights.

## Example 2: deny calls outside trusted source IP ranges

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "execute-api:Invoke",
      "Resource": "execute-api:/*",
      "Condition": {
        "NotIpAddress": {
          "aws:SourceIp": [
            "203.0.113.0/24",
            "198.51.100.10/32"
          ]
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "execute-api:Invoke",
      "Resource": "execute-api:/*"
    }
  ]
}
```

Use this when you have a known corporate or partner egress range and want the gateway to reject everything else before the request reaches the service.

## Example 3: allow private API access only from a VPC endpoint

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "execute-api:Invoke",
      "Resource": "execute-api:/*",
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpce": "vpce-0abc1234def567890"
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "execute-api:Invoke",
      "Resource": "execute-api:/*"
    }
  ]
}
```

Use this for private APIs that should only be reachable through an approved VPC endpoint.

## Example 4: allow private API access only from a specific VPC

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "execute-api:Invoke",
      "Resource": "execute-api:/*",
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpc": "vpc-0123456789abcdef0"
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "execute-api:Invoke",
      "Resource": "execute-api:/*"
    }
  ]
}
```

Use when the policy boundary is the source VPC rather than a specific endpoint.

## Example 5: method and stage scoping

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:role/reporting-client"
      },
      "Action": "execute-api:Invoke",
      "Resource": [
        "execute-api:/staging/GET/reports/*"
      ]
    }
  ]
}
```

Do not grant `execute-api:/*` unless the role truly needs every stage, path, and method.

## Terraform example for resource policy attachment

```hcl
resource "aws_api_gateway_rest_api_policy" "orders_api" {
  rest_api_id = aws_api_gateway_rest_api.orders.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect    = "Deny"
        Principal = "*"
        Action    = "execute-api:Invoke"
        Resource  = "execute-api:/*"
        Condition = {
          StringNotEquals = {
            "aws:SourceVpce" = aws_vpc_endpoint.execute_api.id
          }
        }
      },
      {
        Effect    = "Allow"
        Principal = "*"
        Action    = "execute-api:Invoke"
        Resource  = "execute-api:/*"
      }
    ]
  })
}
```

## How gateway policy complements application auth

| Layer                     | Good at                              | Not enough for                                     |
| ------------------------- | ------------------------------------ | -------------------------------------------------- |
| gateway policy            | network and principal boundary       | object ownership, role entitlements, tenant checks |
| JWT / IAM auth            | verifying caller identity            | business-specific authorization decisions          |
| application authorization | data access, tenancy, workflow rules | early traffic narrowing                            |

## Common mistakes

| Mistake                                                     | Consequence                            |
| ----------------------------------------------------------- | -------------------------------------- |
| using the gateway as the only authorization layer           | business logic bypass risk remains     |
| granting broad `execute-api:/*` permissions                 | overexposure of methods and stages     |
| leaving private APIs reachable from the wrong VPC/VPCE path | internal boundary collapses            |
| mixing prod and non-prod policy                             | environment separation becomes fragile |

## Related pages

* [API Authentication and Authorization](/architecture-api-crypto-and-identity/index/api-authentication-and-authorization.md)
* [API Abuse Resilience and Rate Limits](/architecture-api-crypto-and-identity/index/api-abuse-resilience-and-rate-limits.md)
* [AWS IAM Snippet Pack](/cloud-kubernetes-and-infrastructure-security/index/aws-iam-snippet-pack.md)
* [AWS Networking and Policy Baseline](https://github.com/D3One/Product-Security-Gitbook/blob/main/08-infrastructure-and-cloud-security/aws-networking-and-policy-baseline.md)

***

*Author attribution: Ivan Piskunov, 2026 - Educational and defensive-engineering use.*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.product-security.expert/architecture-api-crypto-and-identity/index/api-gateway-policy-examples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
