passvault-cli 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ e81d8a33-4837-4bf9-93e1-0c76f931902a
@@ -0,0 +1,32 @@
1
+ name: tests
2
+
3
+ on:
4
+ push:
5
+ branches: ["**"]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ name: pytest (${{ matrix.os }}, py${{ matrix.python-version }})
11
+ runs-on: ${{ matrix.os }}
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ os: [ubuntu-latest, windows-latest, macos-latest]
16
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Set up Python
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+
26
+ - name: Install
27
+ run: |
28
+ python -m pip install --upgrade pip
29
+ pip install -e ".[dev]"
30
+
31
+ - name: Run tests
32
+ run: pytest --cov=passvault --cov-report=term-missing
@@ -0,0 +1,46 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ build/
8
+ dist/
9
+ *.egg-info/
10
+ *.egg
11
+ eggs/
12
+ .eggs/
13
+ wheels/
14
+
15
+ # Virtual environments
16
+ .venv/
17
+ venv/
18
+ env/
19
+ ENV/
20
+
21
+ # Test / coverage artifacts
22
+ .pytest_cache/
23
+ .coverage
24
+ .coverage.*
25
+ htmlcov/
26
+ .tox/
27
+ .mypy_cache/
28
+ .ruff_cache/
29
+
30
+ # Environment / secrets
31
+ .env
32
+ .env.*
33
+ *.env
34
+
35
+ # Local test vault files (never commit real vaults)
36
+ *.dat
37
+ vault.dat
38
+ test-vault/
39
+ tmp_vault*
40
+
41
+ # Editors / OS
42
+ .idea/
43
+ .vscode/
44
+ *.swp
45
+ .DS_Store
46
+ Thumbs.db
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 passvault contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,211 @@
1
+ Metadata-Version: 2.5
2
+ Name: passvault-cli
3
+ Version: 0.1.0
4
+ Summary: A local, encrypted, offline password manager CLI.
5
+ Project-URL: Homepage, https://github.com/Ajeet2005/passvault
6
+ Project-URL: Repository, https://github.com/Ajeet2005/passvault
7
+ Project-URL: Issues, https://github.com/Ajeet2005/passvault/issues
8
+ Author: passvault contributors
9
+ License: MIT License
10
+
11
+ Copyright (c) 2026 passvault contributors
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ License-File: LICENSE
31
+ Keywords: cli,encryption,offline,password-manager,security,vault
32
+ Classifier: Development Status :: 3 - Alpha
33
+ Classifier: Environment :: Console
34
+ Classifier: Intended Audience :: End Users/Desktop
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3.10
38
+ Classifier: Programming Language :: Python :: 3.11
39
+ Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: Programming Language :: Python :: 3.13
41
+ Classifier: Topic :: Security :: Cryptography
42
+ Classifier: Topic :: Utilities
43
+ Requires-Python: >=3.10
44
+ Requires-Dist: argon2-cffi>=23.1
45
+ Requires-Dist: cryptography>=42.0
46
+ Requires-Dist: inquirerpy>=0.3.4
47
+ Requires-Dist: platformdirs>=4.0
48
+ Requires-Dist: pyperclip>=1.8
49
+ Requires-Dist: rich>=13.0
50
+ Requires-Dist: typer>=0.12
51
+ Provides-Extra: dev
52
+ Requires-Dist: build>=1.2; extra == 'dev'
53
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
54
+ Requires-Dist: pytest>=8.0; extra == 'dev'
55
+ Requires-Dist: twine>=5.0; extra == 'dev'
56
+ Description-Content-Type: text/markdown
57
+
58
+ # passvault
59
+
60
+ A local, encrypted, offline password manager CLI.
61
+
62
+ > **PyPI note:** the distribution is published as
63
+ > [`passvault-cli`](https://pypi.org/project/passvault-cli/) because the name
64
+ > `passvault` was already taken. The installed command and import name are
65
+ > still `passvault`.
66
+
67
+ - No network calls, no accounts, no telemetry.
68
+ - Everything lives in a single encrypted file on your machine.
69
+ - Your master password is required on **every** command. There is no session
70
+ caching and no OS keychain integration — by design.
71
+
72
+ ## How it works
73
+
74
+ Entries are stored as a JSON object and encrypted with
75
+ [Fernet](https://cryptography.io/en/latest/fernet/) (AES-128-CBC + HMAC-SHA256,
76
+ authenticated encryption).
77
+
78
+ The encryption key is derived from your master password with **Argon2id**
79
+ (memory-hard, 64 MiB, 3 passes) using a random 16-byte salt.
80
+
81
+ The vault file is laid out as:
82
+
83
+ ```
84
+ salt (16 bytes) || Fernet token
85
+ ```
86
+
87
+ The salt is generated once at vault creation and never rotated. Deriving the
88
+ key requires the master password, which is never stored, logged, or written
89
+ anywhere. A wrong master password fails loudly — authenticated decryption means
90
+ we never return garbage plaintext.
91
+
92
+ ## Install
93
+
94
+ From PyPI:
95
+
96
+ ```bash
97
+ pip install passvault-cli
98
+ ```
99
+
100
+ Or from source:
101
+
102
+ ```bash
103
+ git clone https://github.com/Ajeet2005/passvault.git
104
+ cd passvault
105
+ python -m venv .venv
106
+ # Windows: .venv\Scripts\activate
107
+ source .venv/bin/activate
108
+ pip install -e .
109
+ ```
110
+
111
+ Requires Python 3.10+.
112
+
113
+ ## Usage
114
+
115
+ ### Create a vault
116
+
117
+ ```bash
118
+ passvault init
119
+ ```
120
+
121
+ Refuses to run if a vault already exists. You'll be asked for your master
122
+ password twice.
123
+
124
+ ### Add an entry
125
+
126
+ ```bash
127
+ passvault add github --generate --length 24 --username me@example.com
128
+ passvault add email # prompt for the password (hidden input)
129
+ ```
130
+
131
+ Existing entries are only overwritten after a confirmation prompt. Passwords
132
+ are never echoed back to the terminal.
133
+
134
+ ### List entries
135
+
136
+ ```bash
137
+ passvault list
138
+ ```
139
+
140
+ Shows names, usernames, and whether notes are set. **Never** prints stored
141
+ passwords.
142
+
143
+ ### Retrieve a password
144
+
145
+ ```bash
146
+ passvault get github # print the password to stdout
147
+ passvault get github --clipboard # copy to the clipboard, don't print it
148
+ ```
149
+
150
+ The behavior is always explicit: you choose whether the secret is printed or
151
+ copied. There is no silent default.
152
+
153
+ ### Delete an entry
154
+
155
+ ```bash
156
+ passvault delete github
157
+ ```
158
+
159
+ Asks for confirmation first.
160
+
161
+ ### Generate a password without a vault
162
+
163
+ ```bash
164
+ passvault generate --length 32
165
+ passvault generate --no-symbols
166
+ passvault generate --no-digits --clipboard
167
+ ```
168
+
169
+ ## Vault location
170
+
171
+ The vault lives in your OS's user data directory:
172
+
173
+ | OS | Path |
174
+ | ------- | ------------------------------------------------- |
175
+ | Windows | `%LOCALAPPDATA%\passvault\vault.dat` |
176
+ | macOS | `~/Library/Application Support/passvault/vault.dat` |
177
+ | Linux | `~/.local/share/passvault/vault.dat` |
178
+
179
+ ## Development
180
+
181
+ ```bash
182
+ pip install -e ".[dev]"
183
+ pytest --cov=passvault
184
+ ```
185
+
186
+ Test layout:
187
+
188
+ - `tests/test_crypto.py` — key derivation determinism, round trips, wrong-password
189
+ failure.
190
+ - `tests/test_storage.py` — create/load/save round trips, salt persistence,
191
+ refusing writes on a wrong password.
192
+ - `tests/test_generator.py` — length and character-class guarantees.
193
+ - `tests/test_cli.py` — end-to-end command tests via Typer's `CliRunner`.
194
+
195
+ ## Security notes
196
+
197
+ - The master password is never stored, in any form.
198
+ - Decrypted passwords are only printed when you explicitly run `get` without
199
+ `--clipboard`.
200
+ - All randomness uses Python's `secrets` module, never `random`.
201
+ - A wrong master password always fails loudly.
202
+ - No session caching and no OS keychain support in this version.
203
+
204
+ ## Disclaimer
205
+
206
+ This is a learning project. It has **not** been audited. For real secrets, use a
207
+ battle-tested password manager.
208
+
209
+ ## License
210
+
211
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,154 @@
1
+ # passvault
2
+
3
+ A local, encrypted, offline password manager CLI.
4
+
5
+ > **PyPI note:** the distribution is published as
6
+ > [`passvault-cli`](https://pypi.org/project/passvault-cli/) because the name
7
+ > `passvault` was already taken. The installed command and import name are
8
+ > still `passvault`.
9
+
10
+ - No network calls, no accounts, no telemetry.
11
+ - Everything lives in a single encrypted file on your machine.
12
+ - Your master password is required on **every** command. There is no session
13
+ caching and no OS keychain integration — by design.
14
+
15
+ ## How it works
16
+
17
+ Entries are stored as a JSON object and encrypted with
18
+ [Fernet](https://cryptography.io/en/latest/fernet/) (AES-128-CBC + HMAC-SHA256,
19
+ authenticated encryption).
20
+
21
+ The encryption key is derived from your master password with **Argon2id**
22
+ (memory-hard, 64 MiB, 3 passes) using a random 16-byte salt.
23
+
24
+ The vault file is laid out as:
25
+
26
+ ```
27
+ salt (16 bytes) || Fernet token
28
+ ```
29
+
30
+ The salt is generated once at vault creation and never rotated. Deriving the
31
+ key requires the master password, which is never stored, logged, or written
32
+ anywhere. A wrong master password fails loudly — authenticated decryption means
33
+ we never return garbage plaintext.
34
+
35
+ ## Install
36
+
37
+ From PyPI:
38
+
39
+ ```bash
40
+ pip install passvault-cli
41
+ ```
42
+
43
+ Or from source:
44
+
45
+ ```bash
46
+ git clone https://github.com/Ajeet2005/passvault.git
47
+ cd passvault
48
+ python -m venv .venv
49
+ # Windows: .venv\Scripts\activate
50
+ source .venv/bin/activate
51
+ pip install -e .
52
+ ```
53
+
54
+ Requires Python 3.10+.
55
+
56
+ ## Usage
57
+
58
+ ### Create a vault
59
+
60
+ ```bash
61
+ passvault init
62
+ ```
63
+
64
+ Refuses to run if a vault already exists. You'll be asked for your master
65
+ password twice.
66
+
67
+ ### Add an entry
68
+
69
+ ```bash
70
+ passvault add github --generate --length 24 --username me@example.com
71
+ passvault add email # prompt for the password (hidden input)
72
+ ```
73
+
74
+ Existing entries are only overwritten after a confirmation prompt. Passwords
75
+ are never echoed back to the terminal.
76
+
77
+ ### List entries
78
+
79
+ ```bash
80
+ passvault list
81
+ ```
82
+
83
+ Shows names, usernames, and whether notes are set. **Never** prints stored
84
+ passwords.
85
+
86
+ ### Retrieve a password
87
+
88
+ ```bash
89
+ passvault get github # print the password to stdout
90
+ passvault get github --clipboard # copy to the clipboard, don't print it
91
+ ```
92
+
93
+ The behavior is always explicit: you choose whether the secret is printed or
94
+ copied. There is no silent default.
95
+
96
+ ### Delete an entry
97
+
98
+ ```bash
99
+ passvault delete github
100
+ ```
101
+
102
+ Asks for confirmation first.
103
+
104
+ ### Generate a password without a vault
105
+
106
+ ```bash
107
+ passvault generate --length 32
108
+ passvault generate --no-symbols
109
+ passvault generate --no-digits --clipboard
110
+ ```
111
+
112
+ ## Vault location
113
+
114
+ The vault lives in your OS's user data directory:
115
+
116
+ | OS | Path |
117
+ | ------- | ------------------------------------------------- |
118
+ | Windows | `%LOCALAPPDATA%\passvault\vault.dat` |
119
+ | macOS | `~/Library/Application Support/passvault/vault.dat` |
120
+ | Linux | `~/.local/share/passvault/vault.dat` |
121
+
122
+ ## Development
123
+
124
+ ```bash
125
+ pip install -e ".[dev]"
126
+ pytest --cov=passvault
127
+ ```
128
+
129
+ Test layout:
130
+
131
+ - `tests/test_crypto.py` — key derivation determinism, round trips, wrong-password
132
+ failure.
133
+ - `tests/test_storage.py` — create/load/save round trips, salt persistence,
134
+ refusing writes on a wrong password.
135
+ - `tests/test_generator.py` — length and character-class guarantees.
136
+ - `tests/test_cli.py` — end-to-end command tests via Typer's `CliRunner`.
137
+
138
+ ## Security notes
139
+
140
+ - The master password is never stored, in any form.
141
+ - Decrypted passwords are only printed when you explicitly run `get` without
142
+ `--clipboard`.
143
+ - All randomness uses Python's `secrets` module, never `random`.
144
+ - A wrong master password always fails loudly.
145
+ - No session caching and no OS keychain support in this version.
146
+
147
+ ## Disclaimer
148
+
149
+ This is a learning project. It has **not** been audited. For real secrets, use a
150
+ battle-tested password manager.
151
+
152
+ ## License
153
+
154
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,62 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ # PyPI distribution name; the importable package remains `passvault`.
7
+ name = "passvault-cli"
8
+ version = "0.1.0"
9
+ description = "A local, encrypted, offline password manager CLI."
10
+ readme = "README.md"
11
+ requires-python = ">=3.10"
12
+ license = { file = "LICENSE" }
13
+ authors = [{ name = "passvault contributors" }]
14
+ keywords = ["password-manager", "cli", "encryption", "security", "offline", "vault"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Environment :: Console",
18
+ "Intended Audience :: End Users/Desktop",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Security :: Cryptography",
26
+ "Topic :: Utilities",
27
+ ]
28
+ dependencies = [
29
+ "typer>=0.12",
30
+ "rich>=13.0",
31
+ "inquirerpy>=0.3.4",
32
+ "cryptography>=42.0",
33
+ "argon2-cffi>=23.1",
34
+ "pyperclip>=1.8",
35
+ "platformdirs>=4.0",
36
+ ]
37
+
38
+ [project.optional-dependencies]
39
+ dev = [
40
+ "pytest>=8.0",
41
+ "pytest-cov>=5.0",
42
+ "build>=1.2",
43
+ "twine>=5.0",
44
+ ]
45
+
46
+ [project.urls]
47
+ Homepage = "https://github.com/Ajeet2005/passvault"
48
+ Repository = "https://github.com/Ajeet2005/passvault"
49
+ Issues = "https://github.com/Ajeet2005/passvault/issues"
50
+
51
+ [project.scripts]
52
+ passvault = "passvault.cli:app"
53
+
54
+ [tool.hatch.build.targets.wheel]
55
+ packages = ["src/passvault"]
56
+
57
+ [tool.pytest.ini_options]
58
+ testpaths = ["tests"]
59
+ addopts = "-q"
60
+
61
+ [tool.coverage.run]
62
+ source = ["passvault"]
@@ -0,0 +1,7 @@
1
+ """passvault — a local, encrypted, offline password manager CLI."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __version__ = "0.1.0"
6
+
7
+ __all__ = ["__version__"]