bedrock — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited bedrock (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Amazon Bedrock provides access to foundation models (FMs) from AI companies through a unified API. Build generative AI applications with text generation, embeddings, and image generation capabilities.
Pre-trained models available through Bedrock:
In commercial Regions, access to all serverless models is enabled by default (no console opt-in). In GovCloud (US), models are still enabled manually on the Model access page (third-party models also in the linked commercial account):
aws-marketplace:Subscribe, Unsubscribe, ViewSubscriptionsbedrock-runtime need a one-time use case form per account/org (put-use-case-for-model-access)bedrock:InvokeModel and bedrock:InvokeModelWithResponseStream on it (SCP/IAM); streaming APIs such as ConverseStream use the latter. Denying aws-marketplace:Subscribe alone does not block first use| Endpoint | APIs | Use for |
|---|---|---|
bedrock-runtime.{region}.amazonaws.com (recommended) | InvokeModel, Converse, Anthropic Messages (/anthropic), OpenAI Responses/Chat Completions (/openai/v1) | Guardrails, cross-Region inference, prompt routing, application inference profiles |
bedrock-mantle.{region}.api.aws | OpenAI Responses/Chat Completions (/openai/v1), Anthropic Messages | Server-side tools (Web Search), background=true async, Projects/Workspaces, single-Region access to CRIS-only models |
AWS_BEARER_TOKEN_BEDROCK)bedrock:InvokeModel (runtime) vs bedrock-mantle:CreateInference (mantle)bedrock-runtime is synchronous only and has no server-side toolsbedrock-runtime: use a geo (us., eu., au.) or global. inference profile ID as modelIdActive -> Legacy -> EOL (see modelLifecycle in get-foundation-model). Legacy: no new Provisioned Throughput, fine-tuning, or quota increases; EOL: requests failtype: MANAGED): Bedrock runs storage, indexing, and retrieval. Only type that supports AgenticRetrieveStream (query decomposition, iterative retrieval, optional AgentCore Memory via memoryConfiguration)twelvelabs.marengo-embed-3-0-v1:0); query with text via Retrieve only (no RetrieveAndGenerate)CreateAgent/InvokeInlineAgent return 403 without prior 12-month usage), model catalog frozen. Build new agents on Amazon Bedrock AgentCore| Type | Use Case | Pricing |
|---|---|---|
| On-Demand | Variable workloads | Per token |
| Provisioned Throughput | Consistent high-volume | Hourly commitment |
| Batch Inference | Async large-scale | Discounted per token |
AWS CLI:
# Invoke Claude
aws bedrock-runtime invoke-model \
--model-id us.anthropic.claude-sonnet-5 \
--content-type application/json \
--accept application/json \
--cli-binary-format raw-in-base64-out \
--body '{
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 4096,
"messages": [
{"role": "user", "content": "Explain AWS Lambda in 3 sentences."}
]
}' \
response.json
# Claude Sonnet 5/Opus 5 think by default: content may start with a thinking block
cat response.json | jq -r '.content[] | select(.type=="text") | .text'boto3:
import boto3
import json
bedrock = boto3.client('bedrock-runtime')
def invoke_claude(prompt, max_tokens=4096):
response = bedrock.invoke_model(
modelId='us.anthropic.claude-sonnet-5',
contentType='application/json',
accept='application/json',
body=json.dumps({
'anthropic_version': 'bedrock-2023-05-31',
'max_tokens': max_tokens,
'messages': [
{'role': 'user', 'content': prompt}
]
})
)
result = json.loads(response['body'].read())
# Skip thinking blocks (adaptive thinking is on by default for Sonnet 5).
# max_tokens caps thinking + text, so a truncated response may have no text block.
if result['stop_reason'] == 'max_tokens':
print('Truncated at max_tokens: raise it or lower output_config.effort')
return next((b['text'] for b in result['content'] if b['type'] == 'text'), '')
# Usage
response = invoke_claude('What is Amazon S3?')
print(response)import boto3
import json
bedrock = boto3.client('bedrock-runtime')
def stream_claude(prompt):
response = bedrock.invoke_model_with_response_stream(
modelId='us.anthropic.claude-sonnet-5',
contentType='application/json',
accept='application/json',
body=json.dumps({
'anthropic_version': 'bedrock-2023-05-31',
'max_tokens': 4096,
'messages': [
{'role': 'user', 'content': prompt}
]
})
)
for event in response['body']:
chunk = json.loads(event['chunk']['bytes'])
if chunk['type'] == 'content_block_delta':
yield chunk['delta'].get('text', '')
# Usage
for text in stream_claude('Write a haiku about cloud computing.'):
print(text, end='', flush=True)import boto3
import json
bedrock = boto3.client('bedrock-runtime')
def get_embedding(text):
response = bedrock.invoke_model(
modelId='amazon.titan-embed-text-v2:0',
contentType='application/json',
accept='application/json',
body=json.dumps({
'inputText': text,
'dimensions': 1024,
'normalize': True
})
)
result = json.loads(response['body'].read())
return result['embedding']
# Usage
embedding = get_embedding('AWS Lambda is a serverless compute service.')
print(f'Embedding dimension: {len(embedding)}')import boto3
import json
bedrock = boto3.client('bedrock-runtime')
class Conversation:
def __init__(self, system_prompt=None):
self.messages = []
self.system = system_prompt
def chat(self, user_message):
self.messages.append({
'role': 'user',
'content': user_message
})
body = {
'anthropic_version': 'bedrock-2023-05-31',
'max_tokens': 4096,
'messages': self.messages
}
if self.system:
body['system'] = self.system
response = bedrock.invoke_model(
modelId='us.anthropic.claude-sonnet-5',
contentType='application/json',
accept='application/json',
body=json.dumps(body)
)
result = json.loads(response['body'].read())
if result['stop_reason'] == 'max_tokens':
# max_tokens caps thinking + text; don't store a truncated/empty turn
self.messages.pop()
raise RuntimeError('Truncated at max_tokens: raise it or lower output_config.effort')
assistant_message = next(
(b['text'] for b in result['content'] if b['type'] == 'text'), ''
)
self.messages.append({
'role': 'assistant',
'content': assistant_message
})
return assistant_message
# Usage
conv = Conversation(system_prompt='You are an AWS solutions architect.')
print(conv.chat('What database should I use for a chat application?'))
print(conv.chat('What about for time-series data?'))# List all foundation models
aws bedrock list-foundation-models \
--query 'modelSummaries[*].[modelId,modelName,providerName]' \
--output table
# Filter by provider
aws bedrock list-foundation-models \
--by-provider anthropic \
--query 'modelSummaries[*].modelId'
# Get model details (includes modelLifecycle.status)
aws bedrock get-foundation-model \
--model-identifier anthropic.claude-sonnet-5# agreementAvailability.status AVAILABLE / NOT_AVAILABLE, authorizationStatus
aws bedrock get-foundation-model-availability \
--model-id anthropic.claude-sonnet-5
# Anthropic one-time use case form (base64-encoded JSON:
# companyName, companyWebsite, intendedUsers, industryOption, otherIndustryOption, useCases)
aws bedrock put-use-case-for-model-access --form-data <base64-json>
# Programmatic agreement for third-party models
aws bedrock list-foundation-model-agreement-offers --model-id <model-id>
aws bedrock create-foundation-model-agreement --model-id <model-id> --offer-token <token># Free; returns inputTokens. Not supported for every model (e.g. CRIS-only Claude models)
aws bedrock-runtime count-tokens \
--model-id anthropic.claude-3-5-haiku-20241022-v1:0 \
--input '{"converse": {"messages": [{"role": "user", "content": [{"text": "Hello"}]}]}}'| Command | Description | |
|---|---|---|
aws bedrock list-foundation-models | List available models | |
aws bedrock get-foundation-model | Get model details | |
aws bedrock list-custom-models | List fine-tuned models | |
aws bedrock create-model-customization-job | Start fine-tuning | |
aws bedrock list-provisioned-model-throughputs | List provisioned capacity | |
aws bedrock get-foundation-model-availability | Check access/agreement status for a model | |
aws bedrock put-use-case-for-model-access | Submit Anthropic first-time use case form | |
aws bedrock list-inference-profiles | List system/application inference profiles | |
aws bedrock create-model-invocation-job | Start batch job (`--model-invocation-type InvokeModel\ | Converse`) |
| Command | Description |
|---|---|
aws bedrock-runtime invoke-model | Invoke model synchronously |
aws bedrock-runtime converse | Multi-turn conversation API |
aws bedrock-runtime count-tokens | Count input tokens (--input with invokeModel or converse) |
aws bedrock-runtime apply-guardrail | Evaluate content against a guardrail |
InvokeModelWithResponseStream and ConverseStream are SDK-only (not in AWS CLI v2).
| Command | Description |
|---|---|
aws bedrock-agent-runtime retrieve | Query knowledge base |
aws bedrock-agent-runtime retrieve-and-generate | RAG query |
InvokeAgent, RetrieveAndGenerateStream, and AgenticRetrieveStream are SDK-only (event streams).
"thinking": {"type": "disabled"} or lower output_config.effort if not needed, and revisit max_tokens (it caps thinking + text)--model-invocation-type Converse keeps one request shape across modelsbedrock-runtime; use bedrock-mantle only for mantle-only featuresexternal_web_access: false to keep Fetch inside the AWS boundary; AmazonBedrockFullAccess lacks bedrock-websearch:ExternalWebAccess, so the default true silently fails FetchmodelLifecycle and migrate off Legacy models before EOL{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": [
"arn:aws:bedrock:us-east-1:123456789012:inference-profile/us.anthropic.claude-sonnet-5",
"arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v2:0"
]
},
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "arn:aws:bedrock:*::foundation-model/anthropic.claude-sonnet-5",
"Condition": {
"StringEquals": {
"bedrock:InferenceProfileArn": "arn:aws:bedrock:us-east-1:123456789012:inference-profile/us.anthropic.claude-sonnet-5"
}
}
}
]
}Inference profiles need access to the profile ARN plus the foundation model in every destination Region (list them with aws bedrock get-inference-profile --inference-profile-identifier <id>, models field). SCPs that deny Regions must allow those destinations (or exempt via bedrock:InferenceProfileArn).
Causes:
aws-marketplace:Subscribe on first use of a third-party model (auto-subscription fails; may take ~2 min after fixing)bedrock:InvokeModel, or missing destination-Region foundation-model ARNs for an inference profileCreateAgent/InvokeInlineAgent in accounts without prior usage (use AgentCore)Debug:
# Check model access status
aws bedrock get-foundation-model-availability \
--model-id anthropic.claude-sonnet-5
# Test IAM permissions
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:role/my-role \
--action-names bedrock:InvokeModel \
--resource-arns "arn:aws:bedrock:us-east-1:123456789012:inference-profile/us.anthropic.claude-sonnet-5"
# The profile ARN can pass while cross-Region routing is still denied: also simulate each
# destination-Region model ARN (models field of get-inference-profile) with the profile context
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:role/my-role \
--action-names bedrock:InvokeModel \
--resource-arns "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-sonnet-5" \
"arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-sonnet-5" \
--context-entries '[{"ContextKeyName":"bedrock:InferenceProfileArn","ContextKeyType":"string","ContextKeyValues":["arn:aws:bedrock:us-east-1:123456789012:inference-profile/us.anthropic.claude-sonnet-5"]}]'Cause: Model is still being provisioned or temporarily unavailable.
Solution: Implement retry with exponential backoff:
import time
from botocore.exceptions import ClientError
def invoke_with_retry(bedrock, body, max_retries=3):
for attempt in range(max_retries):
try:
return bedrock.invoke_model(
modelId='us.anthropic.claude-sonnet-5',
body=json.dumps(body)
)
except ClientError as e:
if e.response['Error']['Code'] == 'ModelNotReadyException':
time.sleep(2 ** attempt)
else:
raise
raise Exception('Max retries exceeded')Causes:
bedrock-runtime) or tokens-per-day quotaSolutions:
max_tokens: it affects quota deductionCommon issues:
us./global. prefix)thinking.type: "enabled" with budget_tokens on models that only accept adaptive/disabled (e.g. Claude Sonnet 5)output_config.format (structured outputs) sent to bedrock-mantle (use Converse/InvokeModel on bedrock-runtime)Debug:
# Check model-specific requirements
aws bedrock get-foundation-model \
--model-identifier anthropic.claude-sonnet-5 \
--query 'modelDetails.[inferenceTypesSupported,modelLifecycle.status]'~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.