Background:
This is the architecture of the platform I'm working on:
The API has several secured endpoints for accessing the database. Users login on the Front End with their credentials, and if they're valid the API returns a JSON Web Token (JWT). The JWT is generated using a secret symmetric key.
The API does not know the servers, but the servers know the API. Meaning, there could be one or many servers, but I would like to avoid updating the API with a list of all available servers.
The Problem:
There are several servers that run applications that need to make calls to the API. Currently, the way that this is being done is that each application on the server has the secret key, and creates its own JWT with it. Then that JWT is sent on the request to the API, granting access to proceed with the request.
This is obviously not ideal since the secret should exist only in one spot, and only be used by the API itself. Also, it significantly increases the risk of exposure, since the number of servers is going to grow.
Looking over this question, it seems like it may be the way to go (the server makes a request to the API, the API returns a JWT, the server then uses that JWT) - however, how do I know that the server is one of the ones I should allow access to?
The Question:
Is there a tried-and-true way to authenticate these servers without sharing the secret key? Could public/private keys be used for authentication?
Since the API does not keep track of the servers, could a server provide some data to the API which would identify them as a valid server to communicate with? Or is a white list unavoidable at this point?