本文へスキップ
CoRISE

Cloudflare Zero TrustとEntra — Conditional Accessの判定責任を分ける

EntraのIdentity Assurance,Cloudflareの入場・経路制御,Applicationの認可を分けます.Authentication Context,Session,SCIM失効と設定例を扱います.

T. Asano公開 更新 約19分で読めます
  • Identity
  • Security
  • zero-trust
目次を開く

Cloudflare Zero TrustとMicrosoft Entra IDを組み合わせると,MFA,端末の準拠状態,グループ,接続経路をアクセス条件にできます.しかし,同じIntuneの準拠判定を両製品へ設定しても,独立した防御が一つ増えるとは限りません.取得時刻とセッションの扱いが異なり,拒否理由を追いにくくすることもあります.

本稿では,EntraがIdentity Assurance,CloudflareがResource Admissionとアクセス経路,Applicationが業務上の認可を担当する設計を考えます.境界にはEntra Authentication Contextを使います.製品が持つ機能の限界ではなく,組織が選ぶ責任分担です.Entraもリソースへのアクセスを制御でき,CloudflareもMFAやリスクを扱えます.

ゼロトラストをアクセス製品で終わらせないで述べた境界を,Self-hosted HTTP Applicationの具体的な設定へ落とします.以下は設計・レビュー用の例です.実テナントへの適用,認証,失効,OpenTofuの実行は行っていません.

1.三つの判定を分ける

管理ポータルへ入る操作を考えます.Entraへのサインインが成功しても,その利用者を管理ポータルへ通してよいとは限りません.ポータルへ到達できても,すべてのクラスタを削除してよいわけではありません.

境界この構成で担当する問い主な管理者
Entra本人か.必要な認証強度と端末準拠条件を満たすかIdentity担当
Cloudflare Accessこの利用者を,必要な保証と経路でこのApplicationへ通すかPlatform / Security担当
ApplicationこのTenant・Resourceに対してこの操作を許可するかApplication担当

横にスクロールして図全体をご覧いただけます.

Identity,入場,業務操作の三つの境界 Entraが認証強度と端末準拠を評価し,Cloudflareが必要なContext,Group,GatewayでApplicationへの入場を制御する.ApplicationはTenantとResourceごとの操作を認可する.
Fig. 01 — Identity,入場,業務操作の三つの境界
図を文章で読む

Entraが認証強度と端末準拠を評価し,Cloudflareが必要なContext,Group,GatewayでApplicationへの入場を制御する.ApplicationはTenantとResourceごとの操作を認可する.

グループの所属情報はEntraが管理し,CloudflareがApplicationへの入場判定に利用します.Cloudflare側へ業務RBACを丸ごと移植せず,Applicationは操作ごとの認可を残します.

2.条件のOwnerと評価時点を一緒に決める

「どちらでも設定できる」条件ほど,判定元,利用先,再評価の契機を記録します.Microsoft-nativeな認証強度,Sign-in Risk,Intune ComplianceをEntraへ集め,Cloudflareには必要な保証レベルとCloudflare固有の経路条件を置くのが,本稿の基本形です.[1][2]

Signal / Decision主担当評価・更新の境界
認証強度,Sign-in Risk,端末準拠EntraEntraが関与する認証・トークン取得と対応する再評価
Group membershipEntraが管理,Accessが利用Accessの認証時のIdP情報.変更伝播は別途設計
必要なAuthentication ContextCloudflareが要求,Entraが評価Contextを要求する認証フローとAccessセッション
Gateway / WARP / 対応するPostureCloudflare新しいHTTP Requestでの評価と,元データの更新周期
ApplicationのToken / SessionCloudflarePolicy・Application・Global・One Clientの設定
業務Resourceへの操作権限Application保護する操作の実行時

これはEntraの全機能を「ログイン時だけ」と分類する表ではありません.Continuous Access Evaluationなどの機能が,任意の外部ApplicationやCloudflare Sessionへ自動的に適用されると仮定しないための整理です.

