Skip to content

Instantly share code, notes, and snippets.

@bootswithdefer
Created April 29, 2026 22:46
Show Gist options
  • Select an option

  • Save bootswithdefer/31b12048a56c046fe38563814374950d to your computer and use it in GitHub Desktop.

Select an option

Save bootswithdefer/31b12048a56c046fe38563814374950d to your computer and use it in GitHub Desktop.

Project Proposal — Centralized MCP Gateway Pilot

Executive Summary

This proposal describes a controlled pilot for centralized Model Context Protocol (MCP) access at ASU, aligned with the enterprise MCP strategy's phased roadmap. The pilot deploys a managed MCP gateway on AWS, authenticated via Cloudflare Access, serving ~100 developers with two MCP servers (AWS Documentation and GitHub) and group-based per-tool access control. It validates the centralized hosting model the strategy recommends before broader enterprise adoption.

Background

MCP is an open protocol that connects AI applications to enterprise tools, data sources, and workflows through structured interfaces. Rather than giving AI models direct, unmanaged access to enterprise systems, MCP creates a controlled integration layer with defined capabilities and boundaries.

The enterprise MCP strategy identifies two deployment models:

  • Local user-managed — fast experimentation, but creates configuration drift, inconsistent updates, limited governance visibility, and complex support
  • Centrally hosted enterprise — standardized authentication, logging, deployment, and containerized services with control, observability, and security alignment

The strategy recommends using local environments to learn, but transitioning enterprise adoption toward centralized governance. This pilot is the first step in that transition.

Problem Statement

Approximately 100 developers currently configure MCP servers individually. Each developer manages their own server connections, credentials, and tool configurations. This produces:

  • Duplicated effort — every developer repeats the same setup for common servers like AWS Documentation and GitHub
  • Configuration drift — no consistency in which servers are available, how they're configured, or what versions are running
  • Secret sprawl — API keys and tokens stored in individual developer environments with no centralized rotation or revocation
  • No access control — no visibility into which developers access which tools, and no ability to enforce per-tool permissions based on role or team

Proposed Solution

A centralized MCP gateway that provides a single endpoint for all developers, replacing individual server configurations with a managed, authenticated, and access-controlled service.

The gateway uses three layers:

  • Authentication — Cloudflare Access acts as an OIDC identity provider, authenticating developers via the corporate IdP with PKCE-based OAuth. Developers authenticate once per session through their AI tool's built-in OAuth flow.
  • Authorization — A Lambda-based interceptor extracts group claims from the Cloudflare-issued JWT and enforces per-tool RBAC. Permissions are determined entirely by corporate IdP group membership — adding or removing MCP access means adding or removing someone from an IdP group.
  • MCP servers — The gateway routes requests to registered MCP server targets. The pilot includes two: AWS Documentation (containerized and hosted on AWS) and GitHub (vendor-hosted remote endpoint).

As a pilot, this validates:

  • The centralized gateway pattern works for real developer workflows
  • Cloudflare Access OIDC integrates cleanly with AWS-managed MCP infrastructure
  • Group-based RBAC provides sufficient access control granularity
  • The operational model (deployment, monitoring, onboarding) is sustainable at scale

Scope

In scope:

  • Amazon Bedrock AgentCore Gateway with CUSTOM_JWT authentication
  • Cloudflare Access SaaS OIDC application backed by corporate IdP
  • AWS Documentation MCP server (containerized stdio-to-HTTP adapter on AgentCore Runtime)
  • GitHub remote MCP server (vendor-hosted at api.githubcopilot.com)
  • Lambda-based RBAC interceptor with three roles (default, developers, admin)
  • Developer onboarding documentation and standardized client configurations
  • Observability via Datadog dashboards and CloudWatch alarms
  • OpenTofu IaC with existing CI/CD pipeline

Out of scope:

  • Write operations or action-based MCP capabilities (read-only pilot)
  • Additional MCP servers beyond AWS Documentation and GitHub
  • Changes to the corporate IdP or Cloudflare Access tenant configuration beyond the SaaS application
  • Cost optimization or FinOps integration (Phase 3 per enterprise strategy)

Architecture

graph LR
    subgraph Developers
        D1[Kiro / AI Tool]
        D2[Kiro / AI Tool]
    end

    subgraph Cloudflare
        CF[Cloudflare Access<br/>OIDC IdP<br/>SaaS App]
        IDP[Corporate IdP]
    end

    subgraph AWS
        GW[AgentCore Gateway<br/>CUSTOM_JWT auth<br/>Cloudflare OIDC]
        INT[Interceptor Lambda<br/>RBAC enforcement]

        subgraph Targets
            RT[AgentCore Runtime<br/>AWS Docs MCP<br/>containerized stdio]
            GH[GitHub Remote MCP<br/>api.githubcopilot.com]
        end
    end

    D1 & D2 -->|OAuth/PKCE| CF
    CF -->|Authenticate| IDP
    D1 & D2 -->|JWT Bearer| GW
    GW -->|Intercept| INT
    GW --> RT
    GW --> GH
Loading

Components

Component Technology Purpose
Identity provider Cloudflare Access (SaaS OIDC) Authenticates developers via corporate IdP, issues JWTs with group claims
Gateway Amazon Bedrock AgentCore Gateway Managed MCP gateway, validates JWTs, routes to targets
Interceptor AWS Lambda (Python 3.12) Extracts group claims, enforces per-tool RBAC
AWS Documentation MCP AgentCore Runtime (containerized) Searches and retrieves AWS documentation
GitHub MCP Vendor-hosted remote URL Repository, issue, and PR operations via GitHub's MCP endpoint

RBAC Roles

Role IdP Group Allowed Tools
default (no group match) AWS Documentation only
developers mcp-developers AWS Documentation + GitHub
admin mcp-admin All tools

Implementation Plan

The implementation is structured as seven sequential tasks, each producing a GitHub PR for review before merging.

Task Description Dependencies
1 Cloudflare Access SaaS OIDC application None
2 AgentCore Gateway with Cloudflare JWT auth Task 1
3 AWS Documentation MCP server (containerized) Task 2
4 GitHub remote MCP server target Task 2
5 RBAC interceptor Lambda Tasks 2, 3, 4
6 Developer onboarding documentation Tasks 1–5
7 Observability (Datadog dashboards, CloudWatch alarms) Task 2

All infrastructure is defined in OpenTofu and deployed through the existing Jenkins CI/CD pipeline (sandbox on all branches, production on default branch only). Secrets are managed through the existing Vault → Secrets Manager pipeline.

Risks and Mitigations

Per-developer GitHub OAuth passthrough — It is unclear whether AgentCore Gateway supports forwarding per-user OAuth tokens to remote MCP targets. If not, the fallback is per-developer GitHub PATs stored in Secrets Manager, keyed by developer identity. This will be validated during Task 4 implementation.

Cloudflare Access OIDC group claims — The group claim format and availability in Cloudflare-issued JWTs depends on corporate IdP configuration. If group claims are not present or are formatted differently than expected, the IdP team will need to expose group membership in the OIDC token. This should be confirmed before Task 5 (RBAC interceptor) begins.

Stdio-to-HTTP containerization — The AWS Documentation MCP server is a stdio-based tool that must be wrapped in an HTTP transport adapter for gateway hosting. This adapter layer adds a failure point and ongoing maintenance burden. If AgentCore Runtime provides native stdio support, the adapter can be eliminated.

RBAC granularity — The interceptor pattern provides tool-level access control (e.g., "can use GitHub tools") but not resource-level filtering (e.g., "can only access repos in org X"). For the pilot's read-oriented scope this is acceptable, but write-capable MCP servers in future phases will require finer-grained authorization.

Success Criteria

The pilot succeeds if:

  • Developers can connect to the gateway from Kiro (and other MCP clients) using a single mcp.json configuration with no local server setup
  • Authentication via Cloudflare Access completes without manual token management
  • RBAC correctly restricts tool access based on IdP group membership
  • AWS Documentation search/read and GitHub repository/issue/PR operations work through the gateway
  • Observability dashboards show per-tool and per-team usage metrics
  • A new developer can onboard to the gateway in under 5 minutes using the provided documentation

The pilot is ready to scale when these criteria are met and no blocking issues remain in the risk areas above.

Alignment with Enterprise Strategy

This pilot maps directly to the enterprise MCP strategy's recommendations:

Strategy Principle Pilot Implementation
Begin with controlled pilot focused on low-risk, high-value scenarios Read-only access to AWS Documentation and GitHub for ~100 developers
Define initial catalog of approved MCP server patterns Two server patterns: containerized stdio (AWS Docs) and remote URL (GitHub)
Engage Cybersecurity, Identity, and Enterprise Technology early Cloudflare Access OIDC integration requires IdP team coordination; RBAC design reviewed with security
Transition enterprise adoption toward centralized governance Gateway provides single endpoint with authentication, authorization, and observability from day one
Establish lifecycle management for MCP services OpenTofu IaC, CI/CD pipeline, and observability provide the operational foundation for managing MCP server lifecycle

The pilot validates the centralized hosting model at a controlled scale. Subsequent phases can expand the MCP server catalog, add write capabilities with additional governance controls, and integrate FinOps — following the strategy's phased roadmap from controlled pilot through documentation and automation expansion to full governance integration.

Implementation Plan — Centralized MCP Gateway on AWS with Cloudflare Access

Problem Statement

100 developers are each individually configuring common MCP servers. This creates duplicated effort, inconsistent configurations, secret sprawl, and no centralized access control. A single gateway endpoint is needed.

Requirements

  • Amazon Bedrock AgentCore Gateway (managed)
  • ~100 developers authenticated via Cloudflare Access (OIDC IdP), backed by corporate IdP
  • Per-tool RBAC via gateway interceptor pattern
  • MVP servers: AWS Documentation MCP (stdio, needs hosting) + GitHub remote MCP (vendor-hosted)
  • OpenTofu for IaC (project structure and CI/CD pre-existing)
  • Each task submitted as a GitHub PR with user approval before committing or submitting
  • Agent must never run tofu plan or tofu apply
  • Secrets managed via Vault → Secrets Manager pipeline
  • Observability via Datadog + CloudWatch

Background

  • AgentCore Gateway supports CUSTOM_JWT inbound auth, Lambda targets, and remote MCP URL targets.
  • Cloudflare Access for SaaS (OIDC) acts as a full OIDC identity provider with group claims, PKCE, and Authorization Code flow.
  • Kiro supports remote HTTP MCP servers with OAuth in mcp.json.
  • AWS Documentation MCP is a stdio tool (uvx awslabs.aws-documentation-mcp-server@latest) — needs containerization.
  • GitHub MCP is vendor-hosted at https://api.githubcopilot.com/mcp/ with OAuth/PAT auth.
  • RBAC interceptor pattern from mom-chandler-bots: Lambda + target___tool_name format. This project adapts the pattern to use Lambda environment variables instead of DynamoDB.
  • Cloudflare Access SaaS OIDC pattern from nac-arista-guardian-for-network-identity: inline resource with saas_app block.

Execution Constraints

  • Each task produces a feature branch and a GitHub PR via gh pr create
  • Conventional Commits format for PR titles (e.g., feat(gateway): add AgentCore gateway with Cloudflare JWT auth)
  • No tofu plan or tofu apply — validation limited to tofu fmt, tofu validate, and tflint
  • No commits or PRs without explicit user approval
  • OpenTofu (tofu) exclusively — not terraform
  • Python code validated with ruff check and ruff format --line-length 160
  • All resources live in the same Terraform directory — tasks can reference resources from preceding tasks via normal Terraform expressions

Architecture

