小規模VPSのSSO比較:Keycloak、authentik、Zitadel
Keycloak、authentik、Zitadelを1台の小規模VPSで比較します。必要なRAMの下限、SSO非対応アプリを保護できる製品、各製品の弱点を確認できます。
1 台の VPS に適した SSO サーバーはどれか
Keycloak、authentik、Zitadel は、サーバー上のすべてのアプリで 1 つのログインを使いたい場合に候補となる、自己ホスト型のシングルサインオン(SSO)サーバーです。1 台の小規模な VPS では、これらを同じものとして扱うことはできません。自己ホスト型アプリを 3 つまたは 4 つ運用するサーバーでは、authentik が無難な既定の選択です。3 つの中で唯一、独自のログイン機能を持たないアプリの前段にログイン画面を配置できるためです。保護するすべてのアプリが標準プロトコルに対応しており、Java 仮想マシン(JVM)用のメモリを確保できる場合は、Keycloak が適しています。Zitadel は API 経由で製品を提供する開発者向けに設計されており、4 GB 未満の環境では導入しません。
最初に選択してから、インストールしてください。選択したら、VPS への authentik の実践的なインストールでセットアップの手順を確認できます。
各プロジェクトが実際に必要とする RAM 容量はどの程度か
まずはリソースの最低ラインから検討してください。機能要件よりも先に、この数値が候補の絞り込みを決定づけるためです。以下の数値は、2026 年 10 月時点で各プロジェクトが公開している公式のガイドラインであり、負荷テストの結果ではありません。
このグラフのデータ
[
{
"label": "authentik",
"vendor_min_ram_mb": 2048,
"base_containers": 3
},
{
"label": "Keycloak",
"vendor_min_ram_mb": 1250,
"base_containers": 2
},
{
"label": "Zitadel",
"vendor_min_ram_mb": 2048,
"base_containers": 4
}
]authentik の Docker Compose インストールページでは、「少なくとも 2 CPU コアと 2 GB の RAM を備えたホスト」が求められており、これは 2048 MB に相当します。公開されている compose ファイルでは 3 個のコンテナ(PostgreSQL、サーバー、ワーカー)が実行されます。このホストの数値は、データベースを含めた 3 つのコンテナすべてをカバーする必要があります。
Keycloak は 3 という最も具体的な数値を公開しています。サイジングガイドによると、「Realm データと 10,000 セッションのキャッシュを含む Pod のベースメモリ使用量は 1250 MB」とされています。この 1250 MB は、キャッシュを含んだ Keycloak サーバー単体の数値です。ガイドではデータベースのサイジングを別途行っているため、PostgreSQL にはこれとは別にメモリが必要です。同ページではコンテナ制限が重要である理由も説明されています。Keycloak はメモリ制限の 70% をヒープとして確保し、さらに約 300 MB の非ヒープメモリを使用します。ガイドの計算例では、1250 MB のベース値に対して 1360 MB のメモリ制限が設定されています。コンテナに 1 GB を割り当てた場合、ヒープは約 717 MB となり、約 300 MB の非ヒープメモリを加えると合計で約 1017 MB となります。これでは制限値に対して余裕がほとんどありません。一方、ガイドが示す Realm キャッシュと 10,000 セッションを考慮したベース値は 1250 MB です。
Zitadel の compose ページでも、クイックスタートからホームラボ、あるいは準本番環境まで、ガイド全体を通じた前提条件として 2 GB、つまり 2048 MB が求められています。それ以上のサイジングについては、プロダクション向けのページを参照してください。Zitadel プロセス自体は「約 512 MB の RAM を必要とし、1 CPU コア未満で動作可能」です。データベースがリソースを消費する要因であり、「1 秒あたり 100 リクエスト(req/s)ごとに約 1 CPU コアと 4 GB の RAM」が必要とされています。パスワードハッシュ化には「4 CPU コア」が推奨されます。ログインが集中すると CPU スパイクが発生するためです。公式の v4 compose では、追加機能なしで 4 個のコンテナ(プロキシとしての Traefik、Zitadel API、独立したログイン UI コンテナ、PostgreSQL)が実行されます。Redis と OpenTelemetry コレクターは、オプションの compose プロファイルとして用意されています。
結論として、Keycloak と authentik は 4 GB の VPS 上で動作し、保護対象のアプリケーションを動かす余地も残せます。Zitadel は 2 GB でも起動しますが、ログインのたびに PostgreSQL とメモリを奪い合うことになります。Zitadel を 4 GB 未満で運用することは推奨しません。また、他のアプリケーションも同居させるサーバーであれば、8 GB のメモリを用意するのが望ましいでしょう。
各サービスが実際にサーバー上で実行するもの
authentik は、PostgreSQL と、1 つの authentik イメージを使う 2 つのコンテナ(server と worker)で構成されます。server は HTTP に応答し、組み込みの outpost を保持します。worker はディレクトリ同期やメール送信などのバックグラウンドタスクを実行します。公開されているインストール手順は短いものです。
wget https://docs.goauthentik.io/compose.yml
echo "PG_PASS=$(openssl rand -base64 36 | tr -d '\n')" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')" >> .env
docker compose pull
docker compose up -dserver はポート 9000 と 9443 を公開します。ポート 9000 に初めてアクセスすると初期セットアップフローが実行され、デフォルトの akadmin ユーザーのパスワードを設定します。そのポートにインターネットから到達できるようにする前に、正式な証明書を使用するリバースプロキシを前段に配置してください。
Keycloak は、用意したデータベースと 1 つのプロセスで構成されます。クイックスタートでは 1 つのコンテナを使用します。
docker run -p 127.0.0.1:8080:8080 \
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
-e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:26.8.1 start-devstart-dev は動作を確認するためのものです。ローカルの開発用データベースを使用し、TLS(transport layer security)も使用しません。そのため、この方法で起動したコンテナを後から削除すると、レルムも失われます。本番環境では、start を使用します。KC_DB を通じて実際の PostgreSQL に接続し、KC_HOSTNAME を通じて公開ホスト名を使用します。Keycloak の本番環境向けガイドにも、サーバーとの間のすべての通信にはセキュアなチャネルが必要と記載されています。そのため、ここでは HTTPS は任意ではありません。
Zitadel は、前述した 4 コンテナ構成のスタックです。
mkdir zitadel-compose && cd zitadel-compose
curl -fsSLO https://raw.githubusercontent.com/zitadel/zitadel/main/deploy/compose/docker-compose.yml
curl -fsSLO https://raw.githubusercontent.com/zitadel/zitadel/main/deploy/compose/.env.example
cp .env.example .env
docker compose up -d --wait初回起動前に、.env で ZITADEL_MASTERKEY を設定してください。これは、Zitadel がデータベース内の Secret の暗号化に使用する 32 文字のキーです。そのため、このキーを失うと、これらの Secret にアクセスできなくなります。これらのようなスタックの運用が初めてであれば、VPS 向けの Docker Compose の基本で、ID プロバイダーが再起動後も維持されるかどうかを左右するボリュームと再起動ポリシーの選択について説明しています。
各製品はどのプロトコルに対応していますか?
3製品とも、モダンなアプリケーションで利用される OAuth 2.0 上の認証レイヤーである OpenID Connect (OIDC) に対応しており、エンタープライズソフトウェアで依然として利用されている古い標準規格の SAML 2.0 (security assertion markup language) にも対応しています。実質的な違いは LDAP (lightweight directory access protocol) にあり、この用語は対照的な2つの役割を指しています。
LDAP からの読み取りとは、SSO サーバーが既存のディレクトリに対してパスワードを照合することを指します。Keycloak はユーザーフェデレーション機能を通じてこれを行います。Zitadel も同様で、ドキュメントには「ZITADEL に LDAP サーバーを ID プロバイダーとして接続する方法」が記載されています。
LDAP の提供とは、LDAP にしか対応していないアプリケーションが、SSO サーバーをディレクトリであるかのようにバインドすることを指します。これに対応しているのは authentik のみです。その LDAP プロバイダーは、専用の LDAP outpost を介して「authentik データベース内のすべてのユーザーとグループを LDAP ディレクトリ経由で検索可能」にします。この際、636 番ポートで LDAPS が利用可能です。デフォルトでは、バインドされたユーザーは自身の詳細とグループしか検索できないため、アプリケーションがバインドに使用するサービスアカウントには「Search full LDAP directory」権限が必要です。ドキュメントではバインドと検索のみが扱われており、書き込み操作については記載がないため、読み取り専用のディレクトリとして扱う必要があります。ワンタイムコードはパスワードの末尾にセミコロンを付けて付加します(例: password;123456)。なお、バインド時に SMS 認証はサポートされていません。
リスト内のアプリケーションが LDAP にしか対応していない場合、比較はここで終了です。Keycloak と Zitadel はそのバインド要求に応答できないため、それらの横に別のディレクトリを運用し、2つのユーザーリストを同期し続ける必要があります。
ログイン機能がまったくないアプリはどうしますか?
Forward auth が解決策です。これは self-hosted 環境で頻繁に必要になります。リバースプロキシは upstream に転送する前に、SSO サーバーへリクエストが許可されているか問い合わせます。背後のアプリは SSO の存在を認識しません。通常は、プロキシが検証済みのリクエストを受け取り、ヘッダーにユーザー名が含まれます。
authentik の proxy provider では、これを3つのドキュメント化されたモードで実現できます。「Proxy」では、authentik outpost が upstream アプリへ直接トラフィックを転送します。「Forward auth (single application)」では、トラフィックを既存のリバースプロキシに任せ、authentik は認証チェックだけに使用します。「Forward auth (domain level)」では、1つの親ドメイン配下にあるすべてのアプリを単一の provider で保護します。Domain level は便利ですが、ドキュメントに記載された制限があります。保護対象の各アプリに異なるアプリケーションレベルの認可ルールを適用できないため、そのドメイン配下のすべてのアプリで同じポリシーセットを共有します。
Keycloak にはこの機能がありません。付属のプロキシである Keycloak Gatekeeper は Louketo Proxy に改称され、2020年11月にサポート終了となり、2020年12月に GitHub でアーカイブされました。OIDC に対応していないアプリを保護するには、通常 oauth2-proxy などの別コンポーネントをアプリの前段で実行し、Keycloak client を指定します。Zitadel にも独自の forward auth モードはありません。そのため、同じように追加コンポーネントをインストールし、監視し、アップグレードする必要があります。
この追加のホップによってリバースプロキシの設定は単純ではなくなります。そのため、認証 middleware を組み込む前に、複数の Docker Compose アプリを Traefik の前段で公開する方法を読んでください。
アップグレード手順の難易度はどの程度ですか?
2026年10月25日現在、最新のリリースは Keycloak 26.8.1、authentik 2026.8.5、Zitadel v4.20.0 です。これら3つの製品はすべて PostgreSQL に対してスキーママイグレーションを実行するため、アップグレードのたびにデータベースの変更が発生します。毎回必ず、事前にデータベースのバックアップを取得してください。この習慣は、本比較で取り上げるどの機能よりも価値があります。
authentik のルールは最も厳格であり、明示的に次のように定められています。「アップグレードはメジャーリリースの順序に従う必要があります。古いメジャーバージョンから最新バージョンへ直接スキップしないでください」。各バージョン内で最新のパッチを適用してから次のバージョンへ移行する必要があり、「authentik はダウングレードをサポートしていません」。カレンダーバージョンを採用しているプロジェクトで1年分遅れると、1回のアップグレードが連鎖的な作業となり、それぞれでデータベースマイグレーションが必要になります。
Keycloak のアップグレードガイドには、従うべき順序が記載されています。前バージョンからのマイグレーション変更点を確認し、サーバーをアップグレードしてからアダプターをアップグレードします。データベースマイグレーションは自動的に実行されますが、エクスポートして手動で適用することも可能です。これは変更内容を適用前に確認したい場合に有用です。Keycloak の場合、その確認作業がコストとなります。リリースノートには非推奨事項や動作変更が含まれており、見落としやすく、見落とした場合の代償は大きいです。
Zitadel は初期化およびセットアップフェーズを稼働中のサーバーから分離しており、本番環境のガイダンスでは、スケーリング時にセットアップ作業が繰り返されないよう、これらを分離しておくことが推奨されています。単一の VPS 環境では、API が正常と報告される前にセットアップステップが完了している必要があることを意味します。そのため、compose ファイルにはヘルスチェックが組み込まれており、起動コマンドには --wait が使用されています。
各プロジェクトのターゲット層と欠点
Keycloak は Red Hat が提供するアイデンティティサーバーであり、レルム、グループ、ロールマッピング、および既存の企業ディレクトリを持つ組織向けに構築されています。これら3つの中で最も標準仕様に忠実な実装です。しかし、4つのセルフホストアプリを動かす 2 GB の VPS で運用する場合、そのうち半数が OIDC に対応していないと、このツールは適しません。Keycloak サーバーだけで 1250 MB のメモリを消費し、さらにデータベースが必要となります。企業向けに設計されたレルムモデルを学習する必要がある上、結局のところ本来守りたかったアプリのために oauth2-proxy を別途インストールすることになります。
authentik はセルフホストユーザー向けに構築されており、その機能リストにそれが表れています。Forward Auth や LDAP プロバイダーを備え、ログインフローをビジュアルエディタで構築可能です。このツールが適さないのは、エンタープライズ予算をかけずにベンダーサポートを求める場合や、数週間ごとにリリースされる更新サイクルを避けたい場合です。サポートは有料サブスクリプションでのみ提供されます。チケットサポートは 1000 ドルを超える Enterprise サブスクリプションから、SLA 付きの専用サポートは年間 2 万ドルから始まる Enterprise Plus で提供されます。ダウングレードパスがなくバージョンをスキップできないカレンダーバージョニングは、運用上の大きな負担となります。また、本来の目的が単一の OIDC クライアントの設定である場合、フローエディタという新しいモデルを学習することは過剰です。
Zitadel は、自社製品に認証機能を組み込む開発者向けに構築されており、強力な API とマルチテナント機能が第一級の機能として備わっています。このツールが適さないのは、まさに小規模なセルフホスト環境です。4 つのコンテナ、Forward Auth の欠如、そしてコアあたり 4 GB のデータベースサイズという構成は、パスワードマネージャーや Wiki を背後に置く単一の VPS には不向きです。
1 台の VPS で実行する構成と方法
1 台の VPS で自己ホスト型アプリを 3 つまたは 4 つ運用するなら、authentik を使用します。3 つともログイン画面を提供します。判断の決め手は、一部のアプリが OIDC に対応できないことです。authentik なら、別のコンポーネントを追加せず、組み込みの forward auth でこの問題に対応できます。
可能であれば 4 GB を割り当て、隣接するアプリが小規模な場合に限り 2 GB にします。ポート 9000 はパブリックインターネットからアクセスできないようにし、前段のリバースプロキシで TLS を終端します。PostgreSQL のダンプを毎晩取得し、サーバー外に保存します。バックアップのない ID プロバイダーは、その背後にあるすべてのアプリにとって単一障害点になるためです。スタックは root ではなく、専用の非特権アカウントで実行します。VPS で最小権限ユーザーを設定するでは、この構成に必要なアカウントとファイル所有権について説明しています。
保護するすべてのアプリがすでに OIDC または SAML に対応している場合、または Keycloak realm が提供する細粒度のロールモデルが必要な場合は、Keycloak を選択します。他のユーザーがサインアップするアプリを構築しており、API とテナントモデルを利用したい場合は、Zitadel を選択します。どちらも、この記事で扱う 1 台のサーバーに 3 つのアプリを配置するケースには適していません。
最初に遭遇する障害パターン
Keycloak の再起動後にデータがない。 start-dev で起動しています。これはローカルの開発用データベースを使用します。ボリュームを割り当てていないコンテナでは、コンテナを削除すると realm も削除されます。実際のデータベースを KC_DB=postgres で指定し、start に移行してください。
小規模なホストで authentik の worker コンテナが消える。 worker と server は同じイメージを使用し、どちらも Python プロセスを保持します。さらに PostgreSQL も 2 GB のホストメモリを使用します。docker compose ps を実行して、どのサービスが終了したかを確認してください。その後、dmesg で out-of-memory による kill を確認してから、アプリのバグを調べてください。
プロキシの背後で Zitadel の Console が動作しない。 Zitadel API は gRPC を使用するため、upstream まで HTTP/2 が必要です。要件ページでは、upstream 接続で HTTP/2 をサポートするリバースプロキシを求めており、検証済みの Traefik v3.x、NGINX v1.x、Caddy v2.x、Apache httpd 2.4.x のバージョンを示しています。upstream 接続を HTTP/1.1 にダウングレードするプロキシでは、ログインページは読み込めても Console は動作しません。
すべてのアプリでログイン画面に戻される。 SSO サーバーの公開 URL と、アプリに設定した URL は、スキームとポートを含めて完全に一致させる必要があります。Keycloak ではこれを hostname 設定と呼び、Zitadel では external domain と呼びます。一致しない場合、アプリはサーバーが自身の URL と認識しないログイン URL へリダイレクトします。その結果、ブラウザーが2つの URL の間を繰り返し移動します。
FAQ
3 つのうち、2 GB の VPS に適しているのはどれですか?
authentik と Keycloak です。authentik の要件では、少なくとも 2 CPU コアと 2 GB の RAM を備えたホストが必要です。Keycloak のサイジングガイドでは、データベースを除くサーバーのベースメモリを 1250 MB としています。保護対象のアプリを追加すると、2 GB ではどちらも余裕がありません。そのため、余裕を持って運用できる下限は 4 GB と考えてください。Zitadel の compose ガイドにも 2 GB と記載されており、ホームラボまたは準本番構成で動作します。ただし、本番向けの指針では、パスワードハッシュ処理に 4 CPU コア、データベースコア 1 つあたり 4 GB の RAM を求めています。実際のログイン通信が発生すると、2 GB では不足しやすくなります。
独自のログイン機能を持たないアプリを Keycloak または Zitadel で保護できますか?
単独ではできません。どちらにも forward auth コンポーネントは組み込まれていません。Keycloak の旧 companion proxy である Louketo Proxy は 2020 年 11 月にサポートが終了し、GitHub リポジトリも 2020 年 12 月以降アーカイブされています。そのため、これを基盤に構築するべきではありません。reverse proxy とアプリの間に oauth2-proxy などのコンポーネントを配置し、SSO サーバー上の OIDC クライアントを指定します。authentik では、proxy provider を "Forward auth (single application)" または "Forward auth (domain level)" モードで使用して、これを標準機能として実行できます。
LDAP しか話せないアプリの LDAP サーバーとして機能できるのはどれですか?
authentik です。LDAP provider は outpost 上で動作し、authentik のユーザーとグループを LDAP 経由で検索できるようにします。LDAPS は port 636 で利用できます。ドキュメントでは bind と search のみを扱っているため、読み取り専用として扱ってください。Keycloak と Zitadel は逆方向に動作します。どちらも既存の LDAP ディレクトリをユーザーソースとして読み取りますが、アプリケーションからの LDAP bind に応答する機能はありません。
authentik のアップグレードでバージョンを飛ばせますか?
できません。ドキュメントでは、アップグレードはメジャーリリースの順序に従う必要があり、古いメジャーバージョンから最新バージョンへ直接移行してはならないと説明されています。まず各バージョン系列内の最新パッチリリースへ更新し、その後、1 バージョンずつ順番に進めてください。authentik はダウングレードをサポートしておらず、マイグレーションも前方向にしか実行されないため、各手順の前に PostgreSQL をバックアップしてください。