{"id":876,"library":"hvac","title":"HVAC: HashiCorp Vault API Client","description":"HVAC is a Python client library for interacting with HashiCorp Vault. It provides a programmatic interface to manage secrets, policies, and authentication methods within a Vault instance. Currently at version 2.4.0, the library maintains an active development status with regular minor releases addressing new Vault features, bug fixes, and dependency updates, alongside occasional major releases for significant breaking changes.","status":"active","version":"2.4.0","language":"python","source_language":"en","source_url":"https://github.com/hvac/hvac","tags":["vault","hashicorp","secrets management","api client","devops"],"install":[{"cmd":"pip install hvac","lang":"bash","label":"Base installation"},{"cmd":"pip install \"hvac[parser]\"","lang":"bash","label":"With HCL parser support"}],"dependencies":[{"reason":"Required for execution","package":"Python","optional":false,"version_spec":">=3.8, <4.0"}],"imports":[{"note":"The primary interaction with Vault is through an instance of the hvac.Client class.","symbol":"Client","correct":"import hvac\nclient = hvac.Client(...)"}],"quickstart":{"code":"import os\nimport hvac\n\n# Configure these environment variables or replace with direct values\nVAULT_ADDR = os.environ.get('VAULT_ADDR', 'http://127.0.0.1:8200')\nVAULT_TOKEN = os.environ.get('VAULT_TOKEN', 'root-token-for-dev')\n\ntry:\n    client = hvac.Client(url=VAULT_ADDR, token=VAULT_TOKEN)\n\n    if not client.is_authenticated():\n        raise Exception(\"HVAC client not authenticated. Check VAULT_ADDR and VAULT_TOKEN.\")\n\n    print(\"Client authenticated successfully.\")\n\n    # Example: Write a secret to KV v2 engine\n    mount_point = 'secret'\n    path = 'my-app/config'\n    secret_data = {'api_key': 'super-secret-key-123', 'environment': 'dev'}\n\n    print(f\"\\nWriting secret to {mount_point}/{path}...\")\n    client.secrets.kv.v2.create_or_update_secret(\n        mount_point=mount_point,\n        path=path,\n        secret=secret_data,\n    )\n    print(\"Secret written.\")\n\n    # Example: Read the secret from KV v2 engine\n    print(f\"\\nReading secret from {mount_point}/{path}...\")\n    read_response = client.secrets.kv.v2.read_secret_version(\n        mount_point=mount_point,\n        path=path\n    )\n\n    retrieved_data = read_response['data']['data']\n    print(f\"Retrieved secret: {retrieved_data}\")\n\n    # Example: Delete the secret\n    print(f\"\\nDeleting secret {mount_point}/{path}...\")\n    client.secrets.kv.v2.delete_metadata_and_all_versions(\n        mount_point=mount_point,\n        path=path\n    )\n    print(\"Secret deleted.\")\n\nexcept Exception as e:\n    print(f\"An error occurred: {e}\")\n","lang":"python","description":"This quickstart demonstrates how to initialize the `hvac.Client`, authenticate using a token (read from an environment variable), and perform basic CRUD operations (create, read, delete) on a KV v2 secret engine. Ensure a Vault server is running and accessible at `VAULT_ADDR` with a valid `VAULT_TOKEN` for authentication. The KV v2 secret engine should be enabled at the `secret` mount point."},"warnings":[{"fix":"Upgrade Python to 3.8+ and ensure Vault server is 1.11.x or later. Review changelog for specific method removals.","message":"hvac v2.0.0 dropped support for Python 3.6 and 3.7. It also removed support for Vault versions 1.6.x through 1.10.x and previously deprecated methods and code paths. [cite: 2.0.0 release notes]","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Explicitly specify all parameters for `Client.write_data` to ensure desired behavior, rather than relying on implicit defaults.","message":"The `Client.write_data` method's default behavior changed in `v2.1.0` related to a bug fix for a 'potentially dangerous default.' This could alter behavior for users relying on previous default parameters. [cite: 2.1.0 release notes]","severity":"breaking","affected_versions":">=2.1.0"},{"fix":"Pass certificate data as a string directly, rather than a file path, to `create_ca_certificate_role`.","message":"The `certificate` parameter for `create_ca_certificate_role` will no longer accept file paths in `v3.0.0`. [cite: v1.1.0 release notes]","severity":"deprecated","affected_versions":"v1.1.0 - <3.0.0"},{"fix":"Explicitly set `raise_on_deleted_version=True` or `False` when calling `read_secret_version` to ensure consistent behavior regardless of the upcoming default change.","message":"The default value of `raise_on_deleted_version` is planned to change from `True` to `False` in a future major release, impacting how deleted secret versions are handled during reads. [cite: v1.1.0 release notes]","severity":"deprecated","affected_versions":"v1.1.0 - <future_major_release>"},{"fix":"Always use `client.secrets.kv.v2.list_secrets(mount_point='your_mount', path='your/path/')` for listing secrets and paths in KV v2 engines.","message":"For KV v2 secret engines, the generic `client.list()` method does not work as expected for listing paths/folders. You must use `client.secrets.kv.v2.list_secrets()`.","severity":"gotcha","affected_versions":"All versions with KV v2 support"},{"fix":"Ensure the KV secrets engine is explicitly enabled and configured at your desired mount point in production Vault environments before attempting to interact with it via `hvac`.","message":"Vault currently defaults the `secret/` path to KV secrets engine version 2 in 'dev' mode. Outside of 'dev' mode (from Vault v1.1.0 onwards), no KV secrets engine is mounted by default at `secret/` and must be explicitly enabled.","severity":"gotcha","affected_versions":"Vault >=1.1.0"},{"fix":"Update exception handling to catch `VaultPermissionDenied` and `VaultPreconditionFailed` for more specific error management if desired.","message":"New exception types (`hvac.exceptions.VaultPermissionDenied` for 405 and `hvac.exceptions.VaultPreconditionFailed` for 412) were added in v2.2.0. If you were catching generic exceptions for these HTTP status codes, your error handling might need updates. [cite: v2.2.0 release notes, 18]","severity":"gotcha","affected_versions":">=2.2.0"},{"fix":"Ensure the Vault server is running and accessible from the hvac client's environment, and that the client's VAULT_ADDR environment variable or Client initialization parameters correctly specify the Vault server's address and port.","message":"The hvac client failed to establish a connection to the Vault server. This typically occurs if the Vault server is not running, is inaccessible, or is listening on a different address/port than configured in the hvac client (default: http://127.0.0.1:8200).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure your Vault server is running and accessible from where the `hvac` client is executed. Verify the `VAULT_ADDR` environment variable or the `url` parameter in `hvac.Client()` is correctly configured to point to your Vault instance.","message":"The `hvac` client requires a running Vault server to connect. A `Connection refused` error (e.g., `NewConnectionError` or `Max retries exceeded`) indicates the client could not establish a connection to the configured Vault address (default: `http://127.0.0.1:8200`). This is typically an environment setup issue.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T20:41:47.934Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"fix":"Provide the path to the CA certificate bundle using the `verify` parameter, or set `verify=False` for testing (not recommended for production). Example: `client = hvac.Client(url='https://vault.example.com:8200', verify='/path/to/ca_certs.pem')` or `client = hvac.Client(url='https://vault.example.com:8200', verify=False)`","cause":"The Python client cannot verify the authenticity of the Vault server's TLS certificate, often because a self-signed certificate is used or the necessary CA certificate bundle is not provided.","error":"requests.exceptions.SSLError: HTTPSConnectionPool(...) (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (...)')))"},{"fix":"Ensure the Vault token has a policy attached that grants the required capabilities (e.g., `read`, `list`, `create`, `update`, `delete`) on the target path, and if using Vault Enterprise, explicitly pass the `namespace` parameter to the `hvac.Client` constructor or relevant method.","cause":"The authenticated Vault token does not have the necessary permissions (policies) to perform the requested operation on the specified path in Vault, or a Vault Enterprise namespace is not correctly specified.","error":"hvac.exceptions.Forbidden: 1 error occurred: * permission denied"},{"fix":"Explicitly provide the `mount_point` parameter when using `client.secrets.kv.v2.read_secret` or `client.secrets.kv.v1.read_secret`, and ensure the `path` argument is relative to the mount point and includes `/data/` for KV v2 secrets.","cause":"This error often occurs when interacting with a KV secrets engine (especially KV v2) without correctly specifying the `mount_point` or if the path structure (e.g., missing `/data/` for KV v2) is incorrect for the Vault API.","error":"hvac.exceptions.InvalidPath: no handler for route \"secret/kv1/mega_secret\". route entry not found., on get http://localhost:8200"},{"fix":"Install the `hvac` package using pip: `pip install hvac`. If using a virtual environment, activate it first.","cause":"The `hvac` library is not installed in the Python environment where the script is being executed, or the virtual environment is not correctly activated.","error":"ImportError: No module named 'hvac'"},{"fix":"Inspect the `requests.Response` object (e.g., `response.status_code`, `response.text`) to understand the underlying HTTP error before attempting to access dictionary keys. If using Vault Enterprise, verify the `namespace` parameter is correctly passed to the `hvac.Client` constructor.","cause":"The `hvac` client method returned a raw `requests.Response` object instead of a parsed dictionary, typically when an API call fails (e.g., due to an incorrect path or permissions) or when the response structure is not as expected. It can also indicate an issue with namespace handling in Vault Enterprise.","error":"TypeError: 'Response' object is not subscriptable"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":null,"quickstart_tag":null,"pypi_latest":"2.4.0","cli_name":"","cli_version":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","installed_version":"2.4.0","pypi_latest":"2.4.0","is_stale":false,"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.63,"mem_mb":11.8,"disk_size":"23.2M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"parser","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.65,"mem_mb":11.7,"disk_size":"23.1M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"hvac","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.63,"mem_mb":11.5,"disk_size":"22.8M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"hvac","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.67,"mem_mb":11.4,"disk_size":"22.8M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.7,"import_time_s":0.45,"mem_mb":11.8,"disk_size":"24M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"parser","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.48,"mem_mb":11.7,"disk_size":"24M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"hvac","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.2,"import_time_s":0.45,"mem_mb":11.5,"disk_size":"23M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"hvac","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.49,"mem_mb":11.4,"disk_size":"23M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.78,"mem_mb":13.3,"disk_size":"25.4M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"parser","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.88,"mem_mb":13.3,"disk_size":"25.4M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"hvac","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.78,"mem_mb":12.9,"disk_size":"25.0M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"hvac","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.88,"mem_mb":12.8,"disk_size":"25.0M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.2,"import_time_s":0.69,"mem_mb":13.3,"disk_size":"26M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"parser","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.68,"mem_mb":13.3,"disk_size":"26M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"hvac","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.3,"import_time_s":0.69,"mem_mb":12.9,"disk_size":"26M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"hvac","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.67,"mem_mb":12.8,"disk_size":"25M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.73,"mem_mb":13,"disk_size":"17.2M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"parser","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.77,"mem_mb":13,"disk_size":"17.2M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"hvac","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.7,"mem_mb":12.6,"disk_size":"16.8M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"hvac","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.81,"mem_mb":12.6,"disk_size":"16.8M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2,"import_time_s":0.71,"mem_mb":13.1,"disk_size":"18M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"parser","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.77,"mem_mb":13,"disk_size":"18M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"hvac","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2,"import_time_s":0.72,"mem_mb":12.6,"disk_size":"17M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"hvac","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.73,"mem_mb":12.6,"disk_size":"17M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.69,"mem_mb":13.4,"disk_size":"16.9M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"parser","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.75,"mem_mb":13.3,"disk_size":"16.8M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"hvac","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.67,"mem_mb":12.9,"disk_size":"16.5M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"hvac","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.78,"mem_mb":12.9,"disk_size":"16.4M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.1,"import_time_s":0.69,"mem_mb":13.4,"disk_size":"17M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"parser","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.75,"mem_mb":13.3,"disk_size":"17M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"hvac","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2,"import_time_s":0.68,"mem_mb":12.9,"disk_size":"17M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"hvac","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.75,"mem_mb":12.9,"disk_size":"17M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.6,"mem_mb":11.5,"disk_size":"22.4M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"parser","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.61,"mem_mb":11.6,"disk_size":"22.5M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"hvac","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.62,"mem_mb":11.2,"disk_size":"22.1M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"hvac","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.61,"mem_mb":11.3,"disk_size":"22.1M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.7,"import_time_s":0.55,"mem_mb":11.5,"disk_size":"23M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"parser","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.52,"mem_mb":11.6,"disk_size":"23M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"hvac","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.5,"import_time_s":0.55,"mem_mb":11.2,"disk_size":"23M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"hvac","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.54,"mem_mb":11.3,"disk_size":"23M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":null,"tag_description":null,"results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}