QUO CARD Digital Innovation Lab Tech Blog

クオカード デジタルイノベーションラボの技術ブログです

Kibanaでユーザ単位の権限管理をできるようにしました

デジタルイノベーションラボのIです。 QUOカードPayのElasticsearch/Kibana環境でユーザ単位の権限管理をできるようにした件について書こうと思います。

背景

AWSのALBのログをElasticsearchに取り込み、Kibanaで可視化しています。

マネージドサービスであるOpenSearch Serviceを使用しているのですが、VPC外部からアクセスするためにnginxをプロキシとしてKibanaにアクセスしています。そのプロキシECSのALBリスナーにおいてCognito認証を組み込んでいました。下記のような構成です。

今回、あるユーザにおいて特定のフィールドを閲覧できないようにしたいという要求が出ました。

何か方法はないか探したところ、OpenSearch Serviceにおいて「きめ細かなアクセスコントロール」を有効化しCognito認証を行い、ユーザごとに別のIAM Roleを割り当てることで実現できそうでした。

記事①

記事②

基本的にはこの2つの記事の通りに作業を実施したのですが、いくつか考慮すべき点があったのでそのあたりを中心に書きます。

変更点

プロキシのHTTPS化

OpenSearch Serviceできめ細かなアクセスコントロールを有効化する際はトラフィックHTTPS化が必須です。

既存構成ではALBより先ではHTTP(80)で通信していたので、ここをHTTPS(443)化する必要がありました。

記事①を参考にしたのですが、この記事においてはnginxをEC2でホストしています。プロキシのためだけにEC2を運用したくはないので、既存構成と同様にECS(Fargate)+ALBを使うことにしました。つまり下記のような構成です。

nginx公式のDocker imageをベースとし、nginx confファイル差し替えとSSL証明書の設置を行ったimageを作成しました。

confファイルは以下です。基本的には記事①に記載されているとおりですが、2つ差異があります。

まず、Elasticsearch バージョン7.10 を使用しているため、_dashboards ではなく _plugin/kibana エンドポイントを指定しています。

また、nginx 1.15.0 以降ではsslディレクティブはdeprecatedとなっているため削除し、listenディレクティブにsslを追加しています。

server {
    listen 443 ssl;
    server_name $host;
    rewrite ^/$ https://$host/_plugin/kibana redirect;

    ssl_certificate           /etc/nginx/conf.d/ssl/cert.crt;
    ssl_certificate_key       /etc/nginx/conf.d/ssl/cert.key;

    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    location /_plugin/kibana {
        # Forward requests to Dashboards
        proxy_pass https://${PROXY_PASS}/_plugin/kibana;

        # Handle redirects to Cognito
        proxy_redirect https://${COGNITO_DOMAIN} https://$host;

        # Update cookie domain and path
        proxy_cookie_domain ${PROXY_PASS} $host;
        proxy_cookie_path ~*^/$ /_plugin/kibana/;

        # Response buffer settings
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
    }

    location ~ \/(log|sign|fav|forgot|change|saml|oauth2) {
        # Forward requests to Cognito
        proxy_pass https://${COGNITO_DOMAIN};

        # Handle redirects to Dashboards
        proxy_redirect https://${PROXY_PASS} https://$host;

        # Handle redirects to Cognito
        proxy_redirect https://${COGNITO_DOMAIN} https://$host;


        # Update cookie domain
        proxy_cookie_domain ${COGNITO_DOMAIN} $host;
    }
}

既存構成ではALBリスナーにおいてCognito認証を設定していましたが、OpenSearch Serviceで設定するため削除しました。

また前述のnginx設定だとKibanaへ302リダイレクトされるため、ターゲットグループのヘルスチェックのSuccess codesには302を設定しました。プロトコルHTTPSです。

特定フィールドのマスク

記事②の手順24~31にあたる、IAMLimitedUserRoleを割り当てたCognitoユーザーグループ: limited-user-group のKibana操作権限設定の部分です。

今回は読み取り権限のみかつ、request_uri, request_uri_path, request_uri_query, redirect_url というフィールドを閲覧できないようにしたかったので、インデックス許可を以下の様に設定しました。

これにより、limited-user-groupに所属したユーザにおいては、このフィールドのデータが以下のようにマスクされます。

終わりに

繰り返しになりますが、概ねAWS公式ドキュメント通りに進めてやりたいことが実現できました。

そもそもOpenSearch Service側ではなくALBでCognito認証をするというやや邪道な構成だったので、この機会によりよい構成に変更できてよかったです。