Azureセキュリティ要件定義(NIST整合)
- 山崎行政書士事務所
- 9月14日
- 読了時間: 18分

— NIST CSF / SP 800‑53 を“要件”に落とし、Azureの設計・実装・運用・証跡まで一気通貫で回すための実務ガイド —対象読者:上級SE/セキュリティ責任者/法務・コンプライアンス担当。本稿は一般的情報提供で、個別の法的助言ではありません。
0. 目的と前提
目的:NIST を参照して Azure の要件定義を行う際、「何を」「どの粒度で」決めれば設計・実装・運用・監査に耐えるかを、パラメータレベルで提示します。
前提:エンタープライズ(複数サブスクリプション/ハイブリッド接続/個人データあり)を想定。Microsoft Entra ID(旧 Azure AD)を ID 基盤とします。
1. なぜ NIST を参照するのか(要点)
共通言語:NIST CSF の 5 Functions(Identify/Protect/Detect/Respond/Recover)で組織全体の役割と成熟度を共有。
制御の深さ:SP 800‑53(AC/AU/SC/IR/CP/SA…)で要求水準を具体化。監査の物差しにもなる。
Azure の親和性:Azure は FedRAMP 等で 800‑53 ベースの体制を持ち、Defender for Cloud / Policy / Sentinel で要件を強制・検知・証跡化しやすい。
2. “要件”を作る 5 ステップ(定義→設計→証跡)
Step‑1:スコープ & 規制オーバーレイ
データ分類(Public/Internal/Confidential/PII/Restricted)
適用規制(APPI/GDPR/FISC/SOX 等)と追加要求(例:越境/保持年限)
Step‑2:リスクシナリオ → NIST マッピング
例)「外部流出」「内部不正」「可用性喪失」→ CSF→ 800‑53 コントロール候補を選定
Step‑3:Azure 実装パターンに割り付け
Guardrails(Azure Policy/Landing Zone)/Controls(PIM/MFA/PE/WAF/Key Vault 等)
Step‑4:要件文(Acceptance Criteria 付き)に落とす
“〇〇は××でなければならない(MUST)/××が望ましい(SHOULD)”+検証方法(KQL/ARG/CLI)
Step‑5:証跡運用
エビデンスパック(四半期)=契約・ポリシー準拠率・ログ抜粋・改善計画
KPI(Secure Score、SLA、MTTD/MTTR、コンプライアンス準拠率)
3. 要件カタログ(CSF×800‑53×Azure 実装×検証)
3.1 Identify(ID)資産・リスクの特定
REQ‑ID‑001(資産台帳)
MUST:ARG(Azure Resource Graph)で全リソースのタグ必須(Owner,CostCenter,DataClass,BCPTier)。
800‑53:CM‑8, PM‑5 / Azure:Policy「Require tag and its value」、ARG
検証(ARG):
Resources
| where isnull(tags['Owner']) or isnull(tags['DataClass'])
| project name, type, resourceGroup, subscriptionId
REQ‑ID‑002(ハイリスク識別)
MUST:DataClass in ('PII','Restricted') のリソースをPrivate Endpoint(PE) 化、Public Access をDeny。
800‑53:RA‑3, SC‑7 / Azure:Policy(Public Network Access = Disabled), Private DNS
検証(Policy 準拠率):Defender for Cloud/Policy 準拠ダッシュボード 95% 以上
3.2 Protect(PR)防御
REQ‑AC‑001(MFA/条件付きアクセス)
MUST:全ユーザーに MFA、特権は条件付きアクセス(リスクサインイン拒否/準拠端末のみ)。
800‑53:AC‑2, IA‑2 / Azure:Entra CA, Identity Protection, PIM
受入基準:特権ロール割当ユーザーのMFA 適用率 100%、リスクサインイン遮断ログあり。
REQ‑AC‑002(特権の JIT)
MUST:Global Admin/Owner は PIM で時間制・承認制。
800‑53:AC‑6, AC‑17 / Azure:PIM(JIT + Approver)
検証:PIM アクティベーション監査で無承認付与が 0 件。
REQ‑SC‑001(暗号化 & 鍵管理)
MUST:保存暗号化(TDE/Storage SSE)+Key Vault。機密は Managed HSM/BYOK。TLS ≥ 1.2。
800‑53:SC‑12, SC‑13 / Azure:Key Vault/MHSM、SQL TDE、Storage SSE、AppGW TLS Policy
受入:Key Vault RBAC 有効、鍵ローテ 12 か月、診断ログ出力。
REQ‑NET‑003(ネットワーク分離)
MUST:PaaS は Private Endpoint 前提。インターネット公開は例外申請+ WAF/Front Door。
800‑53:SC‑7 / Azure:PE, Private DNS, Azure Firewall, AppGW(WAF), Front Door
検証:Public Endpoint 有効の Storage/SQL が 0、WAF 有効化率 100%。
REQ‑SECRETS‑001(シークレット無配置)
MUST:アプリの接続機密はKey Vault+Managed Identity。コード・変数・Git にシークレットを置かない。
800‑53:CM‑6, SC‑28 / Azure:System/ User‑Assigned Managed Identity, KV Access Policy/RBAC
検証:リポジトリの検出ツール(Secret Scan)でゼロ漏洩、KV アクセスログに API 参照のみ。
3.3 Detect(DE)監視・検知
REQ‑AU‑001(診断ログの強制)
MUST:すべての重要リソースに Diagnostic Settings を標準化し、Log Analytics に集中。
800‑53:AU‑2, AU‑12 / Azure:Policy「DeployIfNotExists で診断設定付与」
受入:配下 RG の診断設定適用率 100%、未適用 0。
REQ‑DE‑002(Sentinel SIEM)
SHOULD:Sentinel で下記の相関ルールを有効化。
異常サインイン(Impossible Travel, MFA 疑義)
大量データダウンロード(Storage/Key Vault)
役割昇格イベント(Privileged Elevation)
KQL(例:大量 DL 検知)
StorageBlobLogs
| where TimeGenerated > ago(1d)
| summarize cnt = count() by UserPrincipalName, bin(TimeGenerated, 15m)
| where cnt > 1000
REQ‑LOG‑RET‑001(保持)
MUST:90 日ホット + 1 年アーカイブ(業界要件で 5 年まで)。
800‑53:AU‑11 / Azure:LA ワークスペース保持+アーカイブ、ストレージ階層
3.4 Respond(RS)対応・自動化
REQ‑IR‑001(インシデント計画 & SLA)
MUST:重大度ごとの初動 SLA(例:MTTD 30 分、暫定封じ込め 4 時間、GDPR 評価 24 時間)。
800‑53:IR‑4, IR‑6 / Azure:Sentinel + Logic Apps(Playbook)
自動化例:悪性 IP を NSG へ Block/侵害疑いアカウント強制リセット/Teams 通知。
3.5 Recover(RC)復旧
REQ‑CP‑001(RPO/RTO)
MUST:業務ごとに RPO/RTO 設定(例:RPO ≤ 15 分、RTO ≤ 60 分)。
Azure:Backup(Vault Policy), ASR(DR ドリル半年毎)
検証:計画フェイルオーバー演習の記録、実測 RTO/RPO を KPI レビュー。
4. “要件票”テンプレート(コピペ可)
id: REQ-AC-001
title: 全ユーザーMFA & 条件付きアクセス
must: true
rationale: なりすまし/特権悪用の一次防止
nist:
csf: PR.AC-1, PR.AC-7
sp80053: [AC-2, IA-2, AC-17]
azure_mapping:
- Entra Conditional Access: MFA required, block legacy auth
- Identity Protection: risk-based policies
- PIM: JIT for Global Admin/Owner (approval required)
acceptance_criteria:
- Privileged roles MFA coverage == 100%
- Legacy authentication sign-ins == 0
- PIM activation requires approval and is time-bound (<= 4h)
verification:
- Entra sign-in logs KQL
- PIM audit export
evidence:
- CA policy export JSON
- Quarterly KPI dashboard (MFA coverage, risky sign-ins)
owner: Security/IAM Lead
review_cycle: Quarterly
5. Azure Policy ガードレール(抜粋:そのまま使える雛形)
5‑1. Storage の HTTPS/TLS 強制 & Public Access 禁止(Deny)
{
"properties": {
"displayName": "Enforce HTTPS and deny public access on Storage",
"policyType": "Custom",
"mode": "Indexed",
"parameters": {},
"policyRule": {
"if": {
"allOf": [
{ "field": "type", "equals": "Microsoft.Storage/storageAccounts" },
{ "anyOf": [
{ "field": "Microsoft.Storage/storageAccounts/enableHttpsTrafficOnly", "equals": "false" },
{ "field": "Microsoft.Storage/storageAccounts/allowBlobPublicAccess", "equals": "true" }
]}
]
},
"then": { "effect": "deny" }
}
}
}
5‑2. 診断設定の強制付与(DeployIfNotExists)
{
"properties": {
"displayName": "Deploy Diagnostic Settings to Log Analytics",
"policyType": "Custom",
"mode": "Indexed",
"parameters": {
"workspaceId": { "type": "String" }
},
"policyRule": {
"if": { "field": "type", "equals": "Microsoft.KeyVault/vaults" },
"then": {
"effect": "deployIfNotExists",
"details": {
"type": "Microsoft.Insights/diagnosticSettings",
"name": "send-to-law",
"existenceCondition": { "field": "Microsoft.Insights/diagnosticSettings/logs.enabled", "equals": "true" },
"roleDefinitionIds": ["/providers/Microsoft.Authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa"],
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [{
"type": "Microsoft.KeyVault/vaults/providers/diagnosticSettings",
"apiVersion": "2021-05-01-preview",
"name": "[format('{0}/Microsoft.Insights/send-to-law', field('name'))]",
"properties": {
"workspaceId": "[parameters('workspaceId')]",
"logs": [{ "category": "AuditEvent", "enabled": true }]
}
}]
}
}
}
}
}
}
}
}
6. IaC パターン(Bicep/Terraform 抜粋)
6‑1. Bicep:Private Endpoint + KV RBAC + 診断
param location string = resourceGroup().location
param kvName string
param laId string
resource kv 'Microsoft.KeyVault/vaults@2023-02-01' = {
name: kvName
location: location
properties: {
enableRbacAuthorization: true
sku: { family: 'A', name: 'standard' }
publicNetworkAccess: 'Disabled'
}
}
resource diag 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
name: 'send-to-law'
scope: kv
properties: {
workspaceId: laId
logs: [ { category: 'AuditEvent', enabled: true } ]
}
}
6‑2. Terraform:Storage の最小化設定
resource "azurerm_storage_account" "s" {
name = var.name
resource_group_name = var.rg
location = var.location
account_tier = "Standard"
account_replication_type = "ZRS"
min_tls_version = "TLS1_2"
allow_blob_public_access = false
https_only = true
network_rules {
default_action = "Deny"
bypass = ["AzureServices"]
private_link_access = []
}
tags = {
Owner = var.owner
DataClass = "PII"
CostCenter = var.cc
}
}
7. セキュリティ検証(KQL/ARG/CLI レシピ)
Public Endpoint 有効な PaaS を列挙(ARG)
Resources
| where type in~ ('microsoft.storage/storageaccounts','microsoft.sql/servers')
| project name,type,public=coalesce(properties.publicNetworkAccess, tostring(properties.networkAcls.defaultAction))
| where public =~ 'Enabled' or public =~ 'Allow'
TLS < 1.2 の検出(Storage)
AzureDiagnostics
| where Category == "StorageRead"
| where tostring(Properties_s) !has "TLSVersion\":\"TLS1_2"
特権ロールの恒久割当検出
AuditLogs
| where OperationName == "Add member to role"
| extend Permanent = tostring(TargetResources[0].modifiedProperties[?].newValue)
| where Permanent !contains "PIM" // JIT 以外
8. メトリクス/KPI(四半期レポートに掲載)
技術:Secure Score(+15〜25pt/期)、Policy 準拠率 ≥ 95%、診断設定適用率 100%
運用:MTTD < 30 分、MTTR < 4 時間、PIM JIT 適用率 100%、脆弱性 SLA(High ≤ 14日)
ログ:LA 取り込み失敗 0、保持方針準拠 100%、Sentinel 誤検知率 < 3%
コンプライアンス:DSR 対応期限遵守 100%、DR 演習 半期 1 回
9. コストと設計のトレードオフ
Sentinel/Log Analytics:取り込み量 × 保持で増大 → アーカイブ階層とルール最適化、データ正規化。
BYOK/Managed HSM:高セキュリティだが月額増 → 機密度に応じた選択(全域適用は避けクリティカルに集中)。
Defender プラン:まずは重要リソースから適用し、効果とアラート整流化を見て拡張。
10. ライフサイクル & ガバナンス(Gate と RACI)
Gate
G1 要件レビュー(NIST トレーサビリティ/規制オーバーレイ)
G2 設計審査(Policy セット/ネットワーク境界/鍵設計)
G3 実装検証(ARG/Policy/ペンテスト)
G4 運用受入(Runbook/アラート SLO/DR 演習記録)
RACI
Security:要件・Policy・SIEM・IR(R)
Infra/Dev:IaC・接続・秘匿情報・パイプライン(R)
法務/コンプラ:規制適用・DPIA・DPA/SLA(A)
事業/調達:ベンダ管理・SLA 監視(C)
11. よくある落とし穴(回避策付き)
Public Network Access が既定のまま → Deny Policy をイニシアティブで適用。
Key/秘密をコードに直書き → Managed Identity+KV 強制、Secret Scan をパイプラインに。
診断設定のばらつき → DeployIfNotExists で自動付与、イメージ化。
特権の恒久付与 → PIM 必須化、Owner の棚卸を月次。
PE だけで DNS 未整備 → Private DNS ゾーンの一元管理(vNet Link/Resolver)。
12. エビデンス運用(提出に耐える形)
ポリシー準拠レポート(PDF/CSV)+逸脱と是正計画
アクセス・削除・昇格イベントの監査ログ(期間指定のエクスポート)
鍵台帳(Key 名/用途/ローテ日/アクセス権者)
DR 演習記録(フェイルオーバー実測 RTO/RPO、課題と改善)
DSR ケース台帳(受付→完了 SLA)
13. まとめ(実務要点)
NIST を“要件文”に落とす:MUST/SHOULD+検証法+証跡をセットで。
Azure ガードレール:Policy で作れない構成は作れない状態に。
ログは最初から設計:診断設定の強制/保持の二層化/KQL ルールは最小の高精度から。
特権と秘密はゼロトラスト:PIM と MI+KV を“既定”に。
証跡ファースト:四半期エビデンスパックで監査・顧客審査に即応。
14. 山崎行政書士事務所のご支援(要件定義→実装→証跡)
NIST 準拠の要件カタログ作成(業界規制オーバーレイ付き)
Azure Policy / Landing Zone 設計・実装(イニシアティブ提供)
Sentinel/Defender 設計 & アラート整流化(KQL ルール/Playbook 同梱)
証跡運用パック(エビデンス雛形、KPI ダッシュボード、四半期レビュー)
DPIA・DPA/SLA 文言整備(技術要件と条項の齟齬解消)
まずはクイック健診(無料):現在のテナントを ARG/Policy/Defender スコアで可視化し、今期に閉じ切る 10 項目を優先度付きでご提示します。
参考
下記の構成は
①要件テンプレート(64項目)
②Policy イニシアティブ&カスタムポリシー
③Bicep/Terraform モジュール
④Sentinel ルール&Playbook(Logic Apps)
⑤検証用 KQL/ARG レシピ です。
※環境差分(サブスクリプション ID、ワークスペース名、VNet 名 等)は置換してください。
0) 使い方(5分で最低限の導入)
Management Group/Subscription を決め、Log Analytics Workspace (LAW) を 1 つ用意
まず 「2) Policy イニシアティブ」 を上位スコープ(MG/Subscription)にデプロイ
「3) Bicep/Terraform」 で KV/Storage/SQL/VNet などをセキュア既定で展開
「4) Sentinel ルール&Playbook」 を LAW + Sentinel 有効化後に投入
「5) 検証 KQL/ARG」 で準拠率・ドリフト・アラート発火を確認
1) 要件テンプレート(64項目、CSV 形式・貼付可)
ファイル名: requirements.csv
id,title,must,csf,sp80053,azure,acceptance,verification,evidence
REQ-GOV-001,全リソースのタグ必須(Owner/CostCenter/DataClass/BCPTier),MUST,ID.AM-1,CM-8,Policy RequireTag,タグ欠落0件,ARG-REQ-GOV-001,Policy準拠レポート
REQ-GOV-002,許可ロケーション制限(MG/Subscription),MUST,ID.AM-4,CM-7,Policy AllowedLocations,未許可リージョン0,Policyコンプライアンス,エクスポートJSON
REQ-GOV-003,命名規則の準拠(SA/KV/SQL等),SHOULD,ID.GV-3,CM-6,Blueprint/Policy(deny),命名逸脱0,ARG-REQ-GOV-003,Naming規程
REQ-GOV-004,サンドボックス隔離(Dev/Test/Prod),MUST,ID.AM-5,SC-7,MG/Subscription分離,横断RBAC無,AccessReview,権限台帳
REQ-GOV-005,コスト/所有者の可視化ダッシュボード,SHOULD,ID.RA-6,PM-5,CostMgmt+PowerBI,四半期レビュー実施,PowerBI更新ログ,議事録
REQ-GOV-006,ALZガードレール適用(MG階層),MUST,ID.GV-3,PM-9,CAF/ALZ+Policy,逸脱<5%,Policyレポート,ALZ設計書
REQ-AC-001,全ユーザーMFA&条件付きアクセス,MUST,PR.AC-1,AC-2/IA-2,Entra CA/Identity Protection,特権MFA=100%,KQL-AC-001,CA設定エクスポート
REQ-AC-002,特権JIT(PIM)時間制&承認制,MUST,PR.AC-4,AC-6,Entra PIM,恒久付与0,Audit-PIM,KPIレポート
REQ-AC-003,来訪者/外部IDの制御と有効期限,MUST,PR.AC-3,AC-2,Entra B2B/B2C,期限切れ消込>98%,KQL-AC-003,外部ID台帳
REQ-AC-004,レガシー認証遮断,MUST,PR.AC-7,AC-17,CA(Legacy Block),旧認証サインイン=0,KQL-AC-004,CAポリシー
REQ-AC-005,リソースRBACは最小権限,MUST,PR.AC-4,AC-6,RBAC/CustomRole,Owner最少化,ARG-AC-005,権限棚卸記録
REQ-AC-006,機密操作の4-eyes原則(承認ワークフロー),SHOULD,PR.MA-1,PS-3,PIM Approver/LogicApps,未承認操作0,AuditLogs,承認記録
REQ-AC-007,API/自動化はManaged Identity使用,MUST,PR.AC-4,AC-3,MI+KeyVault,Secret直置き0,RepoScan/KQL,設計書
REQ-AC-008,SSH/RDPはJust-In-Time,SHOULD,PR.AC-5,SC-7,Defender JIT/VPN,恒常穴0,KQL-AC-008,JIT記録
REQ-AC-009,アクセスレビュー四半期実施,MUST,PR.AC-6,AC-2,Entra Access Reviews,期限内完了=100%,レビュー完了ログ,議事録
REQ-AC-010,SOC/監査向け権限証跡の保全,MUST,PR.DS-5,AU-2,LA+Storageアーカイブ,保持>1年,Retention設定,証跡目録
REQ-NET-001,PaaSはPrivate Endpoint前提,MUST,PR.AC-5,SC-7,PE+Private DNS,Public無効=100%,ARG-NET-001,DNSゾーン設計
REQ-NET-002,東西/北南はFirewall/NSG制御,MUST,PR.PT-4,SC-7,Azure FW/NSG,AnyAny禁止,FlowLogs,KQL-NET-002
REQ-NET-003,WAF(Prevention)で公開アプリ保護,MUST,PR.IP-1,SC-7,AppGW WAF/FrontDoor,有効化率100%,WAFログ,ポリシー定義
REQ-NET-004,DDoS Standardの適用,SHOULD,PR.PT-5,SC-5,DDoS Std,攻撃検知自動応答,Defender通知,設定出力
REQ-NET-005,ハブスポーク/Route設計の一元管理,SHOULD,ID.AM-2,CM-2,vWAN/Hub-Spoke,孤立経路0,Route検証,ネット設計図
REQ-NET-006,VPN/ERは冗長構成,MUST,RC.CO-1,CP-8,VNG/ER冗長,RTO達成,DR演習記録,接続図
REQ-NET-007,Public IPの例外承認制,MUST,PR.AC-5,CM-5,Policy+承認フロー,未承認PIP=0,ARG-NET-007,例外台帳
REQ-NET-008,Private DNSゾーン一元管理,MUST,PR.PT-4,SC-7,Private DNS+Resolver,ゾーン重複0,ARG-NET-008,DNS台帳
REQ-NET-009,TLS1.2+強制(MinTLS),MUST,PR.DS-2,SC-13,AppSvc/AppGW設定,TLS<1.2=0,KQL-NET-009,構成出力
REQ-NET-010,AKSはPrivate Cluster & NSG/WAF,MUST,PR.AC-5,SC-7,AKS Private/AGIC,WAF前段化,KQL-AKS-001,AKS設計
REQ-DATA-001,保存暗号化(KV/MI/TDE/SSE),MUST,PR.DS-1,SC-12,KeyVault/SQL TDE/Storage SSE,暗号化率100%,ARG-DATA-001,設定出力
REQ-DATA-002,BYOK/Managed HSM(高機密),SHOULD,PR.DS-1,SC-12,KV MHSM+BYOK,鍵ローテ<=12ヶ月,KVログ,鍵台帳
REQ-DATA-003,Always Encrypted/AEv2(列暗号),SHOULD,PR.DS-1,SC-28,SQL AE/Client,PII列=AE,設計/テスト記録,DBスキーマ
REQ-DATA-004,機密は二重暗号化領域で保管,SHOULD,PR.DS-1,SC-12,Infra+App層暗号,適用データ識別,設計書,運用記録
REQ-DATA-005,Key VaultはRBAC+Public無効,MUST,PR.AC-4,AC-3/SC-7,KV RBAC/PNAccess:Disabled,RBAC=On,ARG-DATA-005,KV設定
REQ-DATA-006,秘密情報はコード/変数に直置き禁止,MUST,PR.DS-5,CM-6,MI+KV,検出0,SecretScan,レビュー記録
REQ-DATA-007,データ分類&ラベリング(MIP),SHOULD,ID.RA-1,PL-2,MIP/Purview,分類カバレッジ>95%,スキャンレポート,分類ポリシー
REQ-DATA-008,Blob/FilesのPublic Access禁止,MUST,PR.DS-5,AC-3,Storage allowBlobPublicAccess:false,公開0,ARG/KQL,設定出力
REQ-DATA-009,Storage LifeCycle管理(Hot→Cool→Archive→削除),SHOULD,RC.IM-1,SI-12,LCMポリシー,不要データ削減率>20%,設定JSON,費用レポート
REQ-DATA-010,バックアップは暗号化+分離保管,MUST,RC.RP-1,CP-9,Backup Vault+CMK,復元テストOK,演習記録,設定出力
REQ-LOG-001,診断設定の強制(Log Analyticsへ集約),MUST,DE.CM-1,AU-12,Policy DeployIfNotExists,適用率100%,Policy/KQL,LAW設定
REQ-LOG-002,保持90日+アーカイブ1年(>=業界要件),MUST,DE.AE-1,AU-11,LAW Retention+Archive,設定遵守100%,設定SS,運用台帳
REQ-LOG-003,KeyVault/SQL/Storageの監査ログ有効,MUST,DE.CM-7,AU-2,診断カテゴリ有効,無効=0,KQL-LOG-003,診断設定
REQ-LOG-004,SOC向けKQLルール標準化,SHOULD,DE.CM-7,AU-6,Sentinel Scheduled Rules,誤検知<3%,ルール台帳,レビュー記録
REQ-LOG-005,構成ドリフト検知(Policy/ARG),MUST,DE.CM-1,CM-3,Policyコンプライアンス,逸脱<5%,ARG-DRIFT-001,是正票
REQ-LOG-006,重大アラートの自動起票&初動自動化,MUST,RS.AN-1,IR-4,Sentinel+LogicApps,MTTD<30分,Playbook実行ログ,KPI
REQ-LOG-007,費用急増アラート(Cost),SHOULD,DE.AE-3,PM-5,CostMgmt+ActionGroup,検知100%,通知ログ,対処記録
REQ-LOG-008,サービス障害監視(Azure SH),SHOULD,DE.AE-1,CP-2,ServiceHealthアラート,反映手順化,通知/KPI,Runbook
REQ-WKL-001,AppService HTTPS Only+MinTLS1.2,MUST,PR.DS-2,SC-13,AppSvc設定,準拠100%,ARG-WKL-001,構成出力
REQ-WKL-002,FunctionはMI+KV参照,MUST,PR.AC-4,AC-3,Managed Identity+KV,Secret直置き0,RepoScan,設計書
REQ-WKL-003,SQLはPublic無効/PE+Firewall最小化,MUST,PR.AC-5,SC-7,SQL publicNetworkAccess:Disabled,公開0,ARG/KQL,構成
REQ-WKL-004,StorageはVNet制限+PE,MUST,PR.AC-5,SC-7,NetworkRules Deny+PE,公開0,ARG/KQL,設定出力
REQ-WKL-005,AKSはPrivate+AzurePolicy+Defender,MUST,PR.IP-1,SC-7/CM-6,AKS Private/Policy/Defender,基準準拠>95%,Defender評価,AKS設計
REQ-WKL-006,ContainerRegistryはAdmin無効+PrivateLink,MUST,PR.AC-4,SC-7,ACR AdminDisabled+PE,公開0,ARG,構成
REQ-WKL-007,AppGW/WAFはOWASP更新&例外管理,MUST,PR.IP-1,SI-4,WAFポリシー管理,例外根拠化100%,WAFログ,例外台帳
REQ-WKL-008,KeyVaultのPurge/SoftDelete有効,MUST,RC.RP-1,CP-9,KV設定,Purge/SD有効率100%,ARG,構成
REQ-DEV-001,すべてIaC(レビュー/コードオーナ),MUST,ID.GV-3,CM-3,Bicep/Terraform+PR,直接変更0,Repo保護,レビュー記録
REQ-DEV-002,パイプラインのIDはMI/WorkloadID,MUST,PR.AC-4,AC-3,OIDC/MI,長期Secret0,RepoScan,設定出力
REQ-DEV-003,セキュリティスキャン(SAST/Secret/依存),SHOULD,DE.CM-7,SI-2,Pipeline統合,検出→是正SLA遵守,KPI,レポート
REQ-DEV-004,変更加重ゲート(ProdはCAB承認),MUST,RS.PL-1,CM-3,CAB/ChangeFreeze,逸脱0,承認記録,CAB議事録
REQ-DEV-005,Artifact署名/供給鎖対策,SHOULD,PR.DS-6,SR-11,Sign/Policy,未署名禁止,KQL/CIログ,運用規程
REQ-DEV-006,SBOM管理&脆弱性SLA,SHOULD,DE.CM-7,SI-2,SBOM生成+追跡,High<=14日,KPI,是正票
REQ-IR-001,重大度×SLA(MTTD/MTTR)定義,MUST,RS.MI-1,IR-4,運用Runbook,MTTD<30m/MTTR<4h,インシ記録,KPI
REQ-IR-002,72時間報告ルール(法務連絡),MUST,RS.CO-1,IR-6,法務連絡網/雛形,期限厳守,提出控,手順書
REQ-IR-003,自動封じ込め(Disable/Block/IP),SHOULD,RS.MI-2,IR-4,Playbook,平均封じ込め<10m,Playbookログ,KPI
REQ-IR-004,ポストモーテム/恒久対策,SHOULD,RC.IM-1,IR-8,テンプレ+レビュー,再発率↓,報告書,改善計画
REQ-BCP-001,RPO/RTO定義&DR演習(半期),MUST,RC.RP-1,CP-2,ASR/Backup,目標満足,演習ログ,結果報告
REQ-BCP-002,重要データの異常系復旧テスト,MUST,RC.IM-1,CP-4,復元リハーサル,整合性OK,記録,是正
REQ-BCP-003,GRS/RA-GRSの越境説明&同意,SHOULD,PR.IP-8,PL-8,法務整合,説明/同意取得,記録,ポリシー
REQ-BCP-004,Service Health→運用指示の自動連携,SHOULD,DE.AE-1,CP-2,SHアラート→Runbook,反映<30m,通知ログ,Runbook
REQ-COMP-001,DPIA/データ移転の可視化(MS Purview),SHOULD,ID.RA-1,PL-2,Purview,データマップ更新,レポート,承認
REQ-COMP-002,監査エビデンスパック(四半期),MUST,ID.GV-3,AU-6,ダッシュボード出力,期限遵守,エビデンス束,議事録
REQ-COMP-003,DPA/SCC/越境条項の技術整合,MUST,RS.CO-1,SA-9,契約×技術対応表,差分0,対応表,契約控
REQ-COMP-004,ISMS/ISO27001 AnnexAマップ,SHOULD,ID.GV-3,PM-1,対応マトリクス,更新四半期,台帳,レビュー
注:各行の verification で参照している ARG-/KQL- は、本稿 5) にコードを掲載しています。
2) Policy イニシアティブ(カスタム 8 本付き)
2-1. イニシアティブ(ポリシーセット)
ファイル名: initiative-secure-baseline.json
{
"properties": {
"displayName": "Secure Baseline (Yamazaki-LZ)",
"policyType": "Custom",
"description": "タグ必須、公開遮断、TLS、診断設定、SQL/KV/Storage保護、ロケーション制限など基準を強制",
"metadata": { "category": "Security Center" },
"parameters": {
"logAnalytics": { "type": "String", "metadata": { "displayName": "Log Analytics Workspace Resource ID" } },
"allowedLocations": { "type": "Array", "metadata": { "displayName": "Allowed locations" } }
},
"policyDefinitions": [
{ "policyDefinitionId": "[resourceId('Microsoft.Authorization/policyDefinitions','ymz-require-tags')]" },
{ "policyDefinitionId": "[resourceId('Microsoft.Authorization/policyDefinitions','ymz-allowed-locations')]", "parameters": { "list": { "value": "[parameters('allowedLocations')]" } } },
{ "policyDefinitionId": "[resourceId('Microsoft.Authorization/policyDefinitions','ymz-storage-secure')]" },
{ "policyDefinitionId": "[resourceId('Microsoft.Authorization/policyDefinitions','ymz-sql-public-disabled')]" },
{ "policyDefinitionId": "[resourceId('Microsoft.Authorization/policyDefinitions','ymz-kv-rbac-public-disabled')]" },
{ "policyDefinitionId": "[resourceId('Microsoft.Authorization/policyDefinitions','ymz-appsvc-https-tls12')]" },
{ "policyDefinitionId": "[resourceId('Microsoft.Authorization/policyDefinitions','ymz-enforce-diagnostics')]", "parameters": { "logAnalytics": { "value": "[parameters('logAnalytics')]" } } },
{ "policyDefinitionId": "[resourceId('Microsoft.Authorization/policyDefinitions','ymz-deny-public-paas')]" }
]
}
}
2-2. カスタムポリシー定義(代表 8 本)
a) タグ必須 ymz-require-tags.json
{
"properties": {
"displayName": "Require Tags: Owner/CostCenter/DataClass/BCPTier",
"policyType": "Custom",
"mode": "Indexed",
"policyRule": {
"if": {
"anyOf": [
{ "field": "tags['Owner']", "exists": false },
{ "field": "tags['CostCenter']", "exists": false },
{ "field": "tags['DataClass']", "exists": false },
{ "field": "tags['BCPTier']", "exists": false }
]
},
"then": { "effect": "deny" }
}
}
}
b) 許可ロケーション ymz-allowed-locations.json
{
"properties": {
"displayName": "Allowed Locations",
"parameters": { "list": { "type": "Array" } },
"policyType": "Custom",
"mode": "All",
"policyRule": {
"if": { "field": "location", "notIn": "[parameters('list')]" },
"then": { "effect": "deny" }
}
}
}
c) Storage を安全化 ymz-storage-secure.json
{
"properties": {
"displayName": "Storage: HTTPS only, no public, default deny",
"policyType": "Custom",
"mode": "Indexed",
"policyRule": {
"if": { "field": "type", "equals": "Microsoft.Storage/storageAccounts" },
"then": {
"effect": "denyIfNotExists",
"details": {
"type": "Microsoft.Storage/storageAccounts",
"existenceCondition": {
"allOf": [
{ "field": "Microsoft.Storage/storageAccounts/enableHttpsTrafficOnly", "equals": true },
{ "field": "Microsoft.Storage/storageAccounts/allowBlobPublicAccess", "equals": false },
{ "field": "Microsoft.Storage/storageAccounts/networkAcls.defaultAction", "equals": "Deny" }
]
}
}
}
}
}
}
d) SQL 公開無効 ymz-sql-public-disabled.json
{
"properties": {
"displayName": "SQL Server: Public network access disabled",
"policyType": "Custom",
"mode": "Indexed",
"policyRule": {
"if": { "field": "type", "equals": "Microsoft.Sql/servers" },
"then": {
"effect": "denyIfNotExists",
"details": {
"type": "Microsoft.Sql/servers",
"existenceCondition": { "field": "Microsoft.Sql/servers/publicNetworkAccess", "equals": "Disabled" }
}
}
}
}
}
e) Key Vault RBAC & Public 無効 ymz-kv-rbac-public-disabled.json
{
"properties": {
"displayName": "Key Vault: RBAC enabled and Public Network Disabled",
"policyType": "Custom",
"mode": "Indexed",
"policyRule": {
"if": { "field": "type", "equals": "Microsoft.KeyVault/vaults" },
"then": {
"effect": "denyIfNotExists",
"details": {
"type": "Microsoft.KeyVault/vaults",
"existenceCondition": {
"allOf": [
{ "field": "Microsoft.KeyVault/vaults/properties.enableRbacAuthorization", "equals": true },
{ "field": "Microsoft.KeyVault/vaults/publicNetworkAccess", "equals": "Disabled" }
]
}
}
}
}
}
}
f) App Service HTTPS Only & TLS1.2+ ymz-appsvc-https-tls12.json
{
"properties": {
"displayName": "App Service: HTTPS only & Min TLS 1.2",
"policyType": "Custom",
"mode": "Indexed",
"policyRule": {
"if": { "field": "type", "equals": "Microsoft.Web/sites" },
"then": {
"effect": "denyIfNotExists",
"details": {
"type": "Microsoft.Web/sites/config",
"name": "web",
"existenceCondition": {
"allOf": [
{ "field": "Microsoft.Web/sites/config/web.minTlsVersion", "equals": "1.2" },
{ "field": "Microsoft.Web/sites/httpsOnly", "equals": true }
]
}
}
}
}
}
}
g) 診断設定の自動付与 ymz-enforce-diagnostics.json
{
"properties": {
"displayName": "Deploy Diagnostic Settings to LA",
"parameters": { "logAnalytics": { "type": "String" } },
"policyType": "Custom",
"mode": "Indexed",
"policyRule": {
"if": { "anyOf": [
{ "field": "type", "equals": "Microsoft.KeyVault/vaults" },
{ "field": "type", "equals": "Microsoft.Storage/storageAccounts" },
{ "field": "type", "equals": "Microsoft.Sql/servers" }
]},
"then": {
"effect": "deployIfNotExists",
"details": {
"type": "Microsoft.Insights/diagnosticSettings",
"existenceCondition": { "field": "Microsoft.Insights/diagnosticSettings/logs.enabled", "equals": true },
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [{
"type": "Microsoft.Insights/diagnosticSettings",
"apiVersion": "2021-05-01-preview",
"name": "[format('{0}-to-law', uniqueString(resourceId('resourceGroup'), deployment().name))]",
"properties": {
"workspaceId": "[parameters('logAnalytics')]",
"logs": [{ "categoryGroup": "allLogs", "enabled": true }],
"metrics": [{ "category": "AllMetrics", "enabled": true }]
}
}]
}
}
}
}
}
}
}
}
h) PaaS 公開の包括禁止(PE 前提) ymz-deny-public-paas.json
{
"properties": {
"displayName": "Deny public network access on selected PaaS",
"policyType": "Custom",
"mode": "Indexed",
"policyRule": {
"if": {
"anyOf": [
{ "field": "type", "equals": "Microsoft.Storage/storageAccounts" },
{ "field": "type", "equals": "Microsoft.Sql/servers" },
{ "field": "type", "equals": "Microsoft.KeyVault/vaults" }
]
},
"then": { "effect": "deny" }
}
}
}
デプロイ順:policyDefinitions(a〜h)→ initiative-secure-baseline.json を MG/Subscription に割当。
3) Bicep / Terraform モジュール
3-1. Bicep:Log Analytics + Sentinel 有効化
bicep/la-sentinel.bicep
param location string = resourceGroup().location
param laName string
param pricingTier string = 'PerGB2018'
resource law 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
name: laName
location: location
properties: { sku: { name: pricingTier }, retentionInDays: 90 }
}
resource sentinel 'Microsoft.OperationalInsights/workspaces/providers/onboardingStates@2022-11-01-preview' = {
name: '${law.name}/Microsoft.SecurityInsights/default'
properties: { onboardingState: 'Onboarded' }
}
output workspaceId string = law.id
3-2. Bicep:Key Vault セキュア既定
bicep/keyvault-secure.bicep
param kvName string
param location string = resourceGroup().location
param laId string
resource kv 'Microsoft.KeyVault/vaults@2022-07-01' = {
name: kvName
location: location
properties: {
enableRbacAuthorization: true
tenantId: subscription().tenantId
sku: { family: 'A', name: 'standard' }
publicNetworkAccess: 'Disabled'
softDeleteRetentionInDays: 90
enablePurgeProtection: true
}
}
resource diag 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
name: 'send-to-law'
scope: kv
properties: { workspaceId: laId, logs: [{ category: 'AuditEvent', enabled: true }] }
}
3-3. Bicep:Storage セキュア既定
bicep/storage-secure.bicep
param name string
param rgLocation string = resourceGroup().location
param laId string
resource sa 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: name
location: rgLocation
kind: 'StorageV2'
sku: { name: 'Standard_ZRS' }
properties: {
allowBlobPublicAccess: false
minimumTlsVersion: 'TLS1_2'
supportsHttpsTrafficOnly: true
networkAcls: { defaultAction: 'Deny', bypass: 'AzureServices' }
}
}
resource diag 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
name: 'send-to-law'
scope: sa
properties: { workspaceId: laId, logs: [{ categoryGroup: 'allLogs', enabled: true }] }
}
3-4. Bicep:SQL(Public 無効 + Private Endpoint)
bicep/sql-private.bicep
param sqlName string
param vnetId string
param subnetPeName string
param laId string
param location string = resourceGroup().location
resource sql 'Microsoft.Sql/servers@2021-11-01' = {
name: sqlName
location: location
properties: { administratorLogin: 'sqladmin', administratorLoginPassword: 'REPLACE_ME', publicNetworkAccess: 'Disabled' }
}
resource pe 'Microsoft.Network/privateEndpoints@2022-09-01' = {
name: '${sqlName}-pe'
location: location
properties: {
subnet: { id: '${vnetId}/subnets/${subnetPeName}' }
privateLinkServiceConnections: [{
name: 'sqlplink'
properties: {
privateLinkServiceId: sql.id
groupIds: [ 'sqlServer' ]
}
}]
}
}
resource diag 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
name: 'send-to-law'
scope: sql
properties: { workspaceId: laId, logs: [{ categoryGroup: 'allLogs', enabled: true }] }
}
3-5. Terraform:Storage セキュア
terraform/storage_secure.tf
resource "azurerm_storage_account" "secure" {
name = var.name
resource_group_name = var.rg
location = var.location
account_tier = "Standard"
account_replication_type = "ZRS"
min_tls_version = "TLS1_2"
https_only = true
allow_blob_public_access = false
network_rules {
default_action = "Deny"
bypass = ["AzureServices"]
}
tags = {
Owner = var.owner
CostCenter = var.cost_center
DataClass = "PII"
BCPTier = "Tier1"
}
}
3-6. Terraform:Key Vault セキュア
terraform/keyvault_secure.tf
resource "azurerm_key_vault" "kv" {
name = var.name
location = var.location
resource_group_name = var.rg
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
purge_protection_enabled = true
soft_delete_retention_days = 90
enable_rbac_authorization = true
public_network_access_enabled = false
tags = var.tags
}
4) Sentinel ルール & Playbook(Logic Apps)
4-1. 代表 KQL ルール(Scheduled)
a) 大量ダウンロード(Blob) rule-blob-mass-download.json
{
"properties": {
"displayName": "Mass Blob Download by a Principal",
"severity": "High",
"enabled": true,
"queryFrequency": "PT15M",
"queryPeriod": "PT15M",
"query": "StorageBlobLogs | where TimeGenerated > ago(15m) | summarize cnt=count() by UserPrincipalName, bin(TimeGenerated, 15m) | where cnt > 1000",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0,
"tactics": ["Exfiltration"],
"kind": "Scheduled"
}
}
b) 役割昇格検知(Owner/Privileged) rule-role-elevation.json
{
"properties": {
"displayName": "Privileged Role Assignment Detected",
"severity": "Medium",
"enabled": true,
"queryFrequency": "PT5M",
"queryPeriod": "PT5M",
"query": "AuditLogs | where OperationName has 'Add member to role' or OperationName has 'Add eligible member' | project TimeGenerated, ActivityDateTime, InitiatedBy, TargetResources, Result",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0,
"tactics": ["PrivilegeEscalation"],
"kind": "Scheduled"
}
}
c) Key Vault 秘密読み取りスパイク rule-kv-secret-spike.json
{
"properties": {
"displayName": "Key Vault Secret Read Spike",
"severity": "High",
"enabled": true,
"queryFrequency": "PT15M",
"queryPeriod": "PT1H",
"query": "AzureDiagnostics | where Category == 'AuditEvent' and OperationName == 'SecretGet' | summarize cnt = count() by CallerIPAddress, bin(TimeGenerated, 15m) | join kind=leftanti (AzureDiagnostics | where Category == 'AuditEvent' and OperationName == 'SecretGet' | summarize base = avg(1.0) by CallerIPAddress, bin(TimeGenerated, 7d)) on CallerIPAddress | where cnt > 500",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0,
"tactics": ["CredentialAccess"],
"kind": "Scheduled"
}
}
d) NSG 変更(時間外) rule-nsg-change-afterhours.json
{
"properties": {
"displayName": "NSG Rule Change in Afterhours",
"severity": "Medium",
"enabled": true,
"queryFrequency": "PT10M",
"queryPeriod": "PT1H",
"query": "AzureActivity | where OperationNameValue has 'securityRules' and ActivityStatusValue == 'Success' | extend hour = datetime_part('Hour', TimeGenerated) | where hour < 8 or hour > 19",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0,
"tactics": ["DefenseEvasion"],
"kind": "Scheduled"
}
}
同様に、Impossible Travel、App Service Config Change、SQL FW ルール追加、診断設定無効検出 等を追加してください(上記 KQL を雛形化可能)。
4-2. Playbook(Logic Apps:自動封じ込め)
playbook-disable-user-block-ip.json
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2019-05-01/workflowdefinition.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"triggers": {
"When_a_response_to_an_Azure_Sentinel_alert_is_triggered": {
"type": "Request",
"kind": "Http",
"inputs": { "schema": {} }
}
},
"actions": {
"ParseAlert": { "type": "ParseJson", "runAfter": {}, "inputs": { "content": "@triggerBody()", "schema": {} } },
"DisableUser": {
"type": "ApiConnection",
"inputs": {
"host": { "connection": { "name": "@parameters('$connections')['office365']['connectionId']" } },
"method": "post",
"path": "/v2/users/@{triggerBody()?['Essentials']?['UserName']}/disableSignIn"
}
},
"BlockNSG": {
"type": "ApiConnection",
"inputs": {
"host": { "connection": { "name": "@parameters('$connections')['azurefirewall']['connectionId']" } },
"method": "post",
"path": "/providers/Microsoft.Network/operations",
"body": { "action": "blockIp", "ip": "@triggerBody()?['Essentials']?['AlertTargetIPs']" }
}
},
"NotifyTeams": {
"type": "ApiConnection",
"inputs": {
"host": { "connection": { "name": "@parameters('$connections')['teams']['connectionId']" } },
"method": "post",
"path": "/v3/conversations/@{variables('teamsChannelId')}/activities",
"body": { "text": "Sentinel Alert handled: user disabled & IP blocked" }
}
}
},
"outputs": {}
},
"kind": "Stateful"
}
実環境では Graph/NSG 変更用のコネクタ・アプリ権限を設定し、承認ステップ(Approvals)を挟むことを推奨。
5) 検証レシピ(ARG/KQL)
5-1. ARG(タグ/公開遮断/PE)
ARG-REQ-GOV-001:タグ欠落
Resources
| where isnull(tags['Owner']) or isnull(tags['CostCenter']) or isnull(tags['DataClass']) or isnull(tags['BCPTier'])
| project name, type, resourceGroup, subscriptionId
ARG-NET-001:PaaS 公開
Resources
| where type in~ ('microsoft.storage/storageaccounts','microsoft.sql/servers','microsoft.keyvault/vaults')
| extend pub = tostring(properties.publicNetworkAccess)
| where pub =~ 'Enabled' or pub =~ 'True' or isnull(pub)
| project name, type, pub
ARG-WKL-001:App Service TLS
Resources
| where type =~ 'microsoft.web/sites'
| extend tls = tostring(properties.siteConfig.minTlsVersion), httpsOnly = tostring(properties.httpsOnly)
| where tls !~ '1.2' or httpsOnly !~ 'true'
| project name, tls, httpsOnly
5-2. KQL(MFA/Legacy/診断)
KQL-AC-001:特権 MFA カバレッジ
AuditLogs
| where TimeGenerated > ago(30d) and OperationName has "Add eligible member to role"
| summarize by TargetResources
// 特権ユーザー一覧と Entra 側の MFA 設定エクスポートを突合(外部データ連携でも可)
KQL-AC-004:レガシー認証サインイン
SigninLogs
| where AuthenticationRequirement == "singleFactorAuthentication"
and ClientAppUsed in ("IMAP","POP","SMTP","Other clients")
| summarize count() by UserPrincipalName
KQL-LOG-003:診断無効リソース検出
let diag = (AzureDiagnostics | summarize by _ResourceId);
Resources
| where type in~ ('microsoft.keyvault/vaults','microsoft.storage/storageaccounts','microsoft.sql/servers')
| where _ResourceId !in (diag)
| project name, type, resourceGroup
付記:導入・運用メモ(現実解)
優先適用:REQ-AC-001/002/004/005、REQ-NET-001/003、REQ-DATA-001/005/008、REQ-LOG-001/002、REQ-WKL-003/004
コスト最適化:LAW は 90 日ホット+アーカイブ、Sentinel ルールは高精度から開始、Defender は重要リソースから有効化
証跡:四半期毎に Policy 準拠率、タグ準拠、特権レビュー、アラート KPI、DR 演習 をエビデンス束化
6) まとめ
このスターターは、NIST CSF / SP 800‑53 と Azure 実装の対応を最短で形にするための使い切れる最小完結セットです。必要に応じ、上記 64 要件を120 要件規模へ拡張(AKS/Databricks/Synapse/SAP on Azure 等の専門項目、ISMS Annex A マッピング、DPIA 連動)し、Policy/Sentinel/Runbookも貴社業務に合わせてカスタマイズ可能です。





コメント