-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Specification
In some AgentService handlers we need to be able to verify the connecting node information such as the NodeId, certificates and connection information. Since the ForwardProxy
<->ReverseProxy
connection uses mTLS to ensure a secure connection we can obtain this trusted information from the ReverseProxy
.
We need to copy and adapt the authenticator
implementation from the client/utils. it should be called getTrustedConnectionInfo
. This needs to fetch the connection info from the ReverseProxy
. The ReverseProxy
provides the ReverseProxy.getConnectionInfoByProxy()
method for fetching this information. The information will take this form.
type ConnectionInfo = {
nodeId: NodeId;
certificates: Array<Certificate>;
egressHost: Host;
egressPort: Port;
ingressHost: Host;
ingressPort: Port;
};
Within the handler we can obtain the the host and port of the incoming address by using call.getPeer()
This will return the address information in the form of host:port
. This can be used to look up the information from the ReverseProxy
.
Usage
The fix for this introduced a connectionInformationGetter
to the agent service container. This allows you to access it within the service handlers by doing ...
function echo({
connectionInfoGetter,
}: {
connectionInfoGetter: ConnectionInfoGetter;
}) {
return async (
call: grpc.ServerUnaryCall<utilsPB.EchoMessage, utilsPB.EchoMessage>,
callback: grpc.sendUnaryData<utilsPB.EchoMessage>,
): Promise<void> => {
const connectionInfo = connectionInfoGetter(call);
if ( connectionInfo == null) throw new agentErrors.ErrorConnectionInfoMissing();
// ...
};
}
If it can't find the respective connectionInfo connectionInfoGetter
will return undefined but during normal operation when connecting through the proxies this should never happen. You can't obtain any information when connecting directly bypassing proxies. this only happens in testing so far.
connectionInfoGetter
takes the call
as a parameter. It uses call.getPeer()
to get the connection info. This should be parsed as a URL to handle it more robustly. The format of call.getPeer()
is usually Host:Port
but it can be protocol://Host:Port
.
When using connectionInfoGetter
we need an error for when we fail to obtain the ConnectionInfo
. ErrorConnectionInfoMissing
error needs to be created for this. Likely use the sysexits.UNAVAILABLE
exit code in this case.
Additional context
- Relevant discussion found from comments Redesign usage of CDSS with
VaultInternal
#305 (comment) to Redesign usage of CDSS withVaultInternal
#305 (comment). - Session Bin Test Fixes #296 (comment)
- Related Introducing vault sharing and the restrictions of pulling and cloning with vault permissions #266
- Blocking Redesign usage of CDSS with
VaultInternal
#305
Tasks
- 1. create a
getTrustedConnectionInfo
utility that mimics the use ofauthenticator
inclient/utils
.- It needs to take in the call directly as a parameter.
- It needs to handle the peer information as a URL
- when used if the connectionInfo is required by the handler. It should throw an
ErrorConnectionInfoMissing
error. - It needs to fetch and return the connections trusted
ConnectionInfo
fromReverseProxy.getConnectionInfoByProxy()
- It needs to be provided to the service handlers via the
createService(container)
parameter similar to how the clientauthenticator
works
- 2. testing
- We can obtain the connection information
- Add test for multiple connections at a time to check if the proxy information is different for each.