Skip to content

feat: bedrock vpc endpoints support - #6064

Merged
akshaydeo merged 1 commit into
devfrom
08-06-feat_bedrock_vpc_endpoints_support
Aug 11, 2026
Merged

feat: bedrock vpc endpoints support#6064
akshaydeo merged 1 commit into
devfrom
08-06-feat_bedrock_vpc_endpoints_support

Conversation

@TejasGhatte

@TejasGhatte TejasGhatte commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds support for routing AWS Bedrock traffic through interface VPC endpoints (AWS PrivateLink), allowing deployments where Bedrock services are accessed over private networking rather than the public regional endpoints. Each AWS endpoint service Bifrost dials (bedrock-runtime, bedrock, bedrock-mantle, bedrock-agent-runtime, s3) can be independently overridden with a VPC endpoint DNS name per key config.

Changes

  • Introduced BedrockEndpoints schema type holding per-service VPC endpoint host overrides for both BedrockKeyConfig and BedrockMantleKeyConfig.
  • Added resolveBedrockHost utility that returns the configured VPC endpoint host when set, falling back to the public regional hostname. Mantle is handled as a special case since its public host lives under api.aws rather than amazonaws.com.
  • Added bedrockEndpoints helper to safely extract endpoint config from a potentially nil BedrockKeyConfig.
  • Replaced all hardcoded fmt.Sprintf("https://bedrock-runtime.%s.amazonaws.com/...") style URL construction across bedrock.go, mantle.go, and bedrockmantle.go with calls to resolveBedrockHost, covering inference, streaming, agent runtime, control plane, S3 file operations, and batch job endpoints.
  • Updated mantleOpenAIURL, mantleAnthropicURL, and mantleAnthropicCountTokensURL to accept an *schemas.BedrockEndpoints argument so the override propagates through all Mantle call sites.
  • Added NormalizeEndpointHost to strip scheme and path from a pasted endpoint value, so users can paste a full URL from the AWS console without breaking URL construction.
  • Added bedrockService typed constants (bedrockServiceRuntime, bedrockServiceControlPlane, bedrockServiceMantle, bedrockServiceAgentRuntime, bedrockServiceS3) to make service identity explicit and avoid stringly-typed dispatch.
  • Persisted BedrockEndpoints as encrypted JSON columns (bedrock_endpoints_json, bedrock_mantle_endpoints_json) in the config_keys table, with full BeforeSave/AfterFind encrypt/decrypt lifecycle and a database migration.
  • Exposed VPC endpoint hosts in the redacted config view (they are network addresses, not credentials).
  • Added a collapsible VPC Endpoints section to the Bedrock and Bedrock Mantle key forms in the UI, with per-service fields and a validation rule requiring a DNS name (containing a dot) rather than a bare endpoint ID.
  • Updated config.schema.json with the endpoints object for both Bedrock and Bedrock Mantle key configs.
  • Added vpcendpoints_test.go covering default host resolution, per-service override isolation, host normalization edge cases, and SigV4 signing correctness with a VPC endpoint host. Updated existing tests to pass nil endpoints where the new parameter was added.

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

# Core/Transports
go test ./core/providers/bedrock/... ./core/providers/bedrockmantle/... ./framework/configstore/...

# UI
cd ui
pnpm i
pnpm build

To validate end-to-end, configure a Bedrock key with an endpoints.runtime value set to a VPC endpoint DNS name and confirm inference requests are directed to that host. Confirm that omitting the field falls back to the standard bedrock-runtime.{region}.amazonaws.com host. Confirm SigV4 signing still uses the configured region regardless of which host is dialled.

New config fields (BedrockKeyConfig.endpoints):

Field AWS endpoint service Default public host
runtime bedrock-runtime bedrock-runtime.{region}.amazonaws.com
control_plane bedrock bedrock.{region}.amazonaws.com
mantle bedrock-mantle bedrock-mantle.{region}.api.aws
agent_runtime bedrock-agent-runtime bedrock-agent-runtime.{region}.amazonaws.com
s3 s3 s3.{region}.amazonaws.com

Values accept the full DNS name from the VPC console (e.g. vpce-0abc123-x1y2z3.bedrock-runtime.eu-west-2.vpce.amazonaws.com), a URL with scheme, or a URL with a trailing path — all are normalized to a bare host.

Breaking changes

  • Yes
  • No

Security considerations

VPC endpoint hosts are stored encrypted at rest alongside other key config. They are surfaced in plaintext in the redacted config view because they are network addresses rather than credentials. SigV4 signing is unaffected: the credential scope continues to use the configured region, not the hostname, so a VPC endpoint host does not alter the signature scope.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added optional AWS PrivateLink endpoint configuration for Bedrock services.
    • Added endpoint settings to Bedrock and Bedrock Mantle credential forms, with hostname validation.
    • Added support for runtime, control plane, Mantle, agent runtime, and S3 endpoints.
  • Improvements
    • Bedrock requests now honor configured endpoints while retaining default regional routing.
    • Endpoint settings are securely persisted and restored with credentials.
  • Bug Fixes
    • Corrected Mantle URL handling across supported requests.

Walkthrough

Bedrock and Bedrock Mantle now support configurable AWS PrivateLink endpoint hosts. The configuration flows through validation, UI forms, encrypted persistence, host resolution, request routing, and tests.

Changes

Bedrock VPC endpoint support

Layer / File(s) Summary
Endpoint contracts and configuration UI
core/schemas/account.go, transports/config.schema.json, ui/lib/types/*, ui/lib/schemas/providerForm.ts, ui/app/workspace/providers/fragments/apiKeysFormFragment.tsx, helm-charts/bifrost/*
Adds service-specific endpoint fields for Bedrock and Bedrock Mantle. The UI and deployment schemas validate and expose endpoint configuration.
Endpoint persistence and redaction
framework/configstore/...
Adds migration, encrypted JSON persistence, restore and clear behavior, round-trip tests, and redacted configuration support.
Bedrock host resolution and request routing
core/providers/bedrock/types.go, core/providers/bedrock/utils.go, core/providers/bedrock/bedrock.go
Resolves configured or regional hosts for runtime, agent-runtime, control-plane, Mantle, S3, and batch requests. Existing signing remains unchanged.
Mantle endpoint routing
core/providers/bedrock/mantle.go, core/providers/bedrockmantle/*
Uses configured Mantle hosts for OpenAI-compatible, Anthropic, streaming, Responses, model-listing, and count-tokens requests.
Endpoint resolution and persistence validation
core/providers/bedrock/*_test.go, framework/configstore/tables/encryption_test.go
Tests defaults, per-service overrides, normalization, Mantle URLs, SigV4 signing, encrypted persistence, and endpoint removal.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ProviderForm
  participant ConfigStore
  participant BedrockProvider
  participant AWSPrivateLink
  ProviderForm->>ConfigStore: save endpoint host configuration
  ConfigStore->>BedrockProvider: restore endpoint configuration
  BedrockProvider->>AWSPrivateLink: send signed request to resolved host
Loading

Suggested reviewers: akshaydeo, pratham-mishra04

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the main change: support for AWS Bedrock VPC endpoints.
Description check ✅ Passed The description covers the required sections, explains the implementation and testing steps, and documents security, configuration, and breaking-change considerations.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 08-06-feat_bedrock_vpc_endpoints_support

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Trivy (0.72.0)

Trivy execution failed: 2026-08-11T15:34:27Z FATAL Fatal error run error: fs scan error: scan error: scan failed: failed analysis: post analysis error: post analysis error: cloudformation scan error: fs filter error: fs filter error: walk error range error: stat core/.golangci.yml: no such file or directory: range error: stat core/.golangci.yml: no such file or directory


Comment @coderabbitai help to get the list of available commands.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


tejas ghatte seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@TejasGhatte
TejasGhatte marked this pull request as ready for review August 11, 2026 13:58

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
ui/lib/types/schemas.ts (1)

220-220: 🗄️ Data Integrity & Integration | 🔵 Trivial

bedrockMantleKeyConfigSchema.endpoints accepts fields Mantle ignores.

bedrockMantleKeyConfigSchema reuses the full bedrockEndpointsSchema, so runtime, control_plane, and agent_runtime pass validation for a Mantle key even though only mantle has any effect downstream. Restrict the Mantle schema to the mantle field only, or add a .refine() that rejects the other fields for this config.

See the consolidated comment for the paired finding in core/schemas/account.go.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/lib/types/schemas.ts` at line 220, Update bedrockMantleKeyConfigSchema so
its endpoints configuration accepts only the mantle field and rejects runtime,
control_plane, and agent_runtime; do not reuse the unrestricted
bedrockEndpointsSchema for this Mantle-specific config.

Source: Path instructions

core/schemas/account.go (2)

1-1: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Mantle endpoint config accepts fields it never uses. BedrockMantleKeyConfig.Endpoints and the paired Zod schema both validate against the full BedrockEndpoints/bedrockEndpointsSchema shape (runtime, control_plane, mantle, agent_runtime, s3), but the Mantle host-resolution path (mantleHost in core/providers/bedrockmantle/bedrockmantle.go) only reads the mantle field, and the referenced config-schema documentation states Mantle keys support only endpoints.mantle. The UI form already restricts the Mantle section to a single field, but a client calling the API directly (or a config.json sync) can set the other four fields with no validation error, and they will be silently persisted and ignored.

  • core/schemas/account.go#L784-786: narrow BedrockMantleKeyConfig.Endpoints to a Mantle-only type, or add explicit validation elsewhere in the Go path that rejects non-mantle fields for this config.
  • ui/lib/types/schemas.ts#L220-220: restrict bedrockMantleKeyConfigSchema.endpoints to a mantle-only schema (or add a .refine() rejecting the other fields) instead of reusing bedrockEndpointsSchema as-is.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/schemas/account.go` at line 1, Restrict Mantle endpoint validation to
the supported mantle field only. Update BedrockMantleKeyConfig.Endpoints in the
Go schemas and bedrockMantleKeyConfigSchema in the UI schemas to use
Mantle-specific endpoint shapes, rejecting runtime, control_plane,
agent_runtime, and s3 fields while preserving mantle host resolution.

Source: Path instructions


784-786: 🗄️ Data Integrity & Integration | 🔵 Trivial

BedrockMantleKeyConfig.Endpoints accepts fields that Mantle never uses.

BedrockMantleKeyConfig.Endpoints reuses the full BedrockEndpoints type, which exposes Runtime, ControlPlane, AgentRuntime, and S3 in addition to Mantle. The Mantle host-resolution path only reads Endpoints.Mantle (see core/providers/bedrockmantle/bedrockmantle.go's mantleHost), so setting any of the other four fields on a Mantle key is silently accepted and has no effect. This diverges from the documented contract that "Bedrock Mantle keys support only endpoints.mantle."

See the consolidated comment for the corresponding schema-side finding.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/schemas/account.go` around lines 784 - 786, Change
BedrockMantleKeyConfig.Endpoints to use a Mantle-specific endpoint type that
exposes only the Mantle field, rather than the full BedrockEndpoints type.
Update the schema and any related serialization or validation references so
Bedrock Mantle keys reject Runtime, ControlPlane, AgentRuntime, and S3 while
preserving mantleHost’s existing Endpoints.Mantle resolution.

Source: Path instructions

ui/app/workspace/providers/fragments/apiKeysFormFragment.tsx (1)

64-73: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Collapsible section stays closed even when endpoints are already configured.

VPCEndpointsFormField always starts with open = false. When a user edits an existing key that already has one or more VPC endpoint overrides set, the section stays collapsed by default and hides that fact. Other auth-type selectors in this file (bedrockAuthType, azureAuthType, vertexAuthType) detect existing configuration on edit via a useEffect keyed on form.formState.isDirty/form.getValues(...) and set their initial UI state accordingly. Apply the same pattern here: default open to true when any ${configKey}.endpoints.* field already has a value.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/app/workspace/providers/fragments/apiKeysFormFragment.tsx` around lines 64
- 73, Update VPCEndpointsFormField so its open state is initialized or
synchronized to true when any ${configKey}.endpoints.* field already contains a
value, while remaining closed when no endpoints are configured. Follow the
existing bedrockAuthType, azureAuthType, and vertexAuthType useEffect pattern,
keyed appropriately to form dirtiness and current form values.
ui/lib/schemas/providerForm.ts (1)

165-176: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Restrict the Bedrock Mantle key's endpoints schema to the mantle field only.

BedrockMantleKeyConfigSchema reuses the full BedrockEndpointsSchema (all 5 fields: runtime, control_plane, mantle, agent_runtime, s3). transports/config.schema.json's bedrock_mantle_key_config.endpoints only allows mantle (additionalProperties: false rejects the rest), matching the documented contract that "Bedrock Mantle keys support only endpoints.mantle."

Define a dedicated BedrockMantleEndpointsSchema with only the mantle field, and use it here instead of the full BedrockEndpointsSchema, so the UI validator matches the authoritative schema and does not accept fields that are meaningless for a Mantle key.

♻️ Proposed fix
+const BedrockMantleEndpointsSchema = z.object({
+	mantle: VPCEndpointHostSchema,
+});
+
 const BedrockMantleKeyConfigSchema = z
 	.object({
 		access_key: z.string(),
 		secret_key: z.string(),
 		session_token: z.string().optional(),
 		region: z.string().min(1, "Region is required for Bedrock Mantle keys"),
 		role_arn: z.string().optional(),
 		external_id: z.string().optional(),
 		session_name: z.string().optional(),
 		project_id: z.string().optional(),
-		endpoints: BedrockEndpointsSchema.optional(),
+		endpoints: BedrockMantleEndpointsSchema.optional(),
 	})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/lib/schemas/providerForm.ts` around lines 165 - 176, Define a dedicated
BedrockMantleEndpointsSchema containing only the mantle endpoint field, then
update BedrockMantleKeyConfigSchema to use it instead of BedrockEndpointsSchema.
Preserve the existing optional endpoints behavior while rejecting runtime,
control_plane, agent_runtime, and s3 fields.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ui/app/workspace/providers/fragments/apiKeysFormFragment.tsx`:
- Around line 76-85: Replace FormLabel and FormDescription in the VPC Endpoints
section within the CollapsibleTrigger with plain p elements, preserving the
existing text and styling as appropriate. Do not use form-field context
components there, so undefined field metadata cannot generate invalid htmlFor or
id attributes.

---

Nitpick comments:
In `@core/schemas/account.go`:
- Line 1: Restrict Mantle endpoint validation to the supported mantle field
only. Update BedrockMantleKeyConfig.Endpoints in the Go schemas and
bedrockMantleKeyConfigSchema in the UI schemas to use Mantle-specific endpoint
shapes, rejecting runtime, control_plane, agent_runtime, and s3 fields while
preserving mantle host resolution.
- Around line 784-786: Change BedrockMantleKeyConfig.Endpoints to use a
Mantle-specific endpoint type that exposes only the Mantle field, rather than
the full BedrockEndpoints type. Update the schema and any related serialization
or validation references so Bedrock Mantle keys reject Runtime, ControlPlane,
AgentRuntime, and S3 while preserving mantleHost’s existing Endpoints.Mantle
resolution.

In `@ui/app/workspace/providers/fragments/apiKeysFormFragment.tsx`:
- Around line 64-73: Update VPCEndpointsFormField so its open state is
initialized or synchronized to true when any ${configKey}.endpoints.* field
already contains a value, while remaining closed when no endpoints are
configured. Follow the existing bedrockAuthType, azureAuthType, and
vertexAuthType useEffect pattern, keyed appropriately to form dirtiness and
current form values.

In `@ui/lib/schemas/providerForm.ts`:
- Around line 165-176: Define a dedicated BedrockMantleEndpointsSchema
containing only the mantle endpoint field, then update
BedrockMantleKeyConfigSchema to use it instead of BedrockEndpointsSchema.
Preserve the existing optional endpoints behavior while rejecting runtime,
control_plane, agent_runtime, and s3 fields.

In `@ui/lib/types/schemas.ts`:
- Line 220: Update bedrockMantleKeyConfigSchema so its endpoints configuration
accepts only the mantle field and rejects runtime, control_plane, and
agent_runtime; do not reuse the unrestricted bedrockEndpointsSchema for this
Mantle-specific config.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 00d6e434-0240-45a9-b284-861f41f42c9b

📥 Commits

Reviewing files that changed from the base of the PR and between c01a0a2 and d0b4dfe.

📒 Files selected for processing (20)
  • core/providers/bedrock/bedrock.go
  • core/providers/bedrock/mantle.go
  • core/providers/bedrock/mantle_test.go
  • core/providers/bedrock/types.go
  • core/providers/bedrock/utils.go
  • core/providers/bedrock/vpcendpoints_test.go
  • core/providers/bedrockmantle/bedrockmantle.go
  • core/providers/bedrockmantle/counttokens.go
  • core/providers/bedrockmantle/counttokens_test.go
  • core/schemas/account.go
  • framework/configstore/clientconfig.go
  • framework/configstore/migrations.go
  • framework/configstore/rdb.go
  • framework/configstore/tables/encryption_test.go
  • framework/configstore/tables/key.go
  • transports/config.schema.json
  • ui/app/workspace/providers/fragments/apiKeysFormFragment.tsx
  • ui/lib/schemas/providerForm.ts
  • ui/lib/types/config.ts
  • ui/lib/types/schemas.ts

Comment thread ui/app/workspace/providers/fragments/apiKeysFormFragment.tsx Outdated
@TejasGhatte
TejasGhatte force-pushed the 08-06-feat_bedrock_vpc_endpoints_support branch from d0b4dfe to 62a939e Compare August 11, 2026 15:33
@TejasGhatte
TejasGhatte requested a review from a team as a code owner August 11, 2026 15:33

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@helm-charts/bifrost/values.schema.json`:
- Around line 5501-5507: Update both S3 endpoint schema copies to validate
literal hosts with the required `bucket.` prefix while continuing to accept
`env.<NAME>` references. Replace the current period-only pattern on the s3
property in each copy, preserving the existing description and
additionalProperties behavior.
- Around line 6460-6463: Update the virtual-key Bedrock configuration schema
containing the endpoints property to require region, matching the standard
bedrock_key_config contract. Add region to that configuration’s required fields
so endpoint overrides cannot pass Helm validation without a signing region.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5b695941-ae89-4480-9f01-a5bf7357b7c1

📥 Commits

Reviewing files that changed from the base of the PR and between d0b4dfe and 62a939e.

📒 Files selected for processing (5)
  • core/schemas/account.go
  • helm-charts/bifrost/values.schema.json
  • helm-charts/bifrost/values.yaml
  • transports/config.schema.json
  • ui/app/workspace/providers/fragments/apiKeysFormFragment.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • transports/config.schema.json
  • ui/app/workspace/providers/fragments/apiKeysFormFragment.tsx
  • core/schemas/account.go

Comment thread helm-charts/bifrost/values.schema.json
Comment thread helm-charts/bifrost/values.schema.json

akshaydeo commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Merge activity

  • Aug 11, 5:28 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Aug 11, 5:29 PM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo
akshaydeo merged commit 1d8e373 into dev Aug 11, 2026
14 of 15 checks passed
@akshaydeo
akshaydeo deleted the 08-06-feat_bedrock_vpc_endpoints_support branch August 11, 2026 17:29
akshaydeo pushed a commit that referenced this pull request Aug 13, 2026
## Summary

Adds support for routing AWS Bedrock traffic through interface VPC endpoints (AWS PrivateLink), allowing deployments where Bedrock services are accessed over private networking rather than the public regional endpoints. Each AWS endpoint service Bifrost dials (bedrock-runtime, bedrock, bedrock-mantle, bedrock-agent-runtime, s3) can be independently overridden with a VPC endpoint DNS name per key config.

## Changes

- Introduced `BedrockEndpoints` schema type holding per-service VPC endpoint host overrides for both `BedrockKeyConfig` and `BedrockMantleKeyConfig`.
- Added `resolveBedrockHost` utility that returns the configured VPC endpoint host when set, falling back to the public regional hostname. Mantle is handled as a special case since its public host lives under `api.aws` rather than `amazonaws.com`.
- Added `bedrockEndpoints` helper to safely extract endpoint config from a potentially nil `BedrockKeyConfig`.
- Replaced all hardcoded `fmt.Sprintf("https://bedrock-runtime.%s.amazonaws.com/...")` style URL construction across `bedrock.go`, `mantle.go`, and `bedrockmantle.go` with calls to `resolveBedrockHost`, covering inference, streaming, agent runtime, control plane, S3 file operations, and batch job endpoints.
- Updated `mantleOpenAIURL`, `mantleAnthropicURL`, and `mantleAnthropicCountTokensURL` to accept an `*schemas.BedrockEndpoints` argument so the override propagates through all Mantle call sites.
- Added `NormalizeEndpointHost` to strip scheme and path from a pasted endpoint value, so users can paste a full URL from the AWS console without breaking URL construction.
- Added `bedrockService` typed constants (`bedrockServiceRuntime`, `bedrockServiceControlPlane`, `bedrockServiceMantle`, `bedrockServiceAgentRuntime`, `bedrockServiceS3`) to make service identity explicit and avoid stringly-typed dispatch.
- Persisted `BedrockEndpoints` as encrypted JSON columns (`bedrock_endpoints_json`, `bedrock_mantle_endpoints_json`) in the `config_keys` table, with full `BeforeSave`/`AfterFind` encrypt/decrypt lifecycle and a database migration.
- Exposed VPC endpoint hosts in the redacted config view (they are network addresses, not credentials).
- Added a collapsible **VPC Endpoints** section to the Bedrock and Bedrock Mantle key forms in the UI, with per-service fields and a validation rule requiring a DNS name (containing a dot) rather than a bare endpoint ID.
- Updated `config.schema.json` with the `endpoints` object for both Bedrock and Bedrock Mantle key configs.
- Added `vpcendpoints_test.go` covering default host resolution, per-service override isolation, host normalization edge cases, and SigV4 signing correctness with a VPC endpoint host. Updated existing tests to pass `nil` endpoints where the new parameter was added.

## Type of change

- [ ] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [x] UI (React)
- [ ] Docs

## How to test

```sh
# Core/Transports
go test ./core/providers/bedrock/... ./core/providers/bedrockmantle/... ./framework/configstore/...

# UI
cd ui
pnpm i
pnpm build
```

To validate end-to-end, configure a Bedrock key with an `endpoints.runtime` value set to a VPC endpoint DNS name and confirm inference requests are directed to that host. Confirm that omitting the field falls back to the standard `bedrock-runtime.{region}.amazonaws.com` host. Confirm SigV4 signing still uses the configured region regardless of which host is dialled.

**New config fields (`BedrockKeyConfig.endpoints`):**

| Field | AWS endpoint service | Default public host |
|---|---|---|
| `runtime` | `bedrock-runtime` | `bedrock-runtime.{region}.amazonaws.com` |
| `control_plane` | `bedrock` | `bedrock.{region}.amazonaws.com` |
| `mantle` | `bedrock-mantle` | `bedrock-mantle.{region}.api.aws` |
| `agent_runtime` | `bedrock-agent-runtime` | `bedrock-agent-runtime.{region}.amazonaws.com` |
| `s3` | `s3` | `s3.{region}.amazonaws.com` |

Values accept the full DNS name from the VPC console (e.g. `vpce-0abc123-x1y2z3.bedrock-runtime.eu-west-2.vpce.amazonaws.com`), a URL with scheme, or a URL with a trailing path — all are normalized to a bare host.

## Breaking changes

- [ ] Yes
- [x] No

## Security considerations

VPC endpoint hosts are stored encrypted at rest alongside other key config. They are surfaced in plaintext in the redacted config view because they are network addresses rather than credentials. SigV4 signing is unaffected: the credential scope continues to use the configured region, not the hostname, so a VPC endpoint host does not alter the signature scope.

## Checklist

- [x] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [x] I verified the CI pipeline passes locally if applicable
akshaydeo pushed a commit that referenced this pull request Aug 13, 2026
## Summary

Adds support for routing AWS Bedrock traffic through interface VPC endpoints (AWS PrivateLink), allowing deployments where Bedrock services are accessed over private networking rather than the public regional endpoints. Each AWS endpoint service Bifrost dials (bedrock-runtime, bedrock, bedrock-mantle, bedrock-agent-runtime, s3) can be independently overridden with a VPC endpoint DNS name per key config.

## Changes

- Introduced `BedrockEndpoints` schema type holding per-service VPC endpoint host overrides for both `BedrockKeyConfig` and `BedrockMantleKeyConfig`.
- Added `resolveBedrockHost` utility that returns the configured VPC endpoint host when set, falling back to the public regional hostname. Mantle is handled as a special case since its public host lives under `api.aws` rather than `amazonaws.com`.
- Added `bedrockEndpoints` helper to safely extract endpoint config from a potentially nil `BedrockKeyConfig`.
- Replaced all hardcoded `fmt.Sprintf("https://bedrock-runtime.%s.amazonaws.com/...")` style URL construction across `bedrock.go`, `mantle.go`, and `bedrockmantle.go` with calls to `resolveBedrockHost`, covering inference, streaming, agent runtime, control plane, S3 file operations, and batch job endpoints.
- Updated `mantleOpenAIURL`, `mantleAnthropicURL`, and `mantleAnthropicCountTokensURL` to accept an `*schemas.BedrockEndpoints` argument so the override propagates through all Mantle call sites.
- Added `NormalizeEndpointHost` to strip scheme and path from a pasted endpoint value, so users can paste a full URL from the AWS console without breaking URL construction.
- Added `bedrockService` typed constants (`bedrockServiceRuntime`, `bedrockServiceControlPlane`, `bedrockServiceMantle`, `bedrockServiceAgentRuntime`, `bedrockServiceS3`) to make service identity explicit and avoid stringly-typed dispatch.
- Persisted `BedrockEndpoints` as encrypted JSON columns (`bedrock_endpoints_json`, `bedrock_mantle_endpoints_json`) in the `config_keys` table, with full `BeforeSave`/`AfterFind` encrypt/decrypt lifecycle and a database migration.
- Exposed VPC endpoint hosts in the redacted config view (they are network addresses, not credentials).
- Added a collapsible **VPC Endpoints** section to the Bedrock and Bedrock Mantle key forms in the UI, with per-service fields and a validation rule requiring a DNS name (containing a dot) rather than a bare endpoint ID.
- Updated `config.schema.json` with the `endpoints` object for both Bedrock and Bedrock Mantle key configs.
- Added `vpcendpoints_test.go` covering default host resolution, per-service override isolation, host normalization edge cases, and SigV4 signing correctness with a VPC endpoint host. Updated existing tests to pass `nil` endpoints where the new parameter was added.

## Type of change

- [ ] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [x] UI (React)
- [ ] Docs

## How to test

```sh
# Core/Transports
go test ./core/providers/bedrock/... ./core/providers/bedrockmantle/... ./framework/configstore/...

# UI
cd ui
pnpm i
pnpm build
```

To validate end-to-end, configure a Bedrock key with an `endpoints.runtime` value set to a VPC endpoint DNS name and confirm inference requests are directed to that host. Confirm that omitting the field falls back to the standard `bedrock-runtime.{region}.amazonaws.com` host. Confirm SigV4 signing still uses the configured region regardless of which host is dialled.

**New config fields (`BedrockKeyConfig.endpoints`):**

| Field | AWS endpoint service | Default public host |
|---|---|---|
| `runtime` | `bedrock-runtime` | `bedrock-runtime.{region}.amazonaws.com` |
| `control_plane` | `bedrock` | `bedrock.{region}.amazonaws.com` |
| `mantle` | `bedrock-mantle` | `bedrock-mantle.{region}.api.aws` |
| `agent_runtime` | `bedrock-agent-runtime` | `bedrock-agent-runtime.{region}.amazonaws.com` |
| `s3` | `s3` | `s3.{region}.amazonaws.com` |

Values accept the full DNS name from the VPC console (e.g. `vpce-0abc123-x1y2z3.bedrock-runtime.eu-west-2.vpce.amazonaws.com`), a URL with scheme, or a URL with a trailing path — all are normalized to a bare host.

## Breaking changes

- [ ] Yes
- [x] No

## Security considerations

VPC endpoint hosts are stored encrypted at rest alongside other key config. They are surfaced in plaintext in the redacted config view because they are network addresses rather than credentials. SigV4 signing is unaffected: the credential scope continues to use the configured region, not the hostname, so a VPC endpoint host does not alter the signature scope.

## Checklist

- [x] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [x] I verified the CI pipeline passes locally if applicable
@akshaydeo akshaydeo mentioned this pull request Aug 13, 2026
akshaydeo added a commit that referenced this pull request Aug 13, 2026
## ✨ Features

- **MCP Per-User OAuth** - MCP clients can hold per-user OAuth
credentials and per-user headers, configurable from `config.json` as
well as the UI, with a documented shared vs per-identity token lookup
contract and VK/Users filters on the OAuth Grants and MCP Auth Sessions
sidebars
- **Token Exchange IDP Credentials** - New `use_idp_credentials` on
`token_exchange` reuses SSO login app credentials for providers that
require it, such as Microsoft Entra ID; `client_id` becomes optional
when it is set (#6068, #6069)
- **Bedrock VPC Endpoints** - AWS Bedrock keys can target VPC endpoints
(#6064)
- **Per-Request Flat-Fee Pricing** - New `cost_per_request` field flows
through datasheet sync, the cost engine, custom overrides and the UI
override form (#6079)
- **Pricing Overrides in the Model Catalog** - `/api/models/details`
exposes resolved pricing overrides, and catalog rows resolve overrides
server-side (#6055, #6056)
- **MCP Tool Discovery Persistence** - Discovered MCP tools persist and
resync uniformly across all client types through a hash-gated core
callback, surviving restarts and propagating across a cluster
- **W3C Trace ID Propagation** - Requests carry a W3C trace ID on the
context (#5945)
- **Cancellable Log Cost Recalculation** - Log cost recalculation tasks
can be cancelled from the backend (#5801)
- **Separate OTEL Metrics Pipeline** - The OTEL collector supports a
metrics tab independent of traces, plus separate headers for traces and
metrics (#5939, #5940)
- **Roots-Only Log Filter** - New `roots_only` filter collapses fallback
chains into their root entry with child aggregates (#5737)
- **MCP Log Redaction and Plugin Logs** - MCP tool logs carry redaction
mappings and plugin logs (#5744, #5746)
- **User Agent and App Attribution in Logs** - Logs and MCP tool logs
record user agent, app, source, decision, app key and device ID
- **S3 Log Export Metadata** - Additional metadata is written alongside
S3 log exports (#6070)
- **Matview Maintenance Off Switch** - `matview_refresh_interval`
accepts `"off"` to disable logstore matview maintenance entirely (thanks
[@jeremym-tanium](https://github.com/jeremym-tanium)!) (#5693)
- **Video Request Info in Logs UI** - Video requests surface their
details in the logs UI (#5946)
- **Shell Rewriter Hook** - The UI handler exposes a `ShellRewriter`
hook for pre-hydration HTML rewriting (#5807)
- **Auth Skip Path** - Adds a context path letting trusted internal
callers bypass auth resolution

## 🐞 Fixed

- **Path Normalization Auth Bypass** - Fixed a path normalization flaw
that allowed auth to be bypassed (#5763)
- **Minimal Reasoning Effort on GPT-5 Models** - `reasoning_effort:
"minimal"` is preserved for GPT-5-family OpenAI models instead of being
downgraded to `low` (thanks [@jitokim](https://github.com/jitokim)!)
(#6046)
- **Gemini Truncated Response Finish Reason** - Truncated Gemini
responses report `MAX_TOKENS` instead of `OTHER` (thanks
[@AdityaPainuli](https://github.com/AdityaPainuli)!) (#5979)
- **Null Tool-Call Function Name on Streaming** - Streaming continuation
deltas no longer materialize an absent tool-call function name as `null`
(thanks [@AdityaPainuli](https://github.com/AdityaPainuli)!) (#5966)
- **Bedrock Document Uploads** - Fixed Bedrock file handling in
inference so office and PDF documents sent as OpenAI `type: "file"` are
accepted (#5947)
- **xAI Usage Cost** - Fixed USD cost ticks for xAI usage (#5950)
- **Anthropic Encrypted Reasoning** - Added an Anthropic error branch
when stripping encrypted reasoning content
- **MCP Reconnect and Lock Ordering** - Broke a lock-order inversion in
`ConnectionCheckerManager`, rebuilt ephemeral clients across the whole
connect+init retry, preserved last-known tool maps across close-first
reconnects, bound connect attempts to entry identity, deduped background
reconnects and gated SSE `OnConnectionLost` on connection identity
- **MCP OAuth Session Correctness** - Restricted `Reauthorize` to shared
OAuth clients, rejected inactive tokens in `ValidateToken`, made the
OAuth flow claim atomic against concurrent reauth, stopped dropping
stored scopes on decode failure, and closed a verify-headers
double-submit race that also dropped TLS, timeout and per-user-header
fields
- **Session Stickiness Reconciliation** - `needs_session_stickiness` is
pinned across `config.json` reconciliation, so an unrelated file edit
can no longer silently revert a client to per-call
- **Credential Cache Cancellation** - `headerCredentialCache.Fill` and
`userTokenCache.Fill` propagate context so a cancelled request unblocks
instead of waiting on an unrelated leader; LRU entries carry a version
so a rejected stale `Get` cannot evict a concurrently-updated value
- **Governance List-Models Call** - Budgets and rate limits no longer
trigger a list-models call (#6051)
- **Realtime Response Create Input** - Guarded `response.create` input
(#6050)
- **HTTP Server Timeouts** - Configured bounded `http.Server` timeouts
and a request-body limit
- **MCP Client State Badges** - State badges render with spaces instead
of underscores, and the state filter bucket was renamed from
`disconnected` to `unstable`
- **Entra OBO Scope** - `offline_access` is combined with
`<audience>/.default` for Entra OBO instead of replacing it (#6078)

## 🔧 Maintenance

- **Governance Route Families** - Editions can override governance route
families (#5839)
- **Dependency Upgrades** - Dependabot updates across all modules, plus
module path fixes (#6040, #5864)
- **Documentation** - config.schema.json doc fixes and Datadog env var
reference fixes in the helm chart docs (#5938, #6019)

## 🗄️ Database Migrations

**configstore:**

- **add_mcp_client_pending_oauth_config_json_column** - Adds
`pending_oauth_config_json` to `config_mcp_clients`. Reversible: drops
the added column.
- **merge_oauth_token_tables** - Consolidates `oauth_tokens` and
`oauth_user_tokens` into `mcp_oauth_tokens`. **Non-reversible**:
rollback deliberately leaves `mcp_oauth_tokens` in place, because every
OAuth read and write targets it from this migration onward and dropping
it would destroy any token created or refreshed since, forcing every
holder to re-authorize.
- **create_mcp_oauth_flows_table** - Creates `mcp_oauth_flows` to track
in-flight OAuth flows. Reversible: drops the new table.
- **drop_oauth_config_pkce_columns** - Drops CSRF state, PKCE verifier
and `expires_at` from the OAuth config table now that they live on
`mcp_oauth_flows`. **Non-reversible**: forward-only, the dropped values
were per-flow ephemeral and re-adding empty columns would restore
nothing.
- **drop_oauth_config_token_id_column** - Drops `token_id`.
**Non-reversible**: forward-only, it was a pure FK shortcut now
reachable via `(oauth_config_id, auth_mode)`.
- **add_mcp_admin_auth_mode_indexes** - Adds admin partial unique
indexes on `mcp_oauth_tokens` and `mcp_per_user_header_credentials`.
Reversible: drops both indexes.
- **add_mcp_client_token_exchange_json_column** - Adds
`token_exchange_json` to `config_mcp_clients`. Reversible: drops the
added column.
- **add_needs_session_stickiness_column** - Adds
`needs_session_stickiness` to `config_mcp_clients`. Reversible: drops
the added column.
- **add_bedrock_endpoints_columns** - Adds Bedrock VPC endpoint columns
to the keys table. Reversible: drops the added columns.
- **add_cost_per_request_pricing_column** - Adds `cost_per_request` to
model pricing. Reversible: drops the added column.

**logstore:**

- **logs_add_guardrail_debug_column** - Adds `guardrail_debug` to logs.
Reversible: drops the added column.
- **mcp_tool_logs_add_redaction_mapping_column** - Adds the redaction
mapping column to MCP tool logs. **Non-reversible**: rollback is a no-op
because dropping the column would permanently destroy reveal data for
already-redacted MCP logs.
- **logs_add_user_agent_column** - Adds user agent and app columns,
their indexes, and a `UserAgentMapping` table. Reversible: drops the
indexes and the mapping table.
- **mcp_tool_logs_add_user_agent_column** - Adds user agent and app
columns plus indexes to MCP tool logs. Reversible: drops both indexes
and the `app` column.
- **mcp_tool_logs_add_endpoint_columns** - Adds `source`, `decision`,
`app_key` and `device_id` to MCP tool logs. Reversible: drops all four
columns.
- **mcp_tool_logs_add_plugin_logs_column** - Adds `plugin_logs` to MCP
tool logs. Reversible: drops the added column.
- **logs_recreate_matviews_with_user_agent_column** and
**logs_recreate_matviews_with_app_column** - Recreate the log
materialized views to include the new columns. Rollback is a no-op
because `ensureMatViews` recreates them on next startup.

<Warning>
**High-throughput deployments: run the logstore migrations during a
low-activity window.**

Every logstore migration above alters `logs` or `mcp_tool_logs`, the two
highest-insert tables in Bifrost, and several also build indexes on
them. On a busy instance the index builds hold locks that block
concurrent log inserts for the duration of the build, and the matview
recreations rebuild against the full table. Schedule the upgrade for a
low-traffic period, or expect elevated log-write latency and possible
request-path backpressure while the migrations run.
</Warning>

<Warning>
`merge_oauth_token_tables`, `drop_oauth_config_pkce_columns` and
`drop_oauth_config_token_id_column` transform or remove existing OAuth
state and cannot be rolled back. Take a database backup before
upgrading, and do not roll the binary back past this release once the
migration has run.
</Warning>

## 🐙 Closed GitHub Issues

- [#123](#123) - Files API
Support
- [#5472](#5472) - [Bug]:
Bedrock rejects office/PDF document uploads via OpenAI `type:"file"` -
"The PDF specified was not valid"
- [#5900](#5900) - [Bug]:
Streaming continuation chunks materialize omitted tool-call metadata as
null
- [#5978](#5978) - [Bug]:
Gemini egress reports truncated responses as FinishReason OTHER,
IncompleteDetails switch matches a string that never occurs
- [#6044](#6044) - [Bug]:
normalizeOpenAIReasoningEffort maps 'minimal' to 'low' for ALL OpenAI
models, even ones that natively support 'minimal'
akshaydeo pushed a commit that referenced this pull request Aug 14, 2026
## Summary

Adds support for routing AWS Bedrock traffic through interface VPC endpoints (AWS PrivateLink), allowing deployments where Bedrock services are accessed over private networking rather than the public regional endpoints. Each AWS endpoint service Bifrost dials (bedrock-runtime, bedrock, bedrock-mantle, bedrock-agent-runtime, s3) can be independently overridden with a VPC endpoint DNS name per key config.

## Changes

- Introduced `BedrockEndpoints` schema type holding per-service VPC endpoint host overrides for both `BedrockKeyConfig` and `BedrockMantleKeyConfig`.
- Added `resolveBedrockHost` utility that returns the configured VPC endpoint host when set, falling back to the public regional hostname. Mantle is handled as a special case since its public host lives under `api.aws` rather than `amazonaws.com`.
- Added `bedrockEndpoints` helper to safely extract endpoint config from a potentially nil `BedrockKeyConfig`.
- Replaced all hardcoded `fmt.Sprintf("https://bedrock-runtime.%s.amazonaws.com/...")` style URL construction across `bedrock.go`, `mantle.go`, and `bedrockmantle.go` with calls to `resolveBedrockHost`, covering inference, streaming, agent runtime, control plane, S3 file operations, and batch job endpoints.
- Updated `mantleOpenAIURL`, `mantleAnthropicURL`, and `mantleAnthropicCountTokensURL` to accept an `*schemas.BedrockEndpoints` argument so the override propagates through all Mantle call sites.
- Added `NormalizeEndpointHost` to strip scheme and path from a pasted endpoint value, so users can paste a full URL from the AWS console without breaking URL construction.
- Added `bedrockService` typed constants (`bedrockServiceRuntime`, `bedrockServiceControlPlane`, `bedrockServiceMantle`, `bedrockServiceAgentRuntime`, `bedrockServiceS3`) to make service identity explicit and avoid stringly-typed dispatch.
- Persisted `BedrockEndpoints` as encrypted JSON columns (`bedrock_endpoints_json`, `bedrock_mantle_endpoints_json`) in the `config_keys` table, with full `BeforeSave`/`AfterFind` encrypt/decrypt lifecycle and a database migration.
- Exposed VPC endpoint hosts in the redacted config view (they are network addresses, not credentials).
- Added a collapsible **VPC Endpoints** section to the Bedrock and Bedrock Mantle key forms in the UI, with per-service fields and a validation rule requiring a DNS name (containing a dot) rather than a bare endpoint ID.
- Updated `config.schema.json` with the `endpoints` object for both Bedrock and Bedrock Mantle key configs.
- Added `vpcendpoints_test.go` covering default host resolution, per-service override isolation, host normalization edge cases, and SigV4 signing correctness with a VPC endpoint host. Updated existing tests to pass `nil` endpoints where the new parameter was added.

## Type of change

- [ ] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [x] UI (React)
- [ ] Docs

## How to test

```sh
# Core/Transports
go test ./core/providers/bedrock/... ./core/providers/bedrockmantle/... ./framework/configstore/...

# UI
cd ui
pnpm i
pnpm build
```

To validate end-to-end, configure a Bedrock key with an `endpoints.runtime` value set to a VPC endpoint DNS name and confirm inference requests are directed to that host. Confirm that omitting the field falls back to the standard `bedrock-runtime.{region}.amazonaws.com` host. Confirm SigV4 signing still uses the configured region regardless of which host is dialled.

**New config fields (`BedrockKeyConfig.endpoints`):**

| Field | AWS endpoint service | Default public host |
|---|---|---|
| `runtime` | `bedrock-runtime` | `bedrock-runtime.{region}.amazonaws.com` |
| `control_plane` | `bedrock` | `bedrock.{region}.amazonaws.com` |
| `mantle` | `bedrock-mantle` | `bedrock-mantle.{region}.api.aws` |
| `agent_runtime` | `bedrock-agent-runtime` | `bedrock-agent-runtime.{region}.amazonaws.com` |
| `s3` | `s3` | `s3.{region}.amazonaws.com` |

Values accept the full DNS name from the VPC console (e.g. `vpce-0abc123-x1y2z3.bedrock-runtime.eu-west-2.vpce.amazonaws.com`), a URL with scheme, or a URL with a trailing path — all are normalized to a bare host.

## Breaking changes

- [ ] Yes
- [x] No

## Security considerations

VPC endpoint hosts are stored encrypted at rest alongside other key config. They are surfaced in plaintext in the redacted config view because they are network addresses rather than credentials. SigV4 signing is unaffected: the credential scope continues to use the configured region, not the hostname, so a VPC endpoint host does not alter the signature scope.

## Checklist

- [x] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [x] I verified the CI pipeline passes locally if applicable
akshaydeo pushed a commit that referenced this pull request Aug 19, 2026
Adds support for routing AWS Bedrock traffic through interface VPC endpoints (AWS PrivateLink), allowing deployments where Bedrock services are accessed over private networking rather than the public regional endpoints. Each AWS endpoint service Bifrost dials (bedrock-runtime, bedrock, bedrock-mantle, bedrock-agent-runtime, s3) can be independently overridden with a VPC endpoint DNS name per key config.

- Introduced `BedrockEndpoints` schema type holding per-service VPC endpoint host overrides for both `BedrockKeyConfig` and `BedrockMantleKeyConfig`.
- Added `resolveBedrockHost` utility that returns the configured VPC endpoint host when set, falling back to the public regional hostname. Mantle is handled as a special case since its public host lives under `api.aws` rather than `amazonaws.com`.
- Added `bedrockEndpoints` helper to safely extract endpoint config from a potentially nil `BedrockKeyConfig`.
- Replaced all hardcoded `fmt.Sprintf("https://bedrock-runtime.%s.amazonaws.com/...")` style URL construction across `bedrock.go`, `mantle.go`, and `bedrockmantle.go` with calls to `resolveBedrockHost`, covering inference, streaming, agent runtime, control plane, S3 file operations, and batch job endpoints.
- Updated `mantleOpenAIURL`, `mantleAnthropicURL`, and `mantleAnthropicCountTokensURL` to accept an `*schemas.BedrockEndpoints` argument so the override propagates through all Mantle call sites.
- Added `NormalizeEndpointHost` to strip scheme and path from a pasted endpoint value, so users can paste a full URL from the AWS console without breaking URL construction.
- Added `bedrockService` typed constants (`bedrockServiceRuntime`, `bedrockServiceControlPlane`, `bedrockServiceMantle`, `bedrockServiceAgentRuntime`, `bedrockServiceS3`) to make service identity explicit and avoid stringly-typed dispatch.
- Persisted `BedrockEndpoints` as encrypted JSON columns (`bedrock_endpoints_json`, `bedrock_mantle_endpoints_json`) in the `config_keys` table, with full `BeforeSave`/`AfterFind` encrypt/decrypt lifecycle and a database migration.
- Exposed VPC endpoint hosts in the redacted config view (they are network addresses, not credentials).
- Added a collapsible **VPC Endpoints** section to the Bedrock and Bedrock Mantle key forms in the UI, with per-service fields and a validation rule requiring a DNS name (containing a dot) rather than a bare endpoint ID.
- Updated `config.schema.json` with the `endpoints` object for both Bedrock and Bedrock Mantle key configs.
- Added `vpcendpoints_test.go` covering default host resolution, per-service override isolation, host normalization edge cases, and SigV4 signing correctness with a VPC endpoint host. Updated existing tests to pass `nil` endpoints where the new parameter was added.

- [ ] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

- [x] Core (Go)
- [x] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [x] UI (React)
- [ ] Docs

```sh
go test ./core/providers/bedrock/... ./core/providers/bedrockmantle/... ./framework/configstore/...

cd ui
pnpm i
pnpm build
```

To validate end-to-end, configure a Bedrock key with an `endpoints.runtime` value set to a VPC endpoint DNS name and confirm inference requests are directed to that host. Confirm that omitting the field falls back to the standard `bedrock-runtime.{region}.amazonaws.com` host. Confirm SigV4 signing still uses the configured region regardless of which host is dialled.

**New config fields (`BedrockKeyConfig.endpoints`):**

| Field | AWS endpoint service | Default public host |
|---|---|---|
| `runtime` | `bedrock-runtime` | `bedrock-runtime.{region}.amazonaws.com` |
| `control_plane` | `bedrock` | `bedrock.{region}.amazonaws.com` |
| `mantle` | `bedrock-mantle` | `bedrock-mantle.{region}.api.aws` |
| `agent_runtime` | `bedrock-agent-runtime` | `bedrock-agent-runtime.{region}.amazonaws.com` |
| `s3` | `s3` | `s3.{region}.amazonaws.com` |

Values accept the full DNS name from the VPC console (e.g. `vpce-0abc123-x1y2z3.bedrock-runtime.eu-west-2.vpce.amazonaws.com`), a URL with scheme, or a URL with a trailing path — all are normalized to a bare host.

- [ ] Yes
- [x] No

VPC endpoint hosts are stored encrypted at rest alongside other key config. They are surfaced in plaintext in the redacted config view because they are network addresses rather than credentials. SigV4 signing is unaffected: the credential scope continues to use the configured region, not the hostname, so a VPC endpoint host does not alter the signature scope.

- [x] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [x] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [x] I verified the CI pipeline passes locally if applicable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants