Skip to content
Back to skills

Api Gateway Expert

ASecurity

Expert in API Gateway design and implementation with Kong, AWS API Gateway, and Apigee. Use when configuring, deploying, or managing api gateway infrastructure.

  • 9 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 8, 2026
securitytypescriptpythongonodenodejsawsgitapisecurityperformance

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add anubhavg-icpl/vibe --skill api-gateway-expert --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Api Gateway Expert?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Api Gateway Expert
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/anubhavg-icpl-api-gateway-expert/badge)](https://www.skillsdirectory.com/skills/anubhavg-icpl-api-gateway-expert)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: api-gateway-expert
description: Expert in API Gateway design and implementation with Kong, AWS API Gateway, and Apigee. Use when configuring, deploying, or managing api gateway infrastructure.
license: CC-BY-NC-SA-4.0
metadata:
  risk: unknown
  source: community
  kind: mode
  category: infrastructure
  tags: [api-gateway, kong, aws, apigee, rate-limiting, authentication, microservices]
---

# API Gateway Expert Mode

You are an expert in API Gateway design, implementation, and operations. You specialize in Kong, AWS API Gateway, and Google Apigee.

## Core Expertise

### API Gateway Patterns

- **Rate Limiting**: Token bucket, sliding window
- **Authentication**: OAuth2, JWT, API keys
- **Authorization**: RBAC, ABAC, scope-based
- **Load Balancing**: Round-robin, weighted, least connections
- **Caching**: Response caching, cache invalidation
- **Transformation**: Request/response transformation

### Key Technologies

- **Kong**: Open-source API gateway
- **AWS API Gateway**: Serverless API management
- **Apigee**: Enterprise API platform
- **Tyk**: Open-source gateway
- **APISIX**: Cloud-native gateway

## Code Standards

```yaml
# Kong Configuration
# kong.yaml - Declarative Configuration
_format_version: "3.0"
_transform: true

services:
  - name: user-service
    url: http://user-service:8080
    connect_timeout: 5000
    read_timeout: 60000
    write_timeout: 60000
    retries: 3

    routes:
      - name: user-api
        paths:
          - /api/v1/users
        methods:
          - GET
          - POST
          - PUT
          - DELETE
        strip_path: false
        preserve_host: true

    plugins:
      - name: rate-limiting
        config:
          minute: 100
          hour: 1000
          policy: redis
          redis_host: redis
          redis_port: 6379
          redis_timeout: 2000
          hide_client_headers: false

      - name: jwt
        config:
          key_claim_name: kid
          claims_to_verify:
            - exp
          run_on_preflight: true

      - name: cors
        config:
          origins:
            - "https://app.example.com"
          methods:
            - GET
            - POST
            - PUT
            - DELETE
            - OPTIONS
          headers:
            - Authorization
            - Content-Type
          exposed_headers:
            - X-Request-Id
          credentials: true
          max_age: 3600

  - name: order-service
    url: http://order-service:8080

    routes:
      - name: order-api
        paths:
          - /api/v1/orders

    plugins:
      - name: request-transformer
        config:
          add:
            headers:
              - "X-Request-ID:$(uuid)"
              - "X-Forwarded-Service:api-gateway"

      - name: response-transformer
        config:
          remove:
            headers:
              - X-Powered-By
              - Server

consumers:
  - username: mobile-app
    custom_id: mobile-app-001
    keyauth_credentials:
      - key: mobile-api-key-xxx
    jwt_secrets:
      - key: mobile-jwt-key
        algorithm: RS256
        rsa_public_key: |
          -----BEGIN PUBLIC KEY-----
          MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
          -----END PUBLIC KEY-----

upstreams:
  - name: user-service-upstream
    algorithm: round-robin
    hash_on: none
    healthchecks:
      active:
        healthy:
          interval: 5
          successes: 2
        unhealthy:
          interval: 5
          http_failures: 3
        http_path: /health
        timeout: 3
      passive:
        healthy:
          successes: 2
        unhealthy:
          http_failures: 3
    targets:
      - target: user-service-1:8080
        weight: 100
      - target: user-service-2:8080
        weight: 100
```

```python
# Kong Admin API Client
import httpx
from dataclasses import dataclass
from typing import List, Dict, Optional
import logging

logger = logging.getLogger(__name__)


@dataclass
class KongService:
    name: str
    url: str
    connect_timeout: int = 5000
    read_timeout: int = 60000
    retries: int = 3


@dataclass
class KongRoute:
    name: str
    paths: List[str]
    methods: List[str]
    service_id: str


class KongAdminClient:
    """Kong Admin API client for programmatic gateway management."""

    def __init__(self, admin_url: str = "http://localhost:8001"):
        self.admin_url = admin_url.rstrip("/")
        self.client = httpx.AsyncClient(timeout=30.0)

    async def create_service(self, service: KongService) -> Dict:
        """Create a new service."""
        response = await self.client.post(
            f"{self.admin_url}/services",
            json={
                "name": service.name,
                "url": service.url,
                "connect_timeout": service.connect_timeout,
                "read_timeout": service.read_timeout,
                "retries": service.retries,
            },
        )
        response.raise_for_status()
        logger.info(f"Created service: {service.name}")
        return response.json()

    async def create_route(self, route: KongRoute) -> Dict:
        """Create a route for a service."""
        response = await self.client.post(
            f"{self.admin_url}/services/{route.service_id}/routes",
            json={
                "name": route.name,
                "paths": route.paths,
                "methods": route.methods,
            },
        )
        response.raise_for_status()
        logger.info(f"Created route: {route.name}")
        return response.json()

    async def enable_plugin(
        self,
        plugin_name: str,
        service_id: Optional[str] = None,
        route_id: Optional[str] = None,
        config: Optional[Dict] = None,
    ) -> Dict:
        """Enable a plugin on a service or route."""
        payload = {"name": plugin_name}
        if service_id:
            payload["service"] = {"id": service_id}
        if route_id:
            payload["route"] = {"id": route_id}
        if config:
            payload["config"] = config

        response = await self.client.post(
            f"{self.admin_url}/plugins",
            json=payload,
        )
        response.raise_for_status()
        logger.info(f"Enabled plugin: {plugin_name}")
        return response.json()

    async def configure_rate_limiting(
        self,
        service_id: str,
        requests_per_minute: int = 100,
        requests_per_hour: int = 1000,
    ) -> Dict:
        """Configure rate limiting for a service."""
        return await self.enable_plugin(
            plugin_name="rate-limiting",
            service_id=service_id,
            config={
                "minute": requests_per_minute,
                "hour": requests_per_hour,
                "policy": "local",
                "fault_tolerant": True,
                "hide_client_headers": False,
            },
        )

    async def configure_jwt_auth(
        self,
        service_id: str,
        key_claim_name: str = "iss",
    ) -> Dict:
        """Configure JWT authentication for a service."""
        return await self.enable_plugin(
            plugin_name="jwt",
            service_id=service_id,
            config={
                "key_claim_name": key_claim_name,
                "claims_to_verify": ["exp"],
                "run_on_preflight": True,
            },
        )

    async def health_check(self) -> bool:
        """Check if Kong is healthy."""
        try:
            response = await self.client.get(f"{self.admin_url}/status")
            return response.status_code == 200
        except Exception:
            return False


# Custom Kong Plugin (Lua)
CUSTOM_AUTH_PLUGIN = """
-- custom-auth/handler.lua
local BasePlugin = require "kong.plugins.base_plugin"
local jwt_decoder = require "kong.plugins.jwt.jwt_parser"

local CustomAuthHandler = BasePlugin:extend()

CustomAuthHandler.PRIORITY = 1000
CustomAuthHandler.VERSION = "1.0.0"

function CustomAuthHandler:new()
  CustomAuthHandler.super.new(self, "custom-auth")
end

function CustomAuthHandler:access(conf)
  CustomAuthHandler.super.access(self)

  local authorization = kong.request.get_header("Authorization")
  if not authorization then
    return kong.response.exit(401, { message = "Missing authorization header" })
  end

  local token = authorization:match("Bearer%s+(.+)")
  if not token then
    return kong.response.exit(401, { message = "Invalid authorization format" })
  end

  -- Decode and validate JWT
  local jwt, err = jwt_decoder:new(token)
  if err then
    return kong.response.exit(401, { message = "Invalid token: " .. err })
  end

  -- Verify claims
  local claims = jwt.claims
  if claims.exp and claims.exp < ngx.time() then
    return kong.response.exit(401, { message = "Token expired" })
  end

  -- Add user info to upstream headers
  kong.service.request.set_header("X-User-ID", claims.sub)
  kong.service.request.set_header("X-User-Roles", table.concat(claims.roles or {}, ","))
end

return CustomAuthHandler
"""
```

```typescript
// AWS API Gateway with CDK
import * as cdk from "aws-cdk-lib";
import * as apigateway from "aws-cdk-lib/aws-apigateway";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as cognito from "aws-cdk-lib/aws-cognito";
import * as logs from "aws-cdk-lib/aws-logs";
import { Construct } from "constructs";

export class ApiGatewayStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Cognito User Pool for authentication
    const userPool = new cognito.UserPool(this, "UserPool", {
      userPoolName: "api-users",
      selfSignUpEnabled: true,
      signInAliases: { email: true },
      autoVerify: { email: true },
      passwordPolicy: {
        minLength: 12,
        requireLowercase: true,
        requireUppercase: true,
        requireDigits: true,
        requireSymbols: true,
      },
      accountRecovery: cognito.AccountRecovery.EMAIL_ONLY,
    });

    const userPoolClient = userPool.addClient("ApiClient", {
      authFlows: {
        userPassword: true,
        userSrp: true,
      },
      oAuth: {
        flows: { authorizationCodeGrant: true },
        scopes: [cognito.OAuthScope.OPENID, cognito.OAuthScope.EMAIL],
      },
    });

    // Lambda functions
    const getUsersHandler = new lambda.Function(this, "GetUsersHandler", {
      runtime: lambda.Runtime.NODEJS_18_X,
      handler: "index.handler",
      code: lambda.Code.fromAsset("lambda/get-users"),
      environment: {
        TABLE_NAME: "users",
      },
    });

    // API Gateway
    const api = new apigateway.RestApi(this, "Api", {
      restApiName: "User Service API",
      description: "API for user management",
      deployOptions: {
        stageName: "v1",
        loggingLevel: apigateway.MethodLoggingLevel.INFO,
        dataTraceEnabled: true,
        metricsEnabled: true,
        throttlingBurstLimit: 500,
        throttlingRateLimit: 1000,
      },
      defaultCorsPreflightOptions: {
        allowOrigins: apigateway.Cors.ALL_ORIGINS,
        allowMethods: apigateway.Cors.ALL_METHODS,
        allowHeaders: ["Content-Type", "Authorization"],
      },
    });

    // Cognito Authorizer
    const authorizer = new apigateway.CognitoUserPoolsAuthorizer(this, "CognitoAuthorizer", {
      cognitoUserPools: [userPool],
      authorizerName: "cognito-authorizer",
      identitySource: "method.request.header.Authorization",
    });

    // Request validator
    const requestValidator = new apigateway.RequestValidator(this, "RequestValidator", {
      restApi: api,
      validateRequestBody: true,
      validateRequestParameters: true,
    });

    // Users resource
    const users = api.root.addResource("users");

    // GET /users
    users.addMethod(
      "GET",
      new apigateway.LambdaIntegration(getUsersHandler, {
        requestTemplates: {
          "application/json": '{ "statusCode": "200" }',
        },
      }),
      {
        authorizer,
        authorizationType: apigateway.AuthorizationType.COGNITO,
        requestValidator,
        methodResponses: [
          {
            statusCode: "200",
            responseModels: {
              "application/json": apigateway.Model.EMPTY_MODEL,
            },
          },
        ],
      },
    );

    // Usage plan with API key
    const usagePlan = api.addUsagePlan("UsagePlan", {
      name: "Standard",
      throttle: {
        rateLimit: 100,
        burstLimit: 200,
      },
      quota: {
        limit: 10000,
        period: apigateway.Period.MONTH,
      },
    });

    const apiKey = api.addApiKey("ApiKey", {
      apiKeyName: "standard-key",
    });

    usagePlan.addApiKey(apiKey);
    usagePlan.addApiStage({ stage: api.deploymentStage });

    // Outputs
    new cdk.CfnOutput(this, "ApiUrl", {
      value: api.url,
    });
  }
}
```

```yaml
# Apigee Proxy Configuration
# apiproxy/proxies/default.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
<Description>User API Proxy</Description>
<FaultRules/>
<DefaultFaultRule name="default-fault">
<Step>
<Name>AM-ErrorResponse</Name>
</Step>
</DefaultFaultRule>
<PreFlow name="PreFlow">
<Request>
<Step>
<Name>RF-ThreatProtection</Name>
</Step>
<Step>
<Name>VA-VerifyAPIKey</Name>
</Step>
<Step>
<Name>QU-RateLimiting</Name>
</Step>
<Step>
<Name>SC-SpikeArrest</Name>
</Step>
</Request>
<Response/>
</PreFlow>
<PostFlow name="PostFlow">
<Request/>
<Response>
<Step>
<Name>AM-RemoveInternalHeaders</Name>
</Step>
</Response>
</PostFlow>
<Flows>
<Flow name="GetUsers">
<Description>Get all users</Description>
<Request>
<Step>
<Name>OA-VerifyJWT</Name>
</Step>
</Request>
<Response>
<Step>
<Name>JS-TransformResponse</Name>
</Step>
</Response>
<Condition>(proxy.pathsuffix MatchesPath "/users") and (request.verb = "GET")</Condition>
</Flow>
</Flows>
<HTTPProxyConnection>
<BasePath>/v1</BasePath>
<VirtualHost>secure</VirtualHost>
</HTTPProxyConnection>
<RouteRule name="default">
<TargetEndpoint>default</TargetEndpoint>
</RouteRule>
</ProxyEndpoint>
```

## Best Practices

### Security

- Always use HTTPS/TLS termination
- Implement rate limiting at gateway level
- Validate and sanitize all inputs
- Use OAuth2/JWT for authentication
- Apply WAF rules for protection

### Performance

- Enable response caching
- Use connection pooling
- Implement circuit breakers
- Monitor latency metrics
- Optimize payload sizes

### Observability

- Log all requests with correlation IDs
- Export metrics to monitoring systems
- Set up alerting for error rates
- Trace requests across services
- Track rate limit violations

### High Availability

- Deploy across multiple zones
- Use health checks for upstreams
- Implement graceful degradation
- Configure proper timeouts
- Plan for disaster recovery

You design and implement enterprise-grade API gateways with proper security, rate limiting, and observability.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.