同じIntune Complianceを両側で要求することも,意図があれば可能です.ただし,同じ情報源の複製であること,更新遅延,片側が取得不能なときの扱いを説明できる必要があります.Intune Complianceに別のEDR Healthや組織のGateway利用を加える場合は,異なる問いを組み合わせています.

3.Authentication Contextを保証の契約にする

Authentication Contextは,Applicationが必要なConditional Accessの条件を要求するための境界になります.EntraでContextを作り,そのContextをTargetとするCA Policyを関連付けます.CloudflareのPolicyはAzure AD - Auth contextをRequireします.Cloudflare公式の連携手順はこの構成を説明しています.[3][4]

例えばPrivileged Infrastructure v1を,次の契約として管理します.AC3は組織内の説明用の呼称であり,APIの識別子ではありません.

# Design contract; not a deployed Entra resource.
name: Privileged Infrastructure v1
alias: AC3
owner: identity-team
required_controls:
  operator: AND
  authentication_strength: phishing-resistant MFA
  device: Intune compliant
consumers:
  - admin.example.com
context_identifiers: RECORD_FROM_APPROVED_TENANT
policy_state: MUST_BE_ENFORCED_FOR_TARGET_USERS
execution_status: NOT_RUN

Contextの名前だけで保証は成立しません.対象User,除外,Policyの有効状態,複数Grant ControlのAND / OR,併用するCA Policyまで含めて確認します.Report-onlyのPolicyを通過した結果は,強制済みの保証ではありません.[5]

EntraのContext IDはc1〜c99のような識別子です.下流へ公開するPublish to appsも確認します.説明用のAC3,EntraのID,Cloudflareが同期して扱う情報を名前から推測して対応付けないようにします.[4]

横にスクロールして図全体をご覧いただけます.

Contextの同期と強制を分ける Entraで公開したContextをCA Policyへ結び,Cloudflareへ同期する.Access PolicyのRequireとApplicationへの関連付けを別に行う.同期だけでは強制されず,Report-onlyや除外もReviewする.
Fig. 02 — Contextの同期と強制を分ける
図を文章で読む

Entraで公開したContextをCA Policyへ結び,Cloudflareへ同期する.Access PolicyのRequireとApplicationへの関連付けを別に行う.同期だけでは強制されず,Report-onlyや除外もReviewする.

契約を変更するときは,それを要求する全Applicationへの影響を見ます.あるApplicationだけの例外のために共有Contextを弱めると,他の管理画面まで条件が変わります.必要なら別Contextを作り,対象Applicationを明示して移行します.認証方式の変更も,Authentication Strengthが許可する方式と設定を確認します.「Passkeyならすべて同じ強度」とは扱いません.[2]

4.同期,強制,導入を分ける

導入順序は,まずEntraとの基本IdP連携,次にContextとCA,最後にCloudflare Applicationへの要求です.CloudflareのEntra連携はApp registrationを使います.Group supportとPolicy Syncの権限を分け,Microsoft GraphのPolicy.Read.ConditionalAccessはApplication permissionとして追加し,Admin consentを与える手順が公式に示されています.Delegated permissionではこの機能は動きません.[3][6]

CloudflareでPolicy Syncを有効にすることは,Applicationが必要なContextを要求することと同義ではありません.Contextを同期して選べる状態にしたうえで,Access PolicyのRequireに追加し,そのPolicyをApplicationへ関連付けます.この連携のためにCA RuleをCloudflareの条件式へ手動コピーする必要はありません.

Entra側の設計例は次のとおりです.これはGraphへの投入用JSONではありません.

Context: Privileged Infrastructure v1
Publish to apps: Yes
Users: Platform Engineers (pilot scope first)
Target resources: Authentication context
Grant: Require ALL selected controls
  - Require phishing-resistant MFA authentication strength
  - Require device to be marked as compliant
