diff --git a/src/WinGet.RestSource.Infrastructure/Templates/ApiManagement/apiManagement.json b/src/WinGet.RestSource.Infrastructure/Templates/ApiManagement/apiManagement.json new file mode 100644 index 00000000..993378df --- /dev/null +++ b/src/WinGet.RestSource.Infrastructure/Templates/ApiManagement/apiManagement.json @@ -0,0 +1,233 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "apiManagementServiceName": { + "type": "string", + "defaultValue": "[format('apiservice{0}', uniqueString(resourceGroup().id))]", + "metadata": { + "description": "The name of the API Management service instance" + } + }, + "publisherEmail": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "The email address of the owner of the service" + } + }, + "publisherName": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "The name of the owner of the service" + } + }, + "sku": { + "type": "string", + "defaultValue": "Developer", + "allowedValues": [ + "Consumption", + "Developer", + "Basic", + "Basicv2", + "Standard", + "Standardv2", + "Premium" + ], + "metadata": { + "description": "The pricing tier of this API Management service" + } + }, + "skuCount": { + "type": "int", + "defaultValue": 1, + "allowedValues": [ + 0, + 1, + 2 + ], + "metadata": { + "description": "The instance size of this API Management service." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + }, + "serviceUrl": { + "type": "string", + "metadata": { + "description": "Absolute URL of the backend service implementing this API." + } + }, + "clientId": { + "type": "string", + "metadata": { + "description": "The application client id." + } + }, + "tenantId": { + "type": "string", + "metadata": { + "description": "The allowed tenant id." + } + }, + "frontdoorId": { + "type": "string", + "metadata": { + "description": "The front door instance id." + } + } + }, + "resources": [ + { + "type": "Microsoft.ApiManagement/service", + "apiVersion": "2023-05-01-preview", + "name": "[parameters('apiManagementServiceName')]", + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('sku')]", + "capacity": "[parameters('skuCount')]" + }, + "properties": { + "publisherEmail": "[parameters('publisherEmail')]", + "publisherName": "[parameters('publisherName')]" + } + }, + { + "type": "Microsoft.ApiManagement/service/apis", + "apiVersion": "2023-05-01-preview", + "name": "[concat(parameters('apiManagementServiceName'), '/WinGetRest')]", + "dependsOn": [ + "[resourceId('Microsoft.ApiManagement/service', parameters('apiManagementServiceName'))]" + ], + "properties": { + "displayName": "WinGetRest", + "apiRevision": "1", + "subscriptionRequired": false, + "path": "WinGetRest", + "serviceUrl": "[parameters('serviceUrl')]", + "protocols": [ + "https" + ], + "isCurrent": true + } + }, + { + "type": "Microsoft.ApiManagement/service/apis/operations", + "apiVersion": "2023-05-01-preview", + "name": "[concat(parameters('apiManagementServiceName'), '/WinGetRest/information')]", + "dependsOn": [ + "[resourceId('Microsoft.ApiManagement/service/apis', parameters('apiManagementServiceName'), 'WinGetRest')]", + "[resourceId('Microsoft.ApiManagement/service', parameters('apiManagementServiceName'))]" + ], + "properties": { + "displayName": "Information", + "method": "GET", + "urlTemplate": "/information" + } + }, + { + "type": "Microsoft.ApiManagement/service/apis/operations", + "apiVersion": "2023-05-01-preview", + "name": "[concat(parameters('apiManagementServiceName'), '/WinGetRest/GetPackageManifests')]", + "dependsOn": [ + "[resourceId('Microsoft.ApiManagement/service/apis', parameters('apiManagementServiceName'), 'WinGetRest')]", + "[resourceId('Microsoft.ApiManagement/service', parameters('apiManagementServiceName'))]" + ], + "properties": { + "displayName": "Get Package Manifests", + "method": "GET", + "urlTemplate": "/packageManifests/{PackageIdentifier}", + "templateParameters": [ + { + "name": "PackageIdentifier", + "required": true, + "type": "string" + } + ], + "request": { + "headers": [ + { + "name": "Version", + "type": "string" + }, + { + "name": "Windows-Package-Manager", + "type": "string" + } + ], + "queryParameters": [ + { + "name": "Version", + "type": "string" + }, + { + "name": "Channel", + "type": "string" + } + ] + } + } + }, + { + "type": "Microsoft.ApiManagement/service/apis/operations", + "apiVersion": "2023-05-01-preview", + "name": "[concat(parameters('apiManagementServiceName'), '/WinGetRest/SearchManifests')]", + "dependsOn": [ + "[resourceId('Microsoft.ApiManagement/service/apis', parameters('apiManagementServiceName'), 'WinGetRest')]", + "[resourceId('Microsoft.ApiManagement/service', parameters('apiManagementServiceName'))]" + ], + "properties": { + "displayName": "Search Package Manifests", + "method": "POST", + "urlTemplate": "/manifestSearch", + "request": { + "headers": [ + { + "name": "Version", + "type": "string" + }, + { + "name": "Windows-Package-Manager", + "type": "string" + }, + { + "name": "ContinuationToken", + "type": "string" + } + ] + }, + "responses": [ + { + "statusCode": 200 + }, + { + "statusCode": 204, + "description": "No results were found." + }, + { + "statusCode": 400, + "description": "Request contains something thats perceived as client error." + } + ] + } + }, + { + "type": "Microsoft.ApiManagement/service/apis/policies", + "apiVersion": "2020-06-01-preview", + "name": "[concat(parameters('apiManagementServiceName'), '/WinGetRest/policy')]", + "dependsOn": [ + "[resourceId('Microsoft.ApiManagement/service/apis',parameters('apiManagementServiceName'), 'WinGetRest')]" + ], + "properties": { + "value": "[concat(' ', parameters('clientId'), ' ', parameters('tenantId'), '', parameters('frontdoorId'), '')]", + "format": "xml" + } + } + ] +} \ No newline at end of file diff --git a/src/WinGet.RestSource.Infrastructure/Templates/AzureFunction/azurefunction.json b/src/WinGet.RestSource.Infrastructure/Templates/AzureFunction/azurefunction.json index 27932972..0fd869db 100644 --- a/src/WinGet.RestSource.Infrastructure/Templates/AzureFunction/azurefunction.json +++ b/src/WinGet.RestSource.Infrastructure/Templates/AzureFunction/azurefunction.json @@ -190,6 +190,12 @@ "metadata": { "description": "Monitoring Role" } + }, + "frontDoorId": { + "type": "string", + "metadata": { + "description": "Restricts requests to only allow requests from provided FrontDoor id" + } } }, "variables": { @@ -285,6 +291,38 @@ } ] }, + { + "apiVersion": "2023-12-01", + "name": "AzureFunctionAccessRestrictionRules", + "type": "Microsoft.Web/sites/config", + "dependsOn": [ + "[concat('Microsoft.Web/sites/', parameters('functionName'))]" + ], + "properties": { + "ipSecurityRestrictions": [ + { + "ipAddress": "AzureFrontDoor.Backend", + "action": "Allow", + "tag": "ServiceTag", + "priority": 300, + "name": "FrontDoorAccessPolicy", + "description": "Restricts usage to only access through front door.", + "headers": { + "x-azure-fdid": [ + "[parameters('frontDoorId')]" + ] + } + }, + { + "ipAddress": "Any", + "action": "Deny", + "priority": 2147483647, + "name": "Deny all", + "description": "Deny all access" + } + ] + } + }, { "apiVersion": "2019-05-01", "name": "AzureFunctionKeyVaultAccessPolicy",