Certificate added via New-AzureADApplicationKeyCredential not appearing in Azure AD discovery endpoint - azure

I'm adding a new certificate to an existing App Registration in Azure AD using the following command:
New-AzureADApplicationKeyCredential -ObjectId $AppObjectId -CustomKeyIdentifier $base64Thumbprint -Type AsymmetricX509Cert -Usage Verify -Value $base64Value -StartDate $cer.GetEffectiveDateString() -EndDate $validTo
This works OK and I can see the cert added in the Portal.
Should this certificate not also be visible via https://login.microsoftonline.com/{tenant}/discovery/keys?appid={Application(client)ID}
I've also tried adding the certificate info via Set-AzureADApplication & directly via the Portal. Each time I can see the certificate under "Certificates and Secrets" as well as in the App Manifest. No matter what I do I can't see the public cert in the JWKS endpoint.
My assumption on this comes from the following:
https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens
"If your app has custom signing keys as a result of using the claims-mapping feature, you must append an appid query parameter containing the app ID to get a jwks_uri pointing to your app's signing key information, which should be used for validation. For example: https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration?appid=6731de76-14a6-49ae-97bc-6eba6914391e contains a jwks_uri of https://login.microsoftonline.com/{tenant}/discovery/keys?appid=6731de76-14a6-49ae-97bc-6eba6914391e."
Any help would be much appreciated.

As far as I understand, the keys you add to the app are only used for authenticating your app to Azure AD.
Thus there is no need to advertise those keys in the public endpoint, as only Azure AD itself needs to use those public keys to verify assertions sent by your app.

Seems like you set the keyusage to Verify. If you want to use it for signing the token you need to set it to Sign and use a symmetric key:
New-AzureADApplicationKeyCredential -ObjectId $AppId -CustomKeyIdentifier "Test" -StartDate "11/7/2016" -Type "Symmetric" -Usage "Sign" -Value "123"

Related

Automatically update Service Principal client secret on expiry?

I have a Service Principal for a Power Platform environment which will be used by a DevOps platform to make deployments to this environment.
The service principal requires me to set a client secret which will be referenced by my Service Connection in DevOps
You must set a client secret expiry date of up to 2 years and after that time, it won't work. So I would need to go into the Azure portal, update the client secret and then into DevOps and update the service connection.
Is there a way I can do this automatically?
You must set a client secret expiry date of up to 2 years and after that time, it won't work.
Actually, no need to do that, in azure portal, the maximum is 2 years, but you could use azure powershell to create a near-permanent secret, e.g. 100 years.
If you want to custom the secret value, use Az module, login with Connect-AzAccount, then use New-AzADAppCredential as below.
$SecureStringPassword = ConvertTo-SecureString -String "password" -AsPlainText -Force
New-AzADAppCredential -ApplicationId <ApplicationId of the App Registration> -CustomKeyIdentifier "test" -Password $SecureStringPassword -EndDate (Get-Date).AddYears(100)
If you want to generate a secret value automatically, use AzureAD module, login with Connect-AzureAD, then use as New-AzureADApplicationPasswordCredential below.
New-AzureADApplicationPasswordCredential -ObjectId <ObjectId of the App Registration> -EndDate (Get-Date).AddYears(100)

Reset the client secret of Azure Service Principal using powershell

Using powershell commands i want to reset the Service Principal client secret.
I followed the below steps from the article https://learn.microsoft.com/en-us/powershell/azure/create-azure-service-principal-azureps?view=azps-5.8.0
but it didnot reset the password
Remove-AzADSpCredential -DisplayName ServicePrincipalName
$newCredential = New-AzADSpCredential -ServicePrincipalName ServicePrincipalName
can you tell what i am doing wrong. I just want to reset the secret and have new one
I executed the above command and then i went to the app registration of that service principal and there i went to certificates & secrets i see it has not createed new secret.
Using bash i am able to reset the password by executing the below command but i want it to be done using powershell command
az ad sp credential reset --name
I went to the app registration of that service principal and there I went to certificates & secrets I see it has not created new secret.
Well, actually the command New-AzADSpCredential did create a new secret for you.
Firstly, you need to know the relationship between App Registration(AD App) and Service principal, see Application and service principal objects in Azure Active Directory.
In short, the service principal is the local representation for the AD App in a specific tenant. When you create the secret for the service principal, it will not appear in the Certificates & secrets blade, you can just get it with Get-AzADSpCredential.
If you want to reset the secret that you can find in the portal, you need to reset the sceret for the AD App(i.e. App Registration) via Remove-AzADAppCredential and New-AzADAppCredential.
You could refer to the sample below, it resets a secret with value ce96a0ed-5ae8-4a5a-9b3c-630da9ea3023, it is valid for one year, you can find it in the portal.
$obj = (Get-AzADApplication -DisplayName joyappv2).ObjectId
Remove-AzADAppCredential -ObjectId $obj -Force
$azurePassword = ConvertTo-SecureString "ce96a0ed-5ae8-4a5a-9b3c-630da9ea3023" -AsPlainText -Force
$date = Get-Date
$newCredential = New-AzADAppCredential -ObjectId $obj -Password $azurePassword -StartDate $date -EndDate $date.AddYears(1)
Note: You could not get the secret value again after creating it, so please store it when creating.

