mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
feat: add AWS profile support for Bedrock credentials
- Add BEDROCK_AWS_PROFILE environment variable support - Implement AWS SDK credential provider chain for automatic refresh - Update credential loading logic to support profiles, static env vars, and user-provided credentials - Add logging for credential source transparency - Update .env.example with profile configuration documentation Follows S3 implementation pattern for credential handling. Enables users to configure AWS profiles with optional credential_process for automatic token refresh.
This commit is contained in:
parent
f6868fc851
commit
ec31e78eca
2 changed files with 59 additions and 19 deletions
23
.env.example
23
.env.example
|
|
@ -134,8 +134,31 @@ ANTHROPIC_API_KEY=user_provided
|
||||||
#=================#
|
#=================#
|
||||||
# AWS Bedrock #
|
# AWS Bedrock #
|
||||||
#=================#
|
#=================#
|
||||||
|
# AWS Bedrock Credentials Configuration
|
||||||
|
#
|
||||||
|
# Option 1: Use AWS Profile (RECOMMENDED)
|
||||||
|
# 1. Configure credentials in ~/.aws/credentials or ~/.aws/config
|
||||||
|
# 2. Set BEDROCK_AWS_PROFILE to your profile name
|
||||||
|
# The AWS SDK will automatically use the profile's credentials
|
||||||
|
#
|
||||||
|
# Optional: Enable auto-refresh by configuring credential_process in ~/.aws/config
|
||||||
|
# Example:
|
||||||
|
# [profile your-profile-name]
|
||||||
|
# region = us-west-2
|
||||||
|
# credential_process = your-command-to-fetch-credentials --format json
|
||||||
|
#
|
||||||
|
# See: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
|
||||||
|
# For auto-refresh: https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-sourcing-external.html
|
||||||
|
#
|
||||||
|
# Option 2: Use static environment variables (NOT recommended for temporary credentials)
|
||||||
|
# Set BEDROCK_AWS_ACCESS_KEY_ID, BEDROCK_AWS_SECRET_ACCESS_KEY, BEDROCK_AWS_SESSION_TOKEN
|
||||||
|
|
||||||
# BEDROCK_AWS_DEFAULT_REGION=us-east-1 # A default region must be provided
|
# BEDROCK_AWS_DEFAULT_REGION=us-east-1 # A default region must be provided
|
||||||
|
|
||||||
|
# AWS Profile (Option 1 - RECOMMENDED)
|
||||||
|
# BEDROCK_AWS_PROFILE=your-profile-name
|
||||||
|
|
||||||
|
# Static Credentials (Option 2 - use only if not using profiles)
|
||||||
# BEDROCK_AWS_ACCESS_KEY_ID=someAccessKey
|
# BEDROCK_AWS_ACCESS_KEY_ID=someAccessKey
|
||||||
# BEDROCK_AWS_SECRET_ACCESS_KEY=someSecretAccessKey
|
# BEDROCK_AWS_SECRET_ACCESS_KEY=someSecretAccessKey
|
||||||
# BEDROCK_AWS_SESSION_TOKEN=someSessionToken
|
# BEDROCK_AWS_SESSION_TOKEN=someSessionToken
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,14 @@ const {
|
||||||
removeNullishValues,
|
removeNullishValues,
|
||||||
} = require('librechat-data-provider');
|
} = require('librechat-data-provider');
|
||||||
const { getUserKey, checkUserKeyExpiry } = require('~/server/services/UserService');
|
const { getUserKey, checkUserKeyExpiry } = require('~/server/services/UserService');
|
||||||
|
const { logger } = require('@librechat/data-schemas');
|
||||||
|
|
||||||
const getOptions = async ({ req, overrideModel, endpointOption }) => {
|
const getOptions = async ({ req, overrideModel, endpointOption }) => {
|
||||||
const {
|
const {
|
||||||
BEDROCK_AWS_SECRET_ACCESS_KEY,
|
BEDROCK_AWS_SECRET_ACCESS_KEY,
|
||||||
BEDROCK_AWS_ACCESS_KEY_ID,
|
BEDROCK_AWS_ACCESS_KEY_ID,
|
||||||
BEDROCK_AWS_SESSION_TOKEN,
|
BEDROCK_AWS_SESSION_TOKEN,
|
||||||
|
BEDROCK_AWS_PROFILE,
|
||||||
BEDROCK_REVERSE_PROXY,
|
BEDROCK_REVERSE_PROXY,
|
||||||
BEDROCK_AWS_DEFAULT_REGION,
|
BEDROCK_AWS_DEFAULT_REGION,
|
||||||
PROXY,
|
PROXY,
|
||||||
|
|
@ -20,28 +22,38 @@ const getOptions = async ({ req, overrideModel, endpointOption }) => {
|
||||||
const expiresAt = req.body.key;
|
const expiresAt = req.body.key;
|
||||||
const isUserProvided = BEDROCK_AWS_SECRET_ACCESS_KEY === AuthType.USER_PROVIDED;
|
const isUserProvided = BEDROCK_AWS_SECRET_ACCESS_KEY === AuthType.USER_PROVIDED;
|
||||||
|
|
||||||
let credentials = isUserProvided
|
let credentials;
|
||||||
? await getUserKey({ userId: req.user.id, name: EModelEndpoint.bedrock })
|
|
||||||
: {
|
|
||||||
accessKeyId: BEDROCK_AWS_ACCESS_KEY_ID,
|
|
||||||
secretAccessKey: BEDROCK_AWS_SECRET_ACCESS_KEY,
|
|
||||||
...(BEDROCK_AWS_SESSION_TOKEN && { sessionToken: BEDROCK_AWS_SESSION_TOKEN }),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!credentials) {
|
if (isUserProvided) {
|
||||||
throw new Error('Bedrock credentials not provided. Please provide them again.');
|
// User-provided credentials from database
|
||||||
}
|
credentials = await getUserKey({ userId: req.user.id, name: EModelEndpoint.bedrock });
|
||||||
|
|
||||||
if (
|
if (!credentials) {
|
||||||
!isUserProvided &&
|
throw new Error('Bedrock credentials not provided. Please provide them again.');
|
||||||
(credentials.accessKeyId === undefined || credentials.accessKeyId === '') &&
|
}
|
||||||
(credentials.secretAccessKey === undefined || credentials.secretAccessKey === '')
|
|
||||||
) {
|
if (expiresAt) {
|
||||||
|
checkUserKeyExpiry(expiresAt, EModelEndpoint.bedrock);
|
||||||
|
}
|
||||||
|
} else if (BEDROCK_AWS_ACCESS_KEY_ID && BEDROCK_AWS_SECRET_ACCESS_KEY) {
|
||||||
|
// Explicit credentials from environment variables
|
||||||
|
credentials = {
|
||||||
|
accessKeyId: BEDROCK_AWS_ACCESS_KEY_ID,
|
||||||
|
secretAccessKey: BEDROCK_AWS_SECRET_ACCESS_KEY,
|
||||||
|
...(BEDROCK_AWS_SESSION_TOKEN && { sessionToken: BEDROCK_AWS_SESSION_TOKEN }),
|
||||||
|
};
|
||||||
|
logger.info('[Bedrock] Using explicit credentials from environment variables');
|
||||||
|
} else {
|
||||||
|
// Use AWS SDK default credential provider chain
|
||||||
|
// This supports: AWS profiles, IAM roles, EC2/ECS metadata, SSO, etc.
|
||||||
credentials = undefined;
|
credentials = undefined;
|
||||||
}
|
if (BEDROCK_AWS_PROFILE) {
|
||||||
|
logger.info(
|
||||||
if (expiresAt && isUserProvided) {
|
`[Bedrock] Using AWS credential provider chain with profile: ${BEDROCK_AWS_PROFILE}`,
|
||||||
checkUserKeyExpiry(expiresAt, EModelEndpoint.bedrock);
|
);
|
||||||
|
} else {
|
||||||
|
logger.info('[Bedrock] Using AWS credential provider chain with default profile');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -84,6 +96,11 @@ const getOptions = async ({ req, overrideModel, endpointOption }) => {
|
||||||
llmConfig.credentials = credentials;
|
llmConfig.credentials = credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pass AWS profile to the SDK if specified and no explicit credentials
|
||||||
|
if (!credentials && BEDROCK_AWS_PROFILE) {
|
||||||
|
llmConfig.profile = BEDROCK_AWS_PROFILE;
|
||||||
|
}
|
||||||
|
|
||||||
if (BEDROCK_REVERSE_PROXY) {
|
if (BEDROCK_REVERSE_PROXY) {
|
||||||
llmConfig.endpointHost = BEDROCK_REVERSE_PROXY;
|
llmConfig.endpointHost = BEDROCK_REVERSE_PROXY;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue