Amazon Bedrock Projects, announced in general availability on February 26, 2026, is the workload-isolation and cost-attribution mechanism for Bedrock’s newer bedrock-mantle inference engine. A Project is a logical boundary — analogous to an OpenAI Organization project — scoped to a set of inference requests, not to a specific model. It provides three capabilities bundled together: IAM-based access isolation, cost allocation tags that flow into CUR and Cost Explorer, and a distinct ARN you can reference in SCP and permission boundaries.
Every AWS account gets a default project automatically. All bedrock-mantle inference requests that do not specify a project ID land in default, making attribution invisible unless you create named projects.
Key distinguishing properties:
- Belongs to the
bedrock-mantleservice namespace, notbedrockorbedrock-runtime - Not tied to a model; one project can span dozens of models per request
- Project ID is passed at the SDK client level (not per-call), so all calls from that client inherit project context
- Up to 1,000 projects per AWS account
- No additional charge — you pay only the underlying per-token model pricing
- Projects can be archived but not deleted; archived projects reject new inference but retain 30 days of historical metrics
Launch timeline:
- 2026-02-26: Bedrock Projects API GA (bedrock-mantle endpoint, Responses API + Chat Completions)
- 2026-03-xx: Projects ARN appears in IAM condition keys;
bedrock-mantle:CreateProjectaction documented - 2026-05-xx: Request-level usage attribution expanded to InvokeModel/InvokeModelWithResponseStream (bedrock-runtime only; does not affect Projects)
- 2026-06-01: OpenAI frontier models (gpt-5.5, gpt-5.4) added to bedrock-mantle via
/openai/v1/responsespath; Projects attribution applies to these too
2. Projects vs. Application Inference Profiles — The Endpoint Fork
The single most important architectural decision is which endpoint your workload targets. Projects and AIPs are not interchangeable — they are endpoint-specific.
Endpoint comparison
| Dimension | bedrock-mantle | bedrock-runtime |
|---|---|---|
| URL pattern | bedrock-mantle.{region}.api.aws |
bedrock-runtime.{region}.amazonaws.com |
| Workload isolation mechanism | Projects | Application Inference Profiles (AIPs) |
| APIs supported | Responses API, Chat Completions, Anthropic Messages API | InvokeModel, Converse, Chat Completions, Messages API |
| Cross-region inference | Not available | Available (geographic + global profiles) |
| Stateful conversation management | Yes (server-side) | No |
| Async / long-running inference | Yes | No |
| Server-side tool use | Yes | No |
| Per-request metadata tagging | Not currently available | Available (Converse, InvokeModel, ConverseStream, InvokeModelWithResponseStream) |
| Attribution granularity in CUR | Per usage-type per day | Per usage-type per day |
| Throughput model | Work-queue with fair-share scheduling | Fixed per-account RPM/TPM quotas |
| IAM service prefix | bedrock-mantle: |
bedrock: |
Use-case decision matrix
| Scenario | Use |
|---|---|
| Migrating existing OpenAI SDK codebase to Bedrock | Projects + bedrock-mantle (change base URL + API key only) |
| New agentic workflow with tool use, stateful sessions | Projects + bedrock-mantle |
Running Responses API (OpenAI responses.create) |
Projects + bedrock-mantle (Responses API is mantle-only) |
| Existing Converse or InvokeModel workload | AIPs + bedrock-runtime |
| Cross-region failover / geographic load balancing | AIPs + bedrock-runtime (cross-region inference profiles) |
| Per-prompt cost attribution (finest grain) | bedrock-runtime + per-request metadata tagging (neither Projects nor AIPs produce per-request CUR rows) |
| Model not yet available on mantle | AIPs + bedrock-runtime (check endpoint availability table) |
| Chat Completions with OpenAI SDK | Projects + bedrock-mantle (recommended; Chat Completions also works on runtime but mantle is preferred) |
| Mixed workload: some native Bedrock, some OpenAI-compat | Both in parallel — Projects on mantle clients, AIPs on runtime clients |
Why model-scoped AIPs don’t scale
Each AIP is bound to a single model. An organization with 10 teams × 8 models × 3 environments (prod/staging/dev) = 240 AIPs before adding new model versions. Projects collapse this: one project per application or team regardless of how many models it uses. When a new model ships, no new resource is required.
3. How Bedrock Projects Appear in CUR
CUR usage type strings follow a distinct pattern for bedrock-mantle traffic. The -mantle- infix is the signal that a line item originated from a Projects-attributed workload.
Usage type format
{region}-{model}-mantle-{token-type}-{tier}
Examples:
| Usage type | Model | Token type | Tier |
|---|---|---|---|
USE1-openai.gpt-oss-120b-mantle-input-tokens-standard |
OpenAI gpt-oss-120b | Input | Standard |
USE1-openai.gpt-oss-120b-mantle-output-tokens-standard |
OpenAI gpt-oss-120b | Output | Standard |
USE1-Claude4.6Sonnet-mantle-input-tokens-standard |
Claude Sonnet 4.6 | Input | Standard |
USE1-Claude4.6Sonnet-mantle-output-tokens-standard |
Claude Sonnet 4.6 | Output | Standard |
Compare to bedrock-runtime patterns (no -mantle- infix):
USE1-Claude4.6Sonnet-input-tokens # runtime, standard
USE1-Claude4.6Sonnet-output-tokens-priority # runtime, priority tier
USE1-Nova2.0Lite-input-tokens-flex # runtime, flex tier
Four token types to track
CUR generates a separate line item per token type per usage-type-per-day aggregation. Summing only input + output will undercount — especially for Responses API workloads that use the built-in conversation state (which may involve cache reads/writes):
| Token type | CUR pattern suffix |
|---|---|
| Input tokens | -mantle-input-tokens-* |
| Output tokens | -mantle-output-tokens-* |
| Cache read tokens | -cache-read-input-token-count |
| Cache write tokens | -cache-write-input-token-count |
Project tags in CUR columns
Project tags appear in CUR 2.0 with the resourceTags/ prefix. If you tag a project with CostCenter=CC-1001 and Team=PlatformEngineering, CUR 2.0 will expose:
resourceTags/CostCenter → "CC-1001"
resourceTags/Team → "PlatformEngineering"
These columns are empty for any request routed to the default project (no tags). Tags must be activated as cost allocation tags in the AWS Billing and Cost Management console before they appear in CUR or Cost Explorer. Activation has a 24-hour propagation delay and is not retroactive — only costs after activation carry tags.
CUR 2.0 vs. classic CUR
IAM principal attribution (the line_item_iam_principal column) requires CUR 2.0 (AWS Data Exports). Project tag columns are available in both CUR formats, but CUR 2.0 is the recommended format for any new FinOps pipeline as of 2026. Classic CUR lacks the IAM principal fields needed to correlate user identity with project spend.
Grain limitation
CUR aggregates to usage-type per day — there is no per-request row with a requestId. To attribute cost to an individual prompt, join model invocation logs (CloudWatch Logs or S3) to CUR at the model + usage-type grain. Per-request metadata tagging (available on bedrock-runtime) is not currently available on bedrock-mantle, so per-prompt dollar precision requires log-based reconciliation rather than CUR.
4. Project-Level Cost Attribution — Tags, Activation, and Mechanics
Tag assignment at project creation
Tags are set on the project resource, not on individual requests. All requests routed to that project inherit its tags in the billing record.
# Create project with cost allocation tags
curl -X POST "https://bedrock-mantle.us-east-1.api.aws/v1/organization/projects" \
-H "Authorization: Bearer $BEDROCK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "CustomerChatbot-Production",
"tags": {
"Application": "CustomerChatbot",
"Environment": "Production",
"Team": "CustomerExperience",
"CostCenter": "CC-1001",
"BusinessUnit": "RetailDivision"
}
}'
Response includes the project ARN for IAM policy attachment:
{
"arn": "arn:aws:bedrock-mantle:us-east-1:123456789012:project/proj_abc123",
"id": "proj_abc123",
"name": "CustomerChatbot-Production",
"object": "organization.project",
"status": "active",
"tags": { ... }
}
Tag update patterns
There is no full tag-replacement operation. Mutations require explicit add/remove:
# Add tags
curl -X POST ".../organization/projects/proj_abc123" \
-H "Authorization: Bearer $BEDROCK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"add_tags": {"Version": "2.0", "Sprint": "2026-Q2"}}'
# Remove tags
curl -X POST ".../organization/projects/proj_abc123" \
-H "Authorization: Bearer $BEDROCK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"remove_tag_keys": ["Sprint"]}'
Recommended tag taxonomy
| Tag key | Purpose | Example |
|---|---|---|
Application |
Workload identity | CustomerChatbot, InternalSearch |
Environment |
Lifecycle stage | Production, Staging, Development |
Team |
Ownership for chargeback | CustomerExperience, DataScience |
CostCenter |
Finance mapping | CC-1001, CC-2002 |
BusinessUnit |
BU-level rollup | RetailDivision, FinanceOps |
PillarOwner |
Engineering DRI | alice@company.com |
Maximum tag keys per project: follows the standard AWS resource tagging limit (50 user-defined tags).
5. Project Resource Isolation — IAM, Model Access, and Data Boundaries
IAM service namespace
All Projects-related actions use the bedrock-mantle: service prefix, distinct from bedrock: used by runtime. This means Projects permissions require explicit policies in bedrock-mantle — existing Bedrock IAM policies do not automatically extend.
Key IAM actions
bedrock-mantle:CreateProject
bedrock-mantle:GetProject
bedrock-mantle:ListProjects
bedrock-mantle:UpdateProject
bedrock-mantle:ArchiveProject
bedrock-mantle:ListTagsForResources
bedrock-mantle:CreateInference # the inference action scoped to a project
Policy patterns
Read-only access to a specific project (developer can invoke inference but not create/modify projects):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadOnlyProjectAccess",
"Effect": "Allow",
"Action": [
"bedrock-mantle:GetProject",
"bedrock-mantle:ListProjects",
"bedrock-mantle:ListTagsForResources",
"bedrock-mantle:CreateInference"
],
"Resource": "arn:aws:bedrock-mantle:us-east-1:123456789012:project/proj_abc123"
}
]
}
Deny project creation (enforce that only platform team creates projects):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyProjectCreation",
"Effect": "Deny",
"Action": "bedrock-mantle:CreateProject",
"Resource": "*"
}
]
}
Full project admin (platform engineering role):
{
"Sid": "FullProjectAccess",
"Effect": "Allow",
"Action": "bedrock-mantle:*",
"Resource": "arn:aws:bedrock-mantle:us-east-1:123456789012:project/proj_abc123"
}
Model access control
Projects do not themselves restrict which models a request can use — model access is governed by Bedrock model access policies at the account level (same as bedrock-runtime). A project scopes the billing attribution and IAM boundary, but a user with bedrock-mantle:CreateInference on a project can still invoke any model they have account-level access to. To restrict model access per project, combine project-scoped IAM with model-level resource policies or SCP conditions.
Data isolation boundaries
Projects are a single-account construct — they do not span AWS accounts. Cross-account isolation requires separate AWS accounts or AWS Organizations. Projects reduce the need for account sprawl within a single account but are not a substitute for hard multi-tenant account boundaries.
Projects do not provide data residency guarantees beyond what bedrock-mantle already enforces (in-region routing by endpoint region). Cross-region inference is not available on bedrock-mantle, so the region of the endpoint URL is the region where inference executes.
Long-term API keys and Projects
Bedrock API keys (long-term) have a default policy that allows only GetProject and ListProjects. To use long-term keys for project management (create, update, archive), you must attach an additional IAM policy to the key. For production workloads, AWS recommends short-term keys (SigV4 with assumed role) rather than long-term API keys.
6. Projects + AgentCore Integration
AgentCore has a distinct billing surface from Projects. The two intersect at inference attribution but have separate metering.
AgentCore billing model
AgentCore charges across 12 independently billable components grouped into five patterns:
- Per-session active consumption: Runtime (compute while session active), Memory, Code Interpreter
- Per-request: Identity/token management, Gateway API calls
- Per-record: Memory storage reads/writes
- Pass-through: Model inference tokens (billed as standard Bedrock tokens)
- Free/preview: Some components (e.g., Payments preview)
The model inference tokens in AgentCore are pass-through — they appear in CUR as standard bedrock-mantle or bedrock-runtime line items. Whether those line items carry project attribution depends on how AgentCore is configured.
Routing AgentCore inference through a Project
When an AgentCore agent invokes a model via the bedrock-mantle endpoint (Responses API or Chat Completions), setting the project ID on the underlying OpenAI client will attribute those tokens to the project:
from openai import OpenAI
import boto3
# Obtain short-term API key via STS
# (or use long-term key for dev)
client = OpenAI(
api_key=bedrock_api_key,
base_url="https://bedrock-mantle.us-east-1.api.aws/v1",
project="proj_abc123" # Project attribution for all inference from this agent
)
AgentCore-specific components (Memory, Runtime, Code Interpreter) are billed under the bedrock-agentcore service line in CUR, not under bedrock-mantle. Project tags do not flow to these AgentCore-specific line items — only to the inference tokens. To attribute AgentCore infrastructure costs, tag the AgentCore resources (Agent, Memory store, Gateway) directly using standard AWS resource tagging; those tags flow under bedrock-agentcore in CUR using resourceTags/ columns.
Tagging AgentCore resources for per-agent attribution
import boto3
control = boto3.client("bedrock-agentcore-control")
# Tag the agent resource for BU-level attribution
control.tag_resource(
resourceArn="arn:aws:bedrock-agentcore:us-east-1:123456789012:agent/agent-xyz",
tags={
"Team": "CustomerExperience",
"CostCenter": "CC-1001",
"Project": "CustomerChatbot-Production"
}
)
Attribution join strategy
A complete per-agent cost picture requires joining three CUR streams:
bedrock-mantleline items withresourceTags/Team(inference tokens attributed via Projects)bedrock-agentcoreline items withresourceTags/Team(runtime, memory, gateway)- Model invocation logs from CloudWatch for per-prompt-level inference attribution
The join key is the tag dimension (e.g., Team=CustomerExperience) rather than a structural parent-child resource relationship.
7. Multi-Project Organization Design
Granularity options
Three design patterns are in common use. Each trades off management overhead against attribution fidelity.
Pattern A — BU-level projects (coarse)
One project per business unit. Simple tag taxonomy, low project count. Loses application-level attribution within a BU.
RetailDivision-Production (all retail BU prod workloads)
RetailDivision-Development
FinanceOps-Production
FinanceOps-Development
4 projects for 2 BUs × 2 environments. CostCenter tag on the project is sufficient for chargeback.
Pattern B — Application-level projects (recommended for most orgs)
One project per application per environment. Enables per-application chargeback and anomaly scoping. Project count scales with app portfolio.
CustomerChatbot-Production
CustomerChatbot-Staging
CustomerChatbot-Development
InternalSearch-Production
InternalSearch-Development
DataAnalytics-Production
Tags: Application, Environment, Team, CostCenter. Team-level rollup comes from Team tag aggregation in Cost Explorer, not from project naming.
Pattern C — Team-level projects (fine-grained)
One project per team per environment. Enables team-level spend dashboards without relying on tag aggregation. Increases project count.
TeamAlpha-CustomerChatbot-Production
TeamAlpha-CustomerChatbot-Development
TeamBeta-InternalSearch-Production
Tags: Team, Application, Environment, CostCenter. Useful when teams own multiple applications and need a single rollup.
Naming conventions
AWS recommends prefixing by the primary dimension you query on. For FinOps-first orgs, that is usually CostCenter or BusinessUnit. For platform engineering, it is usually Application-Environment.
Limits
- 1,000 projects per AWS account (hard limit as of 2026)
- Projects do not span accounts; for multi-account orgs, create projects per account and rely on AWS Organizations tag policies to enforce consistent tag keys across accounts
- No project hierarchy (no parent/child projects); rollups are purely tag-based in Cost Explorer
Cost Explorer query pattern
After activating cost allocation tags, group by resourceTags/CostCenter and filter service = Amazon Bedrock with line_item_usage_type containing mantle to isolate Project-attributed bedrock-mantle spend:
-- Athena query on CUR 2.0 S3 export
SELECT
resource_tags_user_costcenter AS cost_center,
resource_tags_user_team AS team,
resource_tags_user_application AS application,
line_item_usage_type,
SUM(line_item_unblended_cost) AS total_cost,
SUM(line_item_usage_amount) AS total_tokens
FROM cur_db.cur_table
WHERE product_product_name = 'Amazon Bedrock'
AND line_item_usage_type LIKE '%-mantle-%'
AND line_item_usage_start_date >= '2026-06-01'
GROUP BY 1, 2, 3, 4
ORDER BY total_cost DESC;
8. Projects API — Creating and Managing Projects Programmatically
Projects are managed via the OpenAI-compatible REST API on the bedrock-mantle endpoint. As of mid-2026, the Projects API is cURL/HTTP-native; there is no dedicated boto3 service client for Projects management (boto3 targets bedrock-runtime and bedrock-agentcore-control service clients). For infrastructure-as-code workflows, use the REST API directly or the AWS CLI with --endpoint-url.
Environment setup
export BEDROCK_API_KEY="<your-bedrock-api-key>"
export BEDROCK_BASE_URL="https://bedrock-mantle.us-east-1.api.aws/v1"
Create a project
curl -X POST "$BEDROCK_BASE_URL/organization/projects" \
-H "Authorization: Bearer $BEDROCK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "CustomerChatbot-Production",
"tags": {
"Application": "CustomerChatbot",
"Environment": "Production",
"Team": "CustomerExperience",
"CostCenter": "CC-1001"
}
}'
List all projects (pagination supported)
curl -X GET "$BEDROCK_BASE_URL/organization/projects" \
-H "Authorization: Bearer $BEDROCK_API_KEY"
Get a specific project
curl -X GET "$BEDROCK_BASE_URL/organization/projects/proj_abc123" \
-H "Authorization: Bearer $BEDROCK_API_KEY"
Update project name
curl -X POST "$BEDROCK_BASE_URL/organization/projects/proj_abc123" \
-H "Authorization: Bearer $BEDROCK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "CustomerChatbot-Production-v2"}'
Archive a project
curl -X POST "$BEDROCK_BASE_URL/organization/projects/proj_abc123/archive" \
-H "Authorization: Bearer $BEDROCK_API_KEY"
Python helper using requests (infrastructure provisioning)
import requests
import os
BASE_URL = os.environ["BEDROCK_BASE_URL"]
API_KEY = os.environ["BEDROCK_API_KEY"]
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
def create_project(name: str, tags: dict) -> dict:
resp = requests.post(
f"{BASE_URL}/organization/projects",
headers=HEADERS,
json={"name": name, "tags": tags}
)
resp.raise_for_status()
return resp.json()
def list_projects() -> list[dict]:
resp = requests.get(
f"{BASE_URL}/organization/projects",
headers=HEADERS
)
resp.raise_for_status()
return resp.json()["data"]
def ensure_project(name: str, tags: dict) -> str:
"""Idempotent: returns existing project ID or creates new."""
for p in list_projects():
if p["name"] == name:
return p["id"]
return create_project(name, tags)["id"]
# Usage
proj_id = ensure_project(
name="DataScience-Experiments",
tags={
"Team": "DataScience",
"Environment": "Development",
"CostCenter": "CC-2002"
}
)
print(f"Project ID: {proj_id}")
Using the project for inference (OpenAI SDK)
from openai import OpenAI
client = OpenAI(
api_key=os.environ["BEDROCK_API_KEY"],
base_url="https://bedrock-mantle.us-east-1.api.aws/v1",
project=proj_id # All calls from this client go to this project
)
response = client.chat.completions.create(
model="anthropic.claude-sonnet-4-6",
messages=[{"role": "user", "content": "Summarize this quarter's churn analysis."}]
)
9. LiteLLM Projects Integration
LiteLLM supports Bedrock Mantle via the bedrock_mantle/ model prefix. Project ID assignment routes through the aws_bedrock_project_id parameter in litellm.yaml or as an extra parameter at call time.
litellm.yaml configuration
model_list:
- model_name: claude-sonnet-chatbot-prod
litellm_params:
model: bedrock_mantle/anthropic.claude-sonnet-4-6
api_key: os.environ/BEDROCK_MANTLE_API_KEY
api_base: "https://bedrock-mantle.us-east-1.api.aws/v1"
aws_bedrock_project_id: "proj_abc123" # routes all calls to this project
- model_name: gpt-5.5-datascience
litellm_params:
model: bedrock_mantle/openai.gpt-5.5
api_key: os.environ/BEDROCK_MANTLE_API_KEY
api_base: "https://bedrock-mantle.us-east-1.api.aws/openai/v1"
aws_bedrock_project_id: "proj_def456" # separate project for data science team
Data-retention mode resolution
Bedrock resolves a data-retention mode per request in this priority order: project → account → model default. The first non-inherit value wins. Modes are: default, provider_data_share, none, inherit. Setting data_retention_mode: none on a project prevents any request data from being used for model improvement across the entire project, regardless of account-level defaults.
- model_name: pii-sensitive-chatbot
litellm_params:
model: bedrock_mantle/anthropic.claude-sonnet-4-6
api_key: os.environ/BEDROCK_MANTLE_API_KEY
api_base: "https://bedrock-mantle.us-east-1.api.aws/v1"
aws_bedrock_project_id: "proj_pii789"
# data retention for proj_pii789 should be set to "none" at project creation
Programmatic call-time project override
import litellm
response = litellm.completion(
model="bedrock_mantle/anthropic.claude-sonnet-4-6",
messages=[{"role": "user", "content": "Analyze this contract."}],
api_base="https://bedrock-mantle.us-east-1.api.aws/v1",
api_key=os.environ["BEDROCK_MANTLE_API_KEY"],
extra_headers={"OpenAI-Project": "proj_abc123"}
)
Feature request tracking
As of June 2026, LiteLLM GitHub Issue #30070 tracks full first-class support for configuring a Bedrock project and data-retention mode per model in litellm.yaml. The aws_bedrock_project_id parameter was added in mid-2026 but may not be fully surfaced in all LiteLLM proxy UI cost dashboards yet. Verify your LiteLLM version supports this parameter before relying on it for production cost attribution.
10. Cost Optimization Within Projects — Native Controls and Patterns
Projects have no native per-project spending limits or budget enforcement. This is a confirmed gap. Projects are attribution and isolation constructs, not financial guardrails. Cost control requires building on top of the tag-based attribution that Projects provide.
Available controls
| Control | Mechanism | Latency |
|---|---|---|
| Tag-based AWS Budget | AWS Budgets filtered by resourceTags/CostCenter |
Alert at 80/90/100% threshold; 8-hour CUR lag |
| CloudWatch alarm on token volume | CloudWatch metric filter on bedrock-mantle model invocation logs | Near-real-time (~1 min) |
| Lambda circuit-breaker | Lambda triggered by CloudWatch alarm; updates IAM policy to deny bedrock-mantle:CreateInference on project ARN |
Minutes |
| LiteLLM proxy spend limits | max_budget per virtual key in LiteLLM proxy config |
Real-time (proxy-layer) |
| Service quotas | bedrock-mantle uses fair-share work-queue scheduling; no RPM/TPM quotas analogous to bedrock-runtime | N/A (throughput, not spend) |
AWS Budgets pattern for project cost
aws budgets create-budget \
--account-id 123456789012 \
--budget '{
"BudgetName": "CustomerChatbot-Production-Monthly",
"BudgetLimit": {"Amount": "5000", "Unit": "USD"},
"TimeUnit": "MONTHLY",
"BudgetType": "COST",
"CostFilters": {
"TagKeyValue": ["resourceTags$Application$CustomerChatbot",
"resourceTags$Environment$Production"]
}
}' \
--notifications-with-subscribers '[{
"Notification": {
"NotificationType": "ACTUAL",
"ComparisonOperator": "GREATER_THAN",
"Threshold": 80
},
"Subscribers": [{"SubscriptionType": "EMAIL",
"Address": "platform-eng@company.com"}]
}]'
Known limitation: AWS Budgets has an 8-hour CUR data lag. A bursty inference workload can overshoot a budget by hours before a budget action fires. For hard spend caps, layer in CloudWatch + Lambda enforcement at the application layer or use LiteLLM proxy budget tracking (which operates on real-time token counts, not CUR dollars).
Cost Anomaly Detection
AWS Cost Anomaly Detection supports cost monitors scoped to a tag dimension. Create a monitor on resourceTags/Application and subscribe per application project for automatic ML-based anomaly alerts:
aws ce create-anomaly-monitor \
--anomaly-monitor '{
"MonitorName": "BedRockProjectsMonitor",
"MonitorType": "DIMENSIONAL",
"MonitorDimension": "SERVICE"
}'
Then subscribe with a tag filter for the project application tag for tighter scoping.
11. Projects Limitations — What Still Requires AIPs or Direct Model Invocation
Hard limitations (architectural, not roadmap)
| Limitation | Detail |
|---|---|
| No cross-region inference | bedrock-mantle does not support cross-region or global inference profiles. If your workload needs cross-region failover, you must use bedrock-runtime + AIPs |
| No per-request CUR rows | Projects produce per-usage-type-per-day CUR aggregates. Per-request cost attribution requires model invocation log join, not CUR |
| No per-request metadata tagging | The per-request metadata tagging feature (released May 2026 for bedrock-runtime) is not available on bedrock-mantle. You cannot attach arbitrary key-value metadata to individual inference calls for per-prompt billing |
| No native spend limits | Projects have no built-in budget enforcement or quota-based spending caps |
| Single-account scope | Projects do not span AWS accounts; cannot be used as a multi-account chargeback mechanism without tag policy enforcement at the Organizations layer |
| No project hierarchy | Flat namespace; parent/child project relationships do not exist. Team-to-BU rollup is tag-based only |
| Model access not restricted by project | Projects gate IAM inference permissions but do not restrict which models can be called. Model-level restrictions require separate model access policies |
Models not available on bedrock-mantle
A subset of foundation models remains bedrock-runtime-only (primarily models without OpenAI-compatible API mappings). For workloads requiring these models, AIPs remain the attribution mechanism. Check the AWS endpoint availability table for current model coverage.
Anthropic Messages API — dual-endpoint caveat
The Anthropic Messages API (/messages) is available on both bedrock-mantle and bedrock-runtime. For Messages API workloads, the choice of endpoint determines the attribution mechanism:
- bedrock-mantle + Messages API → Projects
- bedrock-runtime + Messages API → AIPs
Choosing mantle for Messages API gets you Projects attribution plus stateful conversation management; choosing runtime gets you AIPs attribution plus cross-region inference. Pick based on which capability matters more to your workload.
PrivateLink
bedrock-mantle supports AWS PrivateLink (VPC interface endpoints) as of February 2026. This eliminates NAT gateway egress costs for workloads running inside a VPC and is compatible with Projects — private endpoint traffic is still attributed to the specified project.
Summary — Decision Checklist
Before choosing Projects vs. AIPs, answer:
- Which endpoint am I on? bedrock-mantle → Projects. bedrock-runtime → AIPs. No choice to make.
- Do I need cross-region inference? Yes → bedrock-runtime + AIPs (Projects can’t help here).
- Do I need per-request metadata tagging? Yes → bedrock-runtime + per-request tagging (Projects can’t help here).
- Am I migrating an OpenAI SDK codebase? Yes → bedrock-mantle + Projects (swap base URL only).
- Do I want one attribution resource per application regardless of model count? Yes → Projects (AIPs require one resource per model per application).
- Do I need stateful sessions or async inference? Yes → bedrock-mantle + Projects.
- Do I need a hard spending cap enforced at the infrastructure layer? Neither Projects nor AIPs provide this natively; build budget enforcement with AWS Budgets + CloudWatch + Lambda, or use LiteLLM proxy budget controls.
Sources: AWS Bedrock documentation (docs.aws.amazon.com/bedrock/), AWS What’s New announcements (aws.amazon.com/about-aws/whats-new), LiteLLM documentation (docs.litellm.ai), AWS Builder Center architecture guides. Research synthesized June 18, 2026.