Metadata-Version: 2.4
Name: branxas
Version: 0.1.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Rust
Classifier: Typing :: Typed
Classifier: Topic :: Security
License-File: LICENSE-MIT
License-File: LICENSE-APACHE
Summary: Typed Python client for the Branxas secrets server
Keywords: secrets,vault,mtls,branxas
Author-email: Riyad Febrian <riyadfebrian@gmail.com>
License-Expression: MIT OR Apache-2.0
Requires-Python: >=3.11
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# branxas

Typed Python bindings for the **Branxas secrets server**. This package speaks only to a Branxas server; it is not a generic vault client. The implementation is a small PyO3 binding over the public Rust `branxas` crate.

```python
from branxas import Client

with Client.from_env() as client:
    client.wait_unsealed(30.0)
    secret = client.get("apps/billing/token")
    token = secret.reveal()  # Explicitly disclose the value only where it is needed.
    names = client.get_env("apps/billing")
```

```python
from branxas import load_env

loaded_names = load_env("apps/billing")  # Returns names, never values.
```

Asyncio is available as `branxas.aio.Client`; its operations are awaitable:

```python
from branxas.aio import Client

async with Client.from_env() as client:
    await client.wait_unsealed(30.0)
    values = await client.get_env("apps/billing")
```

The client does not expose seal, unseal, passphrase, or administrative operations. It never unseals the server. Install and configure the server separately.

`Client.from_env()` requires `BRANXAS_URL` (HTTPS base URL), `BRANXAS_CA` (trusted CA PEM path), `BRANXAS_CERT` (registered client certificate path), and `BRANXAS_KEY` (client private key path). The constructor accepts PEM bytes or path-like values. TLS 1.3 is used, server names are verified, and only the supplied CA is trusted.

`Secret` never includes its value in repr, str, or formatting. Call `reveal()` or `reveal_bytes()` deliberately. Python strings are immutable and cannot be zeroized; copies may remain in memory until garbage collection. `load_env` stores values in `os.environ`, where child processes and same-user readers of `/proc/<pid>/environ` may see them, just as with python-dotenv. For tighter handling, use `get()` and pass the value explicitly without placing it in the process environment.

The sync and asyncio clients are thread-safe. They share one lazily created Tokio runtime with at most two worker threads; sync calls release the GIL while waiting on I/O. `close()` releases the client's transport handle. Clients inherited across `fork()` are rejected; create a new client in the child process. Wheels target CPython 3.11+ through abi3. Linux wheels target manylinux 2.28 on x86_64 and aarch64. macOS wheel builds must currently be made on macOS; see `PUBLISHING.md`.

## Development

```sh
uv venv
uv pip install --python .venv/bin/python pytest pytest-asyncio mypy pyright ruff
uv run --python .venv/bin/python --with maturin maturin develop
```