Session: Evaluate an appropriate sign-in frequency
Risk: Review applicable organization-wide risk policies
Exclusions: Explicitly reviewed emergency identities
Rollout: Report-only -> enforced pilot -> reviewed expansion

複数Grant ControlではRequire all the selected controlsを選ぶ意図を明示します.組織全体のRisk PolicyとContext専用Policyの適用範囲が違う場合は,対象利用者を両方で確認します.CAはP1,Risk-based CAはP2の機能を含むため,契約と対象Userのライセンスを確認します.IntuneやCloudflareの利用条件も別に確認が必要です.[1]

Report-onlyで影響を調べ,限定したPilotを強制し,否定ケースを確認してから広げます.Report-onlyでも端末準拠の評価で証明書選択などが発生する場合があり,「利用者に一切影響しない」とは扱いません.[5]

5.Cloudflareでは入場対象と経路を絞る

Allow Policyは,Includeで対象集合を作り,Requireで条件を追加し,Excludeで除外します.Includeが複数あればOR,RequireはANDです.例えばグループとGatewayを両方Includeへ入れると,「グループ所属またはGateway利用」という意図しない許可になり得ます.[7]

本稿ではPlatform EngineersをIncludeし,ContextとGatewayをRequireします.ここでGatewayは,組織のZero Trustへ登録されたOne Clientの経路を要求する条件です.WARP条件だけではConsumer版も含むため,同じ意味ではありません.端末の所有やIntune準拠までGatewayから推論しないようにします.[8]

複数のAllow Policyの条件が自動で積み重なるわけでもありません.BypassとService Authが先に評価され,その後のAllow / Blockにも順序があります.別の緩いAllowやBypassが残っていれば,厳しいPolicyを一つ追加しただけではApplication全体の保証になりません.Hostname・Pathの範囲と全Policyを一緒にReviewします.[7]

6.OpenTofuではPolicyの関連付けまで示す

以下はCloudflare Provider 5.23.0の公開Schemaに照合した例です.Providerの実行検証はしていません.Gatewayはtype = "gateway"のDevice Posture Ruleとして作成し,device_posture.integration_uidからそのRule IDを参照します.DashboardのSelector名とAPI上の表現を混同しないため,Ruleも例に含めます.[9]

resource "cloudflare_zero_trust_device_posture_rule" "gateway" {
  account_id = var.cloudflare_account_id
  name       = "Organization Gateway"
  type       = "gateway"
}

resource "cloudflare_zero_trust_access_policy" "infra_admin" {
  account_id       = var.cloudflare_account_id
  name             = "ACCESS-Admin-Require-AC3-Gateway"
  decision         = "allow"
  session_duration = "1h"

  include = [{
    azure_ad = {
      id                   = var.platform_engineers_group_id
      identity_provider_id = var.entra_identity_provider_id
    }
  }]

  # Entra owns authentication strength and Intune compliance.
  # Cloudflare requires the context and organizational path.
  require = [
    {
      auth_context = {
        id                   = var.synced_auth_context_id
        ac_id                = var.synced_auth_context_ac_id
        identity_provider_id = var.entra_identity_provider_id
      }
    },
    {
      device_posture = {
        integration_uid = cloudflare_zero_trust_device_posture_rule.gateway.id
      }
    }
  ]
}

auth_context.id,ac_id,identity_provider_idはそれぞれ必須です.Provider文書は前二つをContextのIDとACIDとして定義しますが,表示名から値を導く規則は示していません.実環境で同期済みのContextとPolicyのAPI表現を確認し,対応する値を記録して渡します.両者を同じ値と仮定したり,AC3をそのまま入力したりしません.

Reusable Policyを作るだけではApplicationへ適用されません.関連付けを明示します.

