Skip to content

Commit 15e4818

Browse files
committed
added prototype config rule for kb vector store secrete
1 parent 742f13a commit 15e4818

File tree

4 files changed

+155
-0
lines changed

4 files changed

+155
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
"""Config rule to check knowledge base vector store secret configuration for Bedrock environments.
2+
3+
Version: 1.0
4+
5+
Config rule for SRA in the repo, https://github.com/aws-samples/aws-security-reference-architecture-examples
6+
7+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
8+
SPDX-License-Identifier: MIT-0
9+
"""
10+
import json
11+
import logging
12+
import os
13+
from typing import Any
14+
15+
import boto3
16+
from botocore.exceptions import ClientError
17+
18+
# Setup Default Logger
19+
LOGGER = logging.getLogger(__name__)
20+
log_level = os.environ.get("LOG_LEVEL", logging.INFO)
21+
LOGGER.setLevel(log_level)
22+
LOGGER.info(f"boto3 version: {boto3.__version__}")
23+
24+
# Get AWS region from environment variable
25+
AWS_REGION = os.environ.get("AWS_REGION")
26+
27+
# Initialize AWS clients
28+
bedrock_agent_client = boto3.client("bedrock-agent", region_name=AWS_REGION)
29+
secretsmanager_client = boto3.client("secretsmanager", region_name=AWS_REGION)
30+
config_client = boto3.client("config", region_name=AWS_REGION)
31+
32+
def evaluate_compliance(rule_parameters: dict) -> tuple[str, str]:
33+
"""Evaluate if Bedrock Knowledge Base vector stores are using KMS encrypted secrets.
34+
35+
Args:
36+
rule_parameters (dict): Rule parameters from AWS Config rule.
37+
38+
Returns:
39+
tuple[str, str]: Compliance type and annotation message.
40+
"""
41+
try:
42+
non_compliant_kbs = []
43+
paginator = bedrock_agent_client.get_paginator("list_knowledge_bases")
44+
45+
for page in paginator.paginate():
46+
for kb in page["knowledgeBaseSummaries"]:
47+
kb_id = kb["knowledgeBaseId"]
48+
kb_name = kb.get("name", kb_id)
49+
50+
try:
51+
# Get knowledge base details
52+
kb_details = bedrock_agent_client.get_knowledge_base(knowledgeBaseId=kb_id)
53+
vector_store = kb_details.get("vectorStoreConfiguration")
54+
55+
if vector_store:
56+
secret_arn = vector_store.get("secretArn")
57+
if not secret_arn:
58+
non_compliant_kbs.append(f"{kb_name} (no secret configured)")
59+
continue
60+
61+
try:
62+
# Check if secret uses CMK
63+
secret_details = secretsmanager_client.describe_secret(SecretId=secret_arn)
64+
if not secret_details.get("KmsKeyId"):
65+
non_compliant_kbs.append(f"{kb_name} (secret not using CMK)")
66+
except ClientError as e:
67+
LOGGER.error(f"Error checking secret {secret_arn}: {str(e)}")
68+
if e.response["Error"]["Code"] == "AccessDeniedException":
69+
non_compliant_kbs.append(f"{kb_name} (secret access denied)")
70+
else:
71+
raise
72+
73+
except ClientError as e:
74+
LOGGER.error(f"Error checking knowledge base {kb_name}: {str(e)}")
75+
if e.response["Error"]["Code"] == "AccessDeniedException":
76+
non_compliant_kbs.append(f"{kb_name} (access denied)")
77+
else:
78+
raise
79+
80+
if non_compliant_kbs:
81+
return "NON_COMPLIANT", f"The following knowledge bases have vector store secret issues: {'; '.join(non_compliant_kbs)}"
82+
return "COMPLIANT", "All knowledge base vector stores are using KMS encrypted secrets"
83+
84+
except Exception as e:
85+
LOGGER.error(f"Error evaluating Bedrock Knowledge Base vector store secrets: {str(e)}")
86+
return "ERROR", f"Error evaluating compliance: {str(e)}"
87+
88+
def lambda_handler(event: dict, context: Any) -> None:
89+
"""Lambda handler.
90+
91+
Args:
92+
event (dict): Lambda event object
93+
context (Any): Lambda context object
94+
"""
95+
LOGGER.info("Evaluating compliance for AWS Config rule")
96+
LOGGER.info(f"Event: {json.dumps(event)}")
97+
98+
invoking_event = json.loads(event["invokingEvent"])
99+
rule_parameters = json.loads(event["ruleParameters"]) if "ruleParameters" in event else {}
100+
101+
compliance_type, annotation = evaluate_compliance(rule_parameters)
102+
103+
evaluation = {
104+
"ComplianceResourceType": "AWS::::Account",
105+
"ComplianceResourceId": event["accountId"],
106+
"ComplianceType": compliance_type,
107+
"Annotation": annotation,
108+
"OrderingTimestamp": invoking_event["notificationCreationTime"],
109+
}
110+
111+
LOGGER.info(f"Compliance evaluation result: {compliance_type}")
112+
LOGGER.info(f"Annotation: {annotation}")
113+
114+
config_client.put_evaluations(Evaluations=[evaluation], ResultToken=event["resultToken"])
115+
116+
LOGGER.info("Compliance evaluation complete.")

