> ## Documentation Index
> Fetch the complete documentation index at: https://mcp-server-langgraph.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# IAM and RBAC Requirements

> Multi-cloud IAM/RBAC permissions for CI/CD deployments

# IAM and RBAC Requirements for Multi-Cloud Deployment

**Last Updated**: 2025-11-02
**Applies To**: GCP GKE, AWS EKS, Azure AKS
**Purpose**: Comprehensive IAM/RBAC permissions required for CI/CD deployments

***

## Overview

This document defines all required IAM roles, permissions, and RBAC policies needed to deploy MCP Server LangGraph to Kubernetes across all three major cloud providers.

### Principle: Least Privilege

All permissions follow the **principle of least privilege** - granting only the minimum permissions necessary for each operation.

***

## GCP (Google Kubernetes Engine)

### Service Account: `mcp-staging-sa@PROJECT_ID.iam.gserviceaccount.com`

#### Required IAM Roles

| Role                                 | Permission   | Purpose                                 | Required For           |
| ------------------------------------ | ------------ | --------------------------------------- | ---------------------- |
| `roles/artifactregistry.writer`      | **CRITICAL** | Push Docker images to Artifact Registry | Docker build & push    |
| `roles/container.developer`          | **CRITICAL** | Deploy to GKE, manage workloads         | kubectl apply, rollout |
| `roles/logging.logWriter`            | Standard     | Write application logs                  | Runtime logging        |
| `roles/monitoring.metricWriter`      | Standard     | Write metrics and traces                | Observability          |
| `roles/secretmanager.secretAccessor` | Standard     | Access application secrets              | Runtime configuration  |
| `roles/cloudsql.client`              | Optional     | Connect to Cloud SQL databases          | Database access        |

#### Grant Commands

```bash theme={null}
PROJECT_ID="your-project-id"
SERVICE_ACCOUNT="mcp-staging-sa@${PROJECT_ID}.iam.gserviceaccount.com"

# CRITICAL: Artifact Registry Writer
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/artifactregistry.writer"

# CRITICAL: Container Developer
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/container.developer"

# Standard: Logging
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/logging.logWriter"

# Standard: Monitoring
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/monitoring.metricWriter"

# Standard: Secrets
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/secretmanager.secretAccessor"

# Optional: Cloud SQL (if using managed PostgreSQL)
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/cloudsql.client"
```

#### Workload Identity Federation (GitHub Actions)

**Pool**: `github-actions-pool`
**Provider**: `github-provider`

```bash theme={null}
# Allow GitHub Actions to impersonate service account
gcloud iam service-accounts add-iam-policy-binding \
  "${SERVICE_ACCOUNT}" \
  --role="roles/iam.workloadIdentityUser" \
  --member="principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/github-actions-pool/attribute.repository/${GITHUB_REPO}"
```

#### Kubernetes RBAC (In-Cluster)

**Service Account**: `mcp-server-langgraph` (in namespace)

```yaml theme={null}
apiVersion: v1
kind: ServiceAccount
metadata:
  name: mcp-server-langgraph
  namespace: staging-mcp-server-langgraph
  annotations:
    iam.gke.io/gcp-service-account: mcp-staging-sa@PROJECT_ID.iam.gserviceaccount.com
```

#### Verification

```bash theme={null}
# Check all IAM roles
gcloud projects get-iam-policy $PROJECT_ID \
  --flatten="bindings[].members" \
  --filter="bindings.members:${SERVICE_ACCOUNT}" \
  --format="table(bindings.role)"

# Expected output:
# roles/artifactregistry.writer     ✓
# roles/container.developer         ✓
# roles/logging.logWriter           ✓
# roles/monitoring.metricWriter     ✓
# roles/secretmanager.secretAccessor ✓
# roles/cloudsql.client             ✓
```

***

## AWS (Elastic Kubernetes Service)

### IAM Role: `mcp-eks-deployment-role`

#### Required IAM Policies

| Policy                           | Type        | Purpose                    | Required For        |
| -------------------------------- | ----------- | -------------------------- | ------------------- |
| `AmazonEKSClusterPolicy`         | AWS Managed | EKS cluster management     | Cluster operations  |
| `AmazonEKSServicePolicy`         | AWS Managed | EKS service linking        | Service integration |
| `AmazonEKSVPCResourceController` | AWS Managed | VPC resource management    | Network policies    |
| Custom: ECR Push/Pull            | Custom      | Push/pull container images | Docker build & push |
| Custom: EKS Deploy               | Custom      | Deploy to EKS workloads    | kubectl apply       |
| Custom: CloudWatch Logs          | Custom      | Write application logs     | Logging             |
| Custom: CloudWatch Metrics       | Custom      | Publish metrics            | Observability       |
| Custom: Secrets Manager          | Custom      | Access secrets             | Runtime config      |

#### Custom IAM Policy: ECR Access

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ECRPushPull",
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:GetDownloadUrlForLayer",
        "ecr:PutImage",
        "ecr:InitiateLayerUpload",
        "ecr:UploadLayerPart",
        "ecr:CompleteLayerUpload",
        "ecr:BatchGetImage"
      ],
      "Resource": "*"
    }
  ]
}
```

#### Custom IAM Policy: EKS Deployment

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EKSDeploy",
      "Effect": "Allow",
      "Action": [
        "eks:DescribeCluster",
        "eks:ListClusters",
        "eks:DescribeNodegroup",
        "eks:ListNodegroups"
      ],
      "Resource": "arn:aws:eks:*:ACCOUNT_ID:cluster/mcp-*"
    }
  ]
}
```

#### IRSA (IAM Roles for Service Accounts)

**Service Account Annotation**:

```yaml theme={null}
apiVersion: v1
kind: ServiceAccount
metadata:
  name: mcp-server-langgraph
  namespace: mcp-server-langgraph
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/mcp-eks-pod-role
```

**Trust Policy**:

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.REGION.amazonaws.com/id/CLUSTER_ID"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.eks.REGION.amazonaws.com/id/CLUSTER_ID:sub": "system:serviceaccount:mcp-server-langgraph:mcp-server-langgraph"
        }
      }
    }
  ]
}
```

#### Grant Commands (AWS CLI)

```bash theme={null}
# Create IAM role for EKS deployment
aws iam create-role \
  --role-name mcp-eks-deployment-role \
  --assume-role-policy-document file://trust-policy.json

# Attach AWS managed policies
aws iam attach-role-policy \
  --role-name mcp-eks-deployment-role \
  --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy

# Create and attach custom ECR policy
aws iam put-role-policy \
  --role-name mcp-eks-deployment-role \
  --policy-name ECRAccess \
  --policy-document file://ecr-policy.json
```

***

## Azure (Azure Kubernetes Service)

### Service Principal / Managed Identity: `mcp-aks-sp`

#### Required Azure RBAC Roles

| Role                                         | Scope              | Purpose                    | Required For        |
| -------------------------------------------- | ------------------ | -------------------------- | ------------------- |
| `Azure Kubernetes Service Cluster User Role` | AKS Cluster        | Access cluster credentials | kubectl access      |
| `AcrPush`                                    | Container Registry | Push container images      | Docker build & push |
| `AcrPull`                                    | Container Registry | Pull container images      | Deployment          |
| `Contributor` (limited scope)                | Resource Group     | Manage AKS resources       | Deployment updates  |
| `Monitoring Metrics Publisher`               | Subscription       | Publish metrics            | Observability       |
| `Key Vault Secrets User`                     | Key Vault          | Access secrets             | Runtime config      |

#### Grant Commands (Azure CLI)

```bash theme={null}
RESOURCE_GROUP="mcp-production-rg"
CLUSTER_NAME="mcp-production"
ACR_NAME="mcpcontainerregistry"
SUBSCRIPTION_ID=$(az account show --query id -o tsv)

# Create service principal
SP_INFO=$(az ad sp create-for-rbac \
  --name mcp-aks-sp \
  --role "Azure Kubernetes Service Cluster User Role" \
  --scopes /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP)

SP_OBJECT_ID=$(echo $SP_INFO | jq -r '.appId')

# Grant ACR Push role
az role assignment create \
  --assignee $SP_OBJECT_ID \
  --role AcrPush \
  --scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.ContainerRegistry/registries/$ACR_NAME

# Grant ACR Pull role
az role assignment create \
  --assignee $SP_OBJECT_ID \
  --role AcrPull \
  --scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.ContainerRegistry/registries/$ACR_NAME

# Grant Contributor (scoped to resource group)
az role assignment create \
  --assignee $SP_OBJECT_ID \
  --role Contributor \
  --scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP

# Grant Monitoring Metrics Publisher
az role assignment create \
  --assignee $SP_OBJECT_ID \
  --role "Monitoring Metrics Publisher" \
  --scope /subscriptions/$SUBSCRIPTION_ID
```

#### Workload Identity (Azure AD Pod Identity)

**Pod Identity**:

```yaml theme={null}
apiVersion: "aadpodidentity.k8s.io/v1"
kind: AzureIdentity
metadata:
  name: mcp-identity
  namespace: mcp-server-langgraph
spec:
  type: 0  # User-assigned managed identity
  resourceID: /subscriptions/SUBSCRIPTION_ID/resourcegroups/RESOURCE_GROUP/providers/Microsoft.ManagedIdentity/userAssignedIdentities/mcp-identity
  clientID: CLIENT_ID
```

**Pod Identity Binding**:

```yaml theme={null}
apiVersion: "aadpodidentity.k8s.io/v1"
kind: AzureIdentityBinding
metadata:
  name: mcp-identity-binding
  namespace: mcp-server-langgraph
spec:
  azureIdentity: mcp-identity
  selector: mcp-server-langgraph
```

***

## Kubernetes RBAC (Common to All Platforms)

### Namespace-Level Permissions

#### ServiceAccount

```yaml theme={null}
apiVersion: v1
kind: ServiceAccount
metadata:
  name: mcp-server-langgraph
  namespace: mcp-server-langgraph
```

#### Role

```yaml theme={null}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: mcp-server-langgraph
  namespace: mcp-server-langgraph
rules:
  # Allow reading ConfigMaps
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "watch"]

  # Allow reading Secrets
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "list"]

  # Allow reading Services
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["get", "list"]

  # Allow creating Events
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "patch"]
```

#### RoleBinding

```yaml theme={null}
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: mcp-server-langgraph
  namespace: mcp-server-langgraph
subjects:
  - kind: ServiceAccount
    name: mcp-server-langgraph
    namespace: mcp-server-langgraph
roleRef:
  kind: Role
  name: mcp-server-langgraph
  apiGroup: rbac.authorization.k8s.io
```

***

## CI/CD Service Account Permissions

### GitHub Actions (All Platforms)

**Required Permissions**:

1. **Pull from source repository** - GitHub token (automatic)
2. **Authenticate to cloud provider** - Workload Identity Federation / OIDC
3. **Push container images** - Container registry write access
4. **Deploy to Kubernetes** - Cluster access with deployment permissions

### Deployment Pipeline Permissions

```yaml theme={null}
# GitHub Actions workflow permissions
permissions:
  contents: read        # Read repository contents
  id-token: write       # Request OIDC tokens for cloud auth
  packages: write       # Push to GitHub Container Registry (optional)
  deployments: write    # Create deployment statuses
```

***

## Validation Scripts

### GCP Validation

```bash theme={null}
#!/bin/bash
# validate-gcp-permissions.sh

SERVICE_ACCOUNT="mcp-staging-sa@PROJECT_ID.iam.gserviceaccount.com"

REQUIRED_ROLES=(
  "roles/artifactregistry.writer"
  "roles/container.developer"
  "roles/logging.logWriter"
  "roles/monitoring.metricWriter"
  "roles/secretmanager.secretAccessor"
)

echo "Validating GCP IAM roles..."
GRANTED_ROLES=$(gcloud projects get-iam-policy $PROJECT_ID \
  --flatten="bindings[].members" \
  --filter="bindings.members:${SERVICE_ACCOUNT}" \
  --format="value(bindings.role)")

for role in "${REQUIRED_ROLES[@]}"; do
  if echo "$GRANTED_ROLES" | grep -q "$role"; then
    echo "✓ $role"
  else
    echo "✗ $role (MISSING)"
    exit 1
  fi
done

echo "✓ All required IAM roles present"
```

### AWS Validation

```bash theme={null}
#!/bin/bash
# validate-aws-permissions.sh

ROLE_NAME="mcp-eks-deployment-role"

echo "Validating AWS IAM policies..."
aws iam list-attached-role-policies --role-name $ROLE_NAME
aws iam list-role-policies --role-name $ROLE_NAME

echo "✓ IAM policies validated"
```

### Azure Validation

```bash theme={null}
#!/bin/bash
# validate-azure-permissions.sh

SP_OBJECT_ID="your-service-principal-id"
RESOURCE_GROUP="mcp-production-rg"

echo "Validating Azure RBAC roles..."
az role assignment list --assignee $SP_OBJECT_ID --resource-group $RESOURCE_GROUP

echo "✓ RBAC roles validated"
```

***

## Troubleshooting

### Common Permission Errors

#### GCP: "Permission denied on Artifact Registry"

**Error**:

```text theme={null}
denied: Permission "artifactregistry.repositories.uploadArtifacts" denied
```

**Fix**:

```bash theme={null}
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/artifactregistry.writer"
```

#### AWS: "AccessDenied ECR"

**Error**:

```yaml theme={null}
denied: User: arn:aws:sts::ACCOUNT:assumed-role/... is not authorized to perform: ecr:PutImage
```

**Fix**:
Apply ECR custom policy (see above)

#### Azure: "Authorization failed for ACR"

**Error**:

```yaml theme={null}
unauthorized: authentication required
```

**Fix**:

```bash theme={null}
az role assignment create \
  --assignee $SP_OBJECT_ID \
  --role AcrPush \
  --scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.ContainerRegistry/registries/$ACR_NAME
```

***

## Security Best Practices

### 1. Use Workload Identity / IRSA

* ✅ **Do**: Use platform-native workload identity (GCP Workload Identity, AWS IRSA, Azure Pod Identity)
* ❌ **Don't**: Use long-lived service account keys

### 2. Principle of Least Privilege

* ✅ **Do**: Grant only required permissions
* ❌ **Don't**: Grant `Owner`, `Editor`, or `Admin` roles

### 3. Scope Permissions Narrowly

* ✅ **Do**: Scope to specific resources (namespace, resource group, etc.)
* ❌ **Don't**: Grant organization-wide or subscription-wide permissions

### 4. Regular Audits

* ✅ **Do**: Regularly review and audit permissions
* ❌ **Don't**: Set-and-forget permissions

### 5. Use Resource-Level Permissions

* ✅ **Do**: Grant access to specific container registries, clusters
* ❌ **Don't**: Grant wildcard (\*) resource access

***

## References

### Documentation

* **GCP**: [GCP Configuration Guide](/deployment/gcp-configuration)
* **AWS**: AWS EKS Configuration (see scripts and Terraform modules below)
* **Azure**: Azure AKS Configuration (see scripts and Terraform modules below)

<Note>
  AWS EKS and Azure AKS deployment documentation is available via deployment scripts and Terraform modules. Dedicated configuration guides are planned for future releases.
</Note>

### Scripts

* **GCP Setup**: `scripts/gcp/setup-staging-infrastructure.sh`
* **AWS Setup**: `scripts/deploy-aws-eks.sh`
* **Azure Setup**: `scripts/deploy-azure-aks.sh`

### Terraform Modules

* **GCP**: `terraform/modules/gke/`
* **AWS**: `terraform/modules/eks/`
* **Azure**: `terraform/modules/aks/`

***

**Maintained By**: DevOps Team
**Last Reviewed**: 2025-11-02
**Next Review**: 2025-12-01
