Authenticate Relay with Managed Identity token - #103
Conversation
Replace locally-stored SAS token in websockets URL with with Azure-generated Managed Identity JWT token in HTTP header.
There was a problem hiding this comment.
I'm a bit confused by the Azure docs which seem to say Prefer ManagedIdentityCredential over DefaultAzureCredential in production
If I understand correctly this PR also means we cannot use a relay connection without MI?
Setting up a relay connection from the Gateway to Manage locally is already complex. My worry is that mandatory MI security introduces another piece of complexity.
[Edit]
Wondering if we can make the presence of env vars (and perhaps environment detection) continue to generate a SAS token for the relay URI and the absence of them attempt to use MI? We'd preserve the simpler local development setup but still be able to enforce Managed Identity for things like end-to-end and smoke tests and production.
|
|
||
| The gateway's managed identity must be assigned the **Azure Relay Listener** role on the hybrid connection resource in Azure. | ||
|
|
||
| `DefaultAzureCredential` is used (rather than `ManagedIdentityCredential` directly) so that the credential chain works in all environments: managed identity in Azure deployments, and Azure CLI credentials on developer machines. |
There was a problem hiding this comment.
https://learn.microsoft.com/en-us/dotnet/azure/sdk/authentication/best-practices?tabs=aspdotnet#use-deterministic-credentials-in-production-environments
https://learn.microsoft.com/en-us/azure/developer/python/sdk/authentication/credential-chains?tabs=dac#usage-guidance-for-defaultazurecredential
Perhaps we can look at whether we should have production specific usage of ManagedIdentityCredential
| f"&sig={urllib.parse.quote_plus(signature)}" | ||
| f"&se={expiry}&skn={self.key_name}" | ||
| ) | ||
| self._credential = DefaultAzureCredential() |
There was a problem hiding this comment.
As mentioned I don't think this the production best practice according to Azure docs.
|
|
||
| ### Negative Consequences | ||
|
|
||
| - **Azure infrastructure dependency:** The managed identity and its role assignment must exist before the service can start; there is no fallback |
There was a problem hiding this comment.
I worry that this is now the norm for local development. The dependency on az login or any other cloud authenticated session is suboptimal given the complexity of running a full end-to-end stack. We can avoid MI when running Manage locally, I wonder if there is a way we can do the same with non-production relay connections.
In non-production environments, use a SAS token if set in the environment, otherwise default to DefaultAzureCredential.
|
Thanks @steventux, have attempted to address your feedback. |
Replace locally-stored SAS token in websockets URL with with Azure-generated Managed Identity JWT token in HTTP header.
Jira link
https://nhsd-jira.digital.nhs.uk/browse/DTOSS-12810
Review checklist