La red de interoperabilidad PISEE es una red para los órganos de la administración del Estado (OAE). Sin embargo, ante la necesidad de conectar entidades privadas a los servicios de interoperabilidad que un OAE provea, es que los Nodos de interoperabilidad de la red PISEE tienen la capacidad de permitir esa conexión con la misma tecnología y cumpliendo las mismas medidas de ciberseguridad que utilizan los nodos entre ellos.
A continuación se describe el procedimiento de habilitación, la administración de conexiones y los aspectos principales del protocolo de comunicación empleado para que el intercambio de datos entre OAEs y entidades privadas sea segura, regulada y factible.
En el Nodo que provee los servicios es necesario habilitar un puerto para el protocolo MPGA-2 y asegurar que ese puerto sea visible.
"servidores": {
"interno": {
"puerto":"8084",
"tps": 2,
"backlog": 2
},
"externo": {
"puerto":"8489",
"puerto_mpga2": "8450"
}
},
Usando el Nodo del OAE que provee el servicio cree a la entidad privada que necesita dar acceso.
Esto se hace con el comando privados crear.
./NodoV2 privados crear \
-e "codigo_entidad_privada" \
-n "Nombre de la entidad privada" \
-s "NombreServicioAProveer"
Este comando crea un archivo .ZIP con todo lo necesario para que el privado se conecte.
Por ejemplo si se ejecutó el siguiente comando:
./NodoV2 privados crear \
-e "umbrella" \
-n "Umbrella Corporation" \
-s "consultaNemesisT"
Se creará el archivo: umbrella.zip el cual contiene:
Un archivo de configuración con la llave privada de firma, los datos de la entidad privada y la ruta del servicio al cual se quiere acceder. (conf.yaml)
Ahora es posible compartir ese archivo ZIP a la entidad privada que desea consumir los servicios.
Habiendo generado, desde el OAE proveedor del servicio, el archivo ZIP de la entidad privada ahora esta organización puede conectarse al servicio del OAE siguiendo el protocolo MPGA-2 (véase punto 5), para lo cual se ofrece un código de ejemplo que realiza la conexión y que puede ser adaptado en los software de la entidad privada.
Descarga de código de ejemplo (Go language)
Con este ejemplo la entidad privada puede probar la conexión al servicio.
La conexión a los servicios del OAE es responsabilidad de la entidad privada y debe implementar en sus propios software el código necesario para realizar esa conexión. Sin embargo la entidad privada puede utilizar el código de ejemplo o una adaptación de este como parte del código de su propio software para integrarse.
El código de ejemplo provisto sirve de guía pero cada entidad privada es responsable de la implementación de la conexión en su software.
En el código de ejemplo es necesario rellenar esta sección con los datos del mensaje a enviar indicando el body, cabeceras, path y query params de la llamada.
func main() {
...
// ------------ Define el mensaje a enviar ---------------
cabeceras["content-type"] = "application/json"
//ej. queryParams["dato"] = "valor"
pathParams["codigo"] = "PE-SUB-00031" //pathparam
metodo = MethodType_GET
mensaje = ""
// -------------------------------------------------------
En este ejemplo manda un llamado GET con un pathparam, sin queryparams y sin body.
Para poder administrar las entidades privadas que se conectan a un Nodo de interoperabilidad se deben utilizar los comandos del Nodo.
Comandos:
crear Crear una nueva entidad privada y el archivo
.ZIP con sus credenciales. (véase punto 2)
./NodoV2 privados crear \
-e "codigo_entidad_privada" \
-n "Nombre de la entidad privada" \
-s "NombreServicioAProveer"
autorizar Autoriza el consumo de un servicio web/api
para una entidad privada existente.
./NodoV2 privados autorizar \
-e "codigo_entidad_privada" \
-s "NombreServicioAProveer"
desautorizar Desautoriza el consumo de un servicio para una
entidad privada ya existente
./NodoV2 privados desautorizar \
-e "codigo_entidad_privada" \
-s "NombreServicioAProveer"
eliminar Elimina una entidad privada de la lista de
entidades privadas que se pueden conectar al
Nodo
./NodoV2 privados eliminar -e "codigo_entidad_privada"
listar_entidades Lista todas las entidades privadas que pueden
conectarse a este Nodo.
./NodoV2 privados listar_entidades
(para información más completa)
./NodoV2 privados listar_entidades -a
listar_permisos Listar los permisos otorgados a las entidades
privadas
./NodoV2 privados listar_permisos
(para información más completa)
./NodoV2 privados listar_permisos -a
El protocolo de comunicación MPGA-2 es uno de los protocolos válidos de comunicación dentro de la Red de Interoperabilidad PISEE y se construyó para permitir la transmisión de datos vía streaming entre dos Nodos o entre un Nodo y una entidad que implemente el mismo protocolo de comunicación.
Conexión TCP
La comunicación entre las dos partes se establece utilizando el protocolo de red TCP
Mutual TLS 1.3+
La autenticación entre las dos partes involucradas en la comunicación y el cifrado de extremo a extremo se realiza mediante Mutual TLS 1.3 o superior.
Con este método se garantiza que ambas partes se identifican y se reconocen y que toda transmisión de datos entre ellos pasa cifrada a través de Internet.Ambas partes solo aceptarán conexiones de entidades de las que ya posean su llave publica en una lista de entidades permitidas.
Streaming gRPC sobre HTTP/2
Una vez establecida la conexión entre ambas partes vía TCP con mTLS se crean los canales de streaming entre ambas partes usando la tecnología gRPC sobre HTTP/2.
Ambas partes crean un manejador (Handler) para los mensajes entrantes y pueden utilizar en paralelo la misma conexión para enviar mensajes a la otra parte.
Mensajes Protobuf
A través del canal de streaming ya creado solo se pueden enviar mensajes binarios usando la tecnología Protobuffer según un esquema ya definido.
El esquema de los mensajes MPGA2 está definido en un documento .proto que se adjunta al final de este documento.
Cuando se desea mandar una consulta a través del protocolo MPGA-2 se debe empaquetar completamente el request original en un mensaje protobuffer el cual se desempaquetará en el otro extremo, preservando todas las características del mensaje original, esto incluye el body, método, headers, path params y queryparams.
Token de autorización JWT
En cada mensaje MPGA2 que envíe el consumidor del servicio, en este caso la entidad privada, se debe adjuntar un token de autorización previamente obtenido. Este token corresponde a un JWT firmado digitalmente por el OAE proveedor a través del mismo streaming abierto.
Firma digital del payload del mensaje
Cuando se envía un mensaje o su respuesta, todo el contenido del request original se firma digitalmente y se adjunta ese valor dentro del mensaje protobuffer para que se pueda hacer una verificación en la contraparte.
La firma digital se realiza con las llaves de firma de quien envía un mensaje.
Archivo MPGA2.proto que define los mensajes:
/* MPGA Message V2 */
syntax = "proto3";
package poroto;
option go_package = "MPGA2/mpga2_message";
service ProductService{
rpc SendMPGA2(stream MPGA2) returns (stream MPGA2){}
rpc GetToken(TokenRequest) returns (TokenRequest){}
//rpc HealthCheck(HealthCheckRequestResponse) returns (HealthCheckRequestResponse){}
}
enum AutorizationType {
AUTORIZACION_OAE = 0;
AUTORIZACION_CIUDADANA = 1;
AUTORIZACION_FIJA = 2;
}
enum MethodType {
GET = 0;
HEAD = 1;
POST = 2;
PUT = 3;
DELETE = 4;
CONNECT = 5;
OPTIONS = 6;
TRACE = 7;
PATCH = 8;
}
// Message MPGA-2 for exchange data between state entities
message MPGA2 {
reserved 6 to 10, 14 to 19;
string ulid = 1;
string signature = 2;
bool isResponse = 4;
bool confidencial = 5;
Resultado resultado = 11;
Autorization autorization = 12;
OriginalRequest originalRequest = 13;
}
message Autorization {
reserved 6 to 10;
AutorizationType tipo = 1;
string service = 2;
string organismoOrigen = 3;
string organismoDestino = 4;
string token = 5;
}
message OriginalRequest {
reserved 7 to 10;
MethodType metodo = 1;
bytes body = 2;
map<string, string> header = 3;
map<string, string> pathparam = 4;
map<string, string> queryparam = 5;
bool multipart = 6;
}
message Resultado {
reserved 3 to 10;
int32 status = 1;
string error = 2;
}
// Message for Health check
message HealthCheckRequestResponse {
reserved 5 to 10;
string service = 1;
bool status = 2;
bool dial = 3;
bool head = 4;
}
// Message for token request
message TokenRequest {
reserved 5 to 10;
string servicio = 1;
string organismoSolicitante = 2;
string organismoAutorizador = 3;
string token = 4;
}