fedramp-20x-mcp 0.4.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fedramp_20x_mcp/__init__.py +14 -0
- fedramp_20x_mcp/__main__.py +12 -0
- fedramp_20x_mcp/data_loader.py +673 -0
- fedramp_20x_mcp/prompts/__init__.py +62 -0
- fedramp_20x_mcp/prompts/api_design_guide.txt +432 -0
- fedramp_20x_mcp/prompts/ato_package_checklist.txt +75 -0
- fedramp_20x_mcp/prompts/audit_preparation.txt +592 -0
- fedramp_20x_mcp/prompts/authorization_boundary_review.txt +76 -0
- fedramp_20x_mcp/prompts/azure_ksi_automation.txt +997 -0
- fedramp_20x_mcp/prompts/continuous_monitoring_setup.txt +61 -0
- fedramp_20x_mcp/prompts/documentation_generator.txt +499 -0
- fedramp_20x_mcp/prompts/gap_analysis.txt +25 -0
- fedramp_20x_mcp/prompts/initial_assessment_roadmap.txt +202 -0
- fedramp_20x_mcp/prompts/ksi_implementation_priorities.txt +283 -0
- fedramp_20x_mcp/prompts/migration_from_rev5.txt +440 -0
- fedramp_20x_mcp/prompts/quarterly_review_checklist.txt +231 -0
- fedramp_20x_mcp/prompts/significant_change_assessment.txt +50 -0
- fedramp_20x_mcp/prompts/vendor_evaluation.txt +349 -0
- fedramp_20x_mcp/prompts/vulnerability_remediation_timeline.txt +45 -0
- fedramp_20x_mcp/server.py +270 -0
- fedramp_20x_mcp/templates/__init__.py +75 -0
- fedramp_20x_mcp/templates/bicep/afr.txt +33 -0
- fedramp_20x_mcp/templates/bicep/cna.txt +48 -0
- fedramp_20x_mcp/templates/bicep/generic.txt +47 -0
- fedramp_20x_mcp/templates/bicep/iam.txt +211 -0
- fedramp_20x_mcp/templates/bicep/mla.txt +82 -0
- fedramp_20x_mcp/templates/bicep/rpl.txt +44 -0
- fedramp_20x_mcp/templates/bicep/svc.txt +54 -0
- fedramp_20x_mcp/templates/code/generic_csharp.txt +65 -0
- fedramp_20x_mcp/templates/code/generic_powershell.txt +65 -0
- fedramp_20x_mcp/templates/code/generic_python.txt +63 -0
- fedramp_20x_mcp/templates/code/iam_csharp.txt +150 -0
- fedramp_20x_mcp/templates/code/iam_powershell.txt +162 -0
- fedramp_20x_mcp/templates/code/iam_python.txt +224 -0
- fedramp_20x_mcp/templates/code/mla_python.txt +124 -0
- fedramp_20x_mcp/templates/terraform/afr.txt +29 -0
- fedramp_20x_mcp/templates/terraform/cna.txt +50 -0
- fedramp_20x_mcp/templates/terraform/generic.txt +40 -0
- fedramp_20x_mcp/templates/terraform/iam.txt +219 -0
- fedramp_20x_mcp/templates/terraform/mla.txt +29 -0
- fedramp_20x_mcp/templates/terraform/rpl.txt +32 -0
- fedramp_20x_mcp/templates/terraform/svc.txt +46 -0
- fedramp_20x_mcp/tools/__init__.py +167 -0
- fedramp_20x_mcp/tools/definitions.py +154 -0
- fedramp_20x_mcp/tools/documentation.py +155 -0
- fedramp_20x_mcp/tools/enhancements.py +2256 -0
- fedramp_20x_mcp/tools/evidence.py +701 -0
- fedramp_20x_mcp/tools/export.py +753 -0
- fedramp_20x_mcp/tools/ksi.py +90 -0
- fedramp_20x_mcp/tools/requirements.py +163 -0
- fedramp_20x_mcp-0.4.8.dist-info/METADATA +877 -0
- fedramp_20x_mcp-0.4.8.dist-info/RECORD +55 -0
- fedramp_20x_mcp-0.4.8.dist-info/WHEEL +4 -0
- fedramp_20x_mcp-0.4.8.dist-info/entry_points.txt +2 -0
- fedramp_20x_mcp-0.4.8.dist-info/licenses/LICENSE +27 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Infrastructure and code templates for FedRAMP 20x evidence collection.
|
|
3
|
+
|
|
4
|
+
This module provides Bicep, Terraform, and code generation templates
|
|
5
|
+
organized by KSI family (IAM, MLA, AFR, CNA, RPL, SVC).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
# Template directory
|
|
11
|
+
TEMPLATES_DIR = Path(__file__).parent
|
|
12
|
+
|
|
13
|
+
def load_template(category: str, name: str) -> str:
|
|
14
|
+
"""
|
|
15
|
+
Load a template file by category and name.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
category: Template category (bicep, terraform, code)
|
|
19
|
+
name: Template name (iam, mla, afr, cna, rpl, svc, generic)
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
Template content as string
|
|
23
|
+
|
|
24
|
+
Raises:
|
|
25
|
+
FileNotFoundError: If template doesn't exist
|
|
26
|
+
"""
|
|
27
|
+
template_path = TEMPLATES_DIR / category / f"{name}.txt"
|
|
28
|
+
|
|
29
|
+
if not template_path.exists():
|
|
30
|
+
raise FileNotFoundError(f"Template not found: {template_path}")
|
|
31
|
+
|
|
32
|
+
return template_path.read_text(encoding='utf-8')
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def get_infrastructure_template(ksi_family: str, infra_type: str) -> str:
|
|
36
|
+
"""
|
|
37
|
+
Get infrastructure template for a KSI family.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
ksi_family: KSI family code (iam, mla, afr, cna, rpl, svc)
|
|
41
|
+
infra_type: Infrastructure type (bicep, terraform)
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Template content wrapped in markdown code blocks
|
|
45
|
+
"""
|
|
46
|
+
try:
|
|
47
|
+
template = load_template(infra_type, ksi_family.lower())
|
|
48
|
+
return template
|
|
49
|
+
except FileNotFoundError:
|
|
50
|
+
# Fall back to generic template
|
|
51
|
+
template = load_template(infra_type, 'generic')
|
|
52
|
+
return template
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_code_template(ksi_family: str, language: str) -> str:
|
|
56
|
+
"""
|
|
57
|
+
Get code generation template for a KSI family.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
ksi_family: KSI family code (iam, mla, afr, cna, rpl, svc)
|
|
61
|
+
language: Programming language (python, csharp, powershell)
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
Code template content
|
|
65
|
+
"""
|
|
66
|
+
try:
|
|
67
|
+
# Try family-specific template
|
|
68
|
+
template_name = f"{ksi_family.lower()}_{language.lower()}"
|
|
69
|
+
template = load_template('code', template_name)
|
|
70
|
+
return template
|
|
71
|
+
except FileNotFoundError:
|
|
72
|
+
# Fall back to generic template
|
|
73
|
+
template_name = f"generic_{language.lower()}"
|
|
74
|
+
template = load_template('code', template_name)
|
|
75
|
+
return template
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
## Bicep Template
|
|
2
|
+
|
|
3
|
+
```bicep
|
|
4
|
+
// main.bicep - Authorization Framework Evidence Collection
|
|
5
|
+
param location string = resourceGroup().location
|
|
6
|
+
|
|
7
|
+
// Storage for vulnerability scan results and authorization evidence
|
|
8
|
+
resource evidenceStorage 'Microsoft.Storage/storageAccounts@2023-01-01' = {
|
|
9
|
+
name: 'stfedrampafrevidence'
|
|
10
|
+
location: location
|
|
11
|
+
sku: { name: 'Standard_GRS' }
|
|
12
|
+
properties: {
|
|
13
|
+
supportsHttpsTrafficOnly: true
|
|
14
|
+
minimumTlsVersion: 'TLS1_2'
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Microsoft Defender for Cloud (configured via Policy)
|
|
19
|
+
// This provides vulnerability scanning automatically
|
|
20
|
+
|
|
21
|
+
// Container Registry with scanning enabled
|
|
22
|
+
resource acr 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
|
|
23
|
+
name: 'acrfedrampvuln'
|
|
24
|
+
location: location
|
|
25
|
+
sku: { name: 'Premium' } // Required for Defender scanning
|
|
26
|
+
properties: {
|
|
27
|
+
adminUserEnabled: false
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
output storageAccountName string = evidenceStorage.name
|
|
32
|
+
output containerRegistryName string = acr.name
|
|
33
|
+
```
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
## Bicep Template
|
|
2
|
+
|
|
3
|
+
```bicep
|
|
4
|
+
// main.bicep - Cloud Native Architecture Evidence
|
|
5
|
+
param location string = resourceGroup().location
|
|
6
|
+
|
|
7
|
+
// AKS cluster with monitoring
|
|
8
|
+
resource aks 'Microsoft.ContainerService/managedClusters@2023-10-01' = {
|
|
9
|
+
name: 'aks-fedramp-prod'
|
|
10
|
+
location: location
|
|
11
|
+
identity: {
|
|
12
|
+
type: 'SystemAssigned'
|
|
13
|
+
}
|
|
14
|
+
properties: {
|
|
15
|
+
dnsPrefix: 'fedramp'
|
|
16
|
+
enableRBAC: true
|
|
17
|
+
networkProfile: {
|
|
18
|
+
networkPlugin: 'azure'
|
|
19
|
+
networkPolicy: 'calico' // For KSI-CNA-01
|
|
20
|
+
serviceCidr: '10.0.0.0/16'
|
|
21
|
+
dnsServiceIP: '10.0.0.10'
|
|
22
|
+
}
|
|
23
|
+
addonProfiles: {
|
|
24
|
+
omsagent: {
|
|
25
|
+
enabled: true
|
|
26
|
+
config: {
|
|
27
|
+
logAnalyticsWorkspaceResourceID: logAnalytics.id
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
azurePolicy: {
|
|
31
|
+
enabled: true // For KSI-CNA-08
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
|
|
38
|
+
name: 'log-fedramp-aks'
|
|
39
|
+
location: location
|
|
40
|
+
properties: {
|
|
41
|
+
sku: { name: 'PerGB2018' }
|
|
42
|
+
retentionInDays: 730
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
output aksClusterName string = aks.name
|
|
47
|
+
output workspaceId string = logAnalytics.id
|
|
48
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
## Bicep Template
|
|
2
|
+
|
|
3
|
+
```bicep
|
|
4
|
+
// main.bicep - Generic KSI Evidence Collection Infrastructure
|
|
5
|
+
param location string = resourceGroup().location
|
|
6
|
+
param ksiId string
|
|
7
|
+
|
|
8
|
+
// Evidence Storage Account
|
|
9
|
+
resource evidenceStorage 'Microsoft.Storage/storageAccounts@2023-01-01' = {
|
|
10
|
+
name: 'st${toLower(replace(ksiId, '-', ''))}evidence'
|
|
11
|
+
location: location
|
|
12
|
+
kind: 'StorageV2'
|
|
13
|
+
sku: {
|
|
14
|
+
name: 'Standard_GRS'
|
|
15
|
+
}
|
|
16
|
+
properties: {
|
|
17
|
+
supportsHttpsTrafficOnly: true
|
|
18
|
+
minimumTlsVersion: 'TLS1_2'
|
|
19
|
+
encryption: {
|
|
20
|
+
keySource: 'Microsoft.Storage'
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Container for evidence files
|
|
26
|
+
resource evidenceContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-01-01' = {
|
|
27
|
+
name: '${evidenceStorage.name}/default/evidence'
|
|
28
|
+
properties: {
|
|
29
|
+
publicAccess: 'None'
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Log Analytics for metrics
|
|
34
|
+
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
|
|
35
|
+
name: 'log-${toLower(ksiId)}'
|
|
36
|
+
location: location
|
|
37
|
+
properties: {
|
|
38
|
+
sku: {
|
|
39
|
+
name: 'PerGB2018'
|
|
40
|
+
}
|
|
41
|
+
retentionInDays: 730
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
output storageAccountName string = evidenceStorage.name
|
|
46
|
+
output workspaceId string = logAnalytics.properties.customerId
|
|
47
|
+
```
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
// main.bicep - IAM Evidence Collection Infrastructure
|
|
2
|
+
// Follows Azure CAF naming conventions and WAF best practices
|
|
3
|
+
param location string = resourceGroup().location
|
|
4
|
+
param environmentName string = 'prod'
|
|
5
|
+
param workloadName string = 'fedramp'
|
|
6
|
+
|
|
7
|
+
// CAF recommended tags for governance
|
|
8
|
+
param tags object = {
|
|
9
|
+
Environment: environmentName
|
|
10
|
+
Workload: workloadName
|
|
11
|
+
CostCenter: 'Security'
|
|
12
|
+
ManagedBy: 'IaC'
|
|
13
|
+
Compliance: 'FedRAMP'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Log Analytics Workspace for IAM logs (CAF naming: log-<workload>-<env>-<purpose>)
|
|
17
|
+
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
|
|
18
|
+
name: 'log-${workloadName}-${environmentName}-iam'
|
|
19
|
+
location: location
|
|
20
|
+
tags: tags
|
|
21
|
+
properties: {
|
|
22
|
+
sku: {
|
|
23
|
+
name: 'PerGB2018'
|
|
24
|
+
}
|
|
25
|
+
retentionInDays: 730 // 2 years retention for FedRAMP
|
|
26
|
+
features: {
|
|
27
|
+
immediatePurgeDataOn30Days: false // Prevent accidental data loss
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Storage Account for evidence (CAF naming: st<workload><env><unique>)
|
|
33
|
+
resource evidenceStorage 'Microsoft.Storage/storageAccounts@2023-05-01' = {
|
|
34
|
+
name: 'st${workloadName}${environmentName}iam'
|
|
35
|
+
location: location
|
|
36
|
+
kind: 'StorageV2'
|
|
37
|
+
tags: tags
|
|
38
|
+
sku: {
|
|
39
|
+
name: 'Standard_GRS' // Geo-redundant for WAF Reliability
|
|
40
|
+
}
|
|
41
|
+
identity: {
|
|
42
|
+
type: 'SystemAssigned' // Enable managed identity
|
|
43
|
+
}
|
|
44
|
+
properties: {
|
|
45
|
+
supportsHttpsTrafficOnly: true
|
|
46
|
+
minimumTlsVersion: 'TLS1_2'
|
|
47
|
+
allowBlobPublicAccess: false // WAF Security: Block public access
|
|
48
|
+
networkAcls: {
|
|
49
|
+
defaultAction: 'Deny' // WAF Security: Default deny
|
|
50
|
+
bypass: 'AzureServices'
|
|
51
|
+
}
|
|
52
|
+
encryption: {
|
|
53
|
+
keySource: 'Microsoft.Storage'
|
|
54
|
+
requireInfrastructureEncryption: true // Double encryption
|
|
55
|
+
services: {
|
|
56
|
+
blob: {
|
|
57
|
+
enabled: true
|
|
58
|
+
}
|
|
59
|
+
file: {
|
|
60
|
+
enabled: true
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Blob service configuration
|
|
68
|
+
resource blobService 'Microsoft.Storage/storageAccounts/blobServices@2023-05-01' = {
|
|
69
|
+
parent: evidenceStorage
|
|
70
|
+
name: 'default'
|
|
71
|
+
properties: {
|
|
72
|
+
deleteRetentionPolicy: {
|
|
73
|
+
enabled: true
|
|
74
|
+
days: 30 // Soft delete for 30 days
|
|
75
|
+
}
|
|
76
|
+
containerDeleteRetentionPolicy: {
|
|
77
|
+
enabled: true
|
|
78
|
+
days: 30
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Container for IAM evidence
|
|
84
|
+
resource evidenceContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = {
|
|
85
|
+
parent: blobService
|
|
86
|
+
name: 'iam-evidence'
|
|
87
|
+
properties: {
|
|
88
|
+
publicAccess: 'None'
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Application Insights for monitoring (CAF naming: appi-<workload>-<env>-<purpose>)
|
|
93
|
+
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
|
|
94
|
+
name: 'appi-${workloadName}-${environmentName}-iam'
|
|
95
|
+
location: location
|
|
96
|
+
tags: tags
|
|
97
|
+
kind: 'web'
|
|
98
|
+
properties: {
|
|
99
|
+
Application_Type: 'web'
|
|
100
|
+
WorkspaceResourceId: logAnalytics.id
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Azure Function for IAM data collection (CAF naming: func-<workload>-<env>-<purpose>)
|
|
105
|
+
resource appServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = {
|
|
106
|
+
name: 'asp-${workloadName}-${environmentName}-iam'
|
|
107
|
+
location: location
|
|
108
|
+
tags: tags
|
|
109
|
+
sku: {
|
|
110
|
+
name: 'Y1' // Consumption plan for cost optimization
|
|
111
|
+
tier: 'Dynamic'
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
resource functionApp 'Microsoft.Web/sites@2023-12-01' = {
|
|
116
|
+
name: 'func-${workloadName}-${environmentName}-iam'
|
|
117
|
+
location: location
|
|
118
|
+
kind: 'functionapp'
|
|
119
|
+
tags: tags
|
|
120
|
+
identity: {
|
|
121
|
+
type: 'SystemAssigned' // WAF Security: Use managed identity
|
|
122
|
+
}
|
|
123
|
+
properties: {
|
|
124
|
+
serverFarmId: appServicePlan.id
|
|
125
|
+
httpsOnly: true // WAF Security: Force HTTPS
|
|
126
|
+
siteConfig: {
|
|
127
|
+
minTlsVersion: '1.2'
|
|
128
|
+
ftpsState: 'Disabled' // WAF Security: Disable FTP
|
|
129
|
+
appSettings: [
|
|
130
|
+
{
|
|
131
|
+
name: 'AzureWebJobsStorage__accountName'
|
|
132
|
+
value: evidenceStorage.name // WAF Security: Managed identity auth
|
|
133
|
+
}
|
|
134
|
+
{
|
|
135
|
+
name: 'FUNCTIONS_EXTENSION_VERSION'
|
|
136
|
+
value: '~4'
|
|
137
|
+
}
|
|
138
|
+
{
|
|
139
|
+
name: 'FUNCTIONS_WORKER_RUNTIME'
|
|
140
|
+
value: 'dotnet-isolated'
|
|
141
|
+
}
|
|
142
|
+
{
|
|
143
|
+
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
|
144
|
+
value: appInsights.properties.ConnectionString
|
|
145
|
+
}
|
|
146
|
+
{
|
|
147
|
+
name: 'LOG_ANALYTICS_WORKSPACE_ID'
|
|
148
|
+
value: logAnalytics.properties.customerId
|
|
149
|
+
}
|
|
150
|
+
{
|
|
151
|
+
name: 'EVIDENCE_STORAGE_ACCOUNT'
|
|
152
|
+
value: evidenceStorage.name // Reference by name for managed identity
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// RBAC: Grant Function App Storage Blob Data Contributor role
|
|
160
|
+
resource storageRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
|
|
161
|
+
name: guid(evidenceStorage.id, functionApp.id, 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')
|
|
162
|
+
scope: evidenceStorage
|
|
163
|
+
properties: {
|
|
164
|
+
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe') // Storage Blob Data Contributor
|
|
165
|
+
principalId: functionApp.identity.principalId
|
|
166
|
+
principalType: 'ServicePrincipal'
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Metric alert for function failures (WAF Reliability)
|
|
171
|
+
resource alertRule 'Microsoft.Insights/metricAlerts@2018-03-01' = {
|
|
172
|
+
name: 'alert-${workloadName}-${environmentName}-iam-failures'
|
|
173
|
+
location: 'global'
|
|
174
|
+
tags: tags
|
|
175
|
+
properties: {
|
|
176
|
+
description: 'Alert when IAM evidence collection fails'
|
|
177
|
+
severity: 2
|
|
178
|
+
enabled: true
|
|
179
|
+
scopes: [
|
|
180
|
+
functionApp.id
|
|
181
|
+
]
|
|
182
|
+
evaluationFrequency: 'PT5M'
|
|
183
|
+
windowSize: 'PT15M'
|
|
184
|
+
criteria: {
|
|
185
|
+
'odata.type': 'Microsoft.Azure.Monitor.SingleResourceMultipleMetricCriteria'
|
|
186
|
+
allOf: [
|
|
187
|
+
{
|
|
188
|
+
name: 'FunctionErrors'
|
|
189
|
+
metricName: 'FunctionExecutionCount'
|
|
190
|
+
dimensions: [
|
|
191
|
+
{
|
|
192
|
+
name: 'Status'
|
|
193
|
+
operator: 'Include'
|
|
194
|
+
values: ['Failed']
|
|
195
|
+
}
|
|
196
|
+
]
|
|
197
|
+
operator: 'GreaterThan'
|
|
198
|
+
threshold: 5
|
|
199
|
+
timeAggregation: 'Total'
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
actions: [] // Configure action group for notifications
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Outputs
|
|
208
|
+
output logAnalyticsWorkspaceId string = logAnalytics.properties.customerId
|
|
209
|
+
output evidenceStorageAccountName string = evidenceStorage.name
|
|
210
|
+
output functionAppName string = functionApp.name
|
|
211
|
+
output functionAppPrincipalId string = functionApp.identity.principalId
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
## Bicep Template
|
|
2
|
+
|
|
3
|
+
```bicep
|
|
4
|
+
// main.bicep - Monitoring, Logging & Analysis Infrastructure
|
|
5
|
+
param location string = resourceGroup().location
|
|
6
|
+
param environmentName string = 'fedramp'
|
|
7
|
+
|
|
8
|
+
// Sentinel Workspace (includes Log Analytics)
|
|
9
|
+
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
|
|
10
|
+
name: 'log-${environmentName}-sentinel'
|
|
11
|
+
location: location
|
|
12
|
+
properties: {
|
|
13
|
+
sku: {
|
|
14
|
+
name: 'PerGB2018'
|
|
15
|
+
}
|
|
16
|
+
retentionInDays: 730
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Enable Microsoft Sentinel
|
|
21
|
+
resource sentinel 'Microsoft.SecurityInsights/onboardingStates@2023-02-01' = {
|
|
22
|
+
name: 'default'
|
|
23
|
+
scope: logAnalytics
|
|
24
|
+
properties: {}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Evidence Storage
|
|
28
|
+
resource evidenceStorage 'Microsoft.Storage/storageAccounts@2023-01-01' = {
|
|
29
|
+
name: 'st${environmentName}mlaevidence'
|
|
30
|
+
location: location
|
|
31
|
+
kind: 'StorageV2'
|
|
32
|
+
sku: {
|
|
33
|
+
name: 'Standard_GRS'
|
|
34
|
+
}
|
|
35
|
+
properties: {
|
|
36
|
+
supportsHttpsTrafficOnly: true
|
|
37
|
+
minimumTlsVersion: 'TLS1_2'
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Data Collection Rules for centralized logging
|
|
42
|
+
resource dataCollectionEndpoint 'Microsoft.Insights/dataCollectionEndpoints@2022-06-01' = {
|
|
43
|
+
name: 'dce-${environmentName}-mla'
|
|
44
|
+
location: location
|
|
45
|
+
properties: {}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
resource dataCollectionRule 'Microsoft.Insights/dataCollectionRules@2022-06-01' = {
|
|
49
|
+
name: 'dcr-${environmentName}-mla'
|
|
50
|
+
location: location
|
|
51
|
+
properties: {
|
|
52
|
+
dataCollectionEndpointId: dataCollectionEndpoint.id
|
|
53
|
+
streamDeclarations: {
|
|
54
|
+
'Custom-SecurityLogs': {
|
|
55
|
+
columns: [
|
|
56
|
+
{name: 'TimeGenerated', type: 'datetime'}
|
|
57
|
+
{name: 'EventType', type: 'string'}
|
|
58
|
+
{name: 'EventData', type: 'dynamic'}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
destinations: {
|
|
63
|
+
logAnalytics: [
|
|
64
|
+
{
|
|
65
|
+
workspaceResourceId: logAnalytics.id
|
|
66
|
+
name: 'centralWorkspace'
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
dataFlows: [
|
|
71
|
+
{
|
|
72
|
+
streams: ['Custom-SecurityLogs']
|
|
73
|
+
destinations: ['centralWorkspace']
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
output workspaceId string = logAnalytics.properties.customerId
|
|
80
|
+
output workspaceKey string = logAnalytics.listKeys().primarySharedKey
|
|
81
|
+
output dataCollectionEndpointUrl string = dataCollectionEndpoint.properties.logsIngestion.endpoint
|
|
82
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
## Bicep Template
|
|
2
|
+
|
|
3
|
+
```bicep
|
|
4
|
+
// main.bicep - Backup & Recovery Evidence Collection
|
|
5
|
+
param location string = resourceGroup().location
|
|
6
|
+
|
|
7
|
+
// Recovery Services Vault
|
|
8
|
+
resource recoveryVault 'Microsoft.RecoveryServices/vaults@2023-04-01' = {
|
|
9
|
+
name: 'rsv-fedramp-backup'
|
|
10
|
+
location: location
|
|
11
|
+
sku: {
|
|
12
|
+
name: 'RS0'
|
|
13
|
+
tier: 'Standard'
|
|
14
|
+
}
|
|
15
|
+
properties: {}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Backup Policy for VMs
|
|
19
|
+
resource backupPolicy 'Microsoft.RecoveryServices/vaults/backupPolicies@2023-04-01' = {
|
|
20
|
+
parent: recoveryVault
|
|
21
|
+
name: 'DailyBackupPolicy'
|
|
22
|
+
properties: {
|
|
23
|
+
backupManagementType: 'AzureIaasVM'
|
|
24
|
+
instantRpRetentionRangeInDays: 5
|
|
25
|
+
schedulePolicy: {
|
|
26
|
+
schedulePolicyType: 'SimpleSchedulePolicy'
|
|
27
|
+
scheduleRunFrequency: 'Daily'
|
|
28
|
+
scheduleRunTimes: ['2023-01-01T02:00:00Z']
|
|
29
|
+
}
|
|
30
|
+
retentionPolicy: {
|
|
31
|
+
retentionPolicyType: 'LongTermRetentionPolicy'
|
|
32
|
+
dailySchedule: {
|
|
33
|
+
retentionTimes: ['2023-01-01T02:00:00Z']
|
|
34
|
+
retentionDuration: {
|
|
35
|
+
count: 30
|
|
36
|
+
durationType: 'Days'
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
output recoveryVaultName string = recoveryVault.name
|
|
44
|
+
```
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
## Bicep Template
|
|
2
|
+
|
|
3
|
+
```bicep
|
|
4
|
+
// main.bicep - Service Management Evidence Collection
|
|
5
|
+
param location string = resourceGroup().location
|
|
6
|
+
|
|
7
|
+
// Key Vault for secret management (KSI-SVC-06)
|
|
8
|
+
resource keyVault 'Microsoft.KeyVault/vaults@2023-02-01' = {
|
|
9
|
+
name: 'kv-fedramp-secrets'
|
|
10
|
+
location: location
|
|
11
|
+
properties: {
|
|
12
|
+
sku: {
|
|
13
|
+
family: 'A'
|
|
14
|
+
name: 'standard'
|
|
15
|
+
}
|
|
16
|
+
tenantId: subscription().tenantId
|
|
17
|
+
enableRbacAuthorization: true
|
|
18
|
+
enableSoftDelete: true
|
|
19
|
+
softDeleteRetentionInDays: 90
|
|
20
|
+
enablePurgeProtection: true
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Diagnostic settings for Key Vault audit logs
|
|
25
|
+
resource keyVaultDiagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
|
|
26
|
+
name: 'kv-diagnostics'
|
|
27
|
+
scope: keyVault
|
|
28
|
+
properties: {
|
|
29
|
+
workspaceId: logAnalytics.id
|
|
30
|
+
logs: [
|
|
31
|
+
{
|
|
32
|
+
category: 'AuditEvent'
|
|
33
|
+
enabled: true
|
|
34
|
+
retentionPolicy: {
|
|
35
|
+
enabled: true
|
|
36
|
+
days: 730
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
|
|
44
|
+
name: 'log-fedramp-keyvault'
|
|
45
|
+
location: location
|
|
46
|
+
properties: {
|
|
47
|
+
sku: { name: 'PerGB2018' }
|
|
48
|
+
retentionInDays: 730
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
output keyVaultName string = keyVault.name
|
|
53
|
+
output workspaceId string = logAnalytics.id
|
|
54
|
+
```
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
## C# Code (.NET 8)
|
|
2
|
+
|
|
3
|
+
```csharp
|
|
4
|
+
using Azure.Identity;
|
|
5
|
+
using Azure.Storage.Blobs;
|
|
6
|
+
using System.Text.Json;
|
|
7
|
+
|
|
8
|
+
public class KSIEvidenceCollector
|
|
9
|
+
{
|
|
10
|
+
private readonly BlobServiceClient _blobClient;
|
|
11
|
+
|
|
12
|
+
public KSIEvidenceCollector()
|
|
13
|
+
{
|
|
14
|
+
var credential = new DefaultAzureCredential();
|
|
15
|
+
var storageAccount = Environment.GetEnvironmentVariable("EVIDENCE_STORAGE_ACCOUNT");
|
|
16
|
+
|
|
17
|
+
_blobClient = new BlobServiceClient(
|
|
18
|
+
new Uri($"https://{storageAccount}.blob.core.windows.net"),
|
|
19
|
+
credential
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public async Task<Evidence> CollectEvidenceAsync(string ksiId)
|
|
24
|
+
{
|
|
25
|
+
var evidence = new Evidence
|
|
26
|
+
{
|
|
27
|
+
CollectionDate = DateTime.UtcNow,
|
|
28
|
+
KsiId = ksiId,
|
|
29
|
+
ComplianceStatus = "compliant",
|
|
30
|
+
EvidenceData = new Dictionary<string, object>
|
|
31
|
+
{
|
|
32
|
+
// Add your evidence data here
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return evidence;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public async Task StoreEvidenceAsync(Evidence evidence)
|
|
40
|
+
{
|
|
41
|
+
var timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd");
|
|
42
|
+
var blobName = $"evidence/{timestamp}.json";
|
|
43
|
+
|
|
44
|
+
var containerClient = _blobClient.GetBlobContainerClient("evidence");
|
|
45
|
+
await containerClient.CreateIfNotExistsAsync();
|
|
46
|
+
|
|
47
|
+
var blobClient = containerClient.GetBlobClient(blobName);
|
|
48
|
+
var json = JsonSerializer.Serialize(evidence, new JsonSerializerOptions
|
|
49
|
+
{
|
|
50
|
+
WriteIndented = true
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
await blobClient.UploadAsync(BinaryData.FromString(json), overwrite: true);
|
|
54
|
+
Console.WriteLine($"✓ Evidence stored: {blobName}");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public class Evidence
|
|
59
|
+
{
|
|
60
|
+
public DateTime CollectionDate { get; set; }
|
|
61
|
+
public string KsiId { get; set; }
|
|
62
|
+
public string ComplianceStatus { get; set; }
|
|
63
|
+
public Dictionary<string, object> EvidenceData { get; set; }
|
|
64
|
+
}
|
|
65
|
+
```
|