Hello everyone!
Johnson here, and welcome to this quick video on Provide access to Key Vault with an Azure
RBAC
In my previous video, I demonstrated how to access a secret stored in an Azure Key Vault
from an Azure virtual machine, by using managed identity.
In that video, I had an application running on Azure virtual machine, and this application
needs to access an SQL server database running at somewhere, I stored the database connection
string to an Azure Key Vault as an secret,
Then I assigned a managed identity to the virtual machine, and created an access policy
in the key vault to allow my virtual machine's identity to access the secret, and finally
my application running on this virtual machine retrieved the connection string from the key
vault.
And I could use that connection string to access my database.
Now let's take a step forward, imaging that we have another application, which runs on
another Azure virtual machine.
This application also has an SQL server database as its backend database.
Again, we will need to store the database connection string at somewhere.
Given that we have already created a key vault, it makes perfect sense to store this string
as another secret in the same key vault.
And then we can assign a managed identity to the virtual machine and create a new access
policy to allow this identity to access our key vault, just like we did for the first
virtual machine.
The second application could then leverage the virtual machine's managed identity to
retrieve the connection string and use it to access its own backend database.
But this approach has a caveat, the key vault access policies apply to the entire key vault,
and they don’t have the granularity to assign permissions to each secret.
So in this scenario, both of my two applications will not only be able to retrieve its own
secrets, but also have access to all other secrets, and use those secrets to access other
application's backend database.
If this is what you want, then that's great.
But if it is not, how can we solve this problem?
Well, we have two solutions.
The first solution is to create a dedicated key vault for each application.
And store the relevant secrets separately.
We could then create an access policy in each key vault and assign access permissions to
the relevant application.
With this setup, each application will only have access to its own secret.
This solution is not perfect, but it works, the down side is that you will need to manage
more than one key vault.
So can we avoid this unnecessary management overhead?
The answer is yes, and the solution is Azure Role based access control, or RBAC.
This is a feature currently in preview.
This feature allows us to create role assignment not only at the key vault level, but also
at each individual secret level.
In this scenario, both secrets are stored in the same key vault.
virtual machine one will be assigned access to secret one only, and likewise, virtual
machine two will be assigned access to secret two only.
This means that application one and two could only retrieve their own secrets.
OK, that's the theory, now let’s jump to Azure portal to see how it works.
Here from the Azure portal, if I go to the new key vault I have already created.
And go to the access policies page under the settings section, here you can see that the
permission model for this vault is configured to "azure role-based access control", which
is still in preview at this stage.
If you want to use the access policy permission model, you can select this option and save,
but you cannot use both of them for the same key vault.
In this vault, I have two secrets, if I drill down to the first secret secret4VM01 and select
the current version, here you can see the secret vault is "this is the secret for VM01".
And similarly, if I go back to the key vault and select the second secret secret4VM02,
and you can see the secret vault is "This is the secret for VM02".
Now I also have created two Azure virtual machines VM01 and VM02 with system assigned
managed identity.
You can see that VM02 has managed identity assigned as well.
To assign permissions with RABC, let's jump back to the key vault, and select Access control
(IAM), at here you can add role assignment to the virtual machines at the key vault level,
just like how you add role assignment to a normal Azure user.
But this is not we want today, so I will go to secrets, select secret4VM01, and under
here I am goanna select Access control (IAM), and add role assignment from here.
The virtual machine will only need to read this secret, so I will choose "Key Vault Secrets
User" for the role,
Under assign access to, we can assign this role to a user, a group or a service principal,
and we can also assign it to a system assigned managed identity.
At the bottom of this list, we can see virtual machine, which is what we want to assign to.
From the virtual machines list, I am goanna select VM01 and save.
Now let's go back to the second secret, secret4VM02, and do the same role assignment, but this
time, we assign the "Key Vault Secret User" role to VM02.
OK, so now we have both virtual machines assigned to their own secrets.
At this point, the application running inside VM01 should be able to retrieve the first
secret in our key vault, but not the second secret.
To verify this, I have connected to both virtual
machines via SSH, and have installed PowerShell Core and Azure PowerShell module, so I can
run powershell by typing pwsh, and from the powershell prompt, I can run the Azure powershell
command-lets.
To access the secret stored in our Azure key vault, firstly we will need to acquire the
system assigned identity by connecting to Azure with managed identity.
Connect-AzAccount -Identity
Here I used -identity as the parameter for the command Connect-AzAccount, this parameter
tells the command to connect to Azure using the identity assigned to this vm, instead
of asking for a credential.
As you can see here that I logged in to Azure with this MSI account, which is the short
name for Managed Service Identity, and I did not provide any credentials or passwords at
all.
Now we should be able to get the connection string from the key vault.
Let’s use the Azure PowerShell command get-AzKeyVaultSecret to fetch the first secret object and store
it to a variable.
$secret = Get-AzKeyVaultSecret -VaultName kv04-MSI -Name Secret4VM01
The secretvaule property of this object is an encrypted secure string, so we use the
PowerShell command ConvertFrom-SecureString to convert it to a plain text string.
And here we go, we have successfully retrieved the first secret stored in the key vault from
this virtual machine VM01.
But if we try to retrieve the second secret, it failed and the operation returned a "Forbidden"
status code.
So this is VM01, let's verify this on VM02 as well.
First run pwsh to get PowerShell and from the PowerShell prompt, we use Connect-AzAccount
with identity to acquire the managed identity.
Then Let’s use the Azure PowerShell command get-AzKeyVaultSecret to fetch the second secret
object and store it to a variable.
Again the secret vault is encrypted, and let's decrypt it with PowerShell command CovertFrom-SecureString
As you can see that we have successfully retrieved the second secret stored in the key vault
from this virtual machine VM02.
Similarly, if we try to retrieve the first secret from VM02, it failed and the operation
returned a "Forbidden" status code.
Alright, Thank you for your watching, if this video is useful, please give it a like, subscribe,
comment and share.
That's it, until next time, take care!