AuthentikをDockerで構築する:SSO・MFA対応のセルフホストIdentity ProviderとGitLab連携の実践ガイド

Security tutorial - IT technology blog
Security tutorial - IT technology blog

現実の問題:退職した社員のアカウント、誰が削除するのか?

昨年初頭、30人規模の会社のセキュリティ監査に参加した。GitLab、Jira、Confluence、Grafana、Kibanaと6台のLinuxサーバーを運用していた。調査したところ、6ヶ月前に退職した社員3名のアカウントがGitLab上でまだアクティブになっており、そのうち1つはMaintainer権限を持っていた。

誰も意図的に見落としたわけではない。単純に一元的な管理プロセスがなかっただけだ。10種類のシステムで手動でオフボーディングを行えば、1つ漏れるのは当然のことだ。Identity Provider(IdP)はまさにこの問題を解決するために生まれた——すべてのユーザーを一元管理し、一度のログインで全システムにアクセスでき(SSO)、一箇所で削除すれば全システムの権限が失われる。

4つのアプローチを比較する

1. 手動アカウント管理

アプリごとに個別のユーザー名/パスワードを管理する方式。初日からすぐに使え、セットアップは不要だ。

6ヶ月後に問題が浮上する。社員が複数のシステムで同じパスワードを使い回したり、「重要度の低い」アプリに123456を設定し始める。誰かが退職するたびに、ITは10〜15ものシステムで手動削除をしなければならない。監査ログはバラバラに散在し、システム全体で誰が何をしたか追跡できない。

2. LDAP / Active Directory

Windows Server 2000時代からある業界標準だ。Active DirectoryはMicrosoftエコシステムや多くのエンタープライズソフトウェアと非常によく連携する。

しかし、スタックがLinuxとオープンソース中心の場合は話が変わる。OpenLDAPにはフレンドリーなWeb管理UIがなく、LDIF形式での設定はかなり煩雑だ。Active DirectoryはWindows ServerのライセンスとWindowsで動くDomain Controllerが必要になる。さらに、どちらもWebベースのSSOやOIDC/OAuth2をビルトインでは持っておらず、別のコンポーネントを追加する必要がある。

3. クラウドIAM:Okta、Auth0、Azure Entra ID

マネージドサービスのため、自前でサーバーを運用する必要がない。数千のアプリとの統合、自動プロビジョニング、集中型の監査ログ、MFAがデフォルトで利用可能——当日中にセットアップを完了できる。

しかしコストが現実だ。Okta Workforce Identityは約$6/ユーザー/月——50人で年間$3,600、アドオン費用は別途かかる。Auth0は無料プランがあるものの、7,500アクティブユーザー上限があり、エンタープライズ機能も多数欠けている。データレジデンシーに関するコンプライアンス要件がある企業にとって、ユーザーデータが海外ベンダーのサーバーに置かれることは、実質的な障壁となる。

4. セルフホストIdentity Provider

データを自社で管理でき、ベンダー依存がなく、ユーザーごとの費用も発生しない。その代わり、運用・バックアップ・障害対応はすべて自分たちで行う必要がある。この分野で最も知名度の高い2つがKeycloakAuthentikだ。

Authentik vs Keycloak:どちらを選ぶか?

Keycloakはより歴史があり、エコシステムも充実し、エンタープライズ向けドキュメントも豊富だ。しかしセットアップはかなり重め——デフォルトでQuarkus上で動作し、RAMを多く消費し、管理UIも複雑で多くの概念を学ぶ必要がある(Realm、Client、Flow、Scopeなど)。

AuthentikはPython/Django + Vue.jsで書かれた後発のツールだ。UIははるかに直感的で、ドキュメントも都度Googleで調べなくても理解できる。最大の差別化ポイントはOutpost——任意のWebアプリの前段に配置するフォワード認証プロキシで、OIDC/SAMLに対応していないアプリも保護できる。Portainer Community EditionやレガシーのKibanaがOIDCに対応していなくても、Outpostを前段に置くだけで解決する。

率直に言う:IdPが初めてで半日で構築を終えたいなら——Authentikを選べ。すでにKeycloakに慣れたチームがSAPやOracleとの連携を必要とするなら、Keycloakのほうが適している。

AuthentikをDockerにデプロイする

事前準備

  • DockerとDocker Composeがインストール済みのLinuxサーバー(Docker公式ドキュメント参照)
  • サーバーに向けたドメイン——例:auth.company.com
  • SSL証明書(未取得の場合はCertbotを使用——ブログに専用記事あり)
  • 最低2GBのRAM(PostgreSQL + Redis + server + worker)

