Metadata-Version: 2.4
Name: wauth
Version: 0.5.0
Summary: Machine-locked encrypted secret management library with Fernet encryption
Project-URL: Homepage, https://github.com/wisrovi/wauth
Project-URL: Documentation, https://wauth.readthedocs.io/en/latest/
Project-URL: Repository, https://github.com/wisrovi/wauth
Project-URL: Issues, https://github.com/wisrovi/wauth/issues
Project-URL: Changelog, https://github.com/wisrovi/wauth/blob/main/CHANGELOG.md
Author-email: William Steve Rodriguez Villamizar <wisrovi.rodriguez@gmail.com>
License: MIT License
        
        Copyright (c) 2025 William Rodriguez
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: cryptography,encryption,fernet,secret,secrets,security,vault
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: cryptography>=41.0.0
Requires-Dist: loguru>=0.7.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: wsqlite>=0.1.0
Provides-Extra: dev
Requires-Dist: black>=23.0.0; extra == 'dev'
Requires-Dist: mypy>=1.7.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
Requires-Dist: pytest>=7.4.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: furo>=1.1.0; extra == 'docs'
Requires-Dist: myst-parser>=2.0.0; extra == 'docs'
Requires-Dist: sphinx-copybutton>=0.5.0; extra == 'docs'
Requires-Dist: sphinx-design>=0.5.0; extra == 'docs'
Requires-Dist: sphinx-rtd-theme>=2.0.0; extra == 'docs'
Requires-Dist: sphinx-sitemap>=2.5.0; extra == 'docs'
Requires-Dist: sphinx>=7.2.0; extra == 'docs'
Description-Content-Type: text/markdown





# WAuth — Machine-Locked Encrypted Secret Management

[![PyPI version](https://img.shields.io/pypi/v/wauth.svg)](https://pypi.org/project/wauth/)
[![Python 3.9+](https://img.shields.io/pypi/pyversions/wauth.svg)](https://pypi.org/project/wauth/)
[![Pylint Score](https://img.shields.io/badge/pylint-9.95%2F10-brightgreen.svg)](#)
[![Test Coverage](https://img.shields.io/badge/coverage-98%25-brightgreen.svg)](#)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![LTS](https://img.shields.io/badge/LTS-0.5.0-blue.svg)](VERSIONING.md)

> **Store, rotate, back up, retrieve, and verify secrets encrypted with Fernet (AES-256), backed by SQLite — tied to the machine they were created on.**

<img width="1024" height="572" alt="IMG-20260507-WA0007" src="https://github.com/user-attachments/assets/967081db-4ec7-4adb-ab8c-c5737e06aadb" />




---

## Key Features

- **Fernet Encryption** — AES-128-CBC via the `cryptography` library, with a 32-byte machine-derived key (SHA-256 of salted machine ID).
- **SQLite-Backed Persistence** — Secrets stored in a local SQLite database via `wsqlite`, with automatic directory creation.
- **Docker Secret Support** — Read Docker Swarm/Compose secrets from `/run/secrets` when running inside containers.
- **Dual Driver Architecture** — Factory pattern automatically selects between local encrypted vault and Docker secrets based on runtime environment.
- **File & Text Support** — Store both plaintext secrets and encrypted files (`.pem`, `.key`, certificates).
- **Key Rotation** — Rotate encryption keys with automatic re-encryption of all secrets via `rotate_key()`.
- **TTL Support** — Set time-to-live on secrets for automatic expiration.
- **Backup & Restore** — Export and import encrypted vault snapshots.
- **Async Support** — `async_set()`, `async_get()`, `async_delete()`, `async_backup()`, `async_restore()` for async workflows.
- **Secret Verification** — `valid()` and `async_valid()` for secure secret checking without exposing the actual value.
- **Custom Exceptions** — Structured exception hierarchy (`DecryptionError`, `KeyNotFoundError`, `VaultError`, etc.).
- **Structured Logging** — Full `loguru` integration for diagnostics.
- **Configuration File** — TOML-based configuration support.
- **Pydantic Validation** — All secret models validated with Pydantic v2 for type safety.
- **Code Quality** — Pylint score ≥ 9.5 across all modules, 98% test coverage, Google Style Docstrings, full type hints.
- **Security Audited** — Bandit scan with 0 medium/high findings. [See SECURITY.md](SECURITY.md)

## Technical Stack

| Layer | Technology |
|-------|-----------|
| **Language** | Python 3.9+ |
| **Encryption** | Fernet (AES-128-CBC) via `cryptography` |
| **Storage** | SQLite via `wsqlite` (ORM-backed by Pydantic) |
| **Testing** | pytest, pytest-cov |
| **Linting** | Pylint, Ruff, Black, MyPy |
| **Logging** | loguru |
| **Documentation** | Sphinx (furo theme), reStructuredText |
| **CI/CD** | GitHub Actions (lint, test, security, publish) |

## Installation & Setup

### From PyPI

```bash
pip install wauth
```

### From Source

```bash
git clone https://github.com/wisrovi/wauth.git
cd wauth
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,docs]"
```

### Dependencies

```
Runtime:
  cryptography    — Fernet encryption
  wsqlite         — SQLite ORM with Pydantic integration
  pydantic        — Data validation and serialization
  loguru          — Structured logging

Development:
  pytest          — Testing framework
  pytest-cov      — Coverage reporting
  black           — Code formatting
  ruff            — Fast linter
  mypy            — Static type checking

Documentation:
  sphinx          — Documentation generator
  furo            — Modern Sphinx theme
  sphinx-copybutton  — Copy code blocks
  myst-parser     — Markdown support
```

## Architecture & Workflow

### Directory Structure

```
wauth/
├── __init__.py          # WAuth class, functional API, async methods
├── core.py              # CryptoEngine — Fernet encryption/decryption
├── vault.py             # SecretModel (Pydantic) + Vault (SQLite + TTL)
├── utils.py             # Machine ID detection & key derivation
├── exceptions.py        # Custom exception hierarchy
├── deprecation.py       # @deprecated decorator & warn_deprecated()
├── drivers/
│   ├── __init__.py      # DriverFactory — auto-selects local or Docker
│   ├── local.py         # LocalDriver — encrypted local + rotation
│   └── docker.py        # DockerDriver — reads /run/secrets
├── test/
│   ├── conftest.py              # Shared fixtures
│   ├── test_core.py             # CryptoEngine (13 tests)
│   ├── test_vault.py            # Vault & SecretModel (24 tests)
│   ├── test_utils.py            # Utility functions (10 tests)
│   ├── test_drivers.py          # Driver tests (17 tests)
│   ├── test_wauth.py            # WAuth & API (30 tests)
│   ├── test_exceptions.py       # Exception hierarchy (10 tests)
│   └── test_deprecation.py      # Deprecation utilities (7 tests)
├── benchmarks/
│   └── performance.py   # Performance benchmark suite
├── examples/
│   └── 00 base/
│       └── example.py   # Basic usage example
├── docs/                # Sphinx documentation
├── README.md            # This file
├── SECURITY.md          # Security policy & threat model
├── VERSIONING.md        # SemVer & LTS policy
├── MIGRATION.md         # Migration guides between versions
├── PYLINT_REPORT.md     # Static analysis quality report
└── pyproject.toml       # Build configuration, dependencies
```

### System Workflow

```
Application --> WAuth.set(key, value, ttl) --> CryptoEngine (Fernet AES) --> Vault (SQLite)
Application --> WAuth.get(key)            --> Vault --> CryptoEngine --> Decrypt
Docker Container: DriverFactory checks /run/secrets, falls back to LocalDriver
```

### Encryption Flow

```
App:set("API_KEY", "secret") 
  --> WAuth 
    --> CryptoEngine.encrypt() 
      --> Derive key (machine_id or custom_key) 
        --> Fernet.encrypt() 
          --> Vault.save() 
            --> SQLite
```

### File Structure

```
wauth/
├── __init__.py          # WAuth class
├── core.py              # CryptoEngine (Fernet)
├── vault.py             # SecretModel + Vault
├── utils.py             # Machine ID detection
├── exceptions.py        # Exception hierarchy
├── drivers/
│   ├── __init__.py     # DriverFactory
│   ├── local.py         # LocalDriver
│   └── docker.py        # DockerDriver
└── test/                # pytest suite
```

### Encryption Flow

```
# set() operation:
App:set("API_KEY", "secret")
  --> WAuth
    --> CryptoEngine.encrypt()
      --> Derive key (machine_id + salt --> SHA-256)
      --> Fernet.encrypt() --> token
    --> Vault.save(token, "text", ttl)
      --> SQLite INSERT

# get() operation:
App:get("API_KEY")
  --> Vault.get(key)
    --> SQLite SELECT
    --> Check TTL (delete if expired)
  --> CryptoEngine.decrypt(token)
    --> Return plaintext
```

## Configuration

### Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `WAUTH_DB_PATH` | Custom SQLite database path | `~/.wisrovi/wauth.db` |

### TOML Configuration File

Create `~/.wauth.toml`:

```toml
[wauth]
db_path = "~/.wisrovi/wauth.db"
custom_key = "my-encryption-key"  # Optional
```

Usage:
```python
from wauth import WAuth
auth = WAuth(config_path="~/.wauth.toml")
```

### Database Path

By default, WAuth stores secrets in `~/.wisrovi/wauth.db`. To use a custom path:

```python
from wauth import WAuth

# Custom database path
auth = WAuth(db_path="/path/to/my_secrets.db")
auth.set("MY_KEY", "my-secret")
```

### Important Security Note

Encryption keys are **derived from the machine's unique identifier**. This means:

- Secrets encrypted on **Machine A** **cannot** be decrypted on **Machine B**.
- This is intentional — it prevents accidental secret leakage across environments.
- For cross-machine secret sharing, use Docker secrets, environment variables, or the `custom_key` parameter.

## Usage

### Quick Start

```python
from wauth import WAuth

# Initialize
auth = WAuth()

# Store a secret (automatically encrypted)
auth.set("TELEGRAM_TOKEN", "7483920:ABC-DEF-GHI")

# Retrieve the secret (auto-decrypted)
token = auth.get("TELEGRAM_TOKEN")
print(token)  # 7483920:ABC-DEF-GHI
```

### Storing Files

```python
from wauth import WAuth

auth = WAuth()

# Encrypt and store a file (e.g., TLS certificate)
auth.set_file("TLS_CERT", "/etc/ssl/certs/my-cert.pem")

# Retrieve the file contents as bytes
cert_bytes = auth.get("TLS_CERT")
with open("/tmp/restored-cert.pem", "wb") as f:
    f.write(cert_bytes)
```

### Functional API

```python
from wauth import set, get, set_file, delete, list_keys

# No need to instantiate WAuth
set("API_KEY", "sk-12345")
value = get("API_KEY")

# Store a file
set_file("SSH_KEY", "~/.ssh/id_rsa")
key_data = get("SSH_KEY")

# Delete a secret
delete("OLD_KEY")

# List all keys
keys = list_keys()
```

### Delete Secrets

```python
from wauth import WAuth

auth = WAuth()
auth.set("TEMP_TOKEN", "expires-soon")
auth.delete("TEMP_TOKEN")  # Permanently removes the secret
```

### Time-To-Live (TTL)

```python
from wauth import WAuth

auth = WAuth()

# Secret expires after 1 hour (3600 seconds)
auth.set("SESSION_TOKEN", "abc123", ttl=3600)

# After 1 hour, get() returns None
```

### Key Rotation

```python
from wauth import WAuth

auth = WAuth()
auth.set("KEY1", "value1")
auth.set("KEY2", "value2")

# Rotate the encryption key — all secrets are re-encrypted
results = auth.rotate_key("new-encryption-key")
# {"KEY1": True, "KEY2": True}
```

### Backup & Restore

```python
from wauth import WAuth

auth = WAuth()
auth.set("IMPORTANT", "critical-data")

# Export all secrets (still encrypted in the backup)
backup_path = auth.backup("my_vault_backup.wauth")

# Later, or on another machine with the same key
count = auth.restore("my_vault_backup.wauth")
print(f"Restored {count} secrets")
```

### Docker Integration

```python
from wauth import WAuth
from wauth.drivers import DriverFactory

# In a Docker container, DriverFactory tries Docker secrets first
factory = DriverFactory()
value = factory.get_value("DB_PASSWORD")
# Returns Docker secret if available, falls back to local vault
```

### Async Support

```python
import asyncio
from wauth import WAuth

async def main():
    auth = WAuth()
    await auth.async_set("ASYNC_KEY", "async-value")
    value = await auth.async_get("ASYNC_KEY")
    await auth.async_delete("ASYNC_KEY")
    print(value)  # async-value

asyncio.run(main())
```

### Exception Handling

```python
from wauth import WAuth
from wauth.exceptions import DecryptionError, KeyNotFoundError, WAuthError

auth = WAuth(custom_key="my-key")

try:
    value = auth.get("MISSING")
except KeyNotFoundError:
    print("Key does not exist")

try:
    # Decrypting with wrong key raises DecryptionError
    auth._driver.engine.decrypt("invalid-token")
except DecryptionError:
    print("Wrong key or corrupted data")

# Catch any WAuth error
try:
    auth.delete("MISSING")
except WAuthError:
    print("Any WAuth-related error")
```

### Secure Secret Verification

When you only need to check if a value matches a stored secret, use `valid()` instead of `get()`. This prevents the secret from being exposed in your code or logs.

```python
from wauth import WAuth

auth = WAuth()
auth.set("API_KEY", "secret123")

# LESS SECURE: Using get() exposes the secret
# api_key = auth.get("API_KEY")  # DON'T DO THIS
# if api_key == user_input:  # Secret is now in memory

# MORE SECURE: Using valid() never exposes the secret
user_input = input("Enter API key: ")
if auth.valid("API_KEY", user_input):
    print("Access granted")
else:
    print("Access denied")
# The secret never leaves the wauth library
```

The `valid()` method:
- Uses constant-time comparison to prevent timing attacks
- Never returns or exposes the actual secret
- Only returns `True` or `False`

### Async Secret Verification

```python
import asyncio
from wauth import WAuth

async def main():
    auth = WAuth()
    auth.set("API_KEY", "secret123")
    
    user_input = input("Enter API key: ")
    if await auth.async_valid("API_KEY", user_input):
        print("Access granted")

asyncio.run(main())
```

### Running the Examples

```bash
# Basic usage
python "examples/00 base/example.py"

# Secure secret verification (NEW in v0.5.0)
python "examples/18 valid method/example.py"

# Async secret verification
python "examples/19 async valid/example.py"

# Security comparison: get() vs valid()
python "examples/20 security comparison/example.py"
```

### Examples

| # | Example | Description |
|---|----------|-------------|
| 00 | base | Basic usage of WAuth |
| 01 | file storage | Storing encrypted files |
| 02 | TTL expiration | Time-to-live secrets |
| 03 | key rotation | Rotating encryption keys |
| 04 | backup and restore | Vault backup/restore |
| 05 | async API | Async secret operations |
| 06 | exception handling | Handling WAuth errors |
| 07 | functional API | Functional-style API |
| 08 | Docker secrets | Docker integration |
| 09 | config file | TOML configuration |
| 10 | logging integration | Loguru logging |
| 11 | migration from env | Migration from env vars |
| 12 | multiple vaults | Multiple database files |
| 13 | security best practices | Security guidelines |
| 14 | web app integration | Web framework integration |
| 15 | CI-CD pipeline | CI/CD integration |
| 16 | bulk operations | Bulk secret operations |
| 17 | pipeline | WPipe integration |
| 18 | valid method | **NEW** Secure secret verification |
| 19 | async valid | **NEW** Async verification |
| 20 | security comparison | **NEW** get() vs valid() |

## Testing & Quality

```bash
# Run tests with coverage
make test          # pytest with coverage report

# Lint all code
make lint-all      # Pylint on source and tests

# Run benchmarks
python benchmarks/performance.py

# Full quality check
make quality       # lint + test + format check
```

### Quality Metrics

| Metric | Score | Target |
|--------|-------|--------|
| **Version** | 0.5.0 | Latest |
| **Pylint (wauth/)** | 9.95/10 | ≥ 9.5 |
| **Pylint (test/)** | 9.89/10 | ≥ 9.5 |
| **Test Coverage** | 98% | ≥ 95% |
| **Tests** | 129+ passing | 100% |
| **Bandit Security** | 0 medium/high | 0 |

### LTS Status

WAuth v0.5.0 is the **latest stable** release:

- 24 months of security backports
- Stable public API with deprecation guarantees
- SemVer-compliant versioning
- [See VERSIONING.md](VERSIONING.md)
- [See MIGRATION.md](MIGRATION.md)
- [See SECURITY.md](SECURITY.md)

## Documentation

```bash
make html    # Build Sphinx docs
make serve   # Preview docs locally
```

**Online Documentation:**

| Site | URL |
|------|-----|
| **Full API Docs** | https://wauth.readthedocs.io/en/latest/ |
| **GitHub Pages** | https://wisrovi.github.io/wauth/ |
| **PyPI** | https://pypi.org/project/wauth/ |

Full API reference is available at `docs/_build/html/index.html`.

## Integration: WPipe

Combine **WAuth** with **WPipe** for powerful stateful pipelines with secure secret management.

| Library | Purpose |
|---------|---------|
| **WAuth** | Encrypted secret storage with Fernet |
| **WPipe** | Stateful pipelines with conditional logic |

**Example**: Access control pipeline:

```python
from wauth import WAuth
from wpipe import Pipeline, Condition, state

# Store secrets with WAuth
auth = WAuth(db_path="secrets.db", custom_key="my-key")
auth.set("USER_PASSWORD", "secure-pass")

# Use in WPipe pipeline
@state(name="authenticate")
def authenticate(credentials):
    auth = WAuth(db_path="secrets.db", custom_key="my-key")
    real_pass = auth.get("USER_PASSWORD")
    return {"access_granted": credentials.secret == real_pass}

pipeline = Pipeline(pipeline_name="access_control")
pipeline.set_steps([authenticate, Condition(...)])
```

See `examples/17 pipeline/` for the full example.





---

## 🛡️ The Wisrovi Philosophy: Productive Quality

This project is more than just a **wrapper**; it's a layer of **strategic abstraction**.

In today's development ecosystem, the technical complexity of core tools (like Docker, Kafka, or YOLO) often becomes an obstacle to innovation. The **wisrovi SUITE** was born with a clear mission: **to tame technology**.

### Why use this library instead of the core tools?

* **Critical Acceleration:** We reduce the learning curve and development time by a factor of **3.3x**. What used to take hours of configuration is now resolved in minutes.

* **Professional Opinion:** We don't just wrap features; we natively integrate **best practices for security, error handling, and resilience**. * **Business Focus:** By eliminating the boilerplate and unnecessary complexity, we allow developers to focus on creating value, not battling with the infrastructure.

* **Production Standard:** Every component of this suite is designed to be **Production-Ready**. We don't build tools for prototypes, but for solutions that scale in the real world.

> *“We didn't reinvent the wheel; we built the high-performance vehicle that enables businesses to reach the finish line faster.”*



---

## Author

**William Rodríguez — wisrovi**  
*Technology Evangelist & Open Source Advocate*

🔗 [LinkedIn](https://es.linkedin.com/in/wisrovi-rodriguez)  
🐙 [GitHub](https://github.com/wisrovi)

---

*WAuth is designed for developers who need simple, secure, machine-locked secret storage. Perfect for local development environments, CI/CD pipelines, and single-node deployments. LTS since v1.6.0.*



---
### 🛠️ Roadmap & Future Integration (Updated May 2026)

We are entering the **Distributed AI Era**. The wisrovi suite is evolving to support massive-scale machine learning orchestration:

* **⚡ Core Stability:** Maintenance and performance optimization across all `w-libraries`.
* **🤖 Coming Soon: `wtrain`:** Distributed Evolutionary Training for YOLO models.
* **🛰️ Coming Soon: `wcelery`:** High-performance task distribution with native `wauth` security.
* **🎓 Wisrovi Academy:** Official certification and advanced tutorials are on the way.

**Status:** Active development. New major releases coming this quarter.
---
