hvac¶
HashiCorp Vault API client for Python 2.7/3.x
Tested against the latest release, HEAD ref, and 3 previous major versions (counting back from the latest release) of Vault. Currently supports Vault v0.10.4 or later.
Installation¶
pip install hvac
If you would like to be able to return parsed HCL data as a Python dict for methods that support it:
pip install "hvac[parser]"
Getting Started¶
Initialize the Client¶
Using TLS:
>>> client = hvac.Client(url='https://localhost:8200')
>>> client.is_authenticated()
True
Using TLS with client-side certificate authentication:
>>> client = hvac.Client(
... url='https://localhost:8200',
... token=os.environ['VAULT_TOKEN'],
... cert=(client_cert_path, client_key_path),
... verify=server_cert_path,
... )
>>> client.is_authenticated()
True
Using Vault Enterprise namespace:
>>> client = hvac.Client(
... url='https://localhost:8200',
... namespace=os.getenv('VAULT_NAMESPACE'),
... )
Using plaintext / HTTP (not recommended for anything other than development work):
>>> client = hvac.Client(url='http://localhost:8200')
Vault Cluster - Initialize and Seal/Unseal¶
>>> client.sys.is_initialized()
False
>>> shares = 5
>>> threshold = 3
>>> result = client.sys.initialize(shares, threshold)
>>> root_token = result['root_token']
>>> keys = result['keys']
>>> client.sys.is_initialized()
True
>>> client.token = root_token
>>> client.sys.is_sealed()
True
>>> # Unseal a Vault cluster with individual keys
>>> unseal_response1 = client.sys.submit_unseal_key(keys[0])
>>> unseal_response2 = client.sys.submit_unseal_key(keys[1])
>>> unseal_response3 = client.sys.submit_unseal_key(keys[2])
>>> client.sys.is_sealed()
False
>>> # Seal a previously unsealed Vault cluster.
>>> client.sys.seal()
<Response [204]>
>>> client.sys.is_sealed()
True
>>> # Unseal with multiple keys until threshold met
>>> unseal_response = client.sys.submit_unseal_keys(keys)
>>> client.sys.is_sealed()
False
Read and write to secrets engines¶
Note
Vault currently defaults the secret/ path to the KV secrets engine version 2 automatically when the Vault server is started in “dev” mode.
Note
Starting with Vault v1.1.0, _no_ KV secrets engine is mounted by default. I.e., outside of dev mode, a KV engine mounted under path secret/ much be explicitly enabled before use.
KV Secrets Engine - Version 2¶
>>> # Retrieve an authenticated hvac.Client() instance
>>> client = test_utils.create_client()
>>>
>>> # Write a k/v pair under path: secret/foo
>>> create_response = client.secrets.kv.v2.create_or_update_secret(
... path='foo',
... secret=dict(baz='bar'),
... )
>>>
>>> # Read the data written under path: secret/foo
>>> read_response = client.secrets.kv.read_secret_version(path='foo')
>>> print('Value under path "secret/foo" / key "baz": {val}'.format(
... val=read_response['data']['data']['baz'],
... ))
Value under path "secret/foo" / key "baz": bar
>>>
>>> # Delete all metadata/versions for path: secret/foo
>>> client.secrets.kv.delete_metadata_and_all_versions('foo')
<Response [204]>
KV Secrets Engine - Version 1¶
Preferred usage:
>>> client.secrets.kv.default_kv_version = '1'
>>> create_response = client.secrets.kv.create_or_update_secret('foo', secret=dict(baz='bar'))
>>> read_response = client.secrets.kv.read_secret('foo')
>>> print('Value under path "secret/foo" / key "baz": {val}'.format(
... val=read_response['data']['baz'],
... ))
Value under path "secret/foo" / key "baz": bar
>>> delete_response = client.secrets.kv.delete_secret('foo')
Generic usage:
Note
The following read() and write() methods are roughly equivalent to the equivalent Vault CLI commands. These methods do not offer the same level of validation that hvac methods specific to individual auth methods and secrets engines provide.
>>> client.write('secret/foo', baz='bar', lease='1h')
>>> read_response = client.read('secret/foo')
>>> print('Value under path "secret/foo" / key "baz": {val}'.format(
... val=read_response['data']['baz'],
... ))
Value under path "secret/foo" / key "baz": bar
>>> client.delete('secret/foo')
Authentication¶
Basic Token Authentication¶
# Token
>>> client.token = os.environ['VAULT_TOKEN']
>>> client.is_authenticated()
True
LDAP Authentication Example¶
>>> client = hvac.Client(url='https://localhost:8200')
>>> # LDAP, getpass -> user/password, bring in LDAP3 here for teststup?
>>> login_response = client.auth.ldap.login(
... username=os.environ['LDAP_USERNAME'],
... password=os.environ['LDAP_PASSWORD'],
... )
>>> client.is_authenticated()
True
>>> print('The client token returned from the LDAP auth method is: {token}'.format(
... token=login_response['auth']['client_token']
... ))
The client token returned from the LDAP auth method is: ...