はじめに — なぜ今Identity-Aware Proxyなのか
2026年現在、「社内ネットワークにいれば信頼する」という前提は、事実上廃止されたセキュリティモデルです。リモートワークが標準になり、ワークロードはマルチクラウドに分散し、SaaSと社内ツールの境界も曖昧になりました。さらにAIエージェントが人間の代わりに社内システムへアクセスする流れが加わり、「誰が(あるいは何が)どのコンテキストでアクセスするのか」をリクエストごとに検証するidentity-firstセキュリティがデフォルトになっています。
本記事では、Zero Trustの中核的な実装であるIdentity-Aware Proxy(IAP)を扱います。GoogleのBeyondCorp論文が示したモデルを理解し、oauth2-proxyと[Keycloak](https://www.keycloak.org/documentation)を組み合わせてIAPを自分で構築する全過程を、YAMLや設定ファイルのレベルまで追っていきます。最後にCloudflare Access、Google Cloud IAP、Pomeriumといった商用/オープンソースの代替を比較し、段階的な導入ロードマップとAIエージェント時代のアクセス制御まで見ていきます。
境界型セキュリティの終焉とidentity-firstセキュリティ
城と堀モデルの限界
従来のネットワークセキュリティはしばしば「城と堀(castle-and-moat)」モデルと呼ばれます。ファイアウォールとVPNで境界を築き、いったん内部に入ったトラフィックは広く信頼する方式です。このモデルの問題は明確です。
- 攻撃者が境界を一度突破すれば(フィッシング、VPN資格情報の窃取、脆弱性)、内部での水平移動(lateral movement)は自由です。
- VPNはネットワーク全体へのアクセスを付与します。特定のアプリ1つだけ使いたい外部委託者にも、事実上社内ネットワーク全体が開放されます。
- 位置ベースの信頼は、リモートワーク、BYOD、マルチクラウド環境では意味を失います。
- 内部脅威と侵害された端末に対して無防備です。
Zero Trustの基本原則
Zero TrustはNIST SP 800-207で標準化された概念で、次の原則に要約されます。
1. **ネットワーク上の位置は信頼の根拠にならない** — 社内ネットワークでもカフェのWi-Fiでも同一に扱います。
2. **すべてのアクセスは認証・認可されなければならない** — セッション単位ではなくリクエスト単位で検証します。
3. **最小権限** — ユーザーとデバイスは業務に必要なリソースにのみアクセスします。
4. **コンテキストベースの動的ポリシー** — ユーザーの身元、デバイスの状態、位置、時間などを総合してアクセスを判断します。
5. **継続的な検証** — 一度通過したら終わりではなく、シグナルが変われば再評価されます。
この原則をHTTPアプリケーション層で実装するコンポーネントがIdentity-Aware Proxyです。
BeyondCorp論文の核心
Googleは2009年のOperation Aurora侵害事件を契機に、社内VPNを段階的に廃止し、すべての社内アプリケーションをインターネットに公開しつつアクセスプロキシで保護するBeyondCorpプロジェクトを開始しました。[BeyondCorp論文シリーズ](https://research.google/pubs/pub43231/)の主要コンポーネントは次のとおりです。
- **Access Proxy** — すべてのアプリケーションの前段に位置するリバースプロキシ。TLS終端、認証、認可を中央で処理します。
- **Device Inventory Database** — 会社が管理するすべてのデバイスの状態(OSバージョン、パッチレベル、ディスク暗号化の有無)を追跡します。
- **User/Group Database** — HRシステムと同期されるユーザー身元ストアです。
- **Trust Inference** — ユーザーとデバイスのシグナルを総合し、信頼レベル(trust tier)を動的に算出します。
- **Access Control Engine** — 「このユーザーが、このデバイスで、このアプリケーションに」アクセス可能かをポリシーで判断します。
BeyondCorpが残した最も重要な教訓は2つです。第一に、**認証と認可をアプリケーションから切り離してプロキシ層に集約**すれば、数百の社内アプリのセキュリティ水準を一括で引き上げられること。第二に、**ユーザーの身元だけでは不十分で、デバイスの信頼も併せて評価**しなければならないことです。
IAPの動作原理 — すべてのリクエストに認証と認可
IAPの動作を1枚で表すと次のようになります。
+----------------------------+
| Identity Provider (IdP) |
| Keycloak / OIDC |
+-------------+--------------+
| (2) OIDC認証
| Authorization Code + PKCE
+----------+ (1) HTTPS +----------+-----------+ (4) ヘッダー注入 +-------------+
| ユーザーの +-------------->+ Identity-Aware Proxy +------------------->+ 社内アプリ |
| ブラウザ | | (oauth2-proxyなど) | X-Forwarded-* | (adminなど) |
+----------+ +----------+-----------+ +-------------+
|
| (3) ポリシー評価
| - ユーザーのグループ/ロール
| - デバイスの状態
| - 位置/時間コンテキスト
v
+----------------------+
| Policy / Device DB |
+----------------------+
リクエスト処理の流れを段階ごとに見ると次のとおりです。
1. ユーザーが保護対象アプリのURLにアクセスすると、リクエストは必ずIAPを経由します。IAPを迂回した直接アクセスはネットワークポリシーで遮断します。
2. 有効なセッションがなければ、IAPはOIDC Authorization Code Flow(PKCE付き)でIdPに認証を委譲します。
3. 認証が完了すると、IAPはIDトークンのクレーム(グループ、ロール)と追加コンテキスト(デバイス、IP、時間)に基づいて認可ポリシーを評価します。
4. 通過したリクエストにのみユーザー身元ヘッダー(または署名済みJWT)を付与してアップストリームのアプリへ転送します。
5. このプロセスは初回ログイン後も**すべてのリクエストごとに**、セッションCookieの検証とポリシー再評価の形で繰り返されます。セッションは短く保ち、refreshのたびにIdPの最新状態(アカウント無効化、グループ変更)を反映します。
従来型VPNとの違いを表で整理します。
| 項目 | VPN | Identity-Aware Proxy |
| ------------ | ---------------------------- | ----------------------------------- |
| 信頼の単位 | ネットワーク(入れば終わり) | リクエスト(毎回認証/認可) |
| アクセス範囲 | 社内ネットワーク全体やサブネット | アプリケーション単位 |
| 認可の基準 | IP、アカウント | 身元 + グループ + デバイス + コンテキスト |
| 可視性 | トンネル内部は不透明 | リクエスト単位の監査ログ |
| ユーザー体験 | クライアント導入、接続断 | ブラウザだけでSSO |
| L3/L4対応 | 可能 | 基本はHTTP、TCPは別ソリューション |
実践構築 — oauth2-proxy + KeycloakでIAPを作る
それでは実際に作ってみます。構成は次のとおりです。
- IdP: Keycloak 26.6(2026年5月時点で26.6.2が最新、パスキーのログイン統合とFAPI 2.0 Final対応を含む)
- IAP: [oauth2-proxy](https://oauth2-proxy.github.io/oauth2-proxy/) 7.x
- リバースプロキシ: nginx ingress(auth_requestパターン)
- 保護対象: Kubernetesにデプロイされた社内admin用ダッシュボード
ステップ1 — Keycloakクライアントの設定
まずKeycloakにoauth2-proxy用のconfidential clientを作成します。realmはinternalと仮定します。Keycloak Admin CLI(kcadm)で次のように作成します。
Keycloak admin CLIにログイン
kcadm.sh config credentials \
--server https://keycloak.example.com \
--realm master \
--user admin
oauth2-proxy用クライアントを作成
kcadm.sh create clients -r internal -f - <<'EOF'
{
"clientId": "oauth2-proxy",
"protocol": "openid-connect",
"publicClient": false,
"standardFlowEnabled": true,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"redirectUris": ["https://admin.example.com/oauth2/callback"],
"attributes": {
"pkce.code.challenge.method": "S256",
"post.logout.redirect.uris": "https://admin.example.com"
}
}
EOF
グループ情報をトークンに含めるため、groupsクレームのマッパーを追加します。
groupsクレームをIDトークンに含めるマッパー
CLIENT_UUID=$(kcadm.sh get clients -r internal -q clientId=oauth2-proxy --fields id --format csv --noquotes)
kcadm.sh create clients/$CLIENT_UUID/protocol-mappers/models -r internal -f - <<'EOF'
{
"name": "groups",
"protocol": "openid-connect",
"protocolMapper": "oidc-group-membership-mapper",
"config": {
"claim.name": "groups",
"full.path": "false",
"id.token.claim": "true",
"access.token.claim": "true",
"userinfo.token.claim": "true"
}
}
EOF
Keycloak 26.6からはログインフォームにパスキーが条件付きUIとして統合されているため、internal realmの認証フローでWebAuthn Passwordlessポリシーを有効にすれば、パスワードレスの一次認証をデフォルトにできます。Zero Trustにおいて、フィッシング耐性のある認証手段は事実上必須です([WebAuthn Level 3](https://www.w3.org/TR/webauthn-3/)、[FIDO passkeys](https://fidoalliance.org/passkeys/)を参照)。
ステップ2 — oauth2-proxyのデプロイ
Kubernetesにoauth2-proxyをデプロイします。マニフェスト全体は次のとおりです。
apiVersion: v1
kind: Secret
metadata:
name: oauth2-proxy-secrets
namespace: iap
type: Opaque
stringData:
client-secret: 'REPLACE_WITH_KEYCLOAK_CLIENT_SECRET'
python -c 'import secrets; print(secrets.token_urlsafe(32))'
cookie-secret: 'REPLACE_WITH_32_BYTE_RANDOM'
apiVersion: apps/v1
kind: Deployment
metadata:
name: oauth2-proxy
namespace: iap
labels:
app: oauth2-proxy
spec:
replicas: 2
selector:
matchLabels:
app: oauth2-proxy
template:
metadata:
labels:
app: oauth2-proxy
spec:
containers:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.8.1
args:
- --provider=keycloak-oidc
- --client-id=oauth2-proxy
- --oidc-issuer-url=https://keycloak.example.com/realms/internal
- --code-challenge-method=S256
- --redirect-url=https://admin.example.com/oauth2/callback
- --email-domain=example.com
- --allowed-group=platform-admins
- --scope=openid email profile groups
- --cookie-secure=true
- --cookie-samesite=lax
- --cookie-refresh=4m
- --cookie-expire=8h
- --session-store-type=redis
- --redis-connection-url=redis://redis.iap.svc.cluster.local:6379
- --set-xauthrequest=true
- --set-authorization-header=true
- --pass-access-token=false
- --skip-provider-button=true
- --reverse-proxy=true
- --http-address=0.0.0.0:4180
- --metrics-address=0.0.0.0:44180
env:
- name: OAUTH2_PROXY_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-secrets
key: client-secret
- name: OAUTH2_PROXY_COOKIE_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-secrets
key: cookie-secret
ports:
- containerPort: 4180
name: http
- containerPort: 44180
name: metrics
readinessProbe:
httpGet:
path: /ping
port: 4180
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 256Mi
apiVersion: v1
kind: Service
metadata:
name: oauth2-proxy
namespace: iap
spec:
selector:
app: oauth2-proxy
ports:
- name: http
port: 4180
targetPort: 4180
この設定で注目すべき点は次のとおりです。
- **code-challenge-method=S256** — OAuth 2.1 draftが事実上義務化したPKCEをconfidential clientにも適用します([RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636)、[draft-ietf-oauth-v2-1](https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-1/))。
- **allowed-group=platform-admins** — Keycloakのグループに基づく一次認可をプロキシで実施します。
- **cookie-refresh=4m** — 4分ごとにrefresh tokenでセッションを更新し、IdPの最新状態を反映します。アカウントが無効化されれば数分以内にアクセスが遮断されます。
- **session-store-type=redis** — Cookieにトークン全体を入れず、Redisにセッションを保存することで、Cookieサイズの問題とトークン露出を軽減します。
- **set-xauthrequest=true** — nginx auth_requestのレスポンスにX-Auth-Request-User、X-Auth-Request-Email、X-Auth-Request-Groupsヘッダーを載せ、アップストリームへ渡せるようにします。
ステップ3 — nginx auth_requestパターンの連携
nginxのauth_requestは「本リクエストを処理する前にサブリクエストを送って認証の有無を確認する」ディレクティブです。IAPパターンの要となる接着剤です。
server {
listen 443 ssl;
server_name admin.example.com;
ssl_certificate /etc/nginx/tls/tls.crt;
ssl_certificate_key /etc/nginx/tls/tls.key;
認証チェックのサブリクエスト — oauth2-proxyの /oauth2/auth は
認証済みなら202、そうでなければ401を返す
location = /oauth2/auth {
internal;
proxy_pass http://oauth2-proxy.iap.svc.cluster.local:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
ボディの転送は不要
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
ログインフロー(リダイレクト、コールバック、ログアウト)
location /oauth2/ {
proxy_pass http://oauth2-proxy.iap.svc.cluster.local:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
auth_request /oauth2/auth;
401ならログインへリダイレクト
error_page 401 = /oauth2/start?rd=$scheme://$host$request_uri;
authサブリクエストのレスポンスヘッダーから身元情報を取り出し
アップストリームへ注入する
auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $email $upstream_http_x_auth_request_email;
auth_request_set $groups $upstream_http_x_auth_request_groups;
proxy_set_header X-Forwarded-User $user;
proxy_set_header X-Forwarded-Email $email;
proxy_set_header X-Forwarded-Groups $groups;
ユーザーが偽造した身元ヘッダーが通らないよう
上のproxy_set_headerが常に上書きする構造を維持する
proxy_pass http://admin-dashboard.apps.svc.cluster.local:8080;
}
}
Kubernetesのingress-nginxを使うなら、同じパターンをアノテーションで表現できます。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: admin-dashboard
namespace: apps
annotations:
nginx.ingress.kubernetes.io/auth-url: 'https://admin.example.com/oauth2/auth'
nginx.ingress.kubernetes.io/auth-signin: 'https://admin.example.com/oauth2/start?rd=$scheme://$host$request_uri'
nginx.ingress.kubernetes.io/auth-response-headers: 'X-Auth-Request-User, X-Auth-Request-Email, X-Auth-Request-Groups'
spec:
ingressClassName: nginx
rules:
- host: admin.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-dashboard
port:
number: 8080
tls:
- hosts:
- admin.example.com
secretName: admin-dashboard-tls
ステップ4 — プロキシ迂回の遮断
IAPは迂回経路が1つでもあれば無力化されます。NetworkPolicyで、アップストリームのアプリがingressコントローラーからのトラフィックのみ受け付けるよう強制します。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: admin-dashboard-only-from-ingress
namespace: apps
spec:
podSelector:
matchLabels:
app: admin-dashboard
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
ports:
- protocol: TCP
port: 8080
さらに、アップストリームのアプリは身元ヘッダーを信頼する前に「このリクエストは本当にプロキシから来たのか」を確認すべきです。最も堅牢な方法は、oauth2-proxyのset-authorization-headerで署名済みIDトークン(JWT)を受け取り、アプリ側で署名を検証することです。平文ヘッダーだけを信頼する構成は、内部ネットワークが侵害された場合に偽造のリスクがあります。
デバイス信頼とコンテキストベースのポリシー
BeyondCorpモデルの半分はデバイス信頼です。ユーザー認証がどれだけ強くても、マルウェアに感染した端末ならアクセスを制限すべきです。実務で段階的に適用できる方法は次のとおりです。
1. **mTLSクライアント証明書** — MDM(Intune、Jamfなど)で会社管理端末にのみクライアント証明書を配布し、プロキシでTLSクライアント認証を要求します。「管理端末かどうか」を最もシンプルに証明する方式です。
2. **デバイスポスチャーのシグナル** — EDR/MDMのAPIからOSバージョン、ディスク暗号化、画面ロックの有無を取得し、ポリシーエンジンに供給します。Cloudflare AccessやPomeriumはデバイスポスチャー連携を内蔵しています。
3. **信頼レベル(trust tier)** — BeyondCorpのようにデバイスをfully-trusted、managed、unknownに分類し、アプリケーションの機密度とマッチングします。例えば決済adminはfully-trusted端末のみ、wikiはmanaged以上でアクセス可能とします。
nginx層でmTLSを要求する設定例は次のとおりです。
server {
listen 443 ssl;
server_name payments-admin.example.com;
ssl_client_certificate /etc/nginx/tls/device-ca.crt;
ssl_verify_client on;
location / {
auth_request /oauth2/auth;
デバイス証明書の情報をアップストリームと監査ログへ渡す
proxy_set_header X-Device-Cert-DN $ssl_client_s_dn;
proxy_set_header X-Device-Cert-Verify $ssl_client_verify;
proxy_pass http://payments-admin.apps.svc.cluster.local:8080;
}
}
コンテキストベースのポリシーとは、「同じユーザーでも状況によって異なる判断」を下すことです。代表的なシグナルとポリシー例は次のとおりです。
| シグナル | ポリシー例 |
| -------------- | ---------------------------------------------------------- |
| デバイスレベル | 非管理端末は読み取り専用アプリのみ許可 |
| 位置 | 許可国以外からのアクセスにはstep-up認証(パスキー再認証)を要求 |
| 時間 | 業務時間外の本番admin操作には承認ワークフローが必要 |
| 認証強度 | パスワードのみでログインしたセッションは機密アプリへアクセス不可 |
| 異常シグナル | 不可能な移動(impossible travel)検知時はセッションを即時失効 |
Keycloakでは認証フローの条件付き実行とstep-up authentication(ACR/LoA)で認証強度ポリシーを実装でき、26.6のWorkflows機能でアカウントライフサイクルの自動化(長期未使用アカウントの無効化など)をrealmレベルで構成できます。
VPN代替シナリオ
IAPでVPNを置き換える典型的なシナリオを整理します。
[Before] 全社員 --> VPN Gateway --> 社内ネットワーク全体 (wiki, CI, admin, DB, SSH ...)
[After]
社員/委託先 --> IAP (HTTPS) --> wiki、CI、adminなどのWebアプリ (トラフィックの大半)
運用者 --> SSH/DB専用ソリューション(Boundary、Teleportなど) (非HTTPプロトコル)
レガシー --> 残存VPN (段階的に縮小、対象サブネットを最小化)
ポイントは次のとおりです。
- 社内トラフィックの大半を占めるWebアプリケーションからIAPへ移行すると、VPNの同時接続負荷とヘルプデスクのチケットが激減します。
- SSH、データベース、RDPのような非HTTPプロトコルはIAPの守備範囲ではないため、Teleport、Boundary、Cloudflare Tunnel(TCP)などの専用ソリューションで同じidentity-firstの原則を適用します。
- 委託先やパートナーにはVPNアカウントの代わりに特定アプリへのIAPアクセスのみを付与します。オフボーディングはIdPでアカウントを無効化するだけで完了します。
Cloudflare Access vs Google Cloud IAP vs Pomerium vs oauth2-proxy
| 項目 | Cloudflare Access | Google Cloud IAP | Pomerium | oauth2-proxy |
| ---------------- | ---------------------- | -------------------------- | ------------------------------ | --------------------- |
| 形態 | SaaS(エッジネットワーク) | GCPマネージド | オープンソース + 商用 | オープンソース |
| 稼働場所 | Cloudflareエッジ | GCP LBと統合 | セルフホスト | セルフホスト |
| IdP連携 | あらゆるOIDC/SAML | Google + 外部IdP連携 | あらゆるOIDC | あらゆるOIDC |
| デバイスポスチャー | 内蔵(WARPクライアント) | 内蔵(Endpoint Verification) | 内蔵(Pomerium Zero含む) | なし(自前で構成) |
| ポリシー表現力 | グループ、国、デバイスなど | IAM条件 + Access Levels | Rego/式ベースの精緻なポリシー | グループ/メール程度 |
| 非HTTP対応 | TCP/UDP (Tunnel) | TCP forwarding | TCP対応 | なし |
| ロックイン | Cloudflare依存 | GCP依存 | 低い | 低い |
| コスト | ユーザー単位課金 | GCP料金に含まれる | OSS無料 + 商用オプション | 無料 |
選定ガイドは次のとおりです。
- **GCP中心のインフラ**なら、Google Cloud IAPがLBとIAMに自然に統合され、運用負担が最も小さくなります。
- **マルチクラウド + SaaSエッジ志向**なら、Cloudflare Accessがデバイスポスチャーと非HTTPまで含む最も完成されたパッケージです。
- **セルフホスト + 精緻なポリシー**が必要なら、Pomeriumがoauth2-proxyよりポリシー表現力(コンテキスト条件、デバイス身元)で優れています。
- **シンプルなグループベース保護 + 最小依存**なら、oauth2-proxy + nginxの組み合わせが軽量で実績のある選択です。
事例 — 社内adminツールの保護
実務で最も一般的で効果が大きい適用対象は社内adminツールです。Grafana、ArgoCD、Airflow、自社開発のバックオフィスのような、「認証が弱い、あるいは独自のアカウント体系を持つ」ツールが対象です。
典型的な適用パターンは次のとおりです。
1. adminツール自体のログイン画面を無効化するか、ヘッダー/OIDC認証モードに切り替えます。例えばGrafanaはauth.proxy設定でX-Forwarded-Userヘッダーを信頼させられます。
grafana.ini — IAPの背後でのヘッダーベース認証
[auth.proxy]
enabled = true
header_name = X-Forwarded-User
header_property = username
auto_sign_up = true
sync_ttl = 60
プロキシのIPのみ信頼(偽造防止の最後の砦)
whitelist = 10.0.0.0/8
2. IAP側でツールごとに許可グループを分けます。ArgoCDはplatformチームのグループのみ、Airflowはdataチームのグループのみ通す、といった具合です。ツールごとにoauth2-proxyを個別に立てるか、Pomeriumのようにルート単位のポリシーをサポートするプロキシを使います。
3. すべてのアクセスを構造化ログに残します。誰が、いつ、どのデバイスで、どのアプリにアクセスしたかがリクエスト単位で記録されるため、監査対応が容易になります。
4. break-glass経路を設計します。IdP障害時にadminツールへアクセスする緊急手順(一時的な静的資格情報 + 強力な監査)を文書化します。
段階的な導入ロードマップ
Zero Trustはビッグバン移行ではなく旅路です。現実的なロードマップは次のとおりです。
Phase 0 現状把握 (1か月)
- 社内アプリのインベントリ、認証方式、機密度の分類
- IdPの整備: グループ/ロール体系、MFA(可能ならパスキー)有効化
Phase 1 パイロット (1〜2か月)
- 低リスクのアプリ2〜3個(wiki、ダッシュボード)をIAPの背後へ移行
- ログインUX、セッションポリシー、障害モードの検証
Phase 2 拡大 (3〜6か月)
- adminツール全体 + 新規アプリはデフォルトでIAP適用
- デバイス証明書(mTLS)の配布、信頼レベルの導入
- 非HTTPアクセス(SSH/DB)にTeleportなどを導入
Phase 3 VPN縮小 (6〜12か月)
- VPNのアクセス対象をレガシーシステムに限定
- コンテキストベースのポリシー(位置、時間、step-up)の高度化
- ポリシーのコード化(IaC)と定期アクセスレビューの自動化
Phase 4 継続的改善
- セッション異常検知、リスクベースの再認証
- ワークロードidentity(SPIFFE)とユーザーidentityのポリシー統合
各フェーズで測定する指標も併せて定義するとよいでしょう。VPN同時接続数、IAPの背後へ移行したアプリの割合、平均オンボーディング/オフボーディング時間、認証関連のヘルプデスクチケット数が代表的です。
2026年の視点 — AIエージェントのアクセス制御まで
2026年の新しい課題は、人間ではない主体、特にAIエージェントによる社内システムへのアクセスです。エージェントが社内wikiを検索しadmin APIを呼び出すシナリオが日常化するにつれ、IAPのポリシー対象は「ユーザー + デバイス」から「ユーザー + デバイス + エージェント」へ拡大しています。
実務的に整理すると次のとおりです。
- **エージェントも第一級のidentityであるべきです。** 人間アカウントのAPIキーをエージェントにコピーして渡すアンチパターンの代わりに、エージェント専用クライアントをIdPに登録し、短命のトークンを発行します。Keycloak 26.6のOAuth Client ID Metadata Document(CIMD)実験的サポートは、MCP(Model Context Protocol)ベースのエージェントが事前登録なしでも標準的にクライアント身元を提示するフローを可能にします。
- **委譲チェーンの保存** — 「どのユーザーの代わりに、どのエージェントが呼び出しているのか」をトークンに記録すべきです。OAuth Token Exchange([RFC 8693](https://datatracker.ietf.org/doc/html/rfc8693))のactorクレームとdelegationパターンが標準のツールです。
- **エージェント専用ポリシー** — エージェントには人間より狭いスコープ、短いトークン寿命、より厳しいレート制限と監査を適用します。IAP層でエージェントのトラフィックを識別(クライアント身元ベース)し、別のポリシーバンドルで評価する構造が定着しつつあります。
- **非HTTPのツール呼び出し** — MCPサーバーのようにエージェントが使うツールエンドポイントもIAPの背後に置き、エージェントのOAuthトークンを検証するパターンが推奨されます。KeycloakがMCP authorization serverの役割を担えるようになったのもこの文脈です。
BeyondCorpが「位置から身元へ」の転換だったとすれば、今は「人間の身元からすべての主体(human + non-human)の身元へ」の転換が進行中です。IAPを導入する際は、ポリシーモデルを人間専用に狭く設計せず、主体(subject)の抽象を広く取っておくことが2026年の設計ポイントです。
運用ベストプラクティスとアンチパターン
最後に運用観点のチェックリストを整理します。
**ベストプラクティス**
- セッションCookieはSecure + HttpOnly + SameSite=Lax以上とし、cookie-refreshでIdPの状態を定期的に反映します。
- IdP、IAP、アップストリームの時計がずれるとトークン検証が壊れます。NTP同期を監視します。
- oauth2-proxyのメトリクス(ポート44180)をPrometheusで収集し、認証失敗率、セッション更新失敗率にアラートを設定します。
- IdP障害は全社アプリ障害に直結するため、Keycloakはマルチインスタンス + 26.6のzero-downtime rolling patch updateで無停止パッチを運用します。
- ポリシー変更はコードレビューを経るIaCで管理し、「誰がどのアプリにアクセスできるのか」を定期的にレビューします。
**アンチパターン**
- 署名検証なしで身元ヘッダーを信頼し、NetworkPolicyもない構成 — ヘッダー偽造一発で突破されます。
- IAP導入後もアプリ自体のログイン経路を残しておくこと — 迂回経路は必ず除去します。
- セッション有効期限を極端に長く(数週間)設定すること — Zero Trustの「継続的な検証」と矛盾します。
- すべてのアプリに同一ポリシーを適用すること — 機密度に基づく差別化ポリシーがZero Trustの本質です。
- VPNを一夜で停止するビッグバン移行 — レガシーと非HTTPトラフィックの対策なしに強行すると業務が止まります。
おわりに
Identity-Aware ProxyはZero Trustを最も早く体感できる実装です。oauth2-proxy + Keycloak + nginx auth_requestという実績あるオープンソースの組み合わせだけで、BeyondCorpの核心である「すべてのリクエストに認証と認可」を今日から始められます。重要なのはツールではなく原則です。位置ではなく身元、セッションではなくリクエスト、静的なルールではなくコンテキスト。そして2026年には、その身元の範囲がAIエージェントまで広がったことを設計の初期から織り込んでください。
次回はIAPの先、すなわちAPI Gatewayとサービスメッシュ層でのトークン検証(Istio、Envoy)を扱います。
参考資料
- [BeyondCorp: A New Approach to Enterprise Security (Google Research)](https://research.google/pubs/pub43231/)
- [NIST SP 800-207 Zero Trust Architecture](https://csrc.nist.gov/pubs/sp/800/207/final)
- [oauth2-proxy 公式ドキュメント](https://oauth2-proxy.github.io/oauth2-proxy/)
- [Keycloak ドキュメント](https://www.keycloak.org/documentation)
- [Keycloak リリースノート](https://www.keycloak.org/docs/latest/release_notes/index.html)
- [nginx auth_request モジュール](https://nginx.org/en/docs/http/ngx_http_auth_request_module.html)
- [RFC 7636 — Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636)
- [RFC 8693 — OAuth 2.0 Token Exchange](https://datatracker.ietf.org/doc/html/rfc8693)
- [RFC 9700 — Best Current Practice for OAuth 2.0 Security](https://datatracker.ietf.org/doc/html/rfc9700)
- [OAuth 2.1 draft (draft-ietf-oauth-v2-1)](https://datatracker.ietf.org/doc/draft-ietf-oauth-v2-1/)
- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)
- [WebAuthn Level 3 (W3C)](https://www.w3.org/TR/webauthn-3/)
- [FIDO Alliance — Passkeys](https://fidoalliance.org/passkeys/)
- [Pomerium ドキュメント](https://www.pomerium.com/docs)
- [Cloudflare Access ドキュメント](https://developers.cloudflare.com/cloudflare-one/policies/access/)
- [Google Cloud IAP ドキュメント](https://cloud.google.com/iap/docs)
현재 단락 (1/396)
2026年現在、「社内ネットワークにいれば信頼する」という前提は、事実上廃止されたセキュリティモデルです。リモートワークが標準になり、ワークロードはマルチクラウドに分散し、SaaSと社内ツールの境界も...