Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: APIM - Removed workaround for secrets #4427

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
389 changes: 262 additions & 127 deletions avm/res/api-management/service/README.md

Large diffs are not rendered by default.

38 changes: 34 additions & 4 deletions avm/res/api-management/service/authorization-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ This module deploys an API Management Service Authorization Server.
| [`clientAuthenticationMethod`](#parameter-clientauthenticationmethod) | array | Method of authentication supported by the token endpoint of this authorization server. Possible values are Basic and/or Body. When Body is specified, client credentials and other parameters are passed within the request body in the application/x-www-form-urlencoded format. - Basic or Body. |
| [`clientRegistrationEndpoint`](#parameter-clientregistrationendpoint) | string | Optional reference to a page where client or app registration for this authorization server is performed. Contains absolute URL to entity being referenced. |
| [`defaultScope`](#parameter-defaultscope) | string | Access token scope that is going to be requested by default. Can be overridden at the API level. Should be provided in the form of a string containing space-delimited values. |
| [`resourceOwnerPassword`](#parameter-resourceownerpassword) | string | Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner password. |
| [`resourceOwnerPassword`](#parameter-resourceownerpassword) | securestring | Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner password. |
| [`resourceOwnerUsername`](#parameter-resourceownerusername) | string | Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner username. |
| [`serverDescription`](#parameter-serverdescription) | string | Description of the authorization server. Can contain HTML formatting tags. |
| [`supportState`](#parameter-supportstate) | bool | If true, authorization server will include state parameter from the authorization request to its response. Client may use state parameter to raise protocol security. |
| [`tokenBodyParameters`](#parameter-tokenbodyparameters) | array | Additional parameters required by the token endpoint of this authorization server represented as an array of JSON objects with name and value string properties, i.e. {"name" : "name value", "value": "a value"}. - TokenBodyParameterContract object. |
| [`tokenBodyParameters`](#parameter-tokenbodyparameters) | array | Additional parameters required by the token endpoint of this authorization server represented as an array of JSON objects with name and value string properties. |
| [`tokenEndpoint`](#parameter-tokenendpoint) | string | OAuth token endpoint. Contains absolute URI to entity being referenced. |

### Parameter: `authorizationEndpoint`
Expand Down Expand Up @@ -83,6 +83,15 @@ Form of an authorization grant, which the client uses to request the access toke

- Required: Yes
- Type: array
- Allowed:
```Bicep
[
'authorizationCode'
'clientCredentials'
'implicit'
'resourceOwnerPassword'
]
```

### Parameter: `name`

Expand Down Expand Up @@ -158,7 +167,7 @@ Access token scope that is going to be requested by default. Can be overridden a
Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner password.

- Required: No
- Type: string
- Type: securestring
- Default: `''`

### Parameter: `resourceOwnerUsername`
Expand Down Expand Up @@ -187,12 +196,33 @@ If true, authorization server will include state parameter from the authorizatio

### Parameter: `tokenBodyParameters`

Additional parameters required by the token endpoint of this authorization server represented as an array of JSON objects with name and value string properties, i.e. {"name" : "name value", "value": "a value"}. - TokenBodyParameterContract object.
Additional parameters required by the token endpoint of this authorization server represented as an array of JSON objects with name and value string properties.

- Required: No
- Type: array
- Default: `[]`

**Required parameters**

| Parameter | Type | Description |
| :-- | :-- | :-- |
| [`name`](#parameter-tokenbodyparametersname) | string | Body parameter name. |
| [`value`](#parameter-tokenbodyparametersvalue) | string | Body parameter value. |

### Parameter: `tokenBodyParameters.name`

Body parameter name.

- Required: Yes
- Type: string

### Parameter: `tokenBodyParameters.value`

Body parameter value.

- Required: Yes
- Type: string

### Parameter: `tokenEndpoint`

OAuth token endpoint. Contains absolute URI to entity being referenced.
Expand Down
28 changes: 24 additions & 4 deletions avm/res/api-management/service/authorization-server/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ param defaultScope string = ''
param serverDescription string = ''

@description('Required. Form of an authorization grant, which the client uses to request the access token. - authorizationCode, implicit, resourceOwnerPassword, clientCredentials.')
param grantTypes array
@allowed([
'authorizationCode'
'clientCredentials'
'implicit'
'resourceOwnerPassword'
])
param grantTypes string[]

@secure()
@description('Optional. Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner password.')
#disable-next-line secure-secrets-in-params // Not a secret
param resourceOwnerPassword string = ''

@description('Optional. Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner username.')
Expand All @@ -59,8 +65,8 @@ param resourceOwnerUsername string = ''
@description('Optional. If true, authorization server will include state parameter from the authorization request to its response. Client may use state parameter to raise protocol security.')
param supportState bool = false

@description('Optional. Additional parameters required by the token endpoint of this authorization server represented as an array of JSON objects with name and value string properties, i.e. {"name" : "name value", "value": "a value"}. - TokenBodyParameterContract object.')
param tokenBodyParameters array = []
@description('Optional. Additional parameters required by the token endpoint of this authorization server represented as an array of JSON objects with name and value string properties.')
param tokenBodyParameters tokenBodyParameterType[] = []

@description('Optional. OAuth token endpoint. Contains absolute URI to entity being referenced.')
param tokenEndpoint string = ''
Expand Down Expand Up @@ -105,3 +111,17 @@ output resourceId string = authorizationServer.id

@description('The resource group the API management service authorization server was deployed into.')
output resourceGroupName string = resourceGroup().name

// =============== //
// Definitions //
// =============== //

@export()
@description('The type for a token body parameter.')
type tokenBodyParameterType = {
@description('Required. Body parameter name.')
name: string

@description('Required. Body parameter value.')
value: string
}
56 changes: 49 additions & 7 deletions avm/res/api-management/service/authorization-server/main.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.33.93.31351",
"templateHash": "6804762094873651550"
"version": "0.33.13.18514",
"templateHash": "12052045734240221562"
},
"name": "API Management Service Authorization Servers",
"description": "This module deploys an API Management Service Authorization Server."
},
"definitions": {
"tokenBodyParameterType": {
"type": "object",
"properties": {
"name": {
"type": "string",
"metadata": {
"description": "Required. Body parameter name."
}
},
"value": {
"type": "string",
"metadata": {
"description": "Required. Body parameter value."
}
}
},
"metadata": {
"__bicep_export!": true,
"description": "The type for a token body parameter."
}
}
},
"parameters": {
"name": {
"type": "string",
Expand Down Expand Up @@ -98,12 +122,21 @@
},
"grantTypes": {
"type": "array",
"items": {
"type": "string"
},
"allowedValues": [
"authorizationCode",
"clientCredentials",
"implicit",
"resourceOwnerPassword"
],
"metadata": {
"description": "Required. Form of an authorization grant, which the client uses to request the access token. - authorizationCode, implicit, resourceOwnerPassword, clientCredentials."
}
},
"resourceOwnerPassword": {
"type": "string",
"type": "securestring",
"defaultValue": "",
"metadata": {
"description": "Optional. Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner password."
Expand All @@ -125,9 +158,12 @@
},
"tokenBodyParameters": {
"type": "array",
"items": {
"$ref": "#/definitions/tokenBodyParameterType"
},
"defaultValue": [],
"metadata": {
"description": "Optional. Additional parameters required by the token endpoint of this authorization server represented as an array of JSON objects with name and value string properties, i.e. {\"name\" : \"name value\", \"value\": \"a value\"}. - TokenBodyParameterContract object."
"description": "Optional. Additional parameters required by the token endpoint of this authorization server represented as an array of JSON objects with name and value string properties."
}
},
"tokenEndpoint": {
Expand All @@ -144,8 +180,14 @@
],
"setAuthorizationMethods": "[union(parameters('authorizationMethods'), variables('defaultAuthorizationMethods'))]"
},
"resources": [
{
"resources": {
"service": {
"existing": true,
"type": "Microsoft.ApiManagement/service",
"apiVersion": "2023-05-01-preview",
"name": "[parameters('apiManagementServiceName')]"
},
"authorizationServer": {
"type": "Microsoft.ApiManagement/service/authorizationServers",
"apiVersion": "2022-08-01",
"name": "[format('{0}/{1}', parameters('apiManagementServiceName'), parameters('name'))]",
Expand All @@ -168,7 +210,7 @@
"clientSecret": "[parameters('clientSecret')]"
}
}
],
},
"outputs": {
"name": {
"type": "string",
Expand Down
4 changes: 2 additions & 2 deletions avm/res/api-management/service/backend/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.33.93.31351",
"templateHash": "4453336321720967633"
"version": "0.33.13.18514",
"templateHash": "13471923779604074887"
},
"name": "API Management Service Backends",
"description": "This module deploys an API Management Service Backend."
Expand Down
4 changes: 2 additions & 2 deletions avm/res/api-management/service/cache/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.33.93.31351",
"templateHash": "18419808380672694533"
"version": "0.33.13.18514",
"templateHash": "3359248846501864533"
},
"name": "API Management Service Caches",
"description": "This module deploys an API Management Service Cache."
Expand Down
4 changes: 2 additions & 2 deletions avm/res/api-management/service/identity-provider/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.33.93.31351",
"templateHash": "13263983509172438133"
"version": "0.33.13.18514",
"templateHash": "9439755619586446330"
},
"name": "API Management Service Identity Providers",
"description": "This module deploys an API Management Service Identity Provider."
Expand Down
4 changes: 2 additions & 2 deletions avm/res/api-management/service/logger/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.33.93.31351",
"templateHash": "9800847829037569395"
"version": "0.33.13.18514",
"templateHash": "13044725911661445483"
},
"name": "API Management Service Loggers",
"description": "This module deploys an API Management Service Logger."
Expand Down
71 changes: 66 additions & 5 deletions avm/res/api-management/service/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ param apis array = []
param apiVersionSets array = []

@description('Optional. Authorization servers.')
@secure()
param authorizationServers object = {}
param authorizationServers authorizationServerType[]?

@description('Optional. Backends.')
param backends array = []
Expand Down Expand Up @@ -150,8 +149,6 @@ param publicIpAddressResourceId string?
@description('Optional. Enable the Developer Portal. The developer portal is not supported on the Consumption SKU.')
param enableDeveloperPortal bool = false

var authorizationServerList = !empty(authorizationServers) ? authorizationServers.secureList : []

var formattedUserAssignedIdentities = reduce(
map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }),
{},
Expand Down Expand Up @@ -312,7 +309,7 @@ module service_apiVersionSets 'api-version-set/main.bicep' = [
]

module service_authorizationServers 'authorization-server/main.bicep' = [
for (authorizationServer, index) in authorizationServerList: {
for (authorizationServer, index) in (authorizationServers ?? []): {
name: '${uniqueString(deployment().name, location)}-Apim-AuthorizationServer-${index}'
params: {
apiManagementServiceName: service.name
Expand Down Expand Up @@ -580,3 +577,67 @@ output systemAssignedMIPrincipalId string? = service.?identity.?principalId

@description('The location the resource was deployed into.')
output location string = service.location

// =============== //
// Definitions //
// =============== //
import { tokenBodyParameterType } from 'authorization-server/main.bicep'

@export()
@description('The type for an authorization server.')
type authorizationServerType = {
@description('Required. Identifier of the authorization server.')
name: string

@description('Required. API Management Service Authorization Servers name. Must be 1 to 50 characters long.')
@maxLength(50)
displayName: string

@description('Required. OAuth authorization endpoint. See <http://tools.ietf.org/html/rfc6749#section-3.2>.')
authorizationEndpoint: string

@description('Optional. HTTP verbs supported by the authorization endpoint. GET must be always present. POST is optional. - HEAD, OPTIONS, TRACE, GET, POST, PUT, PATCH, DELETE.')
authorizationMethods: string[]?

@description('Optional. Specifies the mechanism by which access token is passed to the API. - authorizationHeader or query.')
bearerTokenSendingMethods: string[]?

@description('Optional. Method of authentication supported by the token endpoint of this authorization server. Possible values are Basic and/or Body. When Body is specified, client credentials and other parameters are passed within the request body in the application/x-www-form-urlencoded format. - Basic or Body.')
clientAuthenticationMethod: string[]?

@description('Required. Client or app ID registered with this authorization server.')
@secure()
clientId: string

@description('Optional. Optional reference to a page where client or app registration for this authorization server is performed. Contains absolute URL to entity being referenced.')
clientRegistrationEndpoint: string?

@description('Required. Client or app secret registered with this authorization server. This property will not be filled on \'GET\' operations! Use \'/listSecrets\' POST request to get the value.')
@secure()
clientSecret: string

@description('Optional. Access token scope that is going to be requested by default. Can be overridden at the API level. Should be provided in the form of a string containing space-delimited values.')
defaultScope: string?

@description('Optional. Description of the authorization server. Can contain HTML formatting tags.')
serverDescription: string?

@description('Required. Form of an authorization grant, which the client uses to request the access token. - authorizationCode, implicit, resourceOwnerPassword, clientCredentials.')
grantTypes: ('authorizationCode' | 'clientCredentials' | 'implicit' | 'resourceOwnerPassword')[]

@description('Optional. Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner password.')
@secure()
resourceOwnerPassword: string?

@description('Optional. Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner username.')
resourceOwnerUsername: string?

@description('Optional. If true, authorization server will include state parameter from the authorization request to its response. Client may use state parameter to raise protocol security.')
supportState: bool?

@description('Optional. Additional parameters required by the token endpoint of this authorization server represented as an array of JSON objects with name and value string properties, i.e. {"name" : "name value", "value": "a value"}. - TokenBodyParameterContract object.')
tokenBodyParameters: tokenBodyParameterType[]?

@description('Optional. OAuth token endpoint. Contains absolute URI to entity being referenced.')
tokenEndpoint: string?
}
Loading