I have a project where there are thousands of devices running android apps on our LAN. Those apps need to reach out to services. I'd like to authenticate the applications against Azure AD and then validate the tokens on the server side. There will be no user involved we just want to authenticate the device itself.
What are some recommended best practices in this scenario? We can do client credential grants from the android app against the cloud but then we'd need to provide the clientid/secret to the APK and I don't like the idea of storing a secret in the APK because it can be decompiled. I think you can do a Client Credential grant without a secret, but that seems like a pretty loose authentication mechanism.
I read that Azure AD supports certificate based authentication but I think functionally the same problem exists there, whereas we need to install a certificate on the device and if someone gets access to the device they can gain access to the certificate.
What can be done in this scenario?
Note that: Client credential flow by default requires client Id and client secret or certificate.
Otherwise, you can make use of Azure AD Managed Service Identity (MSI) that allows applications running on Azure to authenticate with Azure AD without passing any secrets or certificates if it suits your setup/scenario.
You can assign application permissions to the managed identity by using the PowerShell script:
$serverApplicationName = "AppName"
$serverServicePrincipal = (Get-MgServicePrincipal -Filter "DisplayName eq '$serverApplicationName'")
$serverServicePrincipalObjectId = $serverServicePrincipal.Id
$appRoleName = "test.read"
$appRoleId = ($serverServicePrincipal.AppRoles | Where-Object {$_.Value -eq $appRoleName }).Id
$managedIdentityObjectId = "MIObjectID"
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $serverServicePrincipalObjectId -PrincipalId $managedIdentityObjectId -ResourceId $serverServicePrincipalObjectId -AppRoleId $appRoleId
Permissions are granted to the managed identity: