SFI - Secure PaaS Resources for Storage Accounts

Abhay Punjabi 20 Reputation points Microsoft Employee

We use managed SFCs, and during deployment, resource groups with the prefix SFC_guid are created with Azure Storage Accounts, Load Balancers, and other resources.

We've received SFI alters to enable Network Security Perimeters for the Storage Accounts. However, these accounts are created by Service Fabric during our deployment, so there is no way to explicitly tie these Storage Accounts to NSPs.

How do you recommend we fix this issue?

For reference, this is one of the storage accounts flagged - Secure PaaS Resources, we have a number of such accounts.

0 comments No comments

Sign in to comment

Answer accepted by question author

Ankit Yadav 14,455 Reputation points Microsoft External Staff Moderator

Hello @Abhay Punjabi

I've to address all your concerns listed out in small question and answer format below, kindly go through them one by one.

Why are these storage accounts being flagged?
Storage accounts under SFC_*GUID* resource groups are automatically created by Service Fabric Managed Clusters for diagnostics and operations. Because they’re created dynamically, they don’t always inherit network restrictions by default, which triggers security alerts.

How can we secure them if we didn’t create them?
You can apply network controls after creation:

  • Allow access only from the VNETs/subnets used by your Service Fabric cluster
    or
  • Use Network Security Perimeters (NSPs) to manage access with service-tag-based rules.

Do we need to allow anything else? Yes. The storage accounts must still allow required access for diagnostics, logging, and operational recovery scenarios used by the cluster.

Can we use NSPs instead of VNET rules?
Yes. NSPs are supported and are a good alternative. You can start in Learning mode to avoid alerts, then move to Enforced mode after validating in non-production.

What should we test first? Before applying changes in production, confirm:

  • No cluster warnings related to diagnostics
  • Logs remain accessible
  • Normal cluster operations continue

What about Service Fabric Managed Clusters (SFMC)? For SFMC, you can associate the storage account directly with your NSP. Once configured, the linkage happens automatically.

  1. Abhay Punjabi 20 Reputation points Microsoft Employee

    Hey Ankit Yadav, we have a number of SFCs deployed across multiple subscriptions in multiple regions and multiple clouds, is there any other way to enable NSPs during creation? We would have to manually go to each SFC and enable an NSP, is there any solution involving an ARM template or a configuration that would mitigate this?

  2. Ankit Yadav 14,455 Reputation points Microsoft External Staff Moderator

    Yes, you can use below ARM template to create NSP:-

    {
     "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
     "contentVersion": "1.0.0.0",
     "parameters": {
     "networkSecurityPerimeterName": {
     "type": "string",
     "metadata": {
     "description": "The name of the NSP."
     }
     },
     "profileName": {
     "type": "string",
     "defaultValue": "defaultProfile",
     "metadata": {
     "description": "The name of the NSP Profile."
     }
     },
     "nspLocation": {
     "type": "string",
     "defaultValue": "[resourceGroup().location]",
     "metadata": {
     "description": "The location in which the NSP resource will be deployed."
     }
     }
     },
     "variables": {},
     "resources": [
     {
     "type": "Microsoft.Network/networkSecurityPerimeters",
     "apiVersion": "2023-08-01-preview",
     "name": "[parameters('networkSecurityPerimeterName')]",
     "location": "[parameters('nspLocation')]",
     "properties": {}
     },
     {
     "type": "Microsoft.Network/networkSecurityPerimeters/profiles",
     "apiVersion": "2023-08-01-preview",
     "name": "[format('{0}/{1}', parameters('networkSecurityPerimeterName'), parameters('profileName'))]",
     "location": "[parameters('nspLocation')]",
     "dependsOn": [
     "[resourceId('Microsoft.Network/networkSecurityPerimeters', parameters('networkSecurityPerimeterName'))]"
     ],
     "properties": {}
     }
     ]
    }
    
    

    and the parameters for it are as follows:-

    {
     "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
     "contentVersion": "1.0.0.0",
     "parameters": {
     "networkSecurityPerimeterName": {
     "value": ""
     },
     "profileName": {
     "value": ""
     },
     "nspLocation": {
     "value": ""
     }
     }
    }
    
    

    Once created, you can use something like below to associate NSP with your resources:-

    {
     "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
     "contentVersion": "1.0.0.0",
     "parameters": {
     "networkSecurityPerimeterName": {
     "type": "string",
     "metadata": {
     "description": "The name of the NSP."
     }
     },
     "profileName": {
     "type": "string",
     "defaultValue": "defaultProfile",
     "metadata": {
     "description": "The name of the NSP Profile."
     }
     },
     "passResourceId": {
     "type": "string",
     "metadata": {
     "description": "The resource id of the resource to associate."
     }
     },
     "resourceAssociationName": {
     "type": "string",
     "defaultValue": "[concat('association-', substring(parameters('passResourceId'), add(lastIndexOf(parameters('passResourceId'), '/'), 1)))]",
     "metadata": {
     "description": "The name of the association corresponding to resource."
     }
     },
     "associationMode": {
     "type": "string",
     "defaultValue": "Learning",
     "metadata": {
     "description": "The association mode."
     }
     }
     },
     "variables": {},
     "resources": [
     {
     "type": "Microsoft.Network/networkSecurityPerimeters/resourceAssociations",
     "apiVersion": "2023-08-01-preview",
     "name": "[concat(parameters('networkSecurityPerimeterName'), '/', parameters('resourceAssociationName'))]",
     "properties": {
     "privateLinkResource": {
     "id": "[parameters('passResourceId')]"
     },
     "profile": {
     "id": "[resourceId('Microsoft.Network/networkSecurityPerimeters/profiles', parameters('networkSecurityPerimeterName'), parameters('profileName'))]"
     },
     "accessMode": "[parameters('associationMode')]"
     }
     }
     ]
    }
    
    

    Parameters for this template can be made using below:

    {
     "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
     "contentVersion": "1.0.0.0",
     "parameters": {
     "networkSecurityPerimeterName": {
     "value": ""
     },
     "profileName": {
     "value": ""
     },
     "passResourceId": {
     "value": ""
     },
     "resourceAssociationName": {
     "value": ""
     },
     "associationMode": {
     "value": ""
     }
     }
    }
    
    
    

    In a resource like the NSP (e.g., Microsoft.Network/networkSecurityPerimeters), set the tags property conditionally. Merge with existing tags if needed:

    "tags": {
     "Environment": "[parameters('environment')]",
     "[if(parameters('createTag'), json('{\"tag1\": \"value1\",\"tag2\":\"value2\"}'), json('{}'))]": {}
    }
    

Sign in to comment

0 additional answers

Sign in to answer

Your answer