aws_sra_examples/solutions/genai/bedrock_org/lambda/src/app.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ def load_sra_cloudwatch_dashboard() -> dict:
208208
+ r'\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*\{(\s*"check_retention"\s*:\s*"(true|false)")?(\s*,\s*"check_encryption"\s*:\s*'
209209
+ r'"(true|false)")?(\s*,\s*"check_access_logging"\s*:\s*"(true|false)")?(\s*,\s*"check_object_locking"\s*:\s*"(true|false)")?(\s*,\s*'
210210
+ r'"check_versioning"\s*:\s*"(true|false)")?\s*\}\}$',
211+
"SRA-BEDROCK-CHECK-KB-VECTOR-STORE-SECRET": r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*'
212+
+ r'"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*(\{\})\}$',
211213
}
212214

213215
# Instantiate sra class objects

aws_sra_examples/solutions/genai/bedrock_org/lambda/src/sra_config_lambda_iam_permissions.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,5 +181,27 @@
181181
"Resource": "arn:aws:s3:::*"
182182
}
183183
]
184+
},
185+
"sra-bedrock-check-kb-vector-store-secret": {
186+
"Version": "2012-10-17",
187+
"Statement": [
188+
{
189+
"Sid": "AllowKnowledgeBaseAccess",
190+
"Effect": "Allow",
191+
"Action": [
192+
"bedrock:ListKnowledgeBases",
193+
"bedrock:GetKnowledgeBase"
194+
],
195+
"Resource": "*"
196+
},
197+
{
198+
"Sid": "AllowSecretsManagerAccess",
199+
"Effect": "Allow",
200+
"Action": [
201+
"secretsmanager:DescribeSecret"
202+
],
203+
"Resource": "*"
204+
}
205+
]
184206
}
185207
}

aws_sra_examples/solutions/genai/bedrock_org/templates/sra-bedrock-org-main.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,17 @@ Parameters:
317317
Example: {"deploy": "true", "accounts": ["123456789012"], "regions": ["us-east-1"], "input_params": {"check_retention": "true", "check_encryption": "true", "check_access_logging": "true", "check_object_locking": "true", "check_versioning": "true"}} or
318318
{"deploy": "false", "accounts": [], "regions": [], "input_params": {}}
319319
320+
pBedrockKBVectorStoreSecretRuleParams:
321+
Type: String
322+
Default: '{"deploy": "true", "accounts": ["444455556666"], "regions": ["us-west-2"], "input_params": {}}'
323+
Description: Bedrock Knowledge Base Vector Store Secret Config Rule Parameters
324+
AllowedPattern: ^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*(\{\})\}$
325+
ConstraintDescription:
326+
"Must be a valid JSON string containing: 'deploy' (true/false), 'accounts' (array of account numbers),
327+
'regions' (array of region names), and 'input_params' object/dict (input params must be empty). Arrays can be empty.
328+
Example: {\"deploy\": \"true\", \"accounts\": [\"123456789012\"], \"regions\": [\"us-east-1\"], \"input_params\": {}} or
329+
{\"deploy\": \"false\", \"accounts\": [], \"regions\": [], \"input_params\": {}}"
330+
320331
Metadata:
321332
AWS::CloudFormation::Interface:
322333
ParameterGroups:
@@ -360,6 +371,7 @@ Metadata:
360371
- pBedrockKBLoggingRuleParams
361372
- pBedrockKBIngestionEncryptionRuleParams
362373
- pBedrockKBS3BucketRuleParams
374+
- pBedrockKBVectorStoreSecretRuleParams
363375
- Label:
364376
default: Bedrock CloudWatch Metric Filters
365377
Parameters:
@@ -433,6 +445,8 @@ Metadata:
433445
default: Bedrock Knowledge Base Data Ingestion Encryption Config Rule Parameters
434446
pBedrockKBS3BucketRuleParams:
435447
default: Bedrock Knowledge Base S3 Bucket Config Rule Parameters
448+
pBedrockKBVectorStoreSecretRuleParams:
449+
default: Bedrock Knowledge Base Vector Store Secret Config Rule Parameters
436450

437451
Resources:
438452
rBedrockOrgLambdaRole:
@@ -716,6 +730,7 @@ Resources:
716730
SRA-BEDROCK-CHECK-KB-LOGGING: !Ref pBedrockKBLoggingRuleParams
717731
SRA-BEDROCK-CHECK-KB-INGESTION-ENCRYPTION: !Ref pBedrockKBIngestionEncryptionRuleParams
718732
SRA-BEDROCK-CHECK-KB-S3-BUCKET: !Ref pBedrockKBS3BucketRuleParams
733+
SRA-BEDROCK-CHECK-KB-VECTOR-STORE-SECRET: !Ref pBedrockKBVectorStoreSecretRuleParams
719734

720735
rBedrockOrgLambdaInvokePermission:
721736
Type: AWS::Lambda::Permission

0 commit comments

Comments
 (0)