ainv
ainv combines AI and environment. It is an agent-first credential delivery
layer: agents select opaque references; intended processes receive credential
values.
Give AI agents the environment they need, not the secrets behind it.
This describes the intended normal workflow, not an enforcement guarantee against malicious agents, repositories, dependencies, or child processes.
It is a small, provider-neutral CLI for humans and shell-capable coding agents that need to:
- add credentials to an existing provider through hidden human input;
- search credential stores using non-sensitive metadata;
- write a selected credential directly into an environment file; and
- inject selected credentials into one child process.
ainv is not a secret manager, vault, daemon, cloud service, or MCP server.
Credential providers remain the source of truth. Its main benefit is context
hygiene: resolved values stay out of routine model context, shell arguments, and
ainv's normal output, but child output can still expose them.
[!IMPORTANT] This project is an early development preview. The current release supports non-synchronizable generic passwords in the default macOS Keychain only.
The proposed product and security contract is documented in SPEC.md.
Installation
[!WARNING] Version 0.1.1 is a pre-alpha evaluation release. In the current
uv tooldistribution, macOS Keychain trusts the uv-managed Python interpreter, not theainvcommand. Do not treat it as a stable, least-privilege identity for unattended high-value credentials. See SECURITY.md before choosing Keychain approval.
Install the published package with:
uv tool install ainv
For development from a local checkout:
uv tool install .
Usage
Add a native Keychain credential through one hidden input prompt:
ainv add OPENAI_API_KEY --provider keychain --account personal
--label is optional. Existing credentials are never overwritten. A human may
paste a newly issued credential from a browser into the hidden prompt. Agents
must never read, inspect, or manipulate the clipboard. On success, the full
opaque reference is labeled Reference (non-secret identifier) so it is not
mistaken for a credential value.
Search Keychain metadata without retrieving secret values:
ainv find openai
ainv find openai --json
The human-readable table abbreviates long references for readability. Use
--json when you need the complete opaque reference for another command.
Use the complete opaque reference returned by find --json to set one dotenv
entry:
ainv set 'keychain://v1/item/REFERENCE' --as OPENAI_API_KEY --file .env
Or inject it into one child process without touching disk:
ainv run 'OPENAI_API_KEY=keychain://v1/item/REFERENCE' -- command
set refuses tracked or non-ignored Git destinations unless explicitly
overridden. Run ainv <command> --help for all options.
[!WARNING]
ainv runkeeps resolved values out of its normal arguments and output, but it gives them to the selected process. That process, its descendants, dependencies, crash reporters, telemetry, and anything it invokes can read, retain, transmit, or expose them. Use it only for an intended, trusted consumer and avoid debug or environment-dumping modes. This is guidance, not an enforcement boundary:ainvdoes not make untrusted agents, repositories, dependencies, or commands safe.
The command surface will not include a generic operation that prints a resolved secret.
References and cleanup
A Keychain reference is an opaque local locator, not portable project configuration or a unique identifier for one immutable credential incarnation. It may become stale after identity metadata changes or deletion. If it no longer resolves, search again rather than reconstructing it from metadata.
For private dogfood, remove an ainv-created Keychain item manually in Keychain
Access by its service, account, and label. Remove a materialized dotenv entry
manually without asking an agent to read the file. If a credential is exposed,
revoke or rotate it with its remote issuer first. Removing the local Keychain
item does not revoke it remotely.
Agent skill
The repository includes an optional agent skill at
skills/ainv. Install it
into the canonical shared skills directory with:
mkdir -p ~/.agents/skills
ditto skills/ainv ~/.agents/skills/ainv
Claude Code additionally needs a discovery symlink:
ln -s ~/.agents/skills/ainv ~/.claude/skills/ainv
Development
Requires Python 3.13 and uv.
uv sync
uv run pytest
uv run ruff check .
uv run ruff format --check .
Security model
ainv reduces accidental credential exposure by keeping resolved values out of
its normal arguments and output. Once a secret is written to a file or injected
into a child process, it can be read, retained, printed, transmitted, or exposed
by that process, its descendants, dependencies, crash reporters, telemetry, or
anything it invokes. Child stdout and stderr pass through unchanged. ainv
does not make untrusted agents, repositories, dependencies, or commands safe.
License
No license has been granted yet. The published pre-alpha package is available for evaluation, but permission to copy, modify, or redistribute it has not been granted.
Metadata
Release files for ainv 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ainv-0.1.1.tar.gz | 19.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ainv-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 42.7 kB
Release files / ainv-0.1.1.tar.gz
| Download URL | ainv-0.1.1.tar.gz |
|---|---|
| Size | 19.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
35b7f0304293d623ae8edda4836beea09d29ffb78bf7258efad8355e1c4b97a9
|
|
BLAKE2b-256 checksum How to use checksums |
c749b0b45579880142e970a8c998e0c9431c29d42c3e375c549eff9cc4da06f5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / ainv-0.1.1-py3-none-any.whl
| Download URL | ainv-0.1.1-py3-none-any.whl |
|---|---|
| Size | 23.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6a706f0642f7fc0f0eb3ca51e25691e92c40059e867535ac53059886ffcacea3
|
|
BLAKE2b-256 checksum How to use checksums |
61ab380a9a9e9fcae0d36c8ebe4318cef3dd280e5e21e6f3601d863cb0b84462
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|