🌥️

社内向けStreamlitのデプロイの現実解

2024/04/23に公開

結論

社内データを扱うアプリケーションを安全にデプロイするならCloudflare Tunnel,Cloudflare Accessを使う。要件次第ではStreamlit in Snowflakeも使える。

はじめに

Streamlitはデータアプリケーションを短時間で作成できる便利なツールですが、社内データを扱うアプリケーションをデプロイする際は外部からの不正アクセスを防ぐように厳重な注意が必要です。
にもかかわらず、Streamlitを安全にデプロイする成熟した方法はまだありません。

本記事では、最も単純なStreamlitのデプロイ構成の例から問題点を再確認し、それらを解決する方法を順に説明します。ただし、本記事で紹介する構成を使うにはドメインのネームサーバーがCloudflareである必要があることに注意してください。

単純な構成はどう危険なのか?

まずは非常に単純なStreamlitアプリケーションのデプロイ構成の例を見ながらセキュリティの問題を再確認しましょう。

図1
図1 最も単純な構成例

この図では、Streamlitは社内ネットワークやクラウドサービスのファイアウォールの背後にデプロイされています。ファイアウォールは8080ポートを許可しており、ブラウザからhttp://203.0.113.0(仮のパブリックIPアドレス)にアクセスすることでアプリケーションに接続できます。

問題点

しかし、この単純な構成には3つの問題があります。
HTTP通信である
公共のネットワークからアクセスした場合、通信内容が盗聴されてデータが流出するリスクがあります。
ファイアウォールのポートを開放している
社内のセキュリティ担当者への連絡と正当性の証明が必要です。アプリケーション廃止後に別のアプリケーションをデプロイした場合、インシデントが発生する可能性があります。
IPアドレスに直接アクセスしている
URLを覚えにくい、スケールできないなど様々な問題があります。

これらの問題を解決するために、次の章ではCloudflare Tunnelを使った改良例を説明します。

インバウンドポートを開放せずアクセスすることは可能なのか?

前章で述べたファイアウォールのインバウンドポート開放に関する問題を解決するために、Cloudflare Tunnelを使用した改良版の構成例を以下に示します。

[図2]Cloudflare Tunnelを使用した改良版の構成例
この構成では、ファイアウォールのインバウンドポートは一切開放されていません。代わりに、同じネットワーク上で動作するcloudflaredというサービスが、アウトバウンド接続のみを利用してユーザーからのリクエストを受け付け、Streamlitアプリケーションに転送しています。

なぜアウトバウンド接続だけでトラフィックを受け付けられるのか?

プライベートネットワーク上にcloudflaredがデプロイされると、cloudflaredはCloudflareサーバーに対して認証リクエストを送信します。このとき環境変数として入力されたCloudflareの管理画面で発行される認証キーを使っています。
https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/

認証が完了すると、cloudflaredとCloudflareサーバーは、エンドツーエンドで暗号化された強固なトンネルを確立します。これ以降、http,ssh,udpなど任意のプロトコルを通して双方向にトラフィックを送受信できるようになります。
このようなアーキテクチャを用いることでアウトバウンド接続だけで双方向の接続が可能になります。ファイアウォールによってインバウンド接続は一切許可されていないため、第三者はどのポートにアクセスしても拒否されます。

これ以降、ユーザーがCloudflareにhttps://{mydomain}/streamlitとして送信したリクエストはCloudflareによって、そのままcloudflaredに転送されます。cloudflaredはCloudflare Tunnelの管理画面から設定した/streamlithttp://streamlit:8080の対応関係からリクエストをプライベートネットワーク内でhttp://streamlit:8080に転送します。Streamlitサーバーによる応答はもう一度トンネルを通り、Cloudflareを通してユーザーに返却されます。

この構成が解決した課題

  • ファイアウォールのインバウンドポートを一切開放せずにStreamlitアプリケーションを外部から接続可能にできる。
  • ユーザーはCloudflareのサーバーとやり取りをするだけなので、SSL化も自動的に対応できる。
  • Cloudflare Tunnelの管理画面から転送設定を変更できるため、設定変更時の再デプロイが不要。

以上のように、Cloudflare Tunnelを活用することで、インバウンドポート開放に関する問題を解決することができます。
しかし、この状態では認証認可の機能が備わっていないため、社外のユーザーもStreamlitアプリケーションにアクセスできてしまいます。

次の章ではCloudflare Accessを使った認証機能の実装例を説明します。

アプリケーションに認証機能を実装せずに認証できるのか?

前章ではCloudflare Tunnelを使ってインバウンドポートの問題を解決しました。次に、Cloudflare Accessを使って認証の問題を解決する方法を説明します。

https://developers.cloudflare.com/cloudflare-one/identity/

[図3]Cloudflare TunnelCloudflare Accessを使用した改良版の構成例

ユーザーがhttps://{mydomain}/streamlit/marketingにアクセスすると、以下のような流れで認証が行われます。

  1. Cloudflareが自動的にユーザーのクッキーやヘッダーを検証し、組織のSSOプロバイダで認証を試みる。
  2. 認証が成功すれば、ユーザーはStreamlitアプリケーションにアクセスできる。
  3. 認証に失敗した場合は、認証プロバイダの認証フローを開始する。
  4. 認証が成功すれば、ユーザーはStreamlitアプリケーションにアクセスできる。