resource "cloudflare_zero_trust_access_application" "infra_admin" {
  account_id = var.cloudflare_account_id
  name       = "Infrastructure administration"
  type       = "self_hosted"
  domain     = "admin.example.com"

  allowed_idps                = [var.entra_identity_provider_id]
  auto_redirect_to_identity   = true
  allow_authenticate_via_warp = false
  session_duration           = "1h"

  policies = [{
    id         = cloudflare_zero_trust_access_policy.infra_admin.id
    precedence = 1
  }]
}

allow_authenticate_via_warp = falseは,One Clientの認証セッションで代替する経路をこの例では使わない設定です.GatewayをRequireすることと,One Clientのセッションで認証することは別です.この設定でもAccess Global Sessionなどの再利用は残り,各RequestでEntraへ戻るわけではありません.

設定例とレビュー資料をダウンロードできます.Providerを固定するversions.tf,変数定義,Context契約,失効・受入確認の記録様式を含みます.IdP登録,Entra CA,SCIM,DNS,Tunnel,Originは作成しません.既存Resourceとの重複やStateの扱いも適用前のReview対象です.

OpenTofuのDependency lock file名は.terraform.lock.hclです.この例ではinitを行っていないため,Lock fileは同梱していません.選んだOpenTofu環境でProviderを解決し,生成されたLock fileをReviewして管理する段階が残っています.Secretは例にもStateの共有資料にも埋め込まず,指定されたSecret管理から供給します.

7.短いSessionは再認証の保証ではない

AccessにはGlobal Session TokenとApplication Tokenがあります.PolicyのSession DurationはApplication Tokenの期限を決め,未指定ならApplicationの設定が使われます.Application Tokenが切れてもGlobal Tokenが有効で条件を満たせば,再発行できます.「Access Session 1時間」から「Entra CAを必ず毎時再評価する」とは導けません.[10]

EntraのSign-in Frequency Every timeも,各HTTP RequestでのMFAではありません.Sessionが評価される場面で再認証を要求する制御であり,ApplicationがEntraへ戻る契機が必要です.Microsoftは5分のClock skewを考慮した動作も説明しています.[11]

横にスクロールして図全体をご覧いただけます.

Application Tokenの期限とIdP再認証は別である 通常のAccessではApplication Tokenの期限後もGlobalが有効なら再発行できる.One Client認証を有効にするとClient Sessionが優先する.EntraのEvery timeはEntraが関与するSession評価時の制御である.
Fig. 03 — Application Tokenの期限とIdP再認証は別である
図を文章で読む

通常のAccessではApplication Tokenの期限後もGlobalが有効なら再発行できる.One Client認証を有効にするとClient Sessionが優先する.EntraのEvery timeはEntraが関与するSession評価時の制御である.

Authenticate with Cloudflare One Clientを有効にすると,Client SessionがApplication・Policy・GlobalのDurationより優先します.Client Sessionが有効なら,Globalが切れてもIdPへの再認証を要求されない場合があります.管理Applicationでは,どの経路でEntraへ戻るのかを実際のブラウザ・Client設定で確認します.[10]

Session Durationは複数の時計です.Origin ApplicationのCookieも独立しています.設定一覧に数値を並べるだけでなく,既存Session,期限後のToken再発行,新規ブラウザ,One Client利用を分けて確認します.

8.継続評価と失効の伝播を測る

Self-hosted HTTP Applicationでは,対応するNon-identity条件は新しいHTTP Requestごとに評価されます.しかし,Requestごとの評価,Postureデータの更新,既存接続の終了は別の出来事です.Ruleを再評価しても古いPosture結果を参照している可能性があり,更新周期や結果の有効期限も確認します.HTTPで説明された性質を,開いているWebSocketやSSHの即時切断へ拡張しません.[7][9]

SCIMも「入れれば即時失効する」機能ではありません.Accessは認証時のIdP情報でIdentityとGroupを評価します.SCIMのUser deprovisioningやGroup変更時の再認証を設定すると,Active Sessionを失効させ,新しい認証で情報を取り直す経路を作れます.GatewayはUser Registryの同期Identityを使うため,Accessと同じ動作ではありません.[6][12]

