-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Area
Infrastructure (Bicep/infra)
Chore Type
Security improvement
Description
The infra/main.bicep file lacks comprehensive parameter validation that could lead to deployment failures or security issues. Missing validation includes:
- IP allowlist format validation for
aiFoundryIpAllowListparameter - Environment name character restrictions and naming conventions
- Principal ID format validation (should be GUID format)
- JSON file reference validation for external dependencies
- Subnet CIDR range validation
- Resource name validation against Azure naming requirements
Justification
Improves security posture by preventing invalid configurations, reduces deployment failures through early validation, enhances user experience with clear error messages, and ensures compliance with Azure naming and security standards.
Acceptance Criteria
- Add regex validation for IP addresses and CIDR ranges in
aiFoundryIpAllowList - Implement environment name character restrictions and length validation
- Add GUID format validation for
principalIdparameter - Create validation for external JSON file references
- Add subnet CIDR range format validation
- Implement Azure resource naming validation patterns
- Update parameter descriptions with validation requirements
- Add comprehensive error messages for validation failures
- Update
infrastructure-deployment-bicep-avm.mdspecification to include parameter validation requirements - Test all validation scenarios with valid and invalid inputs
Resolution Documentation
Step 1: Add IP Address and CIDR Validation
@description('Array of public IPv4 addresses or CIDR ranges for Azure AI Foundry allow-list. Format: ["192.168.1.1", "10.0.0.0/24"]')
param aiFoundryIpAllowList array = []
// Add validation function
func isValidIpOrCidr(ipString string) bool =>
// Regex for IPv4 address
ipString =~ '^((25[0-5]|(2[0-4]|1\\d|[1-9]|)\\d)\\.?\\b){4}$' ||
// Regex for IPv4 CIDR
ipString =~ '^((25[0-5]|(2[0-4]|1\\d|[1-9]|)\\d)\\.?\\b){4}\\/(3[0-2]|[1-2][0-9]|[0-9])$'
// Validate each IP in the array
var validatedIpList = [for ip in aiFoundryIpAllowList: {
value: ip
_validation: isValidIpOrCidr(ip) ? null : error('Invalid IP address or CIDR range: ${ip}')
}]Step 2: Environment Name Validation
@description('Environment name used for resource naming. Must be 1-40 characters, alphanumeric and hyphens only, cannot start/end with hyphen.')
@minLength(1)
@maxLength(40)
@pattern('^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$')
param environmentName stringStep 3: Principal ID GUID Validation
@description('Azure AD Object ID of the user or service principal. Must be a valid GUID format.')
@pattern('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$')
param principalId stringStep 4: Azure Resource Name Validation
@description('Storage account name override. Must be 3-24 characters, lowercase letters and numbers only.')
@minLength(3)
@maxLength(24)
@pattern('^[a-z0-9]+$')
param azureStorageAccountName string = 'default'
// Add validation for generated names
var isValidStorageAccountName = length(storageAccountName) >= 3 && length(storageAccountName) <= 24 &&
storageAccountName =~ '^[a-z0-9]+$'
var storageAccountNameValidation = isValidStorageAccountName ? null :
error('Generated storage account name "${storageAccountName}" is invalid. Must be 3-24 characters, lowercase letters and numbers only.')Step 5: Network Configuration Validation
// Validate subnet CIDR ranges don't overlap and are within address space
func isValidCidr(cidr string) bool =>
cidr =~ '^((25[0-5]|(2[0-4]|1\\d|[1-9]|)\\d)\\.?\\b){4}\\/(3[0-2]|[1-2][0-9]|[0-9])$'
var networkValidation = {
addressSpaceValid: isValidCidr('10.0.0.0/16')
subnetsValid: all([
isValidCidr('10.0.0.0/24'),
isValidCidr('10.0.1.0/24'),
isValidCidr('10.0.2.0/24'),
isValidCidr('10.0.3.0/24'),
isValidCidr('10.0.255.0/27')
])
}Step 6: JSON File Validation
// Add validation that JSON files exist and are properly formatted
var projectsFromJsonValidation = aiFoundryProjectsFromJson ?
(length(loadJsonContent('./sample-ai-foundry-projects.json')) > 0 ? null :
error('sample-ai-foundry-projects.json is empty or invalid')) : null
var openAiModelsValidation = deploySampleOpenAiModels ?
(length(loadJsonContent('./sample-openai-models.json')) > 0 ? null :
error('sample-openai-models.json is empty or invalid')) : nullStep 7: Add Validation Error Messages
// Add descriptive error messages for common validation failures
var validationErrors = [
storageAccountNameValidation
projectsFromJsonValidation
openAiModelsValidation
// Add null checks to filter out successful validations
]
var hasValidationErrors = length(filter(validationErrors, error => error != null)) > 0Side Effects
- Breaking Change: Existing deployments with invalid parameter values will fail validation
- Error Messages: Users will see new validation error messages that may require parameter adjustments
- Performance: Additional validation logic may slightly increase template processing time
- Maintenance: Validation patterns may need updates as Azure requirements change
Priority
High - Important for upcoming release
Additional Context
This addresses security and reliability concerns identified in the infrastructure audit. Proper parameter validation is essential for preventing misconfigurations that could lead to security vulnerabilities or deployment failures. Aligns with Azure Well-Architected Framework security pillar recommendations.