このような構成を行うことで、認証が行われていないユーザーはそもそもStreamlitアプリケーションに到達できないようになります。

なぜこのようなことが可能なのか

これらの機能が実現できるのは、Cloudflare Accessがリバースプロキシとして振る舞い、アプリケーションの手前で認証処理を代行しているためです。ユーザーからのリクエストはまずCloudflare Accessに到達し、ここでSSOプロバイダに対して認証が行われます。認証に成功したリクエストのみがバックエンドのアプリケーションに転送されるため、アプリケーション側では認証処理を実装する必要がありません。
また、Cloudflare Accessは多くの認証プロバイダとの連携が可能で、認証フローの処理も代行してくれます。これにより開発者はアプリケーション内で複雑な認証処理の実装を行う必要がありません。

この構成が解決する問題

  • アプリケーションに認証機能を実装せずに、ユーザー認証を行うことができる。開発者は認証処理のコードを書く必要がない。
  • GUIから認証設定を行えるため、認証周りの実装や保守にかかるコストを大幅に削減できる。
  • ユーザーの所属部門などの属性情報を使った詳細なアクセス制御が可能。
  • 複数のアプリケーションで認証機能を共通化でき、認証周りの実装を再利用できる。

Cloudflare Accessのその他の機能

Cloudflare Accessは、認証だけでなく詳細な認可制御も可能です。例えば、SSOプロバイダから部署情報を取得することで、マーケティング部門のユーザーはstreamlit/marketingにアクセスできるが、streamlit/salesにはアクセスできないといった制御が可能です。

Cloudflare Accessは多様な認証方法に対応しており、Google認証、Microsoft EntraID認証、OpenID Connectなどを設定可能です。
https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/

さらに、StreamlitはCloudflare Accessで認証されたユーザーの情報を利用できます。認証後のリクエストヘッダーに含まれるJWTを使ってユーザーの名前やIDを取得し、アプリケーション内で活用することができます。
https://developers.cloudflare.com/cloudflare-one/identity/authorization-cookie/application-token/

以上のように、Cloudflare Accessを活用することで、認証機能を素早くで実装でき、保守性と再利用性を向上させることができます。

Streamlit in Snowflakeとはなにか?

Streamlitアプリケーションをセキュアにデプロイする際、Cloudflare AccessCloudflare Tunnelを組み合わせる方法以外にも、Streamlit in Snowflakeを利用するという選択肢があります。

https://docs.snowflake.com/ja/developer-guide/streamlit/about-streamlit

Streamlit in Snowflakeは、Snowflake上でStreamlitアプリケーションを直接実行できる機能です。この方法を用いることで、以下のようなメリットが得られます。

  1. Snowflakeのアクセス管理機能がマネージドで提供されるため、安全なデプロイが容易に実現できる。
  2. データの位置とコンピューティングの位置が近いため、Streamlitアプリケーションの実行速度を向上させることができる。
  3. Snowflakeからデータが出ないのでより安全。

以上のことから、Streamlit in Snowflakeは、セキュアなデプロイとパフォーマンスの向上を求めるユースケースにおいて、有望な選択肢の1つといえます。

制限事項

ただし、現時点では以下のような制限事項があります。

  1. Streamlit in Snowflakeを利用するには、Snowflakeアカウントが必要です。
  2. GCPのSnowflakeアカウントでは、まだStreamlit in Snowflakeを利用できません。(2024/04/23)
  3. 一部のPythonライブラリの利用が制限されている。

まとめ

Streamlitアプリケーションを安全にデプロイするには、Cloudflare AccessCloudflare Tunnelを組み合わせるのが効果的です。この方法を用いることで、以下のようなメリットが得られます。

  1. ファイアウォールのインバウンドポートを開放する必要がなくなり、セキュリティリスクを低減できます。
  2. アプリケーションにSSLを簡単に導入でき、通信の機密性を確保できます。
  3. 認証機能を素早くで実装できます。
  4. 詳細な認可制御が可能になり、部門単位でのアクセス制限などが実現できます。
  5. 認証済みユーザーの情報をアプリケーション内で活用できます。

本記事では省略しましたが、Cloudflare Warpを使うことで一層セキュアな構成にすることも可能です。セキュアなStreamlitを使って、社内のデータ活用を爆速で進めていきましょう。

PR

RAKUDEJI株式会社では、データエンジニアリングに特化したサービスを提供しています。
当社には、日本でも数少ないSnowflake公認データエンジニア資格「SnowPro Advanced DataEngineer」を保有するエンジニアが在籍しています。また、Pythonを用いて独自の機械学習モデルを構築し、オープンソースプラットフォーム「HuggingFace」に公開した経験が豊富なエンジニアも在籍しております。

これらの豊富な経験と知見を活かし、貴社のデータ活用を安全かつ効果的に加速させるお手伝いをいたします。Snowflake,Streamlit,AIに関するお困りごとやご相談がございましたら、ぜひRAKUDEJI株式会社の公式サイトからお気軽にお問い合わせください。爆速のデータ活用をお手伝いいたします。
https://rakudeji.co.jp/corp/

Snowflake Data Heroes

Discussion