ステップ1:設定ファイルのダウンロードと環境変数の作成

mkdir -p /opt/authentik && cd /opt/authentik
wget https://goauthentik.io/docker-compose.yml

.envファイルに必要なシークレットを設定する:

# シークレットキーをランダム生成する
echo "PG_PASS=$(openssl rand -base64 36)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60)" >> .env

このステップでは、PostgreSQL用の強力なパスワード生成にtoolcraft.appのパスワードジェネレーターもよく使っている。100%ブラウザ上で動作するため、サーバーへのリクエストが発生せず、一般的なオンラインツールのようにパスワードがネット経由で漏れる心配がない。

ステップ2:docker-compose.ymlの構成を確認する

ダウンロードしたファイルはproduction環境にそのまま使える。主なサービス:

services:
  postgresql:
    image: docker.io/library/postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: ${PG_PASS:?database password required}
      POSTGRES_USER: ${PG_USER:-authentik}
      POSTGRES_DB: ${PG_DB:-authentik}

  redis:
    image: docker.io/library/redis:alpine

  server:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.4}
    command: server
    ports:
      - "9000:9000"   # HTTP
      - "9443:9443"   # HTTPS

  worker:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.4}
    command: worker

ステップ3:起動と管理者アカウントの作成

# イメージを取得して起動する
docker compose pull
docker compose up -d

# サーバーの準備完了をログで確認する
docker compose logs -f server

2〜3分ほど待つ。ログに... Runningが表示されればサーバーは起動完了だ。https://auth.company.com/if/flow/initial-setup/にアクセスして、akadminアカウントのパスワードを設定する。

ステップ4:最初のアプリケーションをOAuth2/OIDCで連携する

社員が1つのアカウントで両方にログインできるようGitLab連携を例に説明する。Authentik Admin UIでApplications → Create with Wizardに進む:

  • Name: GitLab
  • Provider type: OAuth2/OpenID Connect
  • Redirect URI: https://gitlab.company.com/users/auth/openid_connect/callback
  • Signing Key: デフォルトのキーを選択

作成後、Provider settingsセクションからClient IDClient Secretをコピーする。/etc/gitlab/gitlab.rbに以下を追加:

gitlab_rails['omniauth_providers'] = [
  {
    name: 'openid_connect',
    label: 'Authentik SSO',
    args: {
      name: 'openid_connect',
      scope: ['openid', 'profile', 'email'],
      response_type: 'code',
      issuer: 'https://auth.company.com/application/o/gitlab/',
      discovery: true,
      uid_field: 'preferred_username',
      client_options: {
        identifier: 'YOUR_CLIENT_ID',
        secret: 'YOUR_CLIENT_SECRET',
        redirect_uri: 'https://gitlab.company.com/users/auth/openid_connect/callback'
      }
    }
  }
]
gitlab-ctl reconfigure

ステップ5:全ユーザーへのMFA必須化を設定する

Flows & Stagesに移動し、default-authentication-flowを開いて、以下の設定でAuthenticator Validationステージを追加する:

  • Device classes:TOTP Authenticators(Google Authenticator、Authyなど)
  • Not configured action:Force the user to configure an authenticator

これ以降、ユーザーは初回ログイン時にどのアプリにもアクセスする前にTOTPのセットアップが求められる——MFAはIdPレベルで強制されるため、アプリごとに個別設定する必要がない。

数ヶ月の実運用から得た教訓

15人規模のチームで4GB RAMのVPS上でAuthentikを運用しているが、アイドル時の実際のメモリ使用量は約1.5GBだ。5ヶ月間、予期しない再起動は一度もなかった。最大のメリットは:社員のオフボーディング時にAuthentikで1ユーザーを無効化するだけで、SSO連携済みのすべてのアプリへのアクセスが自動的に失われる。30分かかっていた作業が30秒に短縮——10以上のシステムのチェックリストが不要になった。

最も重要なことを覚えておこう:PostgreSQLを定期的にバックアップすること。すべての設定、フロー、アプリケーション、ユーザー情報がそこに保存されている——データベースを失えばゼロから再構築することになる。

# 毎日バックアップするためcrontabに追加する
0 2 * * * docker exec authentik-postgresql-1 pg_dump -U authentik authentik > /backup/authentik-$(date +%Y%m%d).sql

OIDC/SAMLに対応していないアプリ——Portainer Community Edition、旧バージョンのKibana、あるいは社内の任意のWebアプリ——にはAuthentik Outpostが使える。アプリの前段にフォワード認証プロキシとして配置し、アプリのコードに一切手を加えることなくIdP経由で認証させることができる。Keycloakにはこの機能がビルトインされていない。

Share: