SSO OSS比較:Keycloak vs Authentik vs Zitadel でAuth0代替をセルフホスト
オープンソースラボ編集部 ・ 2026年6月13日
SSO OSS比較:Keycloak vs Authentik vs Zitadel でAuth0代替をセルフホスト
Auth0は月$23〜(最低1,000MAU)・Okta は月$2/ユーザーと、ユーザーが増えるほどコストが指数的に増加します。Keycloak(Red Hat製・最も実績多)・Authentik(Python製・モダンUI)・Zitadel(Go製・マルチテナント)はOSSのIdentity Providerで、OAuth2/OIDC・SAML・MFA・ソーシャルログインをセルフホストで実装できます。
SSOツールの選定理由
- コスト削減: Auth0の月5,000MAUプランは月$240。セルフホストでサーバー代のみに
- マルチテナント: SaaSアプリで顧客ごとに独立したユーザーテナントを管理したい
- 社員SSO: Google Workspaceと連携してSAML SSOで全社ツールにシングルサインオン
- カスタムログインUI: ブランドに合わせたログイン画面・MFA・パスキーを実装したい
- Next.js統合: NextAuth.jsやAuthelia経由でOIDCプロバイダーとして接続したい
主要ツールの概要
Keycloak
Red Hat(IBM)が開発・メンテナンスするエンタープライズグレードのIdentity and Access Managementサーバーです。GitHubスター23k+。OAuth2・OIDC・SAML 2.0・WebAuthn・LDAP/AD連携に対応し、世界中の大企業・政府機関で採用されています。
# Keycloakをdocker-composeで起動
version: "3"
services:
keycloak:
image: quay.io/keycloak/keycloak:24.0
restart: always
command: start
ports:
- "8080:8080"
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: keycloak_pass
KC_HOSTNAME: auth.yoursite.com
KC_PROXY: edge
KC_HTTP_ENABLED: "true"
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: your-admin-password
depends_on:
- postgres
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: keycloak_pass
volumes:
- keycloak_db:/var/lib/postgresql/data
volumes:
keycloak_db:
// Next.js + NextAuth.js でKeycloakと連携
// npm install next-auth
// app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth";
import type { NextAuthOptions } from "next-auth";
import KeycloakProvider from "next-auth/providers/keycloak";
export const authOptions: NextAuthOptions = {
providers: [
KeycloakProvider({
clientId: process.env.KEYCLOAK_CLIENT_ID!,
clientSecret: process.env.KEYCLOAK_CLIENT_SECRET!,
issuer: process.env.KEYCLOAK_ISSUER!,
// issuer例: https://auth.yoursite.com/realms/yourapp
}),
],
callbacks: {
async jwt({ token, account }) {
// Keycloakのアクセストークンをセッションに保持
if (account) {
token.accessToken = account.access_token;
token.refreshToken = account.refresh_token;
token.idToken = account.id_token;
}
return token;
},
async session({ session, token }) {
session.accessToken = token.accessToken as string;
return session;
},
},
events: {
async signOut({ token }) {
// Keycloakからもサインアウト(シングルログアウト)
if (token.idToken) {
const params = new URLSearchParams({
id_token_hint: token.idToken as string,
post_logout_redirect_uri: process.env.NEXTAUTH_URL!,
});
await fetch(
`${process.env.KEYCLOAK_ISSUER}/protocol/openid-connect/logout?${params}`
);
}
},
},
};
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
// Keycloak Admin REST APIでユーザーをプログラム的に管理
// サービスアカウントトークンを取得してユーザー操作
async function getAdminToken() {
const res = await fetch(
`${process.env.KEYCLOAK_URL}/realms/master/protocol/openid-connect/token`,
{
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: "admin-cli",
client_secret: process.env.KEYCLOAK_ADMIN_SECRET!,
}),
}
);
const data = await res.json();
return data.access_token;
}
// 新規ユーザーを作成(サインアップ後に自動実行)
async function createKeycloakUser(email: string, firstName: string) {
const token = await getAdminToken();
await fetch(
`${process.env.KEYCLOAK_URL}/admin/realms/yourapp/users`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
username: email,
email,
firstName,
enabled: true,
emailVerified: false,
credentials: [],
requiredActions: ["VERIFY_EMAIL"],
}),
}
);
}
Authentik
Python(Django)製のモダンなIdentity Providerです。GitHubスター14k+。視覚的なフローデザイナーで認証フロー(パスワード→MFA→利用規約同意)をノーコードで設計でき、Keycloakより学習コストが低いです。プロキシモード(Nginx/Traefikと連携してVPNなしでアプリを保護)も特徴です。
# Authentikをdocker-composeで起動
version: "3"
services:
postgresql:
image: postgres:16-alpine
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d authentik -U authentik"]
interval: 5s
timeout: 5s
retries: 5
environment:
POSTGRES_PASSWORD: authentik_pass
POSTGRES_USER: authentik
POSTGRES_DB: authentik
volumes:
- authentik_db:/var/lib/postgresql/data
redis:
image: redis:alpine
restart: unless-stopped
server:
image: ghcr.io/goauthentik/server:2024.4
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: authentik_pass
AUTHENTIK_SECRET_KEY: "your-50-char-secret-key"
AUTHENTIK_ERROR_REPORTING__ENABLED: "false"
AUTHENTIK_EMAIL__HOST: smtp.sendgrid.net
AUTHENTIK_EMAIL__PORT: "587"
AUTHENTIK_EMAIL__USERNAME: apikey
AUTHENTIK_EMAIL__PASSWORD: your-sendgrid-key
AUTHENTIK_EMAIL__FROM: auth@yoursite.com
AUTHENTIK_EMAIL__USE_TLS: "true"
ports:
- "9000:9000"
- "9443:9443"
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_started
worker:
image: ghcr.io/goauthentik/server:2024.4
restart: unless-stopped
command: worker
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: authentik_pass
AUTHENTIK_SECRET_KEY: "your-50-char-secret-key"
depends_on:
postgresql:
condition: service_healthy
volumes:
authentik_db:
Zitadel
Go製のマルチテナント対応Identity Platformです。GitHubスター9k+。SaaS向けのマルチオーガニゼーション管理・カスタムドメイン・ブランド別ログインUI・パスキー(FIDO2)ファーストの設計が特徴で、B2Bプロダクトの認証基盤として使いやすいです。
# ZitadelをDockerで起動(自己完結型)
docker run -d --name zitadel -p 8080:8080 -v zitadel_data:/data -e ZITADEL_MASTERKEY="your-32-byte-masterkey-here!!" -e ZITADEL_DATABASE_POSTGRES_HOST=postgres -e ZITADEL_DATABASE_POSTGRES_PORT=5432 -e ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel -e ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel -e ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=zitadel_pass -e ZITADEL_EXTERNALSECURE=true -e ZITADEL_EXTERNALPORT=443 -e ZITADEL_EXTERNALDOMAIN=auth.yoursite.com ghcr.io/zitadel/zitadel:latest start-from-init --masterkey "your-32-byte-masterkey-here!!"
// Next.js + Zitadel OIDCでログインを実装
// npm install @zitadel/react @zitadel/node
// app/providers.tsx
"use client";
import { ZitadelProvider, createZitadelClient } from "@zitadel/react";
const zitadel = createZitadelClient({
issuer: process.env.NEXT_PUBLIC_ZITADEL_ISSUER!,
clientId: process.env.NEXT_PUBLIC_ZITADEL_CLIENT_ID!,
});
export function AuthProvider({ children }: { children: React.ReactNode }) {
return (
<ZitadelProvider client={zitadel}>
{children}
</ZitadelProvider>
);
}
// ログインボタン
"use client";
import { useZitadel } from "@zitadel/react";
export function LoginButton() {
const { signIn, signOut, user, isAuthenticated } = useZitadel();
if (isAuthenticated) {
return (
<div>
<p>ログイン中: {user?.profile?.name}</p>
<button onClick={() => signOut()}>ログアウト</button>
</div>
);
}
return (
<button onClick={() => signIn()}>
Zitadelでログイン
</button>
);
}
機能比較表
| 比較項目 | Keycloak | Authentik | Zitadel |
|---|---|---|---|
| ライセンス | Apache-2.0 | MIT | Apache-2.0 |
| OAuth2/OIDC | ✅ | ✅ | ✅ |
| SAML 2.0 | ✅ | ✅ | ✅ |
| MFA/TOTP | ✅ | ✅ | ✅ |
| パスキー(FIDO2) | ✅ | ✅ | ✅ 重視 |
| フロービルダー | ❌ | ✅ | ❌ |
| プロキシモード | ❌ | ✅ | ❌ |
| マルチテナント | ✅ | ✅ | ✅ 優秀 |
| 最小RAM | 1GB | 512MB | 512MB |
| GitHub Stars | 23k+ | 14k+ | 9k+ |
SSO・認証と組み合わせるパスワード管理の強化はopen-source-password-manager(/categories/security)を参照。Next.jsでの認証全体の設計はsecurityカテゴリ(/categories/security)でまとめています。
FAQ
Q. Auth0からKeycloakに移行する際、既存ユーザーのパスワードハッシュを移行できますか?
A. ユーザーデータの移行は可能ですが、パスワードハッシュの直接移行は困難です。移行アプローチ: ①Export→Import: Auth0のManagement APIでユーザー一覧をJSONエクスポート→KeycloakのAdmin APIでユーザーをインポート(パスワードなし)。ユーザーは次回ログイン時に「パスワードリセット」のメールを受け取ります②ジャスト・イン・タイム移行: 既存ユーザーが最初にKeycloakにログインしようとした際、裏でAuth0に認証を委譲し成功したらKeycloakにユーザーを作成。Auth0での認証が成功したパスワードをKeycloakに設定(Keycloakのカスタムユーザーストレージプロバイダーで実装)。推奨: 方法②が最もユーザー体験を損なわない移行方法です。移行期間中にAuth0を並行稼働させ、全ユーザーがKeycloakに移行したらAuth0を解約します。
Q. Authentikのプロキシモードを使うとVPNなしで社内ツールを保護できますか?
A. はい、Authentikのプロキシモードは「Reverse Proxy + 認証」を組み合わせた構成で、VPNなしでサービスを保護できます。仕組み: ①Nginx/TraefikがAuthentikをフォワード認証プロバイダーとして設定②ユーザーがサービスにアクセスするとAuthentikにリダイレクト③Authentikで認証成功後、元のサービスに戻る。設定例(Nginx): auth_request /outpost.goauthentik.io/auth/nginx;をNginxのlocationブロックに追加。保護できるサービスの例: Grafana・Kibana・Metabase・Jupyter・Redash・会社の内部ダッシュボード。VPNとの比較: Authentikプロキシはアプリ単位で認証を適用できますが、DBポートやSSHには使えません。DBへのアクセスはWireGuard/Headscaleを引き続き使います。
Q. ZitadelをB2B SaaSに使う場合のマルチテナント設定はどうすればよいですか?
A. Zitadelは「インスタンス→組織→ユーザー」の階層でマルチテナントを管理します。B2B SaaSでの設定パターン: ①1インスタンス・複数組織(推奨): 1つのZitadelインスタンスで顧客企業ごとに「組織」を作成。各組織が独立したユーザー管理・ポリシー・ブランドを持てる②カスタムドメイン: 顧客企業ごとにtenant1.auth.yoursite.comというドメインを付与し、ブランド付きログイン画面を表示③ロール管理: 組織ごとにロール(Admin/Member/Viewer等)を定義し、ZitadelのIDトークンにロール情報を含める。コードでの判定: JWTのurn:zitadel:iam:org:project:rolesクレームを取得してユーザーの権限を判断。Next.js実装: JWTにorg_idとroleを含め、middleware.tsでルートごとのアクセス制御を実装。
Q. KeycloakのSAML SSOをGoogle Workspaceと連携して全社ツールに適用する方法は?
A. 設定の流れはGoogle WorkspaceをIdP(Identity Provider)・Keycloakを中継として使います。①Google Workspace管理コンソール→アプリ→Webアプリとモバイルアプリ→アプリを追加→「カスタムSAMLアプリ」②Google SSO URLとSAML証明書をコピー③Keycloakの設定→Identity Providers→「SAML v2.0」→Google WorkspaceのSSO URLと証明書を貼り付け④Keycloakのグループ・ロールマッピング: GoogleのグループメンバーシップをKeycloakのロールにマッピング(例: Googleのengineeringグループ→Keycloakのdeveloperロール)⑤Keycloakをアプリケーションの認証基盤として設定(各アプリはKeycloakのOIDCを使う)。この構成のメリット: Google Workspaceを離職した社員は全アプリへのアクセスが自動的に無効化されます(Googleアカウント無効化→Keycloakへのログインも不可)。
まとめ
| ユースケース | 推奨ツール |
|---|---|
| エンタープライズ・SAML・実績重視 | Keycloak |
| モダンUI・プロキシモード | Authentik |
| B2B SaaS・マルチテナント | Zitadel |
| Auth0代替のファースト選択 | Authentik |