I have a NodeJS API on Amazon EB and an API on API Gateway.
API Gateway is configure as a proxy to EB.
I can call my API without problem, it's working but I don't know how to manage security.
Actually if I use the API Gateway URL I must sign the request (it's ok!) but I can use the EB URL and nothing is necessary.
Before using API Gateway I was using JWT but now what shall I do on my Node app? API Gateway is using the Authorization header for sign the request, so my Node app must check this signature maybe? Or something else?
The recommended approach to restricting back end access to only API Gateway is to use client side certificates. See documentation here
Note that if using client certificates with ELB, you must configure the ELB in tcp mode and terminate the SSL connection on your application server as ELB does not support client certificate validation.
An alternate approach is to configure your API Gateway to add a header with a secret value and then validate the value on your application server before processing the request. This is generally considered less secure, since its easier for an attacker to obtain your secret value. At a minimum, you would want to use SSL between your API Gateway and your application server so the secret isn't sent in plain text.
Related
I have setup and application which uses a React front-end and Expres/NodeJS back-end. There is an ALB in the mix as well.
So, here is how the flow goes:
The ALB listens on port 443 and there is an Authentication action attached to the listener. This action uses and Amazon Cognito user pool, scope is openid. Once the authentication is successful the ALB redirects the request to the React app which in it's turn sends http requests back to the ALB which redirects them to the Express app on the server-side. I have setup the communication between FE and BE like this because we use Amazon ECS and I don't have a static DNS or IP except for the ALB.
I am unable to get the x-amzn-oidc-data header when console logging the req.headers. This header is important to me because I'd like to verify and work with the JWT that it contains.
I have read most of the docs on the Internet and they say that the ALB automatically sends this header (and couple of others) to the back-end. However, I only see one x-amzn-trace-id which has nothing to do with the JWT issued by Cognito.
Where do you think is my error? My setup seems pretty standard to me - how could I get that header?
Thanks in advance!
I am planning on building a K8s cluster with many microservices (each running in pods with services ensuring communication). I'm trying to understand how to ensure communication between these microservices is secure. By communication, I mean HTTP calls between microservice A and microservice B's API.
Usually, I would implement an OAuth flow, where an auth server would receive some credentials as input and return a JWT. And then the client could use this JWT in any subsequent call.
I expected K8s to have some built-in authentication server that could generate tokens (like a JWT) but I can't seem to find one.
K8s does have authentication for its API server, but that only seems to authenticate calls that perform Kubernetes specific actions such as scaling a pod or getting secrets etc.
However, there is no mention of simply authenticating HTTP calls (GET POST etc).
Should I just create my own authentication server and make it accessible via a service or is there a simple and clean way of authenticating API calls automatically in Kubernetes?
Not sure how to answer this vast question, however, i will try my best.
There are multiple solutions that you could apply but again there is nothing in K8s for auth you can use.
Either you have to set up the third-party OAuth server or IAM server etc, or you write and create your own microservice.
There are different areas which you cannot merge,
For service interconnection service A to service B it would be best to use the service mesh like Istio and LinkerD which provide the mutual TLS support for security and are easy to set up also.
So the connection between services will be HTTPS and secured but it's on you to manage it and set it up.
If you just run plain traffic inside your backend you can follow the same method that you described.
Passing plain HTTP with jwt payload or so in backend services.
Keycloak is also a good idea to use the OAuth server, i would also recommend checking out Oauth2-proxy
Listing down few article also that might be helpful
https://medium.com/codex/api-authentication-using-istio-ingress-gateway-oauth2-proxy-and-keycloak-a980c996c259
My Own article on Keycloak with Kong API gateway on Kubernetes
https://faun.pub/securing-the-application-with-kong-keycloak-101-e25e0ae9ec56
GitHub files for POC : https://github.com/harsh4870/POC-Securing-the--application-with-Kong-Keycloak
Keycloak deployment on K8s : https://github.com/harsh4870/Keycloack-postgres-kubernetes-deployment
Currently doing some research to setup an (azure) api gateway with oauth (jwt token) security.
an external partner/app sends a request to an api endpoint published on the gateway including a valid JWT-token in the header that gets validated by the gateway against AzureAD for example. When validated the request is routed to the backend service. No problems here.
My question is, what is best practice for the external app to obtain that JWT-token (to use for the api call) ?
Obviously, It could send a request to AzureAD with a clientid+secret to obtain a valid JWT token. But to do so it has to call my internal AzureAD directly ? Is this the way to do it ?
or should I expose a 'get-jwt-token' api on my api gateway and route that request to AD ? How should I secure that API ? with basic auth ?
or am I missing something, and is there a much better best/proven practice ?
HOSTING BEST PRACTICE
A reverse proxy or API gateway is placed in front of both APIs and the Authorization Server (AS). This ensures that an attacker who somehow gains access to the back end entry point cannot access data sources.
OAUTH REQUESTS TO GET TOKENS
OAuth requests are typically proxied straight through the reverse proxy / API gateway to the AS with no extra logic. All credentials, auditing of login attempts etc remain in the AS.
MANAGED SERVICES
If using Azure AD as a cloud managed AS, this is a special case: the system is already hardened for internet clients, so most companies don't add their own proxying - though it is possible to do so.
FURTHER INFO
The first of these covers the infra setup and the second gives you an idea of extensibility options once a reverse proxy / gateway is in place.
IAM Primer
API Gateway Guides
I have currently configured express-gateway to communicate with a service on my backend exposed on a unique port on my machine and it's working fine. The gateway serves as a proxy to the services and currently does some security checks and jwt authentication. Then, only authorized request (through jwt validation) gets sent to services as configured. However, I'm concerned that if I don't put some sort of authentication on my service, then anyone who knows the port (or URL) my service runs on can directly access it and bypass the gateway directly. I'm looking for a way I can set up a sort of auth between the gateway and the service (maybe through keys) so that only the gateway can communicate with the services and not any other client. I currently can't find anything in the docs specifically for that. Also, if there's something wrong with my architecture, I'd appreciate it if you could point it out. Thank you.
The path between Express Gateway and your back end should be on a private, encrypted network so there is no way for anyone to bypass the gateway.
With this architecture, you don’t need to authenticate on the server side, and if you use Express Gateway scopes, you don’t even need to check whether the user is authorized to perform the requested action.
I have a Node js backend. I use OAuth 2 for authentication. All the endpoints are secured by this authentication method except one endpoint. I cannot use OAuth in this insecure endpoint because the endpoint is triggered by another server on which I don't have any control. So I cannot tell the other server to send me a token for my backend to validate.
The request to my backend is made with SSL connection. So, in Nodejs is there any way to find out the SSL issuer name or something like that so that my backend can validate the requester? (All the requests to my insecure endpoint comes from the same server)