REST API and CDN for audio streaming - api

I'm facing a bandwith issue on a server that hosts a REST API and I wondered if I could use a CDN to fix it.
Most of the bandwith consumption is due to static assets provision, like audio files.
Access to those assets requires an authentication token (JWT like).
When the user requests for an asset, I first need the API to do some checkups, and then streams an audio file.
A CDN appeared to me as an ideal solution, but it raised two questions :
Can I keep my static audios behind a JWT authentication if they are stored on a CDN ?
Is it possible to redirect the original request to a dynamic link provided by the CDN, and specifically ask for streaming and not raw download ?
Thanks for your time and advices

If you want basic API authentication for CDN request then most CDN's support mechanism to do this - for example the Akamai information is here:
https://techdocs.akamai.com/api-definitions/docs/json-web-token-jwt-val
Answering the second question, so long as the CDN and your client support range requests then you should be able to download chunks, if you are using basic HTTP progressive download type streaming.
If you are using HLS or DASH streaming then nearly all CDN's will support this as standard.

Related

Sveltekit how to call an api with a token

I currently have an API running on Nodejs Express where you can get or upload all types of files (images, videos...) as well as simple json responses.
I would like to connect Sveltekit to this API but it is secured with a SSO so I need to provide an access token for each request.
I already get the access token from the SSO (oidc) on sveltekit.
Solution 1:
a service workers intercept requests to the API and add the access token.
Problems: I don't want to build every time but as the documentation says: service workers only work in the production build, not in development
Solution 2:
send requests to the svletekit backend and then pipe them to the API with the access token
Problems: Works only for basic requests but not for stream, it seems that it is supported recently (https://github.com/sveltejs/kit/issues/5344) but there is no documentation or example and this solution requires more resources (requests should be from the browser to the api)
Solution 3:
Hooks externalFetch
This function allows you to modify (or replace) a fetch request for an external resource that happens inside a load function that runs on the server (or during pre-rendering).
Problems: It doesn't work for requests like the src of an image
Any idea ?
edit: Solution, with the new version of sveltekit node-fetch has been replaced by Undici and the streams are functional, so it is possible to pipe requests from the backend.
For the dev it work well but it's not the best solution for production so you can use both depending on the environnement.

How to restrict api gateway rest api to CloudFront hosted S3 website

I have hosted a S3 static site into CloudFront. That site using rest api deployed into api gateway. API gateway has not access control.
I want to protect my api from being accessed by others. Only my static site can access it. I know I can use api key but that could expose by browser console which is not expected.
Is there other way to control my api access?
Thanks in advance
I have a similar issue as well. It seems like using referer or CORS restrictions are the best way to go. However, in practice I haven't been able to make it work after trying both CORS and referer restrictions. API Gateway has automatic protection against malicious behavior like DDOS attacks according to their FAQs, but it is disheartening that I haven't found a specific solution for protecting my API gateway that is only used for my S3/Cloudfront static site.
Google Cloud allows you to use their API keys on the frontend for integrations with services like Google Maps. The way they protect those keys is through restricting the API keys to certain domains. Unfortunately, I haven't found similar functionality for AWS keys. As you know, the only way to throttle or put quotas on API gateway is through API keys, so it looks like this would be useless for a static site that can't expose those API keys publicly on the frontend.
It defeats the whole purpose of going completely serverless if I am unable to configure my serverless API Gateway the same way I could congfigure a normal backend EC2 server. For now, I've created billing alarms so I don't get surprised with a huge AWS bill if something goes wrong with my unprotected API gateway.

Verifying Origin of HTTP Request

Scenario:
Say I have a RESTful http(s) API running somewhere exposed on a public IP+port, and now I want to make a simple front-end that interacts with this API.
Constraint: I want to use GitHub Pages to serve the front-end, and I would like to make the repository public.
Question: Is there a way to design the API such that only calls originating from the gh-pages website will be successful? That is, if someone were to fork the repository and run their own version of the front-end, could the API notice that the call does not originate from the "official" gh-pages site? I'm really wondering if there is something I can provide in the API call that would prove that the caller is calling from a certain, predetermined place.
If the front-end can be privately hosted I could have a shared secret stored on both servers and use that to authenticate, but I would ideally want to be able to host this via GitHub pages (removing the need to maintain a server my self). Can I somehow use the fact the gh-pages site would have a proper certificate from Github? Or would this certificate be available for all gh-pages sites similarly, and hence not useful to determine origin?
I hope the question is clear, any input would be very much appreciated!
The assumption that the requests are made from gh-pages is wrong. The requests are made from the user's ip browser. Any user will load the contents of a web page in the browser from your own repository or from a fork repository, but the requests to the API will be created from the user's browser.
By default, the browser will not allow requests to an api on a different domain than the one where the html is loaded from. So, loading content from https://pages.github.com/ and requesting your own private server will fail, as it will be on a different domain (see CORS), but there are many ways to avoid this (see Cross-Origin Resource Sharing on GitHub Pages).
So, as long as CORS is enough for you (see above link how to enable requests to your api), you should not worry. Otherwise, there is not much you can do, but authorize the customers.
Is there a way to design the API such that only calls originating from the gh-pages website will be successful?
No.
The only information you have is what the client chooses to tell you.
A client might send a referer header. A custom client definitely can lie about that.

Cloud storage services and session-based file-URLs

I have the following use-case that I am seeking a solution for:
Our website shares files to our clients. The files are stored on a 3rd party cloud service, the file access permissions on our website. When a client on our site requests a file that he has permission to see, it will be served directly from the cloud service (instead of through our own webserver, using our CPU, RAM and bandwidth).
I see services like Amazon S3 and Google Cloud Storage use an approach with a signed URL with a timeout for this purpose, but I would prefer a solution where that URL is only available to the client who requested the resource (and not everyone who has the link during the lifecycle of the URL). The reason for this is that it feels wrong to rely on a duration based un an arbitrary length instead of utilizing a one-time token or in any other way validate the access to the resource before the request is completed.
Does any of the major services provide a feature that would allow for this? Or is it considered "safe enough" to protect sensitive data behind a random URL + timeout period (to me it feels like the answer to the latter is "no")?

Prevent certain referrers from using my oAuth API

According to my Google API console my top referrer is https://www.googleapis.com which I assume is normal, but it's followed closely by http://blocvox.com which I don't know what they are and I am suspicious as to why they are consuming a lot of my requests and jeopardizing my capped usage.
How can I prevent this referrer from accessing my API?
Note: I am not using an API Key (which does support the blocking of referrers) I am using the oAuth method.
The details depend on what your API is written in, but most popular Web frameworks allow you to look at the referrer value for the HTTP request. You could go further; most Web front-end servers allow you to filter/discard/reject/redirect queries based on the referrer field.