Metadata-Version: 2.4
Name: secure-credentials-kit
Version: 0.2.1
Summary: A secure encrypted credentials system for Django and FastAPI, inspired by Rails credentials
License-Expression: MIT
Project-URL: Homepage, https://github.com/lexpank/secure-credentials-kit
Project-URL: Issues, https://github.com/lexpank/secure-credentials-kit/issues
Keywords: django,fastapi,credentials,encryption,security
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
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: Programming Language :: Python :: 3.14
Classifier: Framework :: Django
Classifier: Framework :: FastAPI
Classifier: Topic :: Security
Requires-Python: <3.15,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cryptography>=41.0.0
Requires-Dist: pyyaml>=6.0
Provides-Extra: django
Requires-Dist: Django<6.1,>=5.2; extra == "django"
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.100.0; extra == "fastapi"
Dynamic: license-file

# Secure Credentials Kit

A secure, encrypted credentials system for Django and FastAPI, inspired by Rails credentials.

## Features
- Environment-specific encrypted credentials
- Framework-neutral CLI for generating and editing encrypted credentials
- Master keys for editing credentials and read-only keys for application runtime access
- Signed encrypted credential files backed by an asymmetric signing/verification key pair
- Django management commands
- FastAPI helpers for loading credentials into application state

## Installation

The PyPI distribution, Python package, and CLI are all named for Secure
Credentials Kit:

- Distribution: `secure-credentials-kit`
- Python package: `secure_credentials_kit`
- CLI: `secure-credentials-kit`

Supported versions:

- Python 3.10, 3.11, 3.12, 3.13, and 3.14
- Django 5.2 LTS and Django 6.0

For Django:

```sh
pip install "secure-credentials-kit[django]"
```

For FastAPI:

```sh
pip install "secure-credentials-kit[fastapi]"
```

## Local Development

This project uses `pyproject.toml` for package metadata and uv for local
dependency management.

Install uv, then create a development environment:

```sh
uv sync
```

Install framework extras when you need to test integrations:

```sh
uv sync --extra django
uv sync --extra fastapi
```

Run tests:

```sh
uv run python -m unittest discover -v
```

Build the package:

```sh
uv run python -m build
```

## Credentials Files

Add secret keys to `.gitignore`:

```sh
echo "secrets/*.key" >> .gitignore
```

Generate a new key pair:

```sh
secure-credentials-kit generate-key <environment>
```

This creates two role-specific keys:

- `secrets/<environment>.master.key` can decrypt, edit, encrypt, and sign credentials with the private signing key.
- `secrets/<environment>.readonly.key` can decrypt and verify credentials with the public verification key, but cannot produce accepted credential updates.

Key files are stored as one-line base64url payloads. The decoded payload contains
the key material and format version; the package detects the key role
automatically from the key material, so there is no visible `master:` or
`readonly:` prefix in the file contents.

You can regenerate a read-only key from an existing master key:

```sh
secure-credentials-kit generate-key <environment> --role readonly
```

Edit encrypted credentials:

```sh
secure-credentials-kit edit <environment>
```

Editing requires `secrets/<environment>.master.key`. Applications should normally
run with only `secrets/<environment>.readonly.key`.

The editor opens the decrypted YAML. The YAML root must be a mapping:

```yaml
SOME_ENV_VAR: secret-value
database:
  url: postgres://user:password@localhost:5432/app
api:
  token: token-value
```

Credentials are stored in `secrets/<environment>.yml.enc`, and keys are stored in
`secrets/<environment>.master.key` and `secrets/<environment>.readonly.key`.
The encrypted file is generated by the tool and should not be edited by hand. It
contains a signed encrypted payload similar to:

```json
{
  "version": 2,
  "payload": "gAAAAAB...",
  "signature": "..."
}
```

## Django Usage

Add `secure_credentials_kit` to your `INSTALLED_APPS` in `settings.py`:

```python
INSTALLED_APPS = [
    ...
    'secure_credentials_kit',
    ...
]
```

You can also use Django management commands:

```sh
python manage.py credentials_generate_key <environment>
```

```sh
python manage.py credentials_generate_key <environment> --role readonly
```

```sh
python manage.py credentials_edit <environment>
```

To load the credentials in your Django app:

```python
from secure_credentials_kit.secrets_loader import decrypt_credentials
credentials = decrypt_credentials("environment")
```

Where `credentials` is an instance of class `CredentialsContainer` containing the decrypted credentials.

## FastAPI Usage

Load credentials into FastAPI application state:

```python
from fastapi import Depends, FastAPI
from secure_credentials_kit.fastapi import (
    credentials_dependency,
    setup_secure_credentials_kit,
)

app = FastAPI()
setup_secure_credentials_kit(app, "production")


@app.get("/settings")
def settings(credentials=Depends(credentials_dependency())):
    return {"api_host": credentials.get("api_host")}
```

If no environment is passed to `setup_secure_credentials_kit`, the helper checks
`SECURE_CREDENTIALS_KIT_ENV`, `FASTAPI_ENV`, `ENV`, then falls back to `development`.

## Accessing Credentials

To access a credential:

```python
credentials.get('key')
```

or

```python
credentials.dig('key', 'subkey')
```

for complex nested credentials.
