AWS Bedrock Knowledge Base - błąd Access Denied przy synchronizacji z S3
Naprawa błędu Access Denied w Bedrock Knowledge Base sync: weryfikacja IAM role trust, KMS key policy, S3 bucket policy i VPC endpoint policy.
Ten runbook opisuje rozwiązywanie błędu Access Denied podczas synchronizacji Bedrock Knowledge Base z S3. Pełny przewodnik po architekturze RAG na AWS znajdziesz w artykule Architektura RAG na AWS - S3, OpenSearch, Bedrock: wzorce infrastruktury i koszty. W kwestii projektowania pipeline’ów RAG i konfiguracji Knowledge Base umów konsultacje.
Objaw
Bedrock console pokazuje status synchronizacji jako „Failed”. Ingestion job kończy się z błędem Access Denied bez przetworzenia jakichkolwiek dokumentów:
# Typowe komunikaty błędów:
# "The knowledge base storage configuration is invalid... Access Denied"
# "Failed to access S3 bucket: Access Denied (Service: Amazon S3; Status Code: 403)"
# "The data source sync failed because Bedrock could not access objects in the S3 bucket"
# Sprawdź status ostatniego ingestion job
aws bedrock-agent get-ingestion-job \
--knowledge-base-id KBXXXXXXXX \
--data-source-id DSXXXXXXXX \
--ingestion-job-id IJXXXXXXXX \
--query '{status:ingestionJob.status, failureReasons:ingestionJob.failureReasons, statistics:ingestionJob.statistics}'
# Lista ostatnich ingestion jobs dla data source
aws bedrock-agent list-ingestion-jobs \
--knowledge-base-id KBXXXXXXXX \
--data-source-id DSXXXXXXXX \
--sort-by attribute=STARTED_AT,order=DESCENDING \
--max-results 5 \
--query 'ingestionJobSummaries[].{id:ingestionJobId, status:status, started:startedAt, docs:statistics.numberOfDocumentsScanned}'
# Sprawdź CloudTrail pod kątem błędów Access Denied z Bedrock
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventSource,AttributeValue=s3.amazonaws.com \
--start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
--query 'Events[?contains(CloudTrailEvent, `AccessDenied`) && contains(CloudTrailEvent, `bedrock`)].{time:EventTime, event:EventName, user:Username}' \
-o table
# Szczegółowy event z CloudTrail (znajdź konkretny errorCode)
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventSource,AttributeValue=s3.amazonaws.com \
--start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
--max-results 10 \
--query 'Events[?contains(CloudTrailEvent, `AccessDenied`)].[CloudTrailEvent]' \
--output text | jq -r '. | select(.errorCode == "AccessDenied") | {eventTime, eventName, errorCode, errorMessage, requestParameters, userIdentity}'
Status ingestion job to „FAILED” z failureReasons wskazującym na Access Denied. Statystyki pokazują 0 przetworzonych dokumentów.
Przyczyna
Bedrock Knowledge Base używa IAM role do dostępu do S3 bucket z danymi źródłowymi. Access Denied pojawia się, gdy jakakolwiek warstwa autoryzacji blokuje dostęp:
-
Brak trust policy dla bedrock.amazonaws.com: IAM role przypisana do Knowledge Base nie ma w trust policy wpisu zezwalającego serwisowi
bedrock.amazonaws.comnasts:AssumeRole. Bedrock nie może przyjąć roli i każda operacja S3 kończy się odmową dostępu. -
KMS key policy nie uwzględnia roli Bedrock: Obiekty w S3 są zaszyfrowane kluczem KMS (customer-managed CMK), ale key policy nie zawiera grantu na
kms:Decryptikms:GenerateDataKeydla roli Bedrock. Nawet jeśli IAM policy roli zezwala na S3 GetObject, brak uprawnień KMS skutkuje Access Denied. -
S3 bucket policy z explicit deny: Bucket policy zawiera statement z
"Effect": "Deny"który pasuje do żądań z roli Bedrock - np. deny all except specific VPC endpoint, deny all except specific source IP, lub deny bez konkretnego warunku. Explicit deny w bucket policy nadpisuje wszystkie Allow w IAM policy. -
VPC endpoint policy ogranicza dostęp: Jeśli Bedrock operuje w VPC z S3 Gateway lub Interface endpoint, policy na endpoincie może ograniczać dostęp tylko do określonych bucketów lub principals. Żądania do bucketów spoza listy są blokowane na poziomie endpointu.
-
Obiekty zaszyfrowane customer-managed KMS bez odpowiednich grantów: Nawet jeśli bucket default encryption jest poprawnie skonfigurowany, poszczególne obiekty mogą być zaszyfrowane innym kluczem KMS (np. przesłane przez inny proces z własnym kluczem). Rola Bedrock nie ma uprawnień do tego konkretnego klucza.
Rozwiązanie
A) Naprawa IAM role trust policy:
# Sprawdź aktualną trust policy roli Bedrock Knowledge Base
aws iam get-role \
--role-name AmazonBedrockExecutionRoleForKnowledgeBase_kb123 \
--query 'Role.AssumeRolePolicyDocument' | jq .
# Trust policy MUSI zawierać bedrock.amazonaws.com jako trusted principal
# Jeśli brakuje - zaktualizuj trust policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "bedrock.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "123456789012"
},
"ArnLike": {
"aws:SourceArn": "arn:aws:bedrock:eu-west-1:123456789012:knowledge-base/KBXXXXXXXX"
}
}
}
]
}
# Zapisz powyższy JSON do pliku i zaktualizuj trust policy
aws iam update-assume-role-policy \
--role-name AmazonBedrockExecutionRoleForKnowledgeBase_kb123 \
--policy-document file://trust-policy.json
# Sprawdź też permissions policy roli - musi zawierać s3:GetObject i s3:ListBucket
aws iam list-attached-role-policies \
--role-name AmazonBedrockExecutionRoleForKnowledgeBase_kb123
aws iam get-role-policy \
--role-name AmazonBedrockExecutionRoleForKnowledgeBase_kb123 \
--policy-name BedrockS3Access \
--query 'PolicyDocument' | jq .
B) Aktualizacja KMS key policy:
# Znajdź jaki klucz KMS jest używany do szyfrowania bucket
aws s3api get-bucket-encryption \
--bucket my-kb-documents \
--query 'ServerSideEncryptionConfiguration.Rules[0].ApplyServerSideEncryptionByDefault.KMSMasterKeyID'
# Sprawdź aktualną key policy
aws kms get-key-policy \
--key-id arn:aws:kms:eu-west-1:123456789012:key/mrk-1234abcd \
--policy-name default \
--query 'Policy' --output text | jq .
Dodaj statement do key policy zezwalający roli Bedrock na decrypt:
{
"Sid": "AllowBedrockKnowledgeBaseDecrypt",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/AmazonBedrockExecutionRoleForKnowledgeBase_kb123"
},
"Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:GenerateDataKey"
],
"Resource": "*"
}
# Zaktualizuj key policy (pobierz aktualną, dodaj statement, zapisz)
aws kms get-key-policy \
--key-id mrk-1234abcd \
--policy-name default \
--query 'Policy' --output text > kms-policy.json
# Edytuj kms-policy.json - dodaj powyższy statement do tablicy Statement
aws kms put-key-policy \
--key-id mrk-1234abcd \
--policy-name default \
--policy file://kms-policy.json
C) Naprawa S3 bucket policy:
# Sprawdź bucket policy
aws s3api get-bucket-policy \
--bucket my-kb-documents \
--query 'Policy' --output text | jq .
Jeśli bucket policy zawiera explicit deny - dodaj warunek wyłączający rolę Bedrock z deny:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowBedrockKnowledgeBase",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/AmazonBedrockExecutionRoleForKnowledgeBase_kb123"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-kb-documents",
"arn:aws:s3:::my-kb-documents/*"
]
},
{
"Sid": "DenyNonVpcAccess",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-kb-documents",
"arn:aws:s3:::my-kb-documents/*"
],
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": "vpce-0abc1234def56789"
},
"ArnNotLike": {
"aws:PrincipalArn": "arn:aws:iam::123456789012:role/AmazonBedrockExecutionRoleForKnowledgeBase_kb123"
}
}
}
]
}
# Zastosuj poprawioną bucket policy
aws s3api put-bucket-policy \
--bucket my-kb-documents \
--policy file://bucket-policy.json
D) Aktualizacja VPC endpoint policy:
# Znajdź S3 VPC endpoint
aws ec2 describe-vpc-endpoints \
--filters "Name=service-name,Values=com.amazonaws.eu-west-1.s3" \
--query 'VpcEndpoints[].{id:VpcEndpointId, policy:PolicyDocument, vpcId:VpcId}' | jq .
Dodaj bucket i rolę Bedrock do endpoint policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowBedrockS3Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/AmazonBedrockExecutionRoleForKnowledgeBase_kb123"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-kb-documents",
"arn:aws:s3:::my-kb-documents/*"
]
}
]
}
# Zaktualizuj VPC endpoint policy
aws ec2 modify-vpc-endpoint \
--vpc-endpoint-id vpce-0abc1234def56789 \
--policy-document file://vpce-policy.json
E) Weryfikacja szyfrowania na poziomie obiektów:
# Sprawdź szyfrowanie poszczególnych obiektów w bucket
aws s3api head-object \
--bucket my-kb-documents \
--key documents/handbook.pdf \
--query '{encryption:ServerSideEncryption, kmsKeyId:SSEKMSKeyId}'
# Lista obiektów z różnym szyfrowaniem niż bucket default
aws s3api list-objects-v2 \
--bucket my-kb-documents \
--prefix documents/ \
--max-items 20 \
--query 'Contents[].Key' --output text | \
xargs -I {} aws s3api head-object \
--bucket my-kb-documents \
--key {} \
--query '{key: "{}", kmsKey:SSEKMSKeyId}' 2>/dev/null
# Jeśli obiekty używają innego klucza KMS - dodaj grant dla roli Bedrock
aws kms create-grant \
--key-id arn:aws:kms:eu-west-1:123456789012:key/other-key-5678efgh \
--grantee-principal arn:aws:iam::123456789012:role/AmazonBedrockExecutionRoleForKnowledgeBase_kb123 \
--operations Decrypt DescribeKey \
--name "BedrockKBAccessGrant"
# Alternatywnie - re-encrypt obiekty kluczem bucket default
aws s3 cp \
s3://my-kb-documents/documents/handbook.pdf \
s3://my-kb-documents/documents/handbook.pdf \
--sse aws:kms \
--sse-kms-key-id arn:aws:kms:eu-west-1:123456789012:key/mrk-1234abcd
Walidacja
# 1. Uruchom nowy sync (ingestion job)
aws bedrock-agent start-ingestion-job \
--knowledge-base-id KBXXXXXXXX \
--data-source-id DSXXXXXXXX
# 2. Poczekaj 1-2 minuty i sprawdź status
aws bedrock-agent get-ingestion-job \
--knowledge-base-id KBXXXXXXXX \
--data-source-id DSXXXXXXXX \
--ingestion-job-id $(aws bedrock-agent list-ingestion-jobs \
--knowledge-base-id KBXXXXXXXX \
--data-source-id DSXXXXXXXX \
--sort-by attribute=STARTED_AT,order=DESCENDING \
--max-results 1 \
--query 'ingestionJobSummaries[0].ingestionJobId' --output text) \
--query '{status:ingestionJob.status, stats:ingestionJob.statistics}'
# Expected: status = "COMPLETE", numberOfDocumentsScanned > 0
# 3. Zweryfikuj że dokumenty są zaindeksowane w vector store
aws bedrock-agent-runtime retrieve \
--knowledge-base-id KBXXXXXXXX \
--retrieval-query '{"text": "test query relevant to your documents"}' \
--retrieval-configuration '{"vectorSearchConfiguration": {"numberOfResults": 3}}' \
--query 'retrievalResults[].{score:score, uri:location.s3Location.uri}'
# Expected: wyniki z dokumentów S3, score > 0
# 4. Sprawdź CloudTrail - brak nowych Access Denied
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventSource,AttributeValue=s3.amazonaws.com \
--start-time $(date -u -d '10 minutes ago' +%Y-%m-%dT%H:%M:%S) \
--query 'Events[?contains(CloudTrailEvent, `AccessDenied`) && contains(CloudTrailEvent, `bedrock`)]' \
--output text
# Expected: brak wyników (pusty output)
Jeśli ingestion job zakończył się statusem „COMPLETE”, dokumenty są dostępne w retrieve i brak nowych błędów Access Denied w CloudTrail - problem jest rozwiązany. Uruchom pełny sync jeśli poprzednie częściowe próby mogły pominąć dokumenty.
Bedrock Knowledge Base nie synchronizuje się z S3?
Umów bezpłatną 30-minutową rozmowę. Przejrzymy konfigurację IAM, KMS i bucket policy, aby odblokować sync i przywrócić aktualne odpowiedzi RAG.