Appearance
DDE Subscription-Level Security Controls
Environment: Azure DDE (tenant ff1c5d68, ciriusdde.com) Scope: Baseline security controls expected on every DDE subscription Purpose: Expected state for HIPAA/HITRUST compliance in a customer-facing Medicare billing environment. Deviations are findings. Owner: Rory — all remediation approved before merge Remediation repo: azure-dde-infra
Why These Controls Exist
DDE processes Medicare billing data and publishes applications to external users via AVD. HIPAA requires technical safeguards on storage, key material, network access, and audit logs. HITRUST layers specific control families on top. Defender for Cloud and Azure Policy continuously evaluate these. This doc captures the expected state so audits become a diff operation.
Storage Accounts
Every storage account in DDE must have:
| Control | Expected State | Rationale |
|---|---|---|
| Public blob access | Disabled at account level | HIPAA — no anonymous PHI exposure |
| Network rules | Private endpoint only, default_action = "Deny" | Defense in depth vs. shared-key leakage |
| TLS version | min_tls_version = "TLS1_2" | Azure baseline, HIPAA-relevant |
| Shared key access | shared_access_key_enabled = false where feasible | Entra ID auth preferred |
| Infrastructure encryption | infrastructure_encryption_enabled = true | HIPAA double encryption |
| Soft delete (blob) | 30 days minimum | Ransomware recovery |
| Soft delete (container) | 7 days minimum | Accidental deletion recovery |
| Versioning | Enabled where data mutability exists | Ransomware recovery |
| Diagnostic settings | All categories → cirius-logging-law-central (cross-tenant) | 6-year SIEM-independent archive |
Module: establish a dde-storage module pattern so these defaults are automatic.
Key Vault
Every DDE Key Vault must have:
| Control | Expected State | Rationale |
|---|---|---|
| Access model | enable_rbac_authorization = true | Access policies are a deprecated pattern |
| Network rules | Private endpoint, default_action = "Deny" | No public key material exposure |
| Soft delete | Enabled, 90-day retention | Azure default plus HIPAA |
| Purge protection | purge_protection_enabled = true | Prevents permanent deletion during incident |
| Diagnostic settings | AuditEvent + AzurePolicyEvaluationDetails → cirius-logging-law-central | Detects key theft |
| CMK usage | Vaults backing CMK resources use HSM-backed keys where cost permits | HIPAA technical safeguard |
Module: keyvault-cmk (from azure-infra, ported or referenced in azure-dde-infra).
Network Security Groups
Every NSG in DDE must have:
| Control | Expected State |
|---|---|
| Default posture | Deny-by-default — implicit deny terminal rule above 65000 |
| Inbound internet | No */Internet source without explicit justification in the rule description |
| RDP/SSH from internet | Never — must be behind Twingate, Bastion, or Palo Alto NVA |
| NSG flow logs | Enabled on every NSG, retention 30 days minimum, traffic analytics on |
| Flow logs destination | Storage account in DDE + LAW cirius-logging-law-central (cross-tenant) |
Module: nsg module must default NSG flow logs on and fail closed if the target storage account isn't present.
Diagnostic Settings — Universal
Rule: Every resource in DDE that supports diagnostic settings forwards to cirius-logging-law-central (ID 5d76d1f2, logging subscription in PROD tenant).
| Resource Type | Categories |
|---|---|
| Activity Log | All administrative, security, policy, service-health |
| Azure Policy | Compliance and evaluation events |
| Key Vault | AuditEvent + AzurePolicyEvaluationDetails |
| Storage (blob/file/queue/table) | StorageRead, StorageWrite, StorageDelete |
| NSG | NetworkSecurityGroupEvent + NetworkSecurityGroupRuleCounter |
| AVD session hosts | Connection events via agent + OS logs via Azure Monitor Agent |
| AKS (if introduced) | kube-apiserver, kube-audit, kube-audit-admin, guard |
| Front Door / App Gateway | All categories |
Module: diagnostic-settings — every new resource wires this in. CI Checkov rule flags any resource without diagnostic settings.
Defender for Cloud
| Plan | DDE Posture |
|---|---|
| Defender for Servers Plan 2 | Enabled on all subscriptions (file integrity, JIT, vuln assessment) |
| Defender for Storage | Enabled — malware scan on upload for any PHI-adjacent containers |
| Defender for Key Vault | Enabled |
| Defender for Resource Manager | Enabled |
| Defender for DNS | Enabled |
| Defender for App Service | Enabled where App Service present |
| Defender CSPM | Enabled — continuous posture scoring |
| Secure Score target | >= 80% per subscription; drops below trigger a story |
Continuous export to cirius-logging-law-central for alert correlation with the 17-agent SecOps system.
Azure Policy Assignments
Required assignments on every DDE subscription:
| Initiative | Purpose |
|---|---|
| HIPAA HITRUST | HIPAA-specific technical safeguards |
| ISO 27001:2013 | Broad security baseline |
| Azure Security Benchmark | Defender for Cloud backbone |
| NIST SP 800-53 Rev 5 (audit mode) | Maps to AWS Security Hub R5 equivalence |
Enforcement mode: Most assignments remain in AuditIfNotExists until baseline compliance is reached, then promote specific controls to Deny once remediation is complete.
Activity Log Alerts
Required alert rules per subscription:
| Rule | Trigger |
|---|---|
| Policy assignment changed | `Microsoft.Authorization/policyAssignments/write |
| Security contact changed | `Microsoft.Security/securityContacts/write |
| Role assignment changed at subscription scope | Microsoft.Authorization/roleAssignments/* |
| Network Security Group rule change | Microsoft.Network/networkSecurityGroups/securityRules/* |
| Key Vault deletion or purge | Microsoft.KeyVault/vaults/delete or .../purge |
| Storage account network rule change | Microsoft.Storage/storageAccounts/write with networkAcls diff |
All alerts route to the same action group that feeds SecOps POST /api/incidents.
Managed Disks
| Control | Expected State |
|---|---|
| Encryption at host | encryption_at_host_enabled = true except Palo Alto marketplace images (unsupported — CMK is compensating) |
| CMK encryption | DiskEncryptionSet backed by customer-managed key in DDE Key Vault |
| Public network access | Disabled |
Recovery Services Vaults
| Control | Expected State |
|---|---|
| Soft delete | soft_delete_enabled = true, 14 days minimum |
| Immutability | Unlocked on permanent vaults (never on decommission-bound — blocks cleanup) |
| Cross-region restore | Enabled where DR strategy requires |
| Private endpoint | Enabled |
| Diagnostic settings | All categories → cirius-logging-law-central |
Module: recovery-vault.
Known Gaps (Current State, April 2026)
These are the gaps Defender for Cloud and internal review have surfaced in DDE. Each is a DDEENV story; remediation lands via azure-dde-infra PRs.
| Gap | Notes |
|---|---|
| Storage accounts without private endpoints or VNet rules | Multiple accounts; DDEENV-037 (this workstream) |
| Key Vault without private link | DDEENV-037 remediation |
| NSG flow logs not configured on all NSGs | DDEENV-037 remediation |
| Managed disks without double encryption | Pending CMK rollout per subscription |
| Activity log alerts missing for Policy / Security operations | Pending rollout |
| Storage infrastructure encryption not enabled | Pending per-account update |
| ASR coverage incomplete on DDE VMs | Tracked separately in DDE ASR planning runbook |
| Privileged SPs with permanent admin roles at subscription scope | Tracked in DDE privileged access review |
Related
security/dde-privileged-access-review.md— identity side of the reviewrunbooks/dde-asr-configuration.md— DR planning for DDE VMssecurity/terraform-standards.md— Terraform compliance expectationssecurity/lpriv-baseline.md— PROD tenant equivalent