Python Azure sdk: How to retrieve secrets from keyvault?
Asked Answered
B

5

7

I need to retrieve secrets from keyvault. This is my code so far:

from azure.mgmt.keyvault import KeyVaultManagementClient
from azure.common.credentials import ServicePrincipalCredentials


subscription_id = 'x'
# See above for details on creating different types of AAD credentials
credentials = ServicePrincipalCredentials(
    client_id = 'x',
    secret = 'x',
    tenant = 'x'
)

kv_client = KeyVaultManagementClient(credentials, subscription_id)

for vault in kv_client.vaults.list():
    print(vault)

But I am getting this error:

msrestazure.azure_exceptions.CloudError: Azure Error: AuthorizationFailed Message: The client 'x' with object id 'x' does not have authorization to perform action 'Microsoft.Resources/subscriptions/resources/read' over scope '/subscriptions/x'.

Now I am able to access the same keyvault with same credentials using C# code/ POwershell so there is definitely nothing wrong with authorization. Not sure why it isnt working using SDK. Please help.

Basutoland answered 30/8, 2017 at 18:44 Comment(4)
No idea, the Bearer token may have the wrong audience in or something along those lines - try asking in github.com/Azure/azure-sdk-for-python/issues if you're sure the SPN is good for that resource. Try to find a way to turn on tracing, maybe it hints you about what's in the token.Paxon
Your code works for me, I could list secrets in the key vault. If possible, could you give your service principal Owner pernission and try again. Assign application to role.Anthropophagi
Also, you could give Contributer permission, it also works for me. It is very strange, I am not sure why the service principal works on C# and PowerShell. But, I suggest you could check and try give permission.Anthropophagi
What's the specific azure python you're using? I assume you are using the latest one which is 2.0.0rc6Thorfinn
L
6

If you are looking to access via a ServicePrincipalCredentials instance, you can just use:

from azure.keyvault import KeyVaultClient, KeyVaultAuthentication
from azure.common.credentials import ServicePrincipalCredentials

credentials = None

def auth_callback(server, resource, scope):
    credentials = ServicePrincipalCredentials(
        client_id = '',
        secret = '',
        tenant = '',
        resource = "https://vault.azure.net"
    )
    token = credentials.token
    return token['token_type'], token['access_token']

client = KeyVaultClient(KeyVaultAuthentication(auth_callback))

secret_bundle = client.get_secret("https://vault_url", "secret_id", "")

print(secret_bundle.value)

This assumes that you don't want to pass a version. If you do, you can substitute the last parameter for it.

Lamarre answered 7/4, 2018 at 0:5 Comment(1)
I am trying with the same code and getting AdalError: Get Token request returned http error: 404.Frivol
T
4

I run your code sample above and it is able to list the key vaults without any issue, hence it is not a code issue.

I have assigned the Contributor role to my AD application on the subscription where the key vault is provisioned and set the Access Policies to allow GET & LIST permissions for Key and Secret to the AD application.

The versions of my Azure Python packages used running under Python 3.6.2 runtime environment:

  • azure.common (1.1.8)
  • azure.mgmt.keyvault (0.40.0)
  • msrestazure(0.4.13)

I'll recommend you to try on the Python runtime version and Azure Python packages versions which is verified working.

Addendum:

If the above Python runtime environment version as well as Azure Python packages also does not work for you, you should probably consider creating a new issue in the Azure SDK for Python GitHub as it is working with the same credential with Azure .NET SDK as well as PowerShell.

Thorfinn answered 31/8, 2017 at 6:42 Comment(0)
A
2

You can also get secret by the name of the secret instead of ID:

secret_bundle = client.get_secret(<VAULT URL>, "<NAME>", "")

Afroasian answered 2/11, 2018 at 19:10 Comment(0)
V
2

There are some good answers already, but the Azure SDK has since released new packages for working with Key Vault in Python that replace azure-keyvault:

azure-identity is also the package that should be used with these for authentication.

Documentation for working with the secrets library can be found on the azure-sdk-for-python GitHub repository, and here's a sample for retrieving secrets as you were doing:

from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient

credential = DefaultAzureCredential()

secret_client = SecretClient(
    vault_url="https://my-key-vault.vault.azure.net/",
    credential=credential
)
secret = secret_client.get_secret("secret-name")

You can provide the same credentials that you used for ServicePrincipalCredentials by setting environment variables corresponding to the client_id, secret, and tenant:

export AZURE_CLIENT_ID="client_id"
export AZURE_CLIENT_SECRET="secret"
export AZURE_TENANT_ID="tenant"

(I work on the Azure SDK in Python)

Viceroy answered 10/12, 2020 at 22:2 Comment(0)
S
1

One can use the below class from azure.identity i.e ClientSecretCredential, find the below code ex: snippet

from azure.identity import ClientSecretCredential
from azure.keyvault.secrets import SecretClient

TENANT= <TenantId-in-string>
CLIENT_ID = <ClientId-in-string>
CLIENT_SECRET= <ClientSecret-in-string>
credential = ClientSecretCredential(TENANT,CLIENT_ID,CLIENT_SECRET)
VAULT_URL= <AzureVault-url-in-string>
client = SecretClient(vault_url=VAULT_URL, credential=credential)

print(client)
example_secret = client.get_secret(<secret_name_in_string>)
print(example_secret.value)
Supersonics answered 9/11, 2021 at 15:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.