Skip to content

Authenticate Relay with Managed Identity token - #103

Merged
carlosmartinez merged 4 commits into
mainfrom
feat/relay-managed-identity
Apr 30, 2026
Merged

Authenticate Relay with Managed Identity token#103
carlosmartinez merged 4 commits into
mainfrom
feat/relay-managed-identity

Conversation

@carlosmartinez

Copy link
Copy Markdown
Contributor

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

  • Check database queries are correctly scoped to current_provider

Replace locally-stored SAS token in websockets URL with with Azure-generated
Managed Identity JWT token in HTTP header.

@steventux steventux left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

@steventux steventux Apr 29, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment thread src/relay_listener.py Outdated
f"&sig={urllib.parse.quote_plus(signature)}"
f"&se={expiry}&skn={self.key_name}"
)
self._credential = DefaultAzureCredential()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

@steventux steventux Apr 29, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.
@carlosmartinez

Copy link
Copy Markdown
Contributor Author

Thanks @steventux, have attempted to address your feedback.

@steventux steventux left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💻 ♻️ 💻

Comment thread src/relay_listener.py Outdated
Comment thread src/relay_listener.py Outdated
@carlosmartinez
carlosmartinez merged commit ff20a06 into main Apr 30, 2026
9 checks passed
@carlosmartinez
carlosmartinez deleted the feat/relay-managed-identity branch April 30, 2026 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants