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): Add new tracing API #23800

Merged
Show file tree
Hide file tree
Changes from 9 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
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,154 @@
}
}
}
},
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ApiManagement/service/{serviceName}/gateways/{gatewayId}/invalidateDebugCredentials": {
"post": {
"tags": [
"GatewayInvalidateDebugCredentials"
],
"operationId": "Gateway_InvalidateDebugCredentials",
"description": "Action is invalidating all debug credentials issued for gateway.",
"x-ms-examples": {
"ApiManagementGatewayInvalidateDebugCredentials": {
"$ref": "./examples/ApiManagementGatewayInvalidateDebugCredentials.json"
}
},
"parameters": [
{
"$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/SubscriptionIdParameter"
},
{
"$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ResourceGroupNameParameter"
},
{
"$ref": "./apimanagement.json#/parameters/ServiceNameParameter"
},
{
"$ref": "./apimanagement.json#/parameters/GatewayIdParameter"
},
{
"$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
}
],
"responses": {
"204": {
"description": "All debug credentials for gateway are now invalidated."
},
"default": {
"description": "Error response describing why the operation failed.",
"schema": {
"$ref": "./apimanagement.json#/definitions/ErrorResponse"
}
}
}
}
},
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ApiManagement/service/{serviceName}/gateways/{gatewayId}/listDebugCredentials": {
"post": {
"tags": [
"GatewayListDebugCredentials"
],
"operationId": "Gateway_ListDebugCredentials",
"description": "Create new debug credentials for gateway.",
"x-ms-examples": {
"ApiManagementGatewayListDebugCredentials": {
"$ref": "./examples/ApiManagementGatewayListDebugCredentials.json"
}
},
"parameters": [
{
"$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/SubscriptionIdParameter"
},
{
"$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ResourceGroupNameParameter"
},
{
"$ref": "./apimanagement.json#/parameters/ServiceNameParameter"
},
{
"$ref": "./apimanagement.json#/parameters/GatewayIdParameter"
},
{
"$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
},
{
"name": "parameters",
"in": "body",
"required": true,
"schema": {
"$ref": "./definitions.json#/definitions/GatewayListDebugCredentialsContract"
}
}
],
"responses": {
"200": {
"description": "The response body contains debug credentials to use in gateway.",
"schema": {
"$ref": "./definitions.json#/definitions/GatewayDebugCredentialsContract"
}
},
"default": {
"description": "Error response describing why the operation failed.",
"schema": {
"$ref": "./apimanagement.json#/definitions/ErrorResponse"
}
}
}
}
},
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ApiManagement/service/{serviceName}/gateways/{gatewayId}/listTrace": {
"post": {
"tags": [
"GatewayListTrace"
],
"operationId": "Gateway_ListTrace",
"description": "Fetches trace collected by gateway.",
"x-ms-examples": {
"ApiManagementGatewayListTrace": {
"$ref": "./examples/ApiManagementGatewayListTrace.json"
}
},
"parameters": [
{
"$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/SubscriptionIdParameter"
},
{
"$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ResourceGroupNameParameter"
},
{
"$ref": "./apimanagement.json#/parameters/ServiceNameParameter"
},
{
"$ref": "./apimanagement.json#/parameters/GatewayIdParameter"
},
{
"$ref": "../../../../../common-types/resource-management/v3/types.json#/parameters/ApiVersionParameter"
},
{
"name": "parameters",
"in": "body",
"required": true,
"schema": {
"$ref": "./definitions.json#/definitions/GatewayListTraceContract"
}
}
],
"responses": {
"200": {
"description": "The response body contains trace collected by gateway.",
"schema": {
"$ref": "./definitions.json#/definitions/GatewayTraceContract"
}
},
"default": {
"description": "Error response describing why the operation failed.",
"schema": {
"$ref": "./apimanagement.json#/definitions/ErrorResponse"
}
}
}
}
}
},
"definitions": {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8761,6 +8761,73 @@
"productId"
],
"description": "Tag-product link entity properties."
},
"GatewayListDebugCredentialsContract": {
"type": "object",
"properties": {
"credentialsExpireAfter": {
"type": "string",
"format": "duration",
"description": "After what period of time to make credentials expire."
Mielek marked this conversation as resolved.
Show resolved Hide resolved
},
"purposes": {
"type": "array",
"description": "Purposes of debug credential.",
"items": {
"type": "string",
"description": "Purpose of debug credential.",
"enum": [
"tracing"
],
"x-ms-enum": {
"name": "GatewayListDebugCredentialsContractPurpose",
"modelAsString": true,
"values": [
{
"value": "tracing",
"description": "The tracing purpose."
}
]
}
}
},
"apiId": {
"type": "string",
"description": "Full resource Id of an API."
Mielek marked this conversation as resolved.
Show resolved Hide resolved
}
},
"required": [
"credentialsExpireAfter",
"purposes",
"apiId"
],
"description": "List debug credentials properties."
},
"GatewayDebugCredentialsContract": {
"type": "object",
"properties": {
"token": {
"type": "string",
"description": "Gateway debug token."
}
Mielek marked this conversation as resolved.
Show resolved Hide resolved
},
"description": "Gateway debug credentials."
},
"GatewayListTraceContract": {
"type": "object",
"properties": {
"traceId": {
"type": "string",
"description": "Trace id."
}
},
"description": "List trace properties."
},
"GatewayTraceContract": {
"type": "object",
"properties": {},
"additionalProperties": true,
"description": "Trace collected in gateway."
}
},
"parameters": {}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"parameters": {
"serviceName": "apimService1",
"resourceGroupName": "rg1",
"api-version": "2023-03-01-preview",
"subscriptionId": "subid",
"gatewayId": "gw1"
},
"responses": {
"204": {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"parameters": {
"serviceName": "apimService1",
"resourceGroupName": "rg1",
"api-version": "2023-03-01-preview",
"subscriptionId": "subid",
"gatewayId": "gw1",
"parameters": {
"credentialsExpireAfter": "PT1H",
"apiId": "/subscriptions/subid/resourceGroups/rg1/providers/Microsoft.ApiManagement/service/apimService1/apis/a1",
"purposes": [
"tracing"
]
}
},
"responses": {
"200": {
"body": {
"token": "p=tracing&aid=a1&ex=20230504000000&sn=ZdfxSJoCsOJE0/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/8LchGl7gu/Q=="
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
{
"parameters": {
"serviceName": "apimService1",
"resourceGroupName": "rg1",
"api-version": "2023-03-01-preview",
"subscriptionId": "subid",
"gatewayId": "gw1",
"parameters": {
"traceId": "CrDvXXXXXXXXXXXXXVU3ZA2-1"
}
},
"responses": {
"200": {
"body": {
"serviceName": "apimService1",
"traceId": "1e0447d4-XXXX-XXXX-XXXX-dbdb8098a0d3",
"traceEntries": {
"inbound": [
{
"source": "api-inspector",
"timestamp": "2023-05-03T12:03:04.6899436Z",
"elapsed": "00:00:00.2983315",
"data": {
"request": {
"method": "GET",
"url": "https://proxy.msitesting.net/6452XXXXXXXXXXXX9c2facb1/64524dXXXXXXXXXXXX2facb3?subscription-key=117313e70XXXXXXXXXXXX38ba4658ca3",
"headers": [
{
"name": "Host",
"value": "proxy.msitesting.net"
}
]
}
}
Copy link
Member

@TimLovellSmith TimLovellSmith May 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there is potential to return sensitive data via uris, headers, etc.

Is there anything you would be planning to do to allow people to avoid tracing and then accidentally disclosing, sensitive information in their traces?

Copy link
Contributor Author

@Mielek Mielek May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TimLovellSmith This is a debug functionality. It targets administrators of system to be able to check how request was processed and find if there is any error in that process. To create trace, customer needs to generate debug credentials. The credentials need to be send in the header with request which goes through APIM gateway proxy. This will allow customer to create trace. Because customer needs to specially craft the request, all possible sensitive data, customer should already know.

The functionality was available in APIM before. Now we want to secure it by applying RBAC security.

@VitaliyKurokhtin Can you please expand on the idea if I am missing something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this whole API is actually a step towards more secure tracing functionality. At the moment we're solving problem of separating ability to make request, ability to request trace and ability to view resulting trace via separate API actions to allow for granular RBAC control. The second phase of changes will include stripping knowingly secret information from traces - this is not at all trivial given the flexibility we allow for how this information may be manipulated. The third phase would result in inclusion of heuristic tools that would strip away anything that looks like a secret. Since actual content of the trace is left not specified on purpose phases two and three would be non-breaking for customers.

},
{
"source": "api-inspector",
"timestamp": "2023-05-03T12:03:04.6969650Z",
"elapsed": "00:00:00.3046329",
"data": {
"configuration": {
"api": {
"from": "/6452XXXXXXXXXXXX9c2facb1",
"to": {
"scheme": "http",
"host": "msitesting.net",
"port": 80,
"path": "/",
"queryString": "",
"query": {},
"isDefaultPort": true
},
"version": null,
"revision": "1"
},
"operation": {
"method": "GET",
"uriTemplate": "/64524dXXXXXXXXXXXX2facb3"
},
"user": "-",
"product": "-"
}
}
},
{
"source": "cors",
"timestamp": "2023-05-03T12:03:04.9901631Z",
"elapsed": "00:00:00.5972352",
"data": "Origin header was missing or empty and the request was classified as not cross-domain. CORS policy was not applied."
},
{
"source": "set-status",
"timestamp": "2023-05-03T12:03:05.0031202Z",
"elapsed": "00:00:00.6107970",
"data": {
"message": [
"Response status code was set to 200",
"Response status reason was set to 'OK'"
]
}
},
{
"source": "return-response",
"timestamp": "2023-05-03T12:03:05.0086543Z",
"elapsed": "00:00:00.6164228",
"data": {
"message": "Return response was applied",
"response": {
"status": {
"code": "OK",
"reason": "OK"
},
"headers": []
}
}
}
],
"outbound": [
{
"source": "transfer-response",
"timestamp": "2023-05-03T12:03:05.0438287Z",
"elapsed": "00:00:00.6510195",
"data": {
"message": "Response has been sent to the caller in full"
}
}
]
}
}
}
}
}