Adding support for MSI
Problem Statement
Currently /schemas/system API only accepts SPN token. We want this API to accept MSI token as well.
Implementation Details
SPN and MSI both will be authenticated by istio and we are adding a filter - AzureIstioSecurityFilter - that will set the authentication context. Using this context, only SPN and MSI will be authorized for /schemas/system API. User token will be unauthorized.
We are also adding a check in AuthorizationServiceForServicePrincipalImpl to make sure the issuer is AAD.
Testing
Tested locally and verified that for /schemas/system API, request is unauthorized if claim set contains "unique-name" or "upn" claim (this means token type is user). If not, then request is authorized (token type is SPN or MSI).
How local testing was done:
Istio sidecar is used to authenticate any request targeted for a given service. The request contains a jwt token which istio inspects to authenticate the request. This jwt token contains a payload which is a json object consisting of “claims”.
Sample payload object is shown below –
`{
"aud": "c47d7590-b904-4d67-85cc-c5415dc76ed5",
"iss": "https://sts.windows.net/58975fd3-4977-44d0-bea8-37af0baac100/",
"iat": 1629978412,
"nbf": 1629978412,
"exp": 1629982312,
"ver": "1.0",
"unique-name": "vibsharm",
}`
Once istio authenticates the request, it appends a header to the request called x-payload
. The value passed to this header is the base 64 encoded version of the payload object. It is important to note that in production scenario where istio is enabled, only istio can add this x-payload
header to the request. Even if the user adds his own value to x-payload
it will be discarded by istio.
The x-payload
value consisting of the claims is used in a few scenarios in services like partition and schema to authorize a request. By checking the claims, it can be determined whether the jwt token is generated by user or service principal/MSI. Based on this information, the services may choose to authorize a given request.
Since it may be time consuming to configure istio locally, changes related to claims
in jwt token can be tested locally as follows –
-
Generate a jwt token
-
Extract only the payload part of the jwt and paste it in jwt.io to decode it. The decoded value is the json object consisting of claims.
-
Add or remove claims from the json object based on test scenario. For example, for the token to be a user token, it should have a claim for “unique-name” or “upn”. (Note that an actual user cannot tamper with jwt in production scenario because at the time of decryption, tampered jwt will not give expected value and request will be unauthenticated by istio.)
-
Encode the claims json obtained in step 3 using base 64 encoder.
-
In your postman request, add header
x-payload
with value obtained in step 4. Hit your service running locally with this request and verify that response is authorized/unauthorized as expected.