Skip to content

DianaSill/Modular-API

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Cross-Account API Gateway — Modular Architecture

Proof of concept for centralising council APIs under a single custom domain using cross-account AWS architecture.

For the complete case study with detailed technical analysis, see CASE_STUDY.md

⚠️ Note: This is a sanitized version for portfolio purposes. All sensitive data, URLs, and identifiers have been anonymized.

Overview

Pattern: Account A hosts API Gateway with a custom domain → Account B (or C, D...) hosts Lambda functions. New services are added without DNS changes.

Architecture

%%{init: {'theme': 'dark', 'themeVariables': {'primaryColor': '#386193', 'primaryTextColor': '#fff', 'primaryBorderColor': '#5a8cc8', 'lineColor': '#5a8cc8', 'secondaryColor': '#1a1a2e', 'tertiaryColor': '#16213e', 'background': '#0d1117', 'mainBkg': '#0d1117', 'nodeBorder': '#5a8cc8'}, 'layout': 'elk'}}%%
flowchart TB
    Client(["External Client"])

    subgraph AccountA["Account A — API Gateway"]
        direction TB
        Domain["api.council.gov.uk<br/>Custom Domain + ACM"]
        APIGW["API Gateway<br/>REST API"]
        Role["APIGatewayExecutionRole<br/>Cross-Account IAM"]
    end

    subgraph AccountB["Account B — Halo ITSM"]
        direction TB
        LambdaB["Lambda Function<br/>.NET 8 Container"]
        PolicyB["Resource Policy<br/>Validates source"]
    end

    subgraph AccountC["Account C — Future Service"]
        direction TB
        LambdaC["Lambda Function"]
        PolicyC["Resource Policy<br/>Validates source"]
    end

    Client -->|"HTTPS"| Domain
    Domain -->|"Route"| APIGW
    APIGW -->|"AssumeRole"| Role
    Role -->|"Invoke /halo-itsm/*"| LambdaB
    Role -->|"Invoke /future/*"| LambdaC
    LambdaB -.->|"Validates"| PolicyB
    LambdaC -.->|"Validates"| PolicyC

    style AccountA fill:#1a1a2e,stroke:#8b5cf6,stroke-width:3px,color:#fff
    style AccountB fill:#1a1a2e,stroke:#2ecc71,stroke-width:2px,color:#fff
    style AccountC fill:#1a1a2e,stroke:#f39c12,stroke-width:2px,stroke-dasharray:5 5,color:#fff
    style Client fill:#386193,stroke:#5a8cc8,stroke-width:2px,color:#fff
    style Domain fill:#2c3e50,stroke:#8b5cf6,stroke-width:2px,color:#fff
    style APIGW fill:#2c3e50,stroke:#8b5cf6,stroke-width:2px,color:#fff
    style Role fill:#2c3e50,stroke:#f39c12,stroke-width:2px,color:#fff
    style LambdaB fill:#2c3e50,stroke:#2ecc71,stroke-width:2px,color:#fff
    style PolicyB fill:#16213e,stroke:#2ecc71,stroke-width:1px,color:#aaa
    style LambdaC fill:#2c3e50,stroke:#f39c12,stroke-width:2px,stroke-dasharray:5 5,color:#fff
    style PolicyC fill:#16213e,stroke:#f39c12,stroke-width:1px,stroke-dasharray:5 5,color:#aaa

    linkStyle 0 stroke:#3498db,stroke-width:2px
    linkStyle 1 stroke:#8b5cf6,stroke-width:2px
    linkStyle 2 stroke:#f39c12,stroke-width:2px
    linkStyle 3 stroke:#2ecc71,stroke-width:2px
    linkStyle 4 stroke:#f39c12,stroke-width:2px,stroke-dasharray:5 5
    linkStyle 5 stroke:#2ecc71,stroke-width:1px,stroke-dasharray:3 3
    linkStyle 6 stroke:#f39c12,stroke-width:1px,stroke-dasharray:3 3
Loading

How It Works

  1. Client calls https://api.council.gov.uk/service-name/endpoint
  2. DNS resolves to API Gateway in Account A
  3. API Gateway assumes APIGatewayExecutionRole
  4. Role invokes Lambda in target account
  5. Lambda resource policy validates source account and API Gateway ARN
  6. Response flows back through API Gateway

Security Model

  • Cross-account IAM role with least privilege (only specific Lambda ARNs)
  • Lambda resource policy validates both source account AND API Gateway ARN
  • CloudWatch logging enabled for full audit trail
  • No public Lambda access — invocation only possible via Account A's gateway

Adding a New Service

  1. Add new route to API Gateway (e.g., /planning/*)
  2. Deploy Lambda in target account
  3. Add Lambda resource policy allowing Account A
  4. Update IAM role with new Lambda ARN
  5. No DNS changes needed

Technology Stack

  • AWS API Gateway (REST API, regional endpoint)
  • AWS Lambda (target functions in separate accounts)
  • AWS IAM (cross-account role assumption)
  • AWS CloudFormation (Infrastructure as Code)
  • Custom Domain via Route 53 + ACM certificate

Key Design Decisions

Decision Rationale
Regional endpoint (not edge) Lower latency for UK users
IAM role (not resource policy only) Centralised permission management
Separate VPCs per service account Blast radius isolation
CloudFormation for gateway Reproducible, version-controlled

Project Structure

├── wncapi/
│   └── account-a-apigateway.yaml    # CloudFormation template
├── openapi.yaml                      # API specification
├── ARCHITECTURE.md                   # Detailed architecture docs
├── CASE_STUDY.md                     # Technical case study
└── README.md

About

Cross-account API Gateway architecture centralising council APIs under a single custom domain

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors