typeerrorhashicorp-vaultvaulthvac

Vault secret fetch using hvac python fails with TypeError where Type of response is <class 'requests.models.Response'>


I am trying to login to Vault using token auth & fetch the credentials from secret/data/my-secret-path

#Reading secrets from the path secret/data/my-secret-path where secretpath = 'my-secret-path' without secret/data

Using Vault with KV Version 2 secret engine mount

import hvac

vault_address = 'my-vault-address/namespace=my-namespace'
vault_token= 'my-secret-token'
client = hvac.Client(url=vault_address, token=vault_token)
print(client.is_authenticated()) -> Returns true 
secretpath = 'my-secret-path' 
secrets = client.secrets.kv.read_secret(secretpath)
secret_cred = secrets['data']['secret']
print(secret_cred)

Getting the below error because of "secret_cred = secrets['data']['secret']"

TypeError: 'Response' object is not subscriptable

Tried with

secrets = client.secrets.kv.v2.read_secret_version(path=secretpath, mount_point='secret',raise_on_deleted_version=True)
secret_cred = secrets['data']['secret']
print(secret_cred)

Got the same error

TypeError: 'Response' object is not subscriptable

Saw same issue mentioned in https://github.com/hvac/hvac/issues/538

TYPE: type(secret_cred) is <class 'requests.models.Response'>

Have also tried several ways to fetch secret from secret_cred like which was not fruitful,

secret_cred.get("data")
secret_cred.json()
json.loads(secret_cred.content)
json.loads(secret_cred.text)

Any guidance to fetch the secret from the type "requests.models.Response" would be really helpful


Solution

  • It looks like you have Vault Enterprise, and that you are using a namespace called my-namespace.

    To use an enterprise namespace with Vault, pass it using the namespace parameter when you create your hvac client, instead of passing it as the URL:

    import hvac
    
    vault_address = 'http://localhost:8200'
    vault_namespace = "my-namespace"
    vault_token = 'root'
    
    client = hvac.Client(url=vault_address, token=vault_token, namespace=vault_namespace)
    

    Then to retrieve the secret, you must index data twice. The second data index has a sibling metadata index that you might need someday.

    Append this code to the previous:

    secretpath = 'my-secret-path' 
    
    secret_cred = client.secrets.kv.read_secret(secretpath)
    secret_cred_latest = secret_cred['data']['data']['secret']
    print(secret_cred_latest)