AI

IdP比較:Keycloak vs Authentik vs Zitadel でSSO・OIDCをセルフホストする

オープンソースラボ編集部2026年6月13日

IdP比較:Keycloak vs Authentik vs Zitadel でSSO・OIDCをセルフホストする

GitHub・Google・Slackのようなシングルサインオン(SSO)・OpenID Connect(OIDC)・SAMLを自社でセルフホストして、社内アプリの認証を一元管理するOSSアイデンティティプロバイダー(IdP)が充実しています。Keycloak(Red Hat製・最大シェア)・Authentik(Python製・DX重視)・Zitadel(Go製・クラウドネイティブ)の3つが2026年のOSS IdPデファクトスタンダードです。

セルフホストIdPを使う理由

  • コスト削減: Auth0($150〜/月)・Okta($2〜/ユーザー/月)→セルフホストで$20/月のVPS費用のみ
  • コンプライアンス: 社内ユーザーデータを外部サービスに送信せずオンプレ・プライベートクラウドで完全管理
  • SSO統合: 社内の全Webアプリ・CLI・APIを1つのログインで一元管理してパスワード管理コストを削減
  • LDAP/AD連携: 既存のActive Directory・LDAPディレクトリとフェデレーションしてユーザー同期

主要ツールの概要

Keycloak

2014年公開(Red Hat)、Java製のOSSです。GitHubスター23k+。世界最大シェアのOSS IdPで、OIDC・OAuth 2.0・SAML 2.0・WebAuthn・LDAP/AD連携・マルチテナント(Realms)・豊富なSPI拡張ポイントを持ちます。

# docker-compose.yml: Keycloak + PostgreSQL
version: "3.8"
services:
  keycloak:
    image: quay.io/keycloak/keycloak:26.0
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      KC_DB: postgres
      KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: ${KC_DB_PASSWORD}
      KC_HOSTNAME: auth.example.com
      KC_HOSTNAME_STRICT: "false"
      KC_HTTP_ENABLED: "true"
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: ${KC_ADMIN_PASSWORD}
    command: start
    depends_on: [postgres]

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: ${KC_DB_PASSWORD}
    volumes:
      - kc_pg_data:/var/lib/postgresql/data

volumes:
  kc_pg_data:
# Python: Keycloak Admin REST APIでユーザー管理を自動化
import requests
import json

KEYCLOAK_URL = 'http://localhost:8080'
REALM = 'myrealm'
ADMIN_USER = 'admin'
ADMIN_PASSWORD = 'admin-password'

def get_admin_token() -> str:
    '''管理者トークンを取得'''
    resp = requests.post(
        f'{KEYCLOAK_URL}/realms/master/protocol/openid-connect/token',
        data={
            'grant_type': 'password',
            'client_id': 'admin-cli',
            'username': ADMIN_USER,
            'password': ADMIN_PASSWORD,
        },
    )
    return resp.json()['access_token']

def create_user(token: str, username: str, email: str, password: str, roles: list[str] = None):
    '''ユーザーを作成して初期パスワードを設定'''
    headers = {'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'}

    # ユーザー作成
    user_data = {
        'username': username,
        'email': email,
        'enabled': True,
        'emailVerified': True,
        'credentials': [{'type': 'password', 'value': password, 'temporary': False}],
        'attributes': {'locale': ['ja']},
    }
    resp = requests.post(
        f'{KEYCLOAK_URL}/admin/realms/{REALM}/users',
        headers=headers,
        json=user_data,
    )
    user_id = resp.headers['Location'].split('/')[-1]

    # ロールを付与
    if roles:
        role_reps = []
        for role_name in roles:
            role_resp = requests.get(
                f'{KEYCLOAK_URL}/admin/realms/{REALM}/roles/{role_name}',
                headers=headers,
            )
            role_reps.append(role_resp.json())
        requests.post(
            f'{KEYCLOAK_URL}/admin/realms/{REALM}/users/{user_id}/role-mappings/realm',
            headers=headers,
            json=role_reps,
        )
    return user_id

def bulk_sync_users(token: str, users: list[dict]):
    '''CSVからユーザーを一括インポート'''
    for user in users:
        create_user(token, user['username'], user['email'], user['temp_password'], user.get('roles', []))
        print(f'作成: {user["username"]}')

# Next.js との OIDC 統合
# next-auth の keycloak プロバイダー設定例
nextauth_config = '''
// app/api/auth/[...nextauth]/route.ts
import NextAuth from 'next-auth'
import KeycloakProvider from 'next-auth/providers/keycloak'

const handler = NextAuth({
  providers: [
    KeycloakProvider({
      clientId: process.env.KEYCLOAK_CLIENT_ID,
      clientSecret: process.env.KEYCLOAK_CLIENT_SECRET,
      issuer: process.env.KEYCLOAK_ISSUER,  // http://localhost:8080/realms/myrealm
    }),
  ],
  callbacks: {
    jwt: async ({ token, account }) => {
      if (account) {
        token.accessToken = account.access_token
        token.roles = account.id_token ? JSON.parse(atob(account.id_token.split(".")[1])).realm_access?.roles : []
      }
      return token
    },
    session: ({ session, token }) => ({
      ...session,
      accessToken: token.accessToken,
      roles: token.roles,
    }),
  },
})
export { handler as GET, handler as POST }
'''

Authentik

2019年公開、Python製のOSSです。GitHubスター14k+。UI/UXとDXに優れたOSS IdPで、Flowデザイナー(GUIでログインフローをノードで設計)・豊富なSocial Login(GitHub・Google・Discord・Twitter)・Outpost(リバースプロキシとして認証バイパス不要のミドルウェア統合)が特徴です。

# docker-compose.yml: Authentik
version: "3.8"
services:
  postgresql:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: ${PG_PASS}
      POSTGRES_USER: authentik
      POSTGRES_DB: authentik
    volumes:
      - database:/var/lib/postgresql/data

  redis:
    image: redis:alpine
    command: --save 60 1 --loglevel warning
    volumes:
      - redis:/data

  server:
    image: ghcr.io/goauthentik/server:2024.12
    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: ${PG_PASS}
      AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
    ports:
      - "9000:9000"

  worker:
    image: ghcr.io/goauthentik/server:2024.12
    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: ${PG_PASS}
      AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}

volumes:
  database:
  redis:

Zitadel

2020年公開、Go製のOSSです。GitHubスター9k+。クラウドネイティブ設計・単一バイナリ・CockroachDB/PostgreSQL対応のGo製IdPです。マルチテナント・組織・プロジェクト管理をAPIファーストで提供し、Kubernetes上での運用に優れています。

# Zitadel 単一バイナリでの起動(開発環境)
curl -L https://github.com/zitadel/zitadel/releases/download/v2.65.0/zitadel_Linux_x86_64.tar.gz | tar xz
./zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled

# Next.js との統合(OIDC)
# ZITADEL_ISSUER=http://localhost:8080
# ZITADEL_CLIENT_ID=<your-client-id>

機能比較表

比較項目KeycloakAuthentikZitadel
SAML 2.0
LDAP/AD連携✅ 最強
FlowデザイナーUI
クラウドネイティブ
メモリ消費△(Java)✅(Go)
GitHub Stars23k+14k+9k+

IdP・認証基盤はセキュリティカテゴリ/categories/securityの中核インフラとして全社アプリのOIDC統合・ロールベースアクセス制御(RBAC)を担います。DevOpsカテゴリ/categories/devopsのGitLab CE・Grafana・MinIOなどのサービスをKeycloakのSAML/OIDCで統合してSSOを実現する構成が大企業で広く採用されています。

FAQ

Q. KeycloakでNext.jsアプリにSSO認証を設定するには?

A. Keycloakでクライアントを作成してnext-authのKeycloakProviderを設定します。Keycloak側: ①Admin UI→Realm作成②Clients→Create→Client ID: nextjs-app・Client Protocol: openid-connect・Root URL: http://localhost:3000③Access Type: confidential→Save→Credentials TabでSecret取得。Next.js側: KEYCLOAK_CLIENT_ID=nextjs-appKEYCLOAK_CLIENT_SECRET=<secret>KEYCLOAK_ISSUER=http://localhost:8080/realms/myrealm.env.localに設定→NextAuthKeycloakProvider設定でログインが動作します。ロール取得: JWTのrealm_access.rolesクレームからロール配列を抽出してNext.jsのsessionオブジェクトに追加することでsession.roles.includes('admin')でRBAC判定が可能です。

Q. AuthentikのOutpostでNginxを認証プロキシとして使うには?

A. AuthentikのProxy Providerを設定してNginxのauth_requestディレクティブで統合します。手順: ①Authentik Admin→Applications→Create→Provider Type: Proxy Provider②Mode: Forward authを選択→External Host: https://myapp.example.com③Outpost(proxy)にアプリを追加④Nginx設定: auth_request /outpost.goauthentik.io/auth/nginx;auth_request_set $auth_cookie $upstream_http_set_cookie;error_page 401 = @goauthentik_proxy_signin;⑤Authentik Dockerコンテナ起動時にOutpostが自動生成されます。効果: これにより認証コードをアプリに追加せずNginx層で全リクエストをAuthentikに認証してもらえます。

Q. KeycloakとAuthentikのどちらを選べばいいですか?

A. エンタープライズ・SAML・LDAP統合・大規模組織ならKeycloakDX重視・Visual Flow・プロダクト内埋め込み認証・スタートアップならAuthentikが向いています。Keycloak優位: ①Java/Quarkusベースで高い拡張性(SPI)②SAP・Oracle・Microsoft ADとのLDAP連携実績が最多③Red HatのエンタープライズサポートRHBK④FAPI(Financial Grade API)対応で金融・決済システム向け認証に準拠。Authentik優位: ①FlowデザイナーでGUIでログインフローをノード設計②Social Login(Discord・Twitch・GitHub)が多く設定が容易③メモリ消費がKeycloakより少ない(Python + DjangoだがKeycloak/JVMより軽量)④UI/UXがモダンで認証画面のカスタマイズが容易。

Q. ZitadelをKubernetesで本番運用するには?

A. Helm ChartでZitadelをKubernetes上にデプロイします。①helm repo add zitadel https://charts.zitadel.comhelm install zitadel zitadel/zitadel --values values.yamlvalues.yamlでPostgreSQL接続・TLS・Ingress・replica数を設定③ZitadelはCockroachDB(分散PostgreSQL互換)と組み合わせると水平スケールが最も容易④メトリクス: /debug/metrics(Prometheus形式)でPrometheus + Grafanaによる監視が可能⑤水平スケール: replicaCount: 3でZitadelをステートレスに3Pod並列実行(DBがセッション管理を担う)。高可用性構成: ZitadelをKubernetes外部のCockroachDBと組み合わせたマルチリージョン構成でRTO(目標復旧時間)を最小化できます。

まとめ

ユースケース推奨ツール
SAML・LDAP・エンタープライズ・大規模Keycloak
Visual Flow・DX重視・プロキシ統合Authentik
Go・K8s・クラウドネイティブ・マルチテナントZitadel

関連外部リソース

他の記事も読む

Let's Build Together

OSS導入、自社だけで悩まない。

ツール選定から構築・運用・AI活用まで、オープンソースラボ運営元のClasslessが伴走します。初回のご相談は無料です。