Azure ApiM unable to create jwt token validation policy with RSA certificate

According to documentation in Azure API Management it is possible to create JWT token validation policy using certificate id of RSA certificate previously uploaded to APIM.
I am trying to build such policy as described in the docs, and it is saved without errors, but when I open the policy definition again, key element is always empty, without the certificate-id attribute I set earlier.
https://learn.microsoft.com/en-us/azure/api-management/api-management-access-restriction-policies#token-validation-with-rsa-certificate
I can also reproduce your issue on my side, after configuration and come back, the policy will be like below.
It looks should be a bug in UI, because if you get the policy with PowerShell Get-AzApiManagementPolicy or REST API - Api Policy - Get directly, we can get the value. So I think the policy should be applied, just ignore it and go on.
Powershell:
$ApiMgmtContext = New-AzApiManagementContext -ResourceGroupName "groupname" -ServiceName "joyapim"
Get-AzApiManagementPolicy -Context $ApiMgmtContext -ApiId 'echo-api'
REST API:

Why does getting a certificate from Azure Key Vault require it to be stored as a secret?

Blogs like the following
https://blogs.technet.microsoft.com/neales/2017/06/26/getting-a-private-certificate-from-key-vault/
Seem to retrive the secret? Does it not matter if it's "stored" as a certificate or not?
It depends on what you are planning to do with the certificate. You could update your question with details about the expected workflow you want to support.
But basically a certificate can be stored as a file. You can see more details (C#) to get inspired on how to do that after the certificate is loaded into a variable.
Exporting a Certificate as BASE-64 encoded .cer
Update
Security considerations to take into account. If you see the certificate stored in the azure key vault as a secret and you want to limit the access to it, then you have to consider how your PowerShell scripts will store the needed credentials for authenticate against the KeyVault.
If you plan on running the script unattended / scheduled without user interaction, you will have to store some kind of credentials on the machine that needs to run the script. BetterCredentials is a great PowerShell native module for storing credentials on the local machine.
I would recommend that you create an Azure Service Principal (App Registration / Registered App), that will get only enough permissions to get the certificate from the KeyVault. The created Service Principal details should then be stored locally on the machine and you should load those credentials first and use them for connecting to the KeyVault.
Example code that should be capable of loading a Service Principal details from the BetterCredentials and sign into Azure:
BetterCredentials\Get-Credential -UserName <application ID> -Store
$azureTenantId = <tenant ID>
$Cred = BetterCredentials\Get-Credential -UserName <application ID>
Add-AzureRmAccount -Credential $Cred -TenantId $azureTenantId -ServicePrincipal

Service principal credentials, set custom identifier?

We are linking personal developers certificates to a certain service principal.
When a developer will leave our team, we will remove that credential from the service principal.
This works perfectly, but it's kind of a hassle because the name of the developer is not linked to the credentials.
I have noticed that their is a customIdentifierKey property on the credentials... but I cannot find how to set the customIdentifierKey.
Anyone knows how to do this?
New-AzureRmADAppCredential -ApplicationId $appId -CertValue $keyValue -EndDate $cert.NotAfter -StartDate $cert.NotBefore
You can use the Azure AD v2 cmdlets to set and get custom key identifiers.
Here I am adding a certificate:
New-AzureADApplicationKeyCredential -ObjectId 2648416a-aaaa-4bc0-9190-aaaab6165710 -CustomKeyIdentifier 'Your key name' -StartDate '2017/06/01' -EndDate '2018/06/01' -Type AsymmetricX509Cert -Usage Verify -Value $keyValue
Assuming your $keyValue contains an X509 certificate. If it is a symmetric key, you can use Symmetric as the Type.
The custom key identifier is stored as bytes, encoded in ASCII.
So when you get one, you need to run it through a decode:
$cred = Get-AzureADApplicationKeyCredential -ObjectId 2648416a-aaaa-4bc0-9190-aaaab6165710
[System.Text.Encoding]::ASCII.GetString($cred.CustomKeyIdentifier)
Interestingly, if you set an identifier on a PasswordCredential (client secret) through Azure Portal, it encodes it in Unicode.

Resources