RESTful API auth basics for a single client

I have an AWS lambda function that gets triggered by a 3rd party service, processes some data, and then sends a POST request to an endpoint in my phoenix app.

I’d like to protect my endpoint so that it only works when requests come from my lambda function.

What’s the conventional approach to this?
Would I generate a token with Phoenix.Token and then hardcode that value into my lambda function’s request header when making the POST request?

That makes sense to me but I’m pretty wet behind the ears in this department and a lot of the resources out there allude to user login auth flows that respond with a token after a successful login request. But I’d like a flow that works more akin to the way we interact with 3rd party APIs where we must config a secret key in order to access them.

That’s one way to do it. Although you want to make sure you are using HTTPS. The only issue is that the repeated use of the token could expose from a security standpoint. As an extra measure, maybe you can filter requests by IP?

1 Like

Yah, I guess it would behoove me to change it every so often.

It looks like I’d have to set up a VPC in AWS and jump thru a few hoops in order to get a static IP from my lambda function so I’ll probably shy away from that for now.

Thanks for the advice! :slightly_smiling_face:

The way I’ve done it before (it was not Elixir but everything should apply) was to set an environment variable on the lambda function env, that it then used when sending the request to the service. Then on the service have that set as an accessible env variable to it as well. Whenever a request would arrive it would check if it contained an header with the correct value. This means you could change it by simply changing the env vars in both the lambda and the back-end. If you’re ok with a minimal interruption of the service when changing the “secret”, or you don’t intend to change it often at all, that’s a simple and ok way to do it (or having a script that updates the function env, and the back-end designed in a way that it allows to update it’s env)

Other way, that is more robust would be to store it as an item in S3, grant your lambda function access to that bucket & key, retrieve the value from it at function startup and use it on each request. On your back-end you would do the same and then whenever you need to change the “secret” you change the S3 item.

If it’s a very high throughput function you might look into ways of caching the S3 request and so on if you really need it, like you can write a trigger that whenever that item in the bucket is changed it fires another lambda that ensures the original function is stopped - so that it can pick the change in case it isn’t “sleeping”, and also issues a request to your backend so it refreshes its own version - e.g. fetches the new version from S3).