Skip to main content

DarkVault Python SDK

PyPI Python CI License: MIT

A synchronous Python client for DarkVault. Read configuration buckets, manage individual secrets, and use optimistic concurrency without implementing JWE yourself.

Install

python -m pip install darkvault-client

Requires Python 3.11+. The package name is darkvault-client; the import is darkvault. The direct runtime dependency is jwcrypto.

Quick start

import os

from darkvault import DarkVaultClient

with DarkVaultClient(
    "https://vault.example.com",
    os.environ["DARKVAULT_TOKEN"],
    timeout=10,
) as vault:
    settings = vault.read_bucket("app_prod")
    database_url = settings["Database:Url"]

The result is a dict[str, str]. Case, Unicode, empty strings, and newlines are preserved. read_bucket_snapshot additionally returns the bucket ID and revision.

Connection and permissions

Use the server's HTTPS origin, for example https://vault.example.com, without an API path, URL credentials, query, or fragment. Tokens are issued in the DarkVault web UI and use the dv1_ format (64 characters total). Supply the token explicitly from a protected source; this SDK does not load CLI configuration.

Bucket arguments are exact names, not UUIDs. Each operation needs its matching token scopes and bucket access. Reading an entire bucket needs bucket:read, secret:read, and secret:list. Bucket creation additionally depends on the token's allowed creation names. Token issuance and revocation are administrative operations, not SDK methods.

Values are strings. Treat returned secrets as sensitive in-memory data; do not log values, Authorization headers, or request bodies. TLS verification must stay enabled. JWE uses ECDH-ES/P-256/A256GCM in addition to HTTPS; the server still sees plaintext secrets, so this is not a zero-knowledge system.

Constructor and lifetime

DarkVaultClient(server, token, *, timeout=30, ssl_context=None)

timeout is a finite number of seconds greater than 0 and at most 30. It covers discovery, retries, and the command together. OS hostname resolution is subject to the platform resolver's behavior.

Reuse a client, preferably with with; alternatively call close() when finished. Calls on one client serialize over a shared HTTPS connection. Use one client per worker for parallel I/O. This SDK is synchronous, not an asyncio client. Invalid constructor settings raise ValueError; a closed client cannot be reused.

Required scopes

Operation Required scopes
List buckets bucket:list
Get bucket metadata bucket:read
Read bucket values bucket:read, secret:read, secret:list
Create bucket bucket:create
Update bucket description bucket:write
Delete empty bucket bucket:delete
Delete bucket recursively bucket:delete, secret:delete
List secret metadata secret:list
Read secret value secret:read
Create, update, or set secret secret:write
Delete secret secret:delete
Inspect own token Any valid token

Scopes do not replace bucket grants.

API reference

Method Result
add_bucket(name, description="") Bucket metadata
get_bucket(bucket) Bucket metadata
list_buckets(*, cursor=None, limit=100) Page
read_bucket(bucket) dict[str, str]
read_bucket_snapshot(bucket) bucketId, revision, secrets
update_bucket(bucket, description, expected_revision) Bucket metadata
delete_bucket(bucket, expected_revision, *, recursive=False) None
add_secret(bucket, key, value) Secret metadata
read_secret(bucket, key) Secret metadata plus value
list_secrets(bucket, *, cursor=None, limit=100) Page of metadata without values
update_secret(bucket, key, value, expected_revision) Secret metadata
set_secret(bucket, key, value, expected_revision=0) Secret metadata
delete_secret(bucket, key, expected_revision) None
get_token_info() Token metadata
execute(operation, parameters) Validated dictionary for a supported data operation; advanced wire API

Names, keys, and descriptions are strings. Secret writes accept string, int/float, bool, or None; ordinary reads expose canonical strings and type metadata. Revisions are integers from 0 through 9007199254740991. List options and recursive are keyword-only.

Metadata is returned as dictionaries with camelCase keys:

  • Bucket: id, name, description, revision, createdAt, updatedAt.
  • Secret metadata: id, bucketId, key, revision, createdAt, updatedAt, type.
  • Page: items, nextCursor.
  • Token: id, name, scopes, bucketIds, allBuckets, creatableBucketNames, expiresAt.

Dates are UTC RFC 3339 strings; expiresAt may be None.

Create, update, and delete

Inside a with DarkVaultClient(...) as vault: block, with an existing bucket:

created = vault.add_secret("app_prod", "Feature:Enabled", "true")

updated = vault.update_secret(
    "app_prod",
    "Feature:Enabled",
    "false",
    expected_revision=created["revision"],
)

vault.delete_secret("app_prod", "Feature:Enabled", updated["revision"])

A stale revision returns revision_conflict. Read current state before deciding whether to retry. set_secret with revision 0 creates only when absent. Deleting a nonempty bucket needs recursive=True; fetch fresh bucket metadata after changing secrets before deleting the bucket.

Pagination

Inside the same client context:

cursor = None

while True:
    page = vault.list_secrets("app_prod", cursor=cursor, limit=100)

    for item in page["items"]:
        # Metadata only.
        print(item["key"])

    cursor = page["nextCursor"]

    if cursor is None:
        break

Limits are 1–200. Treat cursors as opaque and use them for the same listing. The SDK returns one page per call.

Errors and retries

from darkvault import DarkVaultError

try:
    settings = vault.read_bucket("app_prod")
except DarkVaultError as error:
    print(error.code, error.status, error.request_id)

Run this inside the live client context. DarkVaultError carries safe metadata, not credentials or raw payloads. Status is 0 for a local/transport failure. Server errors include unauthorized, forbidden, not_found, already_exists, revision_conflict, and bucket_not_empty.

Reads may retry twice on network failures and plaintext 429/5xx responses. Retry-After is honored within the deadline. An explicit unknown_key response permits one key refresh. Uncertain writes are not retried: on outcome_unknown, read the server state before repeating the mutation.

Private certificates and networking

import ssl

context = ssl.create_default_context()
context.load_verify_locations(cafile="/path/to/company-ca.pem")

with DarkVaultClient(
    "https://vault.example.com",
    token,
    ssl_context=context,
) as vault:
    settings = vault.read_bucket("app_prod")

Here token is the token loaded from your protected source. The CA file contains public trust certificates, not your client token. Disabling certificate or hostname verification is rejected. Redirects and plaintext success responses are rejected. The client connects directly and does not inherit proxy/credential environment settings.

Local installation

From a source checkout: python -m pip install ./clients/python. For consumer applications, use a published PyPI version and pin it through your normal dependency management.

DarkVault and server setup · API schema · Issues · MIT license

Typed configuration

Secret types are string, number, boolean, and null. String reads remain available; typed reads preserve scalar types. See the configuration contract for SDK methods, nested paths, JSON/YAML export, and string fallback rules.

Connection string

Use https://<token>@host[:port]/bucket-name to keep connection settings in one secret variable, for example DARKVAULT_URL. The scheme, token and bucket are required. Bucket names use 1–63 lowercase letters, digits, _ or -, starting with a letter or digit. Additional paths, query strings, fragments and passwords are rejected. Use the literal token and bucket name without percent encoding.

The SDK does not read environment variables automatically. The factory separates the token from the HTTPS origin before making requests. Treat the entire string as a secret. Existing constructors and explicit bucket arguments still work. The default bucket is used for bucket/configuration reads when omitted; other operations can use the exposed default-bucket property explicitly.

with DarkVaultClient.from_url(os.environ["DARKVAULT_URL"]) as vault:
    secrets = vault.read_bucket()
    config = vault.read_configuration()
    secret = vault.read_secret(vault.default_bucket, "ApiKey")

The factory also accepts timeout and ssl_context, with the same TLS checks as the regular constructor.

Load configuration in one call

from darkvault import load_configuration

settings = load_configuration(os.environ["DARKVAULT_URL"])

Returns a typed nested dictionary and always closes the connection, including on failure. Pass nested=False for flat keys; timeout and ssl_context have the same meaning as in the client constructor. This is a synchronous, one-time load; reuse a client when making repeated calls.

Rename a bucket

rename_bucket(bucket, name, expected_revision) renames a bucket with bucket:write and its current revision. Its ID, secrets, description, and token access are preserved. Update the bucket name in application configuration after renaming.

Metadata

Release files for darkvault-client 2.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for darkvault-client 2.1.0
File Size Uploaded Provenance
darkvault_client-2.1.0.tar.gz 17.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for darkvault-client 2.1.0
File Interpreter ABI Platform
darkvault_client-2.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 32.8 kB

Release files / darkvault_client-2.1.0.tar.gz

Download URL darkvault_client-2.1.0.tar.gz
Size 17.7 kB
Tags Source
SHA-256 checksum
How to use checksums
ccb6e9550202520528f9d1f3d4820233f3d9ccf24b5954e29b7a258391cd93d2
BLAKE2b-256 checksum
How to use checksums
2ac1cd3b87f37285e78bbd5971774714dfb9ef1d019638f6c478f22e8d909011
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / darkvault_client-2.1.0-py3-none-any.whl

Download URL darkvault_client-2.1.0-py3-none-any.whl
Size 15.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0a6b412555fdb15eb8b452bd2f149ebbe743f339c05df5353b46610411aa6ec8
BLAKE2b-256 checksum
How to use checksums
3c0d0c35e82b03116b677cd3ae7206d98bd94d9e59fdb1b33a67c6a9f2b19bc8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Security for darkvault-client 2.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for darkvault_client-2.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page