graph LR
    subgraph Developers
        D1[Kiro / AI Tool]
        D2[Kiro / AI Tool]
    end

    subgraph Cloudflare
        CF[Cloudflare Access<br/>OIDC IdP<br/>SaaS App]
        IDP[Corporate IdP]
    end

    subgraph AWS
        GW[AgentCore Gateway<br/>CUSTOM_JWT auth<br/>Cloudflare OIDC]
        INT[Interceptor Lambda<br/>RBAC enforcement]

        subgraph Targets
            RT[AgentCore Runtime<br/>AWS Docs MCP<br/>containerized stdio]
            GH[GitHub Remote MCP<br/>api.githubcopilot.com]
        end
    end

    D1 & D2 -->|OAuth/PKCE| CF
    CF -->|Authenticate| IDP
    D1 & D2 -->|JWT Bearer| GW
    GW -->|Intercept| INT
    GW --> RT
    GW --> GH
Loading

Task Breakdown

Task 1: Create the Cloudflare Access SaaS OIDC application for the MCP gateway

Objective: Create a Cloudflare Access SaaS OIDC application that serves as the OIDC identity provider for the AgentCore Gateway.

Implementation guidance:

  • Follow the pattern from nac-arista-guardian-for-network-identity/terraform/main.tf — define a cloudflare_zero_trust_access_application resource with type = "saas" and saas_app block:
    • auth_type = "oidc"
    • allow_pkce_without_client_secret = true
    • grant_types = ["authorization_code_with_pkce"]
    • redirect_uris = ["http://127.0.0.1:8080"] (Kiro's localhost OAuth callback)
    • scopes = ["openid", "email", "profile", "groups"]
  • Look up identity providers and policies using data sources
  • Set allowed_idps to corporate IdP
  • Attach Access policies controlling who can use the MCP gateway
  • Use Vault-sourced Cloudflare provider credentials
  • Output the OIDC discovery URL and client ID

Validation: tofu fmt, tofu validate, tflint

PR: feat(cloudflare): add Access SaaS OIDC application for MCP gateway

Demo: A working Cloudflare Access OIDC application with discoverable endpoints.


Task 2: Create AgentCore Gateway with Cloudflare JWT inbound auth

Objective: Create a new aws_bedrockagentcore_gateway with CUSTOM_JWT authorizer pointing at Cloudflare Access.

Implementation guidance:

  • Follow mom-chandler-bots/terraform/agentcore-gateway.tf pattern:
    • aws_bedrockagentcore_gateway with authorizer_type = "CUSTOM_JWT", protocol_type = "MCP"
    • authorizer_configuration.custom_jwt_authorizer with discovery_url and allowed_clients referencing the Cloudflare Access application resource from Task 1 (e.g., cloudflare_zero_trust_access_application.this.id for client ID, constructed discovery URL from account/app ID)
  • Create gateway IAM role with bedrock-agentcore.amazonaws.com trust policy
  • Set up CloudWatch log group + log delivery
  • Store gateway endpoint in SSM parameter
  • Use module "product_tags" for naming/tagging
  • No interceptor yet — added in Task 5

Validation: tofu fmt, tofu validate, tflint

PR: feat(gateway): add AgentCore gateway with Cloudflare JWT auth

Demo: Developer authenticates via Cloudflare Access and reaches the live (empty) gateway endpoint.


Task 3: Host and register the AWS Documentation MCP server

Objective: Containerize the stdio-based AWS Documentation MCP server and register it as a gateway target.

Implementation guidance:

  • Create a Dockerfile wrapping uvx awslabs.aws-documentation-mcp-server@latest with a transport adapter to expose as HTTP MCP endpoint at 0.0.0.0:8000/mcp
  • Deploy on AgentCore Runtime (preferred — managed container hosting, no VPC/ALB needed):
    • Define aws_bedrockagentcore_runtime, push container to ECR, register as a runtime target on the gateway from Task 2
    • Fallback to ECS Fargate + internal ALB if AgentCore Runtime doesn't support the use case
  • Reference aws_bedrockagentcore_gateway.gateway.gateway_id from Task 2 for target registration
  • Update gateway IAM role policy from Task 2 to allow invocation of the new target

Validation: tofu fmt, tofu validate, tflint; Docker build succeeds

PR: feat(targets): add AWS Documentation MCP server

Demo: Developer searches/reads AWS documentation through the gateway.


Task 4: Register the GitHub remote MCP server as a gateway target

Objective: Wire up the vendor-hosted GitHub MCP server as a gateway target.

Implementation guidance:

  • Register https://api.githubcopilot.com/mcp/ as a remote MCP URL target on the gateway from Task 2, referencing aws_bedrockagentcore_gateway.gateway.gateway_id
  • Configure outbound auth for per-developer GitHub OAuth — each developer must authenticate to GitHub with their own identity (repo access and org membership are per-user)
  • Note: verify during implementation whether AgentCore Gateway's outbound auth supports per-developer OAuth token passthrough to a remote MCP URL target (Authorization Code flow), or if a different mechanism is needed (e.g., developer supplies their own GitHub PAT stored in Secrets Manager keyed by identity)
  • Update gateway IAM role from Task 2 if needed

Validation: tofu fmt, tofu validate, tflint

PR: feat(targets): add GitHub remote MCP server

Demo: Developer uses GitHub tools (repos, issues, PRs) through the gateway alongside AWS docs.


Task 5: RBAC interceptor and team-based access control

Objective: Deploy the gateway interceptor Lambda with group-based RBAC, adapted for Cloudflare JWT identity.

Implementation guidance:

  • Follow mom-chandler-bots interceptor pattern: Lambda function as gateway interceptor
  • Create interceptor Lambda (Python 3.12, arm64): extracts groups claim from Cloudflare JWT, matches group names to RBAC roles defined in environment variables, filters allowed tools
  • Role definitions passed as a JSON-encoded Lambda environment variable (e.g., RBAC_ROLES), sourced from an OpenTofu variable — no DynamoDB needed
  • Developer permissions are determined entirely by their IdP group membership — adding/removing MCP access = adding/removing someone from a corporate IdP group
  • Define initial RBAC roles in OpenTofu variables using target___tool_name format:
    • default: AWS docs tools only (applied when no group matches)
    • developers: AWS docs + GitHub tools
    • admin: *
  • Update the aws_bedrockagentcore_gateway resource from Task 2 to add the interceptor_configuration block pointing to the new interceptor Lambda
  • IAM role for interceptor with Lambda execution
  • Python code validated with ruff check and ruff format --line-length 160

Validation: tofu fmt, tofu validate, tflint; ruff check; ruff format --line-length 160

PR: feat(rbac): add gateway interceptor with group-based RBAC

Demo: Two developers from different teams see different available tools.


Task 6: Developer onboarding documentation

Objective: Create onboarding docs and standardized client config.

Implementation guidance:

  • README: gateway endpoint URL, first-auth experience, available tools by role
  • Template mcp.json for Kiro:
    {
      "mcpServers": {
        "company-gateway": {
          "type": "http",
          "url": "https://<gateway-endpoint>/mcp",
          "oauth": {
            "redirectUri": "127.0.0.1:8080",
            "oauthScopes": ["openid", "email", "profile", "groups"]
          }
        }
      }
    }
  • Configs for Claude Desktop, Cursor, etc.
  • Setup script for ~/.kiro/settings/mcp.json
  • Troubleshooting guide

PR: docs(onboarding): add developer setup guide and MCP client configs

Demo: Fresh developer machine connected to the gateway in under 5 minutes.


Task 7: Observability and operational readiness

Objective: Set up monitoring, logging, and alerting beyond the CloudWatch log group already created in Task 2.

Implementation guidance:

  • Datadog integration: API key, dashboards for request volume/latency/errors/per-tool/per-team usage
  • CloudWatch alarms: gateway errors, interceptor errors, auth failure spikes
  • Cloudflare Access log correlation
  • CloudWatch Logs to Log Lake module (referencing the log group from Task 2)

Validation: tofu fmt, tofu validate, tflint

PR: feat(observability): add Datadog dashboards and CloudWatch alarms

Demo: Datadog dashboard showing gateway usage with working alerts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment