-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement: AWS S3 Support (with IRSA option) #2898
Comments
firebase is already an option for images, from which you can apply similar policies, and S3 support is planned. It would follow the same dependency injection pattern as firebase. Since the main concern seems to be the ability to store and retrieve images using AWS S3, which is planned, I'm renaming this issue as such. I will keep IRSA in mind as an authentication method to implement for this. |
Our company needs this for file uploads. S3 is generally what we use, and we don't support Firebase or Kubernetes persistent volumes. |
@tip-dteller @jameslamine please have a look at my PR will this work for you both? I'm happy to receive some feedback. |
@rubentalstra looks good! Thank you! |
@d-teller AWS ROLE? Can you explain it a little more? |
@rubentalstra AWS, apart from users, access keys and secret keys. You should utilize roles. Roles can be attached to ec2 machines, ecs, k8s service account. The code needs to be abls to draw that information. Here's a generated claude example import { AssumeRoleCommand, STSClient } from "@aws-sdk/client-sts";
import { S3Client, ListBucketsCommand } from "@aws-sdk/client-s3";
async function assumeRoleAndListBuckets() {
// Initialize STS client
const stsClient = new STSClient({ region: "us-east-1" });
// Define parameters for assuming a role
const params = {
RoleArn: "arn:aws:iam::123456789012:role/example-role",
RoleSessionName: "example-session",
DurationSeconds: 3600, // 1 hour
};
try {
// Assume the role
const assumeRoleResponse = await stsClient.send(new AssumeRoleCommand(params));
if (!assumeRoleResponse.Credentials) {
throw new Error("Failed to obtain credentials");
}
// Create S3 client with temporary credentials from assumed role
const s3Client = new S3Client({
region: "us-east-1",
credentials: {
accessKeyId: assumeRoleResponse.Credentials.AccessKeyId!,
secretAccessKey: assumeRoleResponse.Credentials.SecretAccessKey!,
sessionToken: assumeRoleResponse.Credentials.SessionToken!,
},
});
// Use the temporary credentials to list S3 buckets
const bucketsResponse = await s3Client.send(new ListBucketsCommand({}));
console.log("Buckets:", bucketsResponse.Buckets);
return bucketsResponse.Buckets;
} catch (error) {
console.error("Error:", error);
throw error;
}
}
// Call the function
assumeRoleAndListBuckets()
.then((buckets) => console.log(`Found ${buckets?.length || 0} buckets`))
.catch((err) => console.error("Operation failed:", err)); This example demonstrates:
|
@d-teller thank you for the explanation. but are these roles not assigned to the machine it self? and not the application? this is what I have written so far for the IRSA and non-IRSA the docs I written: https://github.com/LibreChat-AI/librechat.ai/blob/fc0ce22a53f5b87732ea2b3b1a08571b87a54b83/pages/docs/configuration/cdn/s3.mdx const { S3Client } = require('@aws-sdk/client-s3');
const { logger } = require('~/config');
let s3 = null;
/**
* Initializes and returns an instance of the AWS S3 client.
*
* If AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are provided, they will be used.
* Otherwise, the AWS SDK's default credentials chain (including IRSA) is used.
*
* @returns {S3Client|null} An instance of S3Client if the region is provided; otherwise, null.
*/
const initializeS3 = () => {
if (s3) {
return s3;
}
const region = process.env.AWS_REGION;
if (!region) {
logger.error('[initializeS3] AWS_REGION is not set. Cannot initialize S3.');
return null;
}
const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
if (accessKeyId && secretAccessKey) {
s3 = new S3Client({
region,
credentials: { accessKeyId, secretAccessKey },
});
logger.info('[initializeS3] S3 initialized with provided credentials.');
} else {
// When using IRSA, credentials are automatically provided via the IAM Role attached to the ServiceAccount.
s3 = new S3Client({ region });
logger.info('[initializeS3] S3 initialized using default credentials (IRSA).');
}
return s3;
};
module.exports = { initializeS3 }; |
@rubentalstra roles offer a way to communicate with AWS STS service, so that you get temporary credentials, hence roles are assigned to EC2 machines (as instance profile option), to ECS via execution role and to K8s via IRSA. |
Do I understand correctly that with this PR we'll be able to get Code Interpreter to read/write files from/to S3, so we could e.g. store input CSVs for Code Interpreter and output plots from it in S3? Sorry for many questions, I'm trying to understand whether this PR covers everything we're looking for or not. |
Yes but let me clarify. For the Code Interpreter to read files, it needs to be uploaded to its internal ephemeral storage. The actual file is uploaded locally (currently, only Firebase as the alternative, but with this update, also S3) to re-upload once those file references expire in the API's ephemeral storage. Outputs from the API are then stored locally/Firebase/S3.
In general, only images are currently referenced as is (static) in the chat context. When uploading to File Search (RAG API), the file is not kept and transformed to vectors, and I already explained the Code Interpreter behavior.
No, MCP tools have opinionated way of updating files and mainly corresponds to MCP resources. In general, this update mainly concerns storage of images and code interpreter files for re-upload, and eventually other file types that would be stored locally by default, as there are upcoming features to support general file storage for extended use cases such as parsing text, and uploading files directly to LLM providers. |
What features would you like to see added?
When generating images or even python plots, images are stored to disk, which can be mounted to any location.
IconURL however points to anything external .i.e Github.
So when trying to use an S3 address, inherently it fails because the call never goes to AWS, but instead goes through outside the network. (Private trying to access Public).
This was observed in Kubernetes deployment of LibreChat.
Also I believe that storing images on s3, for all intents and purposes, would be better for historical purposes.
If a pod or container suddenly goes down, and the images aren't mapped properly you'd simply lose them.
Can you please add support for IRSA?
I know this requires some code additions.
More details
Example Trust Policy:
Example Policy:
The user that will deploy, ideally. should have base knowledge of K8s and how to utilize a serviceAccount.
Which components are impacted by your request?
General
Pictures
No response
Code of Conduct
The text was updated successfully, but these errors were encountered: