Metadata-Version: 2.4
Name: securecfg
Version: 0.1.0
Summary: Lightweight encrypted .env secrets manager with key rotation
Author: Secure Config Team
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: cryptography>=42.0.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Provides-Extra: hardware
Requires-Dist: tpm2-pytss>=2.2.0; extra == "hardware"
Requires-Dist: yubikey-manager>=5.4.0; extra == "hardware"

# Secure Config / Secrets Manager

This is a small, practical secrets tool for teams that want encrypted `.env` files without running a full vault platform.
It is meant to stay easy to understand and easy to operate.

## Features

- Encrypted `.env` files using AES-256-GCM
- Key rotation support
- CLI + Python SDK
- JS SDK compatible with the same encrypted file format
- Optional hardware-backed key providers with direct TPM2/YubiKey integrations and command fallback hooks

## Threat model and scope

Secure Config protects secrets at rest in repos, build artifacts, and deployment handoffs.
It does not try to replace enterprise vault systems, and it does not include network auth, dynamic credentials, or deep policy engines.

## Quick start

```bash
cd /home/projects/packets/secure-config-secrets-manager
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip install -e .
```

Initialize a local software key store:

```bash
securecfg init-key
```

Encrypt an env file:

```bash
securecfg encrypt --input .env --output .env.enc.json
```

Decrypt back to plaintext:

```bash
securecfg decrypt --input .env.enc.json --output .env.dec
```

Rotate key and re-encrypt an existing encrypted file:

```bash
securecfg rotate --input .env.enc.json --output .env.enc.json
```

## CLI reference

- `securecfg init-key [--key-id KEY_ID] [--provider software|tpm|yubikey]`
- `securecfg list-keys [--provider ...]`
- `securecfg encrypt --input .env --output .env.enc.json [--provider ...]`
- `securecfg decrypt --input .env.enc.json --output .env [--provider ...]`
- `securecfg rotate --input .env.enc.json --output .env.enc.json [--new-key-id KEY_ID] [--provider ...]`
- `securecfg policy-check [--provider ...]`

## Key providers

### software (default)

Stores 32-byte AES keys in a local JSON keyring at:

- Linux/macOS: `~/.securecfg/keys.json`

The key file is written with restrictive file permissions.

### tpm (optional)

The TPM provider tries direct TPM2 integration first via `tpm2-pytss`, reading from a persistent handle.
If unavailable, it falls back to `SECURECFG_TPM_COMMAND`.

Optional dependencies:

```bash
pip install -e .[hardware]
```

Direct mode settings:

- `SECURECFG_TPM_KEY_HANDLE` (default `0x81010002`)

Fallback mode:

- Set `SECURECFG_TPM_COMMAND` to a command that prints key material to stdout.
- Output can be raw text, hex, or base64 and will be normalized into a 32-byte key via SHA-256 when needed.

Example:

```bash
export SECURECFG_TPM_COMMAND="tpm2_unseal -c 0x81010002"
```

### yubikey (optional)

The YubiKey provider tries direct integration first via `yubikey-manager`/`yubikit` using OTP HMAC challenge-response.
If unavailable, it falls back to `SECURECFG_YUBIKEY_COMMAND`.

Direct mode settings:

- `SECURECFG_YUBIKEY_SLOT` (`1` or `2`, default `2`)
- `SECURECFG_YUBIKEY_CHALLENGE` (default `securecfg-hmac`)

Fallback mode:

- Set `SECURECFG_YUBIKEY_COMMAND` to a command that prints key material to stdout.
- The same normalization rules apply.

Example:

```bash
export SECURECFG_YUBIKEY_COMMAND="ykman oath accounts code securecfg"
```

## Python SDK

```python
from securecfg import SecureConfigManager

mgr = SecureConfigManager(provider_name="software")

mgr.encrypt_env_file(".env", ".env.enc.json")
mgr.decrypt_env_file(".env.enc.json", ".env.dec")
```

## JS SDK

See `sdk/js/README.md`.

## Tests

Run Python tests:

```bash
pip install -e .[dev]
pytest -q
```

Run JS SDK tests:

```bash
cd sdk/js
npm test
```

Interop tests (Python <-> JS) are included in the Python suite and run automatically when `node` is available.

## Docker

Build and run CLI via container:

```bash
docker build -t securecfg .
docker run --rm -v "$HOME/.securecfg:/root/.securecfg" securecfg list-keys --provider software
```

## CI

GitHub Actions workflow is included at `.github/workflows/ci.yml` and runs:

- Python tests (`pytest`)
- JS SDK tests (`npm test`)

## Encrypted format

Encrypted files are JSON envelopes:

```json
{
  "version": 1,
  "algorithm": "AES-256-GCM",
  "key_id": "k-20260407-1",
  "nonce": "...base64...",
  "ciphertext": "...base64...",
  "tag": "...base64...",
  "created_at": "2026-04-07T12:00:00Z",
  "metadata": {
    "source": ".env"
  }
}
```

## Security notes

- Keep plaintext `.env` files out of git and production artifacts.
- Restrict file permissions for key files.
- Prefer dedicated hardware-backed commands in production.
- Rotate keys periodically and on compromise suspicion.

## Simple key lifecycle policy

If you want a bit more safety without extra tooling, enable these environment variables:

- `SECURECFG_KEY_MAX_AGE_DAYS`: blocks new encryption if active key is older than this many days.
- `SECURECFG_ROTATE_AFTER_DAYS`: requires rotation before encryption when active key exceeds this age.
- `SECURECFG_DENY_OLD_KEY_DECRYPT=true`: blocks decryption unless envelope key matches current active key.

Example:

```bash
export SECURECFG_KEY_MAX_AGE_DAYS=90
export SECURECFG_ROTATE_AFTER_DAYS=60
export SECURECFG_DENY_OLD_KEY_DECRYPT=true
```

All policy controls are optional. If you do not set them, Secure Config stays permissive.

Quick check:

```bash
securecfg policy-check
```

Exit codes:

- `0`: policy passes
- `3`: policy fails
