RBAC использует OPA для gRPC и gRPC-web
В существующей системе имеется несколько микросервисов gRPC и внутренних серверов приложений gRPC для внешних панелей мониторинга, которые используют gRPC-веб-прокси для подключения.
Прикладные сервисы взаимодействуют с микросервисами с помощью gRPC.
Задача состоит в том, чтобы внедрить RBAC поверх этих сервисов. Для реализации POC я использую OpenPolicyAgent.
В настоящее время я пытаюсь реверсировать прокси на каждом сервере приложений через Nginx и использовать модуль сценариев njs в качестве слоя авторизации. Например,
Конфигурация Nginx
js_include /etc/nginx/conf.d/rbac.js;
server {
listen 8166 http2;
server_name nginx.serivceB;
location / {
auth_request /_authz;
try_files $uri @serviceB;
}
location @serviceB {
grpc_pass serviceB:5166;
}
location = /_authz {
internal;
js_content authz;
}
location = /_opa {
internal;
proxy_pass http://opa:8181/v1/data/system/serviceA/main;
}
}
JS код для аутентификации:
function authz(req, res) {
req.error("********");
var json_req = JSON.stringify(req.requestBody)
req.error(json_req)
req.error("########");
var opa_data = {
"input": {
"user": "alice",
// "path": req.variables.request_uri,
"api": "sayHello"
}
};
req.log(JSON.stringify(opa_data))
var opts = {
method: "POST",
body: JSON.stringify(opa_data)
};
req.subrequest("/_opa", opts, function(opa) {
req.error("OPA response: " + opa.body);
var body = JSON.parse(opa.body);
if (!body.result) {
res.return(403);
return;
}
if (!body.result.allow) {
res.return(403);
return;
}
res.return(200);
});
}
Мне понравился этот подход, потому что таким образом я должен написать код, связанный с авторизацией, в одном месте. Я сталкиваюсь со следующей проблемой:
Невозможно получить доступ к аргументам gRPC или телу запроса. Это необходимо, потому что атрибуты ввода, требуемые для OPA, должны быть выбраны оттуда.
Журналы Nginx:
nginx_1 | 2019/02/07 16:58:47 [error] 6#6: *1 js: ********
nginx_1 | 2019/02/07 16:58:47 [error] 6#6: *1 js: undefined
nginx_1 | 2019/02/07 16:58:47 [error] 6#6: *1 js: ########
nginx_1 | 2019/02/07 16:58:47 [error] 6#6: *1 js: OPA response: {"result":{"allow":true}}
nginx_1 | 2019/02/07 16:58:47 [warn] 6#6: *1 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0000000040 while sending to client, client: 172.19.0.6, server: nginx.serivceb, request: "POST /protos.ServiceB/StreamHello HTTP/2.0", host: "nginx.serivceB:8166"
nginx_1 | 172.19.0.6 - - [07/Feb/2019:16:58:47 +0000] "POST /protos.ServiceB/StreamHello HTTP/2.0" 200 180 "-" "grpc-go/1.18.0" "-"