- Is there a way to use SecureString or some other in-memory protection with ClientSecretCredential?
No. You could use ClientCertificateCredential instead to utilize a certificate.
But in that case too I believe that an attacker capable of reading your app's memory could also access the private key.
- Are there recommended patterns when Managed Identity is not an option (e.g., cross-tenant scenarios)?
See above for ClientCertificateCredential.
The main advantage of it is that the private key is not sent over the network.
With ClientSecretCredential, the secret is sent over the network every time (encrypted connection but still).
Do you run this application in an untrusted environment?
Like for example a SaaS application deployed to a customer's infrastructure?
In a case like that, you'll have to ensure the credentials that you deploy don't give the customer any more access than what they would have through the app.
If possible, require the user to log in as well. This way the secret alone would not be useful, as a user account would be needed for access.
It is also possible to have a "bootstrapping" process where a user must log in when setting up the app.
Then a refresh token is used periodically to keep the session alive.
This does have the risk of the refresh token no longer working due to various reasons, requiring the user to sign in again (for example OneDrive on Windows might prompt you for authentication after a password change, this is due to the refresh token no longer working).
Also, if the attacker has access to the server, Managed Identity is also compromised in this scenario.
MI is used through an HTTP endpoint accessible from the server.
There is nothing stopping the attacker from making a request to this endpoint from within the server if they gain access.
I'd recommend that you sit down and consider the scenario in which a memory dump attack could happen.
Then think how you can mitigate it/make it harder to pull off.
For example, limit user/network access to the server.
And how could you detect it.
SecureStringrestrictions anyway. Prevent anyone getting access to your memory in the first place, once they are that far it's game over. Putting it another way, if they can access memory they can do whatever you're doing to get the secret.