Guide · AWS Compliance
AWS Config Conformance Packs for MCP Servers
A conformance pack is a collection of AWS Config rules and optional remediation actions packaged as a single CloudFormation template — deploy it once to get a complete compliance baseline rather than creating rules one by one. Three things teams misunderstand about conformance packs: conformance packs are deployed per-account-per-region, not globally (to deploy the same pack across 20 accounts use organizational conformance packs via AWS Organizations, which distribute the pack to every member account automatically), AWS-managed conformance pack templates contain controls that may not apply to your workload (the CIS Level 1 pack has 34 rules; some check EC2 security groups in ways that will always fire NON_COMPLIANT for valid MCP server configurations — you need to either customize the template or suppress specific findings), and the remediation actions in a conformance pack are separate from the rules (a pack can have rules without remediation, rules with auto-remediation, and rules with manual remediation targets — you must explicitly add AWS::Config::RemediationConfiguration resources to the template to get auto-healing).
TL;DR
Create a conformance pack from a CloudFormation template stored in S3 or using an AWS-managed template name. Bundle your 4-6 core Config rules plus their SSM Automation remediation actions into one template. Deploy account-by-account with put-conformance-pack, or organization-wide with put-organization-conformance-pack. Query compliance across the pack with describe-conformance-pack-compliance or use Config advanced queries (SQL) to get a per-rule breakdown across all accounts.
Anatomy of a conformance pack template
A conformance pack template is a standard CloudFormation template with one important constraint: it can only contain AWS::Config::ConfigRule and AWS::Config::RemediationConfiguration resources — no IAM roles, no S3 buckets, no Lambda functions. Any Lambda functions used by custom rules must already exist in the account before the pack is deployed. The template is uploaded to S3 and referenced by ARN, or you specify one of AWS's pre-authored template names.
# Example custom conformance pack template for MCP server compliance
# File: mcp-compliance-pack.yaml — upload to S3 before deploying
Parameters:
RequiredTagKeys:
Type: String
Default: "Environment,Service,Owner"
MaxLambdaConcurrency:
Type: String
Default: "100"
Resources:
# Rule 1: DynamoDB tables must have SSE enabled
DynamoDbEncryptionRule:
Type: AWS::Config::ConfigRule
Properties:
ConfigRuleName: mcp-pack-dynamodb-encryption
Description: DynamoDB tables must have server-side encryption enabled
Source:
Owner: AWS
SourceIdentifier: DYNAMODB_TABLE_ENCRYPTION_ENABLED
Scope:
ComplianceResourceTypes:
- AWS::DynamoDB::Table
# Rule 2: VPCs must have flow logs enabled
VpcFlowLogsRule:
Type: AWS::Config::ConfigRule
Properties:
ConfigRuleName: mcp-pack-vpc-flow-logs
Description: All VPCs must have flow logs enabled
Source:
Owner: AWS
SourceIdentifier: VPC_FLOW_LOGS_ENABLED
InputParameters:
trafficType: ALL
Scope:
ComplianceResourceTypes:
- AWS::EC2::VPC
# Rule 3: Required tags on all supported resource types
RequiredTagsRule:
Type: AWS::Config::ConfigRule
Properties:
ConfigRuleName: mcp-pack-required-tags
Description: Core resources must have Environment, Service, and Owner tags
Source:
Owner: AWS
SourceIdentifier: REQUIRED_TAGS
InputParameters:
tag1Key: Environment
tag1Value: prod,staging,dev
tag2Key: Service
tag3Key: Owner
# Rule 4: Lambda functions must have reserved concurrency set
LambdaConcurrencyRule:
Type: AWS::Config::ConfigRule
Properties:
ConfigRuleName: mcp-pack-lambda-concurrency
Description: Lambda functions must have reserved concurrency to prevent noisy-neighbor throttling
Source:
Owner: AWS
SourceIdentifier: LAMBDA_CONCURRENCY_CHECK
InputParameters:
ConcurrencyLimitHigh: !Ref MaxLambdaConcurrency
Scope:
ComplianceResourceTypes:
- AWS::Lambda::Function
# Remediation: auto-tag non-compliant resources with placeholder values
# (flags them for team review rather than silently leaving untagged)
RequiredTagsRemediation:
Type: AWS::Config::RemediationConfiguration
Properties:
ConfigRuleName: !Ref RequiredTagsRule
TargetType: SSM_DOCUMENT
TargetId: AWS-AddTagsToResource
Automatic: false # manual remediation — wrong tags need human review
MaximumAutomaticAttempts: 1
RetryAttemptSeconds: 60
Parameters:
ResourceARN:
ResourceValue:
Value: RESOURCE_ID
Tags:
StaticValue:
Values:
- '{"Environment":"unknown","Service":"untagged","Owner":"ops-team@company.com"}'
AWS-managed conformance pack templates
AWS provides pre-authored conformance pack templates for common compliance frameworks. You reference these by name in TemplateSSMDocumentDetails or use the AWS Console's "Quick Setup" option. The most relevant for MCP server workloads:
| Template name | Framework | Rules | MCP relevance |
|---|---|---|---|
Operational-Best-Practices-for-CIS-AWS-v1.4-Level1 |
CIS AWS Foundations Benchmark v1.4 Level 1 | ~34 rules | High — covers IAM, CloudTrail, VPC, S3, and logging requirements |
Operational-Best-Practices-for-NIST-800-53-rev-5 |
NIST SP 800-53 Rev 5 | ~200 rules | High for regulated environments — covers access control, audit, and system protection |
Operational-Best-Practices-for-AWS-Well-Architected-Security-Pillar |
AWS Well-Architected Security Pillar | ~80 rules | Medium — general AWS security best practices; some rules apply directly to MCP infrastructure |
Operational-Best-Practices-for-PCI-DSS-3.2.1 |
PCI DSS 3.2.1 | ~140 rules | Use only if handling payment card data in MCP tool calls |
# Deploy the CIS Level 1 AWS-managed pack to a single account
aws configservice put-conformance-pack \
--conformance-pack-name mcp-cis-level1 \
--template-ssm-document-details DocumentName="Operational-Best-Practices-for-CIS-AWS-v1.4-Level1" \
--delivery-s3-bucket mcp-config-delivery-123456789012 \
--region us-east-1
# Check deployment status (takes 5-10 minutes)
aws configservice describe-conformance-pack-status \
--conformance-pack-names mcp-cis-level1 \
--query "ConformancePackStatusDetails[*].{Pack:conformancePackName,Status:conformancePackState,Reason:conformancePackStatusReason}"
Organizational conformance packs — deploying to all accounts
Organizational conformance packs deploy the same template to all member accounts in your AWS Organization simultaneously. The management account (or a delegated Config admin account) runs the put-organization-conformance-pack call. Config service creates a stack set under the hood — each member account gets its own conformance pack resource. Accounts can be excluded individually with ExcludedAccounts.
Critical prerequisite: AWS Config must be enabled in every member account and region where you want the pack deployed. If Config is not enabled in a member account, that account will show CREATE_FAILED for the pack. The organization pack deployment will still proceed for other accounts — a single failing account doesn't block the rest.
# Deploy custom pack organization-wide (from management or delegated admin account)
# Template must be in S3 in the management account — member accounts can't read it directly
aws configservice put-organization-conformance-pack \
--organization-conformance-pack-name mcp-org-compliance-baseline \
--template-s3-uri s3://mcp-config-templates/mcp-compliance-pack.yaml \
--delivery-s3-bucket mcp-config-delivery \
--delivery-s3-key-prefix config-packs \
--excluded-accounts "123456789012" # sandbox account — excluded from org pack
# Check deployment status across all accounts
aws configservice describe-organization-conformance-pack-statuses \
--organization-conformance-pack-names mcp-org-compliance-baseline
# Get per-account failure reasons for accounts that failed to deploy
aws configservice get-organization-conformance-pack-detailed-status \
--organization-conformance-pack-name mcp-org-compliance-baseline \
--filters Status=CREATE_FAILED
Querying conformance pack compliance
Use describe-conformance-pack-compliance to get per-rule compliance status within a pack, and get-conformance-pack-compliance-summary for an aggregate count. For cross-account queries (e.g., "how many accounts have the DynamoDB encryption rule NON_COMPLIANT?"), use Config advanced queries through the aggregator — a SQL query against the aggregated configuration data.
// Get compliance summary for one conformance pack
import {
ConfigServiceClient,
DescribeConformancePackComplianceCommand,
GetConformancePackComplianceSummaryCommand,
} from "@aws-sdk/client-config-service";
const client = new ConfigServiceClient({ region: "us-east-1" });
async function getPackComplianceSummary(packName: string): Promise<void> {
// Aggregate summary: compliant vs non-compliant rule count for the pack
const summary = await client.send(
new GetConformancePackComplianceSummaryCommand({
ConformancePackNames: [packName],
})
);
const pack = summary.ConformancePackComplianceSummaryList?.[0];
console.log(`Pack: ${pack?.ConformancePackName}`, pack?.ConformancePackComplianceStatus);
// Per-rule compliance details
const details = await client.send(
new DescribeConformancePackComplianceCommand({
ConformancePackName: packName,
Filters: { ComplianceType: "NON_COMPLIANT" }, // only show failing rules
})
);
for (const rule of details.ConformancePackRuleComplianceList ?? []) {
console.log(
` Rule: ${rule.ConfigRuleName} — ${rule.ComplianceType}`,
`(${rule.Controls?.join(", ") ?? "no framework controls mapped"})`
);
}
}
// Cross-account SQL query using Config aggregator (requires aggregator to be set up)
// See: /seo/mcp-server-config-aggregator for aggregator setup
const crossAccountQuery = `
SELECT
accountId,
configRuleName,
complianceType,
COUNT(*) as resourceCount
FROM
aws_config_configuration_snapshot
WHERE
configRuleName LIKE 'mcp-pack-%'
AND complianceType = 'NON_COMPLIANT'
GROUP BY
accountId, configRuleName, complianceType
ORDER BY
accountId, configRuleName
`;
Customizing AWS-managed templates — removing inapplicable rules
AWS-managed conformance packs cannot be edited in place — they are read-only templates. To customize, download the template from the AWS Config console (or from the awslabs/aws-config-rules GitHub repo), remove or adjust rules that don't apply to your MCP server workload, upload to your own S3 bucket, and deploy from there. Common rules in the CIS Level 1 pack that generate false positives for MCP servers:
| Rule | Why it fires for MCP servers | Action |
|---|---|---|
EC2_INSTANCE_NO_PUBLIC_IP |
Public Fargate tasks or EC2-hosted MCP servers intentionally need public IPs for client connectivity | Remove if using public-facing MCP endpoints; keep if all access is through ALB |
S3_BUCKET_PUBLIC_READ_PROHIBITED |
MCP servers that serve static assets (JS widget, OpenAPI spec) from S3 may need public read | Remove or use resource scope to exclude the specific public-assets bucket |
RESTRICTED_INCOMING_TRAFFIC |
Checks security groups for unrestricted SSH/RDP — irrelevant for ECS/Lambda-based MCP servers | Keep — even if you don't use SSH, having the check is a valid guard against accidental SG changes |
ACCESS_KEYS_ROTATED |
Fires if any IAM user access keys are older than 90 days — may be intentional for CI/CD service accounts | Customize maxAccessKeyAge parameter; exclude the CI/CD user from evaluation scope |
Failure modes and common mistakes
| Symptom | Root cause | Fix |
|---|---|---|
| Conformance pack stuck in CREATE_IN_PROGRESS for over 30 minutes | Template references a custom rule Lambda that doesn't exist in the account; or S3 bucket for delivery doesn't exist | Create the Lambda and delivery S3 bucket before deploying the pack; check describe-conformance-pack-status for the error reason |
| Organization conformance pack shows CREATE_FAILED for some member accounts | Config recorder not enabled in those accounts, or AWS Config service role missing | Run get-organization-conformance-pack-detailed-status to get per-account reasons; enable Config in failing accounts |
| Pack deployed but rules show NO_CONFIGURATION_ITEMS_SEEN | Config recorder in member accounts has a narrower scope than the rules require | Expand recorder scope to include the resource types the pack rules evaluate; run start-config-rules-evaluation |
| Cannot delete a conformance pack — dependency error | Organizational conformance pack must be deleted from the management/delegated-admin account, not from a member account | Use delete-organization-conformance-pack from the management account, not delete-conformance-pack |
| Conformance pack template exceeds the 50KB size limit | Template stored inline (not in S3) with too many rules and remediations | Always use the --template-s3-uri option for templates with more than ~10 rules; S3-sourced templates don't have the size limit |