Metadata-Version: 2.4
Name: navig-vault
Version: 0.10.0
Summary: NAVIG Vault — a free, standalone, encrypted developer secrets manager (Doppler / 1Password-CLI / Infisical class). Installs without navig; shares one vault.
Author-email: NAVIG Team <opensource@navig.run>
License: Apache-2.0
Project-URL: Homepage, https://navig.run
Project-URL: Documentation, https://github.com/navig-run/core/blob/main/docs/README.md
Keywords: secrets,vault,credentials,secrets-manager,encryption,dotenv,keychain,navig
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cryptography>=42.0
Provides-Extra: argon2
Requires-Dist: argon2-cffi>=21.0; extra == "argon2"
Provides-Extra: keyring
Requires-Dist: keyring>=24.0; extra == "keyring"
Provides-Extra: validators
Requires-Dist: httpx>=0.27; extra == "validators"
Provides-Extra: web
Requires-Dist: tldextract>=5.0; extra == "web"
Provides-Extra: all
Requires-Dist: argon2-cffi>=21.0; extra == "all"
Requires-Dist: keyring>=24.0; extra == "all"
Requires-Dist: httpx>=0.27; extra == "all"
Requires-Dist: tldextract>=5.0; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Dynamic: license-file

# navig-vault

<!-- navig:plugin-card:start -->
<!-- Generated by scripts/gen_plugin_catalog.py — edit the plugin's pyproject.toml, not this block. -->

> A free, standalone, encrypted developer secrets manager (Doppler / 1Password-CLI / Infisical class). Installs without navig; shares one vault.

**Works on its own** — its own CLI, no navig required · v0.10.0 · [PyPI](https://pypi.org/project/navig-vault/)

![navig-vault demo](https://raw.githubusercontent.com/navig-run/plugins/main/navig-vault/docs/demo.gif)

**On its own** (no navig needed)

```bash
pip install navig-vault
nv --help   # no navig needed
```

**With navig**

```bash
pip install navig-vault
```

<!-- navig:plugin-card:end -->

> A free, standalone, encrypted **developer secrets manager** — Doppler / 1Password-CLI /
> Infisical / Bitwarden class — that installs **without** navig and shares **one vault**.

**Status: complete and standalone.**

`pip install navig-vault` gives you a working `nv` with no navig required:

```sh
pip install navig-vault

export OPENAI_KEY=sk-...
nv add openai --from-env OPENAI_KEY     # never on the command line -- see below
nv get openai                            # the secret, on stdout, and nothing else
nv list                                  # never prints secrets
nv test openai                           # check it against the provider (needs [validators])
nv path                                  # which vault is in use
```

**A secret is never taken as an argument.** There is no `--value` flag and there will not be
one: command-line arguments are visible in shell history and to every other process via `ps`.
Values come from `--from-env`, `--from-file`, `--stdin`, or a non-echoing prompt.

### Export to SVG — back up the vault, or hand someone a password

```sh
nv export --svg github                  # vault-<random>.svg + a generated passphrase (shown once)
nv export --svg --all --yes             # the whole vault in one file
nv export --svg --all --yes --each      # one file per secret, each with its own passphrase
nv open vault-1a2b3c4d.svg [--reveal]   # what it holds (writes nothing)
nv import vault-1a2b3c4d.svg            # add to this vault — never overwrites an existing secret
nv opener                               # open-vault-svg.html: opens an export in any browser, offline
```

The export is an ordinary SVG picture with the secrets sealed inside it:

| | |
|---|---|
| Cipher | AES-256-GCM. The info block is bound in as associated data, so editing it breaks the file. |
| Key | PBKDF2-HMAC-SHA256, 600,000 rounds, random 16-byte salt. Every browser's WebCrypto has it. |
| Visible without the passphrase | That a sealed payload exists. No labels, names, counts or sizes; file names are random. |
| The real lock | The passphrase. Anyone holding the file can guess offline, so generated ones are ~125 bits and chosen ones need 14+ characters. |
| Opening it | `nv open/import`, `navig vault open/import`, or **https://navig.run/open** / `open-vault-svg.html` in any browser (local WebCrypto, no network). |

The passphrase comes from a prompt or `NAVIG_VAULT_SVG_PASSPHRASE`, never from argv. Send it
by a different channel than the file, and send the SVG as a file, not a photo: chat apps
re-encode images and destroy the payload. Old plain files from the original *SVG Vault* app
still open (`nv open old.svg --save <folder>`). Format spec: the docstring of
`navig_vault/svg.py`.

**One vault, shared.** A standalone install resolves the same `~/.navig/vault` navig uses
(honouring `NAVIG_CONFIG_DIR` / `NAVIG_VAULT_DIR`), so adding a credential with `nv` makes it
readable by `navig`, and vice versa. That is the `_compat` seam: it delegates to navig's own
helpers when navig is installed and falls back to behaviour-matched implementations when it
is not.

**As a library:**

```python
from navig_vault import SecretStr, Credential, CredentialType, totp_now, vault_dir
from navig_vault.core import get_vault

secret = get_vault().get_api_key("openai")
```

The package is fully annotated and ships `py.typed`. `navig.vault.<module>` inside navig is a
thin shim that aliases to the module here, so there is exactly one implementation and the two
cannot drift.

## What it will be

- **Install-without-navig:** `pip install navig-vault` → `navig-vault` (alias `nv`) works on its
  own. Add navig later and they share the same encrypted vault automatically.
- **Runtime injection:** `navig-vault run -- <cmd>` injects real secret values from the encrypted
  vault into a process's environment at runtime (no plaintext `.env` on disk).
- **Secret types:** API keys, logins, cards, passport, TOTP.
- **Frictionless unlock:** OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret
  Service) with a passphrase fallback.
- **Apache-2.0**, own subdomain **vault.navig.run**.

## Layout

```
navig-vault/
  pyproject.toml        # name "navig-vault", scripts: navig-vault + nv
  LICENSE               # Apache-2.0
  README.md
  navig_vault/
    __init__.py         # package metadata
    cli.py              # `navig-vault` / `nv` entrypoint  (stub)
    __main__.py         # `python -m navig_vault`
  tests/
    test_smoke.py
```

## Develop

```bash
cd navig-vault
python -m pip install -e ".[dev]"
navig-vault --help      # or:  nv --help   or:  python -m navig_vault
pytest -q
```

## Relationship to navig

Inside navig it remains `navig vault`. `navig-vault` owns the code; `navig-core` re-exports it,
so the two never fork. See the implementation plan (extract-from-navig-core, share-don't-fork)
in the project's Claude plans (`i-ant-to-make-staged-prism`).
