Enhance the access protection security model
Closed this issue · 0 comments
Challenge
The current access protection model knows two types of access: public
and private
. When setting the deployment model to a scaled model, these types are not enough.
Public
functions can always be called from any segment, regardless of their location (front end or backend). Private functions cannot be called from any other segment. This model does not support the use case where trusted clients, i.e. backend nodes, can call functions from other segments, but untrusted clients, i.e. front ends, cannot.
To support this use case we need to extend the access protection model. A protected
identifier could be added to fuctions to indicate that these can be called from trusted clients, but not from any untrusted client.
Solution description
A mechanism to trust clients need to be implemented. We could use a simple strategy where a sectet / trust key is configured in the gateway / node configuration, and checked during startup. The configuration could look like the following.
// services/gateway.json
{
"gateway":
{
"SECRET_KEY": "ThisVerySecretKey"
}
}
For each trusted client, we also need to set this key in the node configuration.
// services/node.json
{
"node":
{
"TRUST_KEY": "ThisVerySecretKey"
}
}
When the gateway starts, the key is stored in the configuration and used to verify incoming requests on the /nodes
path.
When a node tries to connect to the gateway on startup, the gateway needs to check if the key that is provided is valid. If the secret is not known, then the node won't be allowed and a forbidden will be returned. In case the node doesn't have a key, it will be allowed as an untrusted client.
After a node is started, the gateway could provide a new secret to the node for access to protected functions, or we can start with the same key for now. The front end is not able to register itself as a node, and thus won't be able to be acknowledged as a trusted client. And any regular call to the gateway won't reveal the secret.
The trust of a client is not kept as a list in the gateway for now. The gateway will look for the header X-Access-Key
and checks this key with its secret key. If that is a match, the protected
functions will also be available for execution. If the header is missing, then only the public
fuctions are considered. And in case the key is incorrect, the gateway will return a forbidden exception.
To get the key to the gateway, the Remote
needs to set this header. It will set the X-Access-Key
header with the value of the trust key from the configuration, or the new secret that the gateway returned at startup. A fixed key has the advantage that if the gateway gets restarted for whatever reason, the keys are still valid and not all nodes need to get restarted as well.
To indicate a function is protected
, the keyword needs to be added to the list of acceptable values in the segment configuration.
// segments/node.json
{
"./domain":
{
"sayPublic": { "access": "public" },
"sayPrivate": { "access": "private" },
"sayProtected": { "access": "protected" }
}
}