How to store client secrets?

Hi, I am creating azure storage file upload feature and I need to keep my tokens as a secret. In the documentation is written that it is not a good idea to keep secrets in env variables. What would be the best practice to keep secrets without using any cloud secrets service?
6 Replies
martinsos
martinsos7mo ago
Hey @Manol T. ! File uploading can be a bit complex (I implemented it in the past, with AWS though, maybe also with Azure can't remember exactly). There are two main ways to do it: 1. User uploads a file to your client, your client(frontend) then sends it to your server(backend) and then your server uploads it to Azure. In this case, what you need is a secret token on the server, via which server will show to Azure that it has the rights to send files to it. And you would normally store this secret token in the ENV var available to the server. 2. User uploads a file to your client, but you don't send that file to your server then, instead your client sends it directly to Azure. In order to be able to do that, it needs to ask your server first to generate a temporary secret that will allow it to do this operation. It usually needs to tell server where it wants to upload the file and its name, and maybe some more details. Then, your server issues your client with a short-lived secret token that can be used only for this specific upload. Client then presents this to Azure while sending file to it, and Azure permits it. In general, approach (2) is better, because it doesn't load your server with the file upload. Imagine if you had 100 users wanting to upload a file at the same time: if using approach (1), there will be 100 files being sent to your server, which you are hosting -> ay yay! But with approach (2), your server will just issue 100 temporary secret tokens (which are quick and easy to do) and then the upload will be happening toward Azure's servers. So it is faster and more efficient and saves your server from unneccessary load. Now, what confused me a bit with your question is: 1. You mention "client secret" in the title. Why "client secret"? Actually there can't really be client secrets, you can't store secret on a client. Unless this is referring to those temporary secret tokens that server issues to a client? 2. The docs say it is not a good idea to keep secrets in env variables -> is this mentioned in Azure docs? What are the alternatives they are suggesting, and what are the arguments they presented? Maybe it would be best if you could share that piece of Azure docs so I can give it a look?
Manol T.
Manol T.7mo ago
hello, I am sorry for the late reply. I began integrating the azure blob uploading feature. this is a sample documentation: https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blob-upload-javascript
Upload a blob with JavaScript - Azure Storage
Learn how to upload a blob to your Azure Storage account using the JavaScript client library.
Manol T.
Manol T.7mo ago
this part: https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blob-javascript-get-started?tabs=azure-ad#create-blobclient-directly where they upload the file, but i use SaS token (the last tab). There's discrepancy in the source code, in the part for SaS they do not have an uploading code, The thing is, i should convert the file object into a stream either a text content / array buffer. Unfortunately I am not aware how to acheieve this trhough react
Get started with Azure Blob Storage and JavaScript - Azure Storage
Get started developing a JavaScript application that works with Azure Blob Storage. This article helps you set up a project and authorizes access to an Azure Blob Storage endpoint.
Manol T.
Manol T.7mo ago
this is my curernt implementation: const uploadFileToBlob = async (data) => { if (!(data.file && data.file.length > 0)) { return; }
const file = data.file[0]; const fileName = await fileUpload(file, 'bookgpt'); console.log(fileName); };
async function fileUpload(file, containerName) { try { let storageAccount = "bookgpt"; const sasToken = encodeURI('sas token here');
const blobService = new BlobServiceClient( https://${storageAccount}.blob.core.windows.net?${sasToken} );
const containerClient = blobService.getContainerClient(containerName); const blobName = encodeURIComponent(file.name); const blobClient = containerClient.getBlockBlobClient(blobName);
const options = { blobHTTPHeaders: { blobContentType: file.type, 'Access-Control-Allow-Origin': '*', }, };

const fileData = await readFileDataAsBinaryString(file); console.log(fileData); const uploadBlobResponse = await blobClient.uploadData(fileData, options); console.log("Blob was uploaded successfully. requestId: ", uploadBlobResponse.requestId); const fileString = https://${storageAccount}.blob.core.windows.net/${containerName}/${blobName}; return fileString;
} catch (error) { console.error("Error uploading file to Azure: ", error); throw error; // Or handle the error as needed } } I am able to upload a file through curl request by passing the file directly to curl, but i didn't manage to make the react part working ..
Manol T.
Manol T.7mo ago
hey, @martinsos , here's the working code for azure: https://github.com/AIAccelerator/BookPlanner/commit/d944956e991179857a3301e40f3819f7bcb3c059 My primary issue with the access in Azure - it was set to private and I wasn't able to uplaod there. As a second thing, my SaS token (the access token) didn't have writing rules. It was a matter of deeper understanding how the azure storage works (although i work with it for a first time). thanks for the help!
martinsos
martinsos7mo ago
Ah, so you got it working! Awesome! Sorry for a bit late response, but I am glad you solved it in the meantime. I remember now, I actually implemented uploading to Azure Blob some years ago, but I don't remember all the details, would need to do some refreshing. I see that you have a server logic that generates SAS token and then client obtains it and uses it do to the uploading -> that sounds good! I believe you can removeUser from entities: [User] for query generateSasToken since it doesn't really return anything related to User. In the future we plan to add functionality to Wasp where we offer the functionality of uploading files already implemented for you, but it will probably take us some time to get there!