notenv 0.15.1__py3-none-win_arm64.whl
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.
|
Binary file
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: notenv
|
|
3
|
+
Version: 0.15.1
|
|
4
|
+
Summary: Your .env, encrypted and off your disk, with no infrastructure to run.
|
|
5
|
+
Home-page: https://dvgils.github.io/notenv/
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Documentation, https://dvgils.github.io/notenv/
|
|
8
|
+
Project-URL: Source, https://github.com/DvGils/notenv
|
|
9
|
+
Project-URL: Changelog, https://github.com/DvGils/notenv/blob/main/CHANGELOG.md
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Topic :: Security
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# notenv
|
|
16
|
+
|
|
17
|
+
[](https://github.com/DvGils/notenv/actions/workflows/ci.yml)
|
|
18
|
+
[](https://github.com/DvGils/notenv/releases/latest)
|
|
19
|
+
[](https://dvgils.github.io/notenv/)
|
|
20
|
+
[](https://pkg.go.dev/github.com/DvGils/notenv)
|
|
21
|
+
[](https://goreportcard.com/report/github.com/DvGils/notenv)
|
|
22
|
+
[](./LICENSE)
|
|
23
|
+
|
|
24
|
+
> Your `.env`, encrypted and off your disk, with no infrastructure to run.
|
|
25
|
+
|
|
26
|
+
notenv replaces `.env` files. Your secrets are encrypted **on your machine** with
|
|
27
|
+
[age](https://github.com/FiloSottile/age), stored as ciphertext in a **local vault** or on
|
|
28
|
+
**storage you already own** (Backblaze B2, S3, Google Drive, SFTP, WebDAV, or anything
|
|
29
|
+
[rclone](https://rclone.org) speaks), and decrypted **only into the environment of the process you
|
|
30
|
+
run**. Plaintext never touches your disk.
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
notenv setup # a local vault: no accounts, no dependencies, one passphrase
|
|
34
|
+
notenv import .env # your existing secrets, encrypted; delete the .env after
|
|
35
|
+
notenv run -- npm run dev # secrets injected as env vars, gone when the process exits
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
There is no server to run, no SaaS to sign up for, and nothing to install beyond notenv itself. You
|
|
39
|
+
hold the key; storage only ever sees ciphertext. When syncing across machines starts to matter,
|
|
40
|
+
`notenv vault copy` moves the same vault to a cloud remote in one command.
|
|
41
|
+
|
|
42
|
+
## Documentation
|
|
43
|
+
|
|
44
|
+
Full docs live at **[dvgils.github.io/notenv](https://dvgils.github.io/notenv/)**:
|
|
45
|
+
|
|
46
|
+
- [Quick start](https://dvgils.github.io/notenv/getting-started/quick-start/) and
|
|
47
|
+
[installation](https://dvgils.github.io/notenv/getting-started/installation/)
|
|
48
|
+
- Guides: [teams and keys](https://dvgils.github.io/notenv/guides/teams-and-keys/),
|
|
49
|
+
[cloud remotes](https://dvgils.github.io/notenv/guides/cloud-remotes/),
|
|
50
|
+
[CI](https://dvgils.github.io/notenv/guides/ci/),
|
|
51
|
+
[AI agents](https://dvgils.github.io/notenv/guides/ai-agents/)
|
|
52
|
+
- Reference: [commands](https://dvgils.github.io/notenv/reference/commands/),
|
|
53
|
+
[configuration](https://dvgils.github.io/notenv/reference/configuration/)
|
|
54
|
+
- Concepts: [how it works](https://dvgils.github.io/notenv/concepts/how-it-works/),
|
|
55
|
+
[keys and slots](https://dvgils.github.io/notenv/concepts/keys-and-slots/)
|
|
56
|
+
- Security: [threat model](https://dvgils.github.io/notenv/security/threat-model/)
|
|
57
|
+
|
|
58
|
+
## Install
|
|
59
|
+
|
|
60
|
+
With uv (or pipx, or pip; the package carries the prebuilt binary, no Python code runs):
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
uv tool install notenv
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
With Go:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
go install github.com/DvGils/notenv/cmd/notenv@latest
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Or download a prebuilt binary for Linux, macOS, or Windows (amd64 / arm64) from the
|
|
73
|
+
[Releases](https://github.com/DvGils/notenv/releases) page and put `notenv` on your `PATH`. Releases
|
|
74
|
+
are reproducible, signed with [cosign](https://github.com/sigstore/cosign) (keyless), and carry SLSA
|
|
75
|
+
build provenance; the
|
|
76
|
+
[installation guide](https://dvgils.github.io/notenv/getting-started/installation/) shows how to
|
|
77
|
+
verify a download.
|
|
78
|
+
|
|
79
|
+
## Quick start
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
notenv setup # 1. set up this machine once (local vault by default)
|
|
83
|
+
cd my-project && notenv init # 2. declare the project (writes notenv.toml, which you commit)
|
|
84
|
+
notenv import .env && rm .env # 3. import existing secrets (or `notenv set KEY` one at a time)
|
|
85
|
+
notenv run -- npm run dev # 4. run anything with the secrets injected
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
That is the whole loop. notenv is a process wrapper, so it works with any language that reads
|
|
89
|
+
environment variables. On a new machine, `git clone` the project, run `notenv setup` with your
|
|
90
|
+
escrowed passphrase, and you are ready. See the
|
|
91
|
+
[quick start](https://dvgils.github.io/notenv/getting-started/quick-start/) for the full walkthrough.
|
|
92
|
+
|
|
93
|
+
## Why notenv
|
|
94
|
+
|
|
95
|
+
Your secrets are probably in a `.env` file right now. That means:
|
|
96
|
+
|
|
97
|
+
- **Everything on your machine can read them.** Your test runner, some package's postinstall
|
|
98
|
+
script, and any coding agent working in your checkout are one read away. An agent that opens
|
|
99
|
+
your `.env` while debugging has just copied your production credentials into a model context and
|
|
100
|
+
a transcript you don't control.
|
|
101
|
+
- **Sharing them means pasting them.** A teammate needs the project's secrets, so the file goes
|
|
102
|
+
over chat. Now it lives in message history, in a downloads folder, on a laptop that will
|
|
103
|
+
eventually be sold. And when someone leaves, nothing expires: there is nothing to revoke.
|
|
104
|
+
- **The official fixes want you to become an operator.** Run a Vault server, or create and manage
|
|
105
|
+
a cloud account just to have somewhere to put five secrets: a subscription, IAM wiring, an SDK
|
|
106
|
+
in your app, and a provider sitting between you and your own credentials.
|
|
107
|
+
|
|
108
|
+
notenv removes the file instead of guarding it. Secrets are encrypted on your machine, live as
|
|
109
|
+
ciphertext in a local vault or on storage you already own, and exist in plaintext only inside the
|
|
110
|
+
environment of the process you run, for as long as it runs. Storage means **anything
|
|
111
|
+
[rclone](https://rclone.org) speaks**: Backblaze B2, S3, Google Drive, Dropbox, SFTP, WebDAV,
|
|
112
|
+
dozens more. Your vault can live on the NAS under your desk, and nobody can stop you from keeping
|
|
113
|
+
it on the SFTP server in your smart fridge. There is nothing to operate and nobody else to trust:
|
|
114
|
+
you hold the key, storage holds ciphertext, and the
|
|
115
|
+
[threat model](https://dvgils.github.io/notenv/security/threat-model/) says precisely what that
|
|
116
|
+
does and does not protect.
|
|
117
|
+
|
|
118
|
+
Reach for it when:
|
|
119
|
+
|
|
120
|
+
- **you're one developer who wants to do this right**, without standing up an account at a cloud
|
|
121
|
+
provider and managing it forever just to have a key vault: `notenv setup` is one passphrase,
|
|
122
|
+
zero accounts, and you're done;
|
|
123
|
+
- **a coding agent works in your repository**, and "the agent can run the app without ever seeing
|
|
124
|
+
the database password" should be a property, not a hope;
|
|
125
|
+
- **a teammate needs in**: onboarding is one command and a string over chat, their first use
|
|
126
|
+
replaces it with a credential only they know, and offboarding re-encrypts everything, so leaving
|
|
127
|
+
actually revokes;
|
|
128
|
+
- **CI needs thirty secrets**, and the CI secret store should hold one;
|
|
129
|
+
- **a laptop dies**, and the recovery plan should be "the passphrase in my password manager", not
|
|
130
|
+
"which machine had the newest .env".
|
|
131
|
+
|
|
132
|
+
And honestly, when not: notenv is not a platform. There is no web console, no SSO, and access is
|
|
133
|
+
scoped per vault rather than per secret: everyone in a vault can read that vault, and you scope by
|
|
134
|
+
making vaults (one per project or per environment is one `setup` away). If your organization has a
|
|
135
|
+
platform team running Vault, keep Vault.
|
|
136
|
+
|
|
137
|
+
### How it compares
|
|
138
|
+
|
|
139
|
+
For readers who know the space: [SOPS](https://getsops.io) + age nail client-side encryption and
|
|
140
|
+
process injection but leave storage and onboarding to you; [Teller](https://github.com/tellerops/teller)
|
|
141
|
+
brokers cloud secret managers, where the provider holds your secrets. notenv is client-side
|
|
142
|
+
encryption with the storage and the onboarding built in, and no provider in the loop.
|
|
143
|
+
|
|
144
|
+
| | notenv | teller | SOPS + age (DIY) |
|
|
145
|
+
|---|---|---|---|
|
|
146
|
+
| Plaintext on disk | never | never | never |
|
|
147
|
+
| You hold the key | yes | no (provider does) | yes |
|
|
148
|
+
| Storage backends | local vault or any rclone remote | per-provider code | you wire it up |
|
|
149
|
+
| Infrastructure to run | none | none (uses your cloud) | none |
|
|
150
|
+
| One-command onboarding | yes | partial | no |
|
|
151
|
+
|
|
152
|
+
## How it works
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
notenv run -- cmd
|
|
156
|
+
|
|
|
157
|
+
|-- fetch ciphertext <- rclone <- your B2 / S3 / Drive / ...
|
|
158
|
+
|-- unlock the master key (from your passphrase; cached after first use)
|
|
159
|
+
|-- decrypt secrets in memory
|
|
160
|
+
|-- build the child environment from notenv.toml
|
|
161
|
+
|-- exec cmd, stream its I/O, exit with its code
|
|
162
|
+
nothing written to disk
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Secrets are encrypted with a random **master key** that never exists in plaintext at rest: a small
|
|
166
|
+
header object holds it wrapped under one or more **key slots** (a person's passphrase, or a
|
|
167
|
+
machine's age public key), the same approach LUKS and restic use. The header is authenticated and version-pinned,
|
|
168
|
+
so a party that can write your storage but holds no key cannot tamper with it or roll it back
|
|
169
|
+
undetected. Full detail in
|
|
170
|
+
[Concepts](https://dvgils.github.io/notenv/concepts/how-it-works/).
|
|
171
|
+
|
|
172
|
+
## For AI agents
|
|
173
|
+
|
|
174
|
+
A `.env` on disk eventually enters a coding agent's context. notenv removes the file and gives the
|
|
175
|
+
agent a verb that separates *using* a credential from *knowing* it:
|
|
176
|
+
|
|
177
|
+
- `notenv run -- cmd` injects secrets into the child only; the value never appears in what the model
|
|
178
|
+
reads, and captured output is masked.
|
|
179
|
+
- `notenv list` tells the agent which secrets exist and what they are for, never their values.
|
|
180
|
+
|
|
181
|
+
There is also an MCP server (`notenv mcp`) and an installable agent skill (`skills/notenv/`). See the
|
|
182
|
+
[AI agents guide](https://dvgils.github.io/notenv/guides/ai-agents/) for the full surface and its
|
|
183
|
+
honest limits.
|
|
184
|
+
|
|
185
|
+
## Security
|
|
186
|
+
|
|
187
|
+
At rest, anywhere, only age ciphertext exists; it is useless without your key, which lives in your
|
|
188
|
+
password manager, not on the storage backend. The
|
|
189
|
+
[threat model](https://dvgils.github.io/notenv/security/threat-model/) covers what notenv defends,
|
|
190
|
+
against whom, and the explicit non-goals. To report a vulnerability, see [SECURITY.md](./SECURITY.md).
|
|
191
|
+
|
|
192
|
+
## Building from source
|
|
193
|
+
|
|
194
|
+
```sh
|
|
195
|
+
git clone https://github.com/DvGils/notenv
|
|
196
|
+
cd notenv
|
|
197
|
+
make build # compile ./notenv
|
|
198
|
+
make test # run the test suite
|
|
199
|
+
make install # install into $(go env GOPATH)/bin
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Releases are produced with [GoReleaser](https://goreleaser.com); `make snapshot` builds the full set
|
|
203
|
+
of release artifacts locally without publishing.
|
|
204
|
+
|
|
205
|
+
## Status
|
|
206
|
+
|
|
207
|
+
Actively developed and being tested. See the
|
|
208
|
+
[roadmap](https://dvgils.github.io/notenv/project/roadmap/) for what works today, what is planned,
|
|
209
|
+
and the non-goals.
|
|
210
|
+
|
|
211
|
+
## License
|
|
212
|
+
|
|
213
|
+
[Apache-2.0](./LICENSE).
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
notenv-0.15.1.data/scripts/notenv.exe,sha256=UpaF0L8cJE8kIuztCn6Z-dgpgZBmSgTxJ_FWVi3dvcU,5979648
|
|
2
|
+
notenv-0.15.1.dist-info/METADATA,sha256=K-O_k1587fYbrM3e2gRWT2dsPV3JHzOwYUSPcNY0EeE,10682
|
|
3
|
+
notenv-0.15.1.dist-info/WHEEL,sha256=1-MColF5g1taWUvGy0FVWv86Qp8198QQ_ElQdpT5d2A,106
|
|
4
|
+
notenv-0.15.1.dist-info/RECORD,,
|