Entra連携ではSCIM用に別のEnterprise Applicationを構成します.その割当範囲と,認証用Applicationから渡されるグループを揃えます.Nested GroupのSCIM同期には制約があるため,直接所属と実際のProvisioning logで確認します.[6]

変更確認する伝播成功のEvidence
Entra Groupから削除Provisioning → Session失効 → 再認証 → Access拒否更新Logと,既存・新規Sessionの拒否時刻
Userを無効化IdPで新規認証拒否,Access側の残存Session処理両側の記録.無効化だけから即時失効を推測しない
Gateway切断経路変化 → 次の保護RequestClient状態,Access結果,実Request時刻
端末が非準拠Intune更新 → Entra評価 → Accessへの影響準拠変更時刻と再評価・拒否の記録
SaaSへサインイン後SaaS自身のSession管理と失効SaaS側の拒否・Session終了記録

SaaSではAccessが強制できるのは初回Sign-onとSaaS Session再発行の時点です.その後のSessionはSaaS側が管理します.同じPolicy名でもSelf-hosted HTTPと保証範囲が違います.[7]

伝播時間は設定値から作ったSLOではなく,変更,配送,失効,最初の拒否を測って評価します.未到着のSCIM更新,失敗時のRetry,長寿命接続も確認対象です.今回の資料には実測値はありません.

9.Applicationの認可とOrigin保護を残す

Accessを通った利用者が業務上何をできるかはApplicationが決めます.OriginではAccess JWTの署名,Issuer,想定ApplicationのAudience,有効期限を検証し,検証済みPrincipalを業務上のUserへ対応付けます.単にIdentity Headerが存在することを信頼しません.[13]

Cloudflare TunnelやOrigin Firewallなどで直接到達経路を制限し,保護対象外のHostname,管理Port,別Ingressも確認します.Tunnelを使っているという理由だけで,全ての迂回経路が閉じているとは判断しません.また,JWTの暗号学的な検証だけで最新の失効情報を取得したことにはなりません.Accessを通る経路とApplicationのSession管理を両方維持します.

Application側ではTenantと対象Resourceの所有,Role,操作を確認します.有効なAccess JWTを提示した別TenantのUserを拒否するケースまで,受入条件へ含めます.

10.人とMachine,緊急経路を分ける

人のアクセスにはEntra認証と必要なContextを使います.Machine accessにはService Auth,限定したService TokenやmTLSなど,対応する認証方式を選びます.人のMFA SessionをAutomationへ流用しません.Service AuthはHuman Allowとは評価順序も違うため,同じApplicationへ追加するときはアクセス範囲と業務権限を別途Reviewします.[7]

EntraのEmergency AccountをCAから除外しても,CloudflareのPolicyやApplicationのRoleが自動で許可するわけではありません.さらにCloudflare自身が停止すれば,Entraの例外だけでは到達経路を復旧できません.

Critical InfrastructureではOut-of-band Consoleなどの独立経路を検討し,使用者,保管先,使用条件,記録,期限付き復旧手順を決めます.常時広く開いたBypassを緊急経路の代わりにしません.復旧後に例外が残っていないことも確認します.

11.拒否理由を境界に沿って追う

「ログインできない」を一つの403として扱うと,調査対象が広がります.Entraによる認証・CAの拒否,Accessによる入場拒否,Originによる業務認可の拒否を分けます.

1. Identify UTC time, principal, application and requested operation.
2. Did Entra authentication succeed? Which CA policies applied?
3. Was the required context enforced for this user and device?
4. Did Access admit the user? Inspect policy and posture results.
5. Did the request reach the origin with a valid Access JWT?
6. Did domain authorization permit this tenant/resource/action?
7. For stale access, inspect SCIM delivery and every session layer.

EntraのSign-in logでは適用CA,認証方式,Device,Riskを調べ,Cloudflareでは対象Application,Policy,Posture,認証・Requestの記録を確認します.Originでは検証済みPrincipal,Tenant,操作,拒否理由を残します.UTC時刻,User識別子,Application,その製品内のRequest / Correlation IDを揃えます.一つのCorrelation IDが全製品へ自動伝播すると仮定せず,Token本体やSecretはLogへ残しません.

横にスクロールして図全体をご覧いただけます.

変更から拒否までを記録する Identity変更からSCIM配送,Access Session失効,再認証と拒否まで時刻を記録する.Gatewayの経路変化とOriginの業務認可は別に確認する.今回の測定と受入確認はすべて未実行である.
Fig. 04 — 変更から拒否までを記録する
図を文章で読む

Identity変更からSCIM配送,Access Session失効,再認証と拒否まで時刻を記録する.Gatewayの経路変化とOriginの業務認可は別に確認する.今回の測定と受入確認はすべて未実行である.

受入ケース期待する結果実行状態
所属,Context,Gatewayがすべて適合Applicationへ到達し,許可された操作のみ実行可能NOT_RUN
非準拠端末 / 不足する認証強度Enforced CAが拒否または追加の認証を要求NOT_RUN
Context PolicyがReport-only / 対象外保証契約の不足として導入Reviewを不合格にするNOT_RUN
Consumer WARPのみ / Gatewayなし管理Applicationへの新規HTTP Requestを拒否NOT_RUN
Group削除後の既存Session伝播と失効を測り,定めた期限内の拒否を確認NOT_RUN
緩いAllow / Bypassの存在期待外の許可を検出し,Policy全体を修正NOT_RUN
偽造JWT / 別Audience / 直接Origin検証または経路制御で拒否NOT_RUN
別Tenant操作 / Emergency経路業務境界を守り,承認された復旧操作だけが可能NOT_RUN

正のケースだけではContractを検証できません.Sessionを残した変更,連携の配送失敗,Originの迂回まで含めます.訓練は対象を限定し,停止条件と復旧手順を用意したうえで別途実施します.

12.Policyの数より,責任を説明できること

Entra Contextの契約にはOwnerと変更理由を,Cloudflare Policyには対象Resourceと必要な保証を,Applicationには操作権限を残します.Policy変更のReviewでは「どの条件を変えたか」に加えて,「誰の判断がいつ更新され,既存Sessionへいつ届くか」を確認します.

EntraとCloudflareの両方にMFAやDevice条件があることは,すべてを重複設定する理由にはなりません.Entraの保証をCloudflareが要求し,Cloudflare固有の経路条件を追加し,Applicationが業務権限を判定する.この構造なら,拒否の理由と変更の影響を境界ごとに説明できます.

同じ条件を二重に書く前に,誰が判断し,どの境界がその結果を利用し,いつ取り直すかを決めます. それが,この構成で最初に文書化する設計です.

参考資料

以下の公式資料を参照しています.Cloudflare Providerは5.23.0のSchemaを参照しました.設定例と受入記録はNOT_RUNであり,顧客環境への採用・検証実績を示すものではありません.

  1. Microsoft Entra Conditional Access overview
  2. Authentication strengths
  3. Cloudflare: Entra Conditional Access integration
  4. Entra target resources and authentication context
  5. Entra report-only mode
  6. Cloudflare Entra integration, groups and SCIM
  7. Access policies, selectors and evaluation order
  8. Require Gateway
  9. Cloudflare Provider v5.23.0: Access policy · Application schema · Device posture rule schema
  10. Access session management
  11. Entra session lifetime and Every time
  12. Cloudflare SCIM policy behavior
  13. Validate Access JWTs

T. Asano

T. Asanoの記事を読む

Contact

技術的な課題を、お聞かせください。

設計や実装、運用の課題について、CoRISEにご相談いただけます。

相談する