I am sharing a solution as I think this will be useful for others.
After following the instructions at https://docs.snowflake.com/en/user-guide/oauth-azure.html to integrate our Azure AD with Oauth to Snowflake, we got a problem. Snowflake only supports one security integration per AAD tenant.
Since we wanted to use both integration on the client level and on the user level;
create security integration (...)
external_oauth_token_user_mapping_claim = 'sub'
vs
external_oauth_token_user_mapping_claim = 'upn'
To get around this we created two custom policies in AAD:
New-AzureADPolicy -Definition @('
{
"ClaimsMappingPolicy":
{
"Version":1,"IncludeBasicClaimSet":"true",
"ClaimsSchema": [{"Source":"application","ID":"objectid","JwtClaimType":"sfuser"}]
}
}') -DisplayName "SnowflakeUserObjectClaims" -Type "ClaimsMappingPolicy"
and
New-AzureADPolicy -Definition @('
{
"ClaimsMappingPolicy":
{
"Version":1,"IncludeBasicClaimSet":"true",
"ClaimsSchema": [{"Source":"user","ID":"userprincipalname","JwtClaimType":"sfuser"}]
}
}') -DisplayName "SnowflakeUserUpnClaims" -Type "ClaimsMappingPolicy"
These could then be associated with one application registration for the application and another for the user ('Add-AzureADServicePrincipalPolicy'). In other words, the claims from each of these would always include the 'sfuser' claim. This also requires a manual change in the application manifest:
"acceptMappedClaims": true,
We could now create the security integration in Snowflake, with our new claim:
create security integration (...)
external_oauth_token_user_mapping_claim = 'sfuser'
And Snowflake was able to use the new claim to authenticate requests from both our app.registrations.