Skip to content

Commit c61ac5e

Browse files
Merge pull request #229841 from dlepow/wksprev
[APIM] Workspaces review updates
2 parents 822649b + b77c7b1 commit c61ac5e

File tree

5 files changed

+29
-17
lines changed

5 files changed

+29
-17
lines changed

articles/api-management/api-management-howto-policies.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ author: dlepow
77

88
ms.service: api-management
99
ms.topic: article
10-
ms.date: 03/23/2022
10+
ms.date: 03/07/2023
1111
ms.author: danlep
1212

1313
---
@@ -83,7 +83,8 @@ Policy expressions provide a sophisticated means to control traffic and modify A
8383
API Management allows you to define policies at the following *scopes*, from most broad to most narrow:
8484

8585
* Global (all APIs)
86-
* Product (APIs associated with a selected product)
86+
* Workspace (all APIs associated with a selected workspace)
87+
* Product (all APIs associated with a selected product)
8788
* API (all operations in an API)
8889
* Operation (single operation in an API)
8990

articles/api-management/api-management-policy-expressions.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ author: dlepow
77

88
ms.service: api-management
99
ms.topic: article
10-
ms.date: 01/13/2023
10+
ms.date: 03/07/2023
1111
ms.author: danlep
1212
---
1313
# API Management policy expressions
@@ -200,12 +200,12 @@ The `context` variable is implicitly available in every policy [expression](api-
200200
|Context Variable|Allowed methods, properties, and parameter values|
201201
|----------------------|-------------------------------------------------------|
202202
|`context`|[`Api`](#ref-context-api): [`IApi`](#ref-iapi)<br /><br /> [`Deployment`](#ref-context-deployment)<br /><br /> Elapsed: `TimeSpan` - time interval between the value of `Timestamp` and current time<br /><br /> [`LastError`](#ref-context-lasterror)<br /><br /> [`Operation`](#ref-context-operation)<br /><br /> [`Product`](#ref-context-product)<br /><br /> [`Request`](#ref-context-request)<br /><br /> `RequestId`: `Guid` - unique request identifier<br /><br /> [`Response`](#ref-context-response)<br /><br /> [`Subscription`](#ref-context-subscription)<br /><br /> `Timestamp`: `DateTime` - point in time when request was received<br /><br /> `Tracing`: `bool` - indicates if tracing is on or off <br /><br /> [User](#ref-context-user)<br /><br /> [`Variables`](#ref-context-variables): `IReadOnlyDictionary<string, object>`<br /><br /> `void Trace(message: string)`|
203-
|<a id="ref-context-api"></a>`context.Api`|`Id`: `string`<br /><br /> `IsCurrentRevision`: `bool`<br /><br /> `Name`: `string`<br /><br /> `Path`: `string`<br /><br /> `Revision`: `string`<br /><br /> `ServiceUrl`: [`IUrl`](#ref-iurl)<br /><br /> `Version`: `string` |
203+
|<a id="ref-context-api"></a>`context.Api`|`Id`: `string`<br /><br /> `IsCurrentRevision`: `bool`<br /><br /> `Name`: `string`<br /><br /> `Path`: `string`<br /><br /> `Revision`: `string`<br /><br /> `ServiceUrl`: [`IUrl`](#ref-iurl)<br /><br /> `Version`: `string` <br /><br /> `Workspace`: [`IWorkspace`](#ref-iworkspace) |
204204
|<a id="ref-context-deployment"></a>`context.Deployment`|[`Gateway`](#ref-context-gateway)<br /><br /> `GatewayId`: `string` (returns 'managed' for managed gateways)<br /><br /> `Region`: `string`<br /><br /> `ServiceId`: `string`<br /><br /> `ServiceName`: `string`<br /><br /> `Certificates`: `IReadOnlyDictionary<string, X509Certificate2>`|
205205
|<a id="ref-context-gateway"></a>`context.Deployment.Gateway`|`Id`: `string` (returns 'managed' for managed gateways)<br /><br /> `InstanceId`: `string` (returns 'managed' for managed gateways)<br /><br /> `IsManaged`: `bool`|
206206
|<a id="ref-context-lasterror"></a>`context.LastError`|`Source`: `string`<br /><br /> `Reason`: `string`<br /><br /> `Message`: `string`<br /><br /> `Scope`: `string`<br /><br /> `Section`: `string`<br /><br /> `Path`: `string`<br /><br /> `PolicyId`: `string`<br /><br /> For more information about `context.LastError`, see [Error handling](api-management-error-handling-policies.md).|
207207
|<a id="ref-context-operation"></a>`context.Operation`|`Id`: `string`<br /><br /> `Method`: `string`<br /><br /> `Name`: `string`<br /><br /> `UrlTemplate`: `string`|
208-
|<a id="ref-context-product"></a>`context.Product`|`Apis`: `IEnumerable<`[`IApi`](#ref-iapi)`>`<br /><br /> `ApprovalRequired`: `bool`<br /><br /> `Groups`: `IEnumerable<`[`IGroup`](#ref-igroup)`>`<br /><br /> `Id`: `string`<br /><br /> `Name`: `string`<br /><br /> `State`: `enum ProductState {NotPublished, Published}`<br /><br /> `SubscriptionLimit`: `int?`<br /><br /> `SubscriptionRequired`: `bool`|
208+
|<a id="ref-context-product"></a>`context.Product`|`Apis`: `IEnumerable<`[`IApi`](#ref-iapi)`>`<br /><br /> `ApprovalRequired`: `bool`<br /><br /> `Groups`: `IEnumerable<`[`IGroup`](#ref-igroup)`>`<br /><br /> `Id`: `string`<br /><br /> `Name`: `string`<br /><br /> `State`: `enum ProductState {NotPublished, Published}`<br /><br /> `SubscriptionLimit`: `int?`<br /><br /> `SubscriptionRequired`: `bool`<br /><br /> `Workspace`: [`IWorkspace`](#ref-iworkspace)|
209209
|<a id="ref-context-request"></a>`context.Request`|`Body`: [`IMessageBody`](#ref-imessagebody) or `null` if request doesn't have a body.<br /><br /> `Certificate`: `System.Security.Cryptography.X509Certificates.X509Certificate2`<br /><br /> [`Headers`](#ref-context-request-headers): `IReadOnlyDictionary<string, string[]>`<br /><br /> `IpAddress`: `string`<br /><br /> `MatchedParameters`: `IReadOnlyDictionary<string, string>`<br /><br /> `Method`: `string`<br /><br /> `OriginalUrl`: [`IUrl`](#ref-iurl)<br /><br /> `Url`: [`IUrl`](#ref-iurl)<br /><br /> `PrivateEndpointConnection`: [`IPrivateEndpointConnection`](#ref-iprivateendpointconnection) or `null` if request doesn't come from a private endpoint connection.|
210210
|<a id="ref-context-request-headers"></a>`string context.Request.Headers.GetValueOrDefault(headerName: string, defaultValue: string)`|`headerName`: `string`<br /><br /> `defaultValue`: `string`<br /><br /> Returns comma-separated request header values or `defaultValue` if the header isn't found.|
211211
|<a id="ref-context-response"></a>`context.Response`|`Body`: [`IMessageBody`](#ref-imessagebody)<br /><br /> [`Headers`](#ref-context-response-headers): `IReadOnlyDictionary<string, string[]>`<br /><br /> `StatusCode`: `int`<br /><br /> `StatusReason`: `string`|
@@ -217,9 +217,10 @@ The `context` variable is implicitly available in every policy [expression](api-
217217
|<a id="ref-imessagebody"></a>`IMessageBody`|`As<T>(bool preserveContent = false): Where T: string, byte[], JObject, JToken, JArray, XNode, XElement, XDocument` <br /><br /> - The `context.Request.Body.As<T>` and `context.Response.Body.As<T>` methods read a request or response message body in specified type `T`. <br/><br/> - Or - <br/><br/>`AsFormUrlEncodedContent(bool preserveContent = false)` <br/></br>- The `context.Request.Body.AsFormUrlEncodedContent()` and `context.Response.Body.AsFormUrlEncodedContent()` methods read URL-encoded form data in a request or response message body and return an `IDictionary<string, IList<string>` object. The decoded object supports `IDictionary` operations and the following expressions: `ToQueryString()`, `JsonConvert.SerializeObject()`, `ToFormUrlEncodedContent().` <br/><br/> By default, the `As<T>` and `AsFormUrlEncodedContent()` methods:<br /><ul><li>Use the original message body stream.</li><li>Render it unavailable after it returns.</li></ul> <br />To avoid that and have the method operate on a copy of the body stream, set the `preserveContent` parameter to `true`, as shown in examples for the [set-body](set-body-policy.md#examples) policy.|
218218
|<a id="ref-iprivateendpointconnection"></a>`IPrivateEndpointConnection`|`Name`: `string`<br /><br /> `GroupId`: `string`<br /><br /> `MemberName`: `string`<br /><br />For more information, see the [REST API](/rest/api/apimanagement/current-ga/private-endpoint-connection/list-private-link-resources).|
219219
|<a id="ref-iurl"></a>`IUrl`|`Host`: `string`<br /><br /> `Path`: `string`<br /><br /> `Port`: `int`<br /><br /> [`Query`](#ref-iurl-query): `IReadOnlyDictionary<string, string[]>`<br /><br /> `QueryString`: `string`<br /><br /> `Scheme`: `string`|
220-
|<a id="ref-iuseridentity"></a>`IUserIdentity`|`Id`: `string`<br /><br /> `Provider`: `string`|
221220
|<a id="ref-isubscriptionkeyparameternames"></a>`ISubscriptionKeyParameterNames`|`Header`: `string`<br /><br /> `Query`: `string`|
222221
|<a id="ref-iurl-query"></a>`string IUrl.Query.GetValueOrDefault(queryParameterName: string, defaultValue: string)`|`queryParameterName`: `string`<br /><br /> `defaultValue`: `string`<br /><br /> Returns comma-separated query parameter values or `defaultValue` if the parameter isn't found.|
222+
|<a id="ref-iuseridentity"></a>`IUserIdentity`|`Id`: `string`<br /><br /> `Provider`: `string`|
223+
|<a id="ref-iworkspace"></a>`IWorkspace`|`Id`: `string`<br /><br /> `Name`: `string`|
223224
|<a id="ref-context-variables"></a>`T context.Variables.GetValueOrDefault<T>(variableName: string, defaultValue: T)`|`variableName`: `string`<br /><br /> `defaultValue`: `T`<br /><br /> Returns variable value cast to type `T` or `defaultValue` if the variable isn't found.<br /><br /> This method throws an exception if the specified type doesn't match the actual type of the returned variable.|
224225
|`BasicAuthCredentials AsBasic(input: this string)`|`input`: `string`<br /><br /> If the input parameter contains a valid HTTP Basic Authentication authorization request header value, the method returns an object of type `BasicAuthCredentials`; otherwise the method returns null.|
225226
|`bool TryParseBasic(input: this string, result: out BasicAuthCredentials)`|`input`: `string`<br /><br /> `result`: `out BasicAuthCredentials`<br /><br /> If the input parameter contains a valid HTTP Basic Authentication authorization value in the request header, the method returns `true` and the result parameter contains a value of type `BasicAuthCredentials`; otherwise the method returns `false`.|

articles/api-management/how-to-create-workspace.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ author: dlepow
55
ms.topic: how-to
66
ms.service: api-management
77
ms.author: danlep
8-
ms.date: 02/22/2023
8+
ms.date: 03/07/2023
99
ms.custom:
1010
---
1111

@@ -36,7 +36,7 @@ The new workspace appears in the list on the **Workspaces** page. Select the wor
3636

3737
## Assign users to workspace - portal
3838

39-
After creating a workspace, assign permissions to users to manage the workspace's resources. Each workspace user must be assigned an RBAC role at the service level and at the workspace level.
39+
After creating a workspace, assign permissions to users to manage the workspace's resources. Each workspace user must be assigned a workspace-specific RBAC role at the service level and at the workspace level, or granted equivalent permissions using custom roles.
4040

4141
At minimum, assign an *administrator* of the workspace. Optionally, assign permissions to other workspace collaborators.
4242

@@ -53,8 +53,9 @@ At minimum, assign an *administrator* of the workspace. Optionally, assign permi
5353
1. Assign the administrator the following role:
5454
* **API Management Service Workspace API Product Manager**
5555

56-
1. Assign the following role to other members of the workspace:
56+
1. Assign one of the following roles to other members of the workspace:
5757
* **API Management Service Workspace Member**
58+
* **API Management Service Workspace API Product Manager**
5859

5960
### Assign a workspace-level role
6061

@@ -65,7 +66,12 @@ At minimum, assign an *administrator* of the workspace. Optionally, assign permi
6566

6667
* **API Management Workspace Owner**
6768

68-
1. Optionally, assign workspace-level roles to other workspace members to manage workspace APIs and other resources. The administrator of the workspace can also assign workspace-level roles.
69+
1. Optionally, assign one of the following workspace-level roles to other workspace members to manage workspace APIs and other resources. The administrator of the workspace can also assign workspace-level roles.
70+
71+
* **API Management Workspace Reader**
72+
* **API Management Workspace Contributor**
73+
* **API Management Workspace API Developer**
74+
* **API Management Workspace API Product Manager**
6975

7076
## Next steps
7177

-10.4 KB
Loading

articles/api-management/workspaces-overview.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
---
22
title: Workspaces in Azure API Management | Microsoft Docs
3-
description: Learn about workspaces in Azure API Management. Workspaces allow decentralized API development teams to manage and productize their own APIs, while a central API platform team maintains the API Management infrastructure.
3+
description: Learn about workspaces (preview) in Azure API Management. Workspaces allow decentralized API development teams to manage and productize their own APIs, while a central API platform team maintains the API Management infrastructure.
44
services: api-management
55
documentationcenter: ''
66
author: dlepow
77

88
ms.service: api-management
99
ms.topic: conceptual
10-
ms.date: 02/22/2023
10+
ms.date: 03/07/2023
1111
ms.author: danlep
1212
ms.custom:
1313
---
@@ -20,6 +20,8 @@ In API Management, *workspaces* allow decentralized API development teams to man
2020

2121
> [!NOTE]
2222
> * Workspaces are a preview feature of API Management and subject to certain [limitations](#preview-limitations).
23+
> * This feature is being released during March and April 2023.
24+
> * Workspaces are supported in API Management REST API version 2022-09-01-preview or later.
2325
> * For pricing considerations, see [API Management pricing](https://azure.microsoft.com/pricing/details/api-management/).
2426
2527

@@ -81,9 +83,9 @@ The following resources can be managed in the workspaces preview.
8183

8284
Azure RBAC is used to configure workspace collaborators' permissions to read and edit entities in the workspace. For a list of roles, see [How to use role-based access control in API Management](api-management-role-based-access-control.md).
8385

84-
Workspace members must be assigned both a service-level role and a workspace-level role. The service-level role enables referencing service-level resources from workspace-level resources. For example, publish an API from a workspace with a service-level product, assign a service-level tag to an API, or organize a user into a workspace-level group to control API and product visibility.
86+
Workspace members must be assigned both a service-level role and a workspace-level role, or granted equivalent permissions using custom roles. The service-level role enables referencing service-level resources from workspace-level resources. For example, publish an API from a workspace with a service-level product, assign a service-level tag to an API, or organize a user into a workspace-level group to control API and product visibility.
8587

86-
## Workspace constraints
88+
## Workspaces and other API Management features
8789

8890
* **Infrastructure features** - API Management platform infrastructure features are managed on the service level only, not at the workspace level. These features include:
8991

@@ -112,10 +114,14 @@ The following resources aren't currently supported in workspaces:
112114

113115
* Client certificates
114116

117+
* Current DevOps tooling for API Management
118+
115119
* Diagnostics
116120

117121
* Loggers
118122

123+
* Synthetic GraphQL APIs
124+
119125
* User-assigned managed identity
120126

121127
Therefore, the following sample scenarios aren't currently supported in workspaces:
@@ -132,6 +138,4 @@ Therefore, the following sample scenarios aren't currently supported in workspac
132138

133139
## Next steps
134140

135-
* [Create a workspace](how-to-create-workspace.md)
136-
137-
* Migrate API Management resources to a workspace
141+
* [Create a workspace](how-to-create-workspace.md)

0 commit comments

Comments
 (0)