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" "-"

0 ответов

Другие вопросы по тегам