
envsec v1.0.0-rc.2
Безопасный CLI-инструмент для управления секретами окружения с использованием встроенных хранилищ учетных данных ОС (связка ключей macOS, Linux Secret Service, диспетчер учетных данных Windows)
envsec
Безопасное управление секретами окружения с использованием встроенных хранилищ учетных данных ОС.
Демо

Возможности
- Хранение секретов во встроенном хранилище учетных данных ОС (не в текстовых файлах)
- Кроссплатформенность: macOS, Linux, Windows
- Организация секретов по контекстам (например,
myapp.dev,stripe-api.prod,work.staging) - Отслеживание метаданных секретов (имена ключей, временные метки) через SQLite
- Поиск контекстов и секретов с помощью glob-шаблонов
- Запуск команд с подстановкой секретов
- Сохранение и повторный запуск команд с помощью
cmd(поиск, список, запуск, удаление) - Экспорт секретов в файлы
.env(с отслеживанием поколений черезaudit) - Экспорт секретов как переменных окружения оболочки (
eval $(envsec env)) - Загрузка секретов из файлов
.env(с обнаружением конфликтов) - Обмен секретами, зашифрованными с помощью GPG, для членов команды
- Интерактивный терминальный интерфейс (
envsec tui) для управления секретами без запоминания команд
Пакеты
Это монорепозиторий, содержащий следующие пакеты:
| Пакет | Описание | npm |
|---|---|---|
envsec | CLI-инструмент для управления секретами | |
@envsec/sdk | SDK для Node.js / Bun для программной загрузки секретов | |
@envsec/core | Основной движок — адаптеры хранилищ учетных данных ОС + база метаданных | |
@envsec/tui | Интерактивный терминальный интерфейс для управления секретами |
Быстрый старт SDK
Для программного доступа к секретам из Node.js или Bun используйте @envsec/sdk:```bash
npm install @envsec/sdk
I'm ready to translate the Kitploit tool content from English to Russian. Please provide chunk 3 of 85.```typescript
import { loadSecrets } from "@envsec/sdk";
// Load and inject into process.env
await loadSecrets({ context: "myapp.dev", inject: true });
// Or use the client for full control
import { EnvsecClient } from "@envsec/sdk";
const client = await EnvsecClient.create({ context: "myapp.dev" });
const apiKey = await client.get("api.key");
await client.close();
См. полную документацию SDK для всех API, поддержки нескольких контекстов и параметров.
Требования
- Node.js >= 22
macOS
Никаких дополнительных зависимостей. Использует встроенную связку ключей Keychain через инструмент командной строки security.
Linux
Требуется libsecret-tools (предоставляет команду secret-tool), которая взаимодействует с GNOME Keyring, KDE Wallet или любым поставщиком Secret Service API через D-Bus.```bash
Debian / Ubuntu
sudo apt install libsecret-tools
Fedora
sudo dnf install libsecret
Arch
sudo pacman -S libsecret
Для работы требуется активная D-Bus-сессия и демон хранилища ключей (например, `gnome-keyring-daemon`). Большинство сред рабочего стола обрабатывают это автоматически.
### Windows
Дополнительных зависимостей нет. Используется встроенный диспетчер учётных данных Windows через `cmdkey` и PowerShell.
## Установка
### Homebrew (macOS / Linux)```bash
brew tap davidnussio/homebrew-tap
brew install envsec
npm```bash
npm install -g envsec
### npx (без установки)```bash
npx envsec
mise```bash
mise use -g npm:envsec
## Использование
Большинство команд требуют указания контекста с помощью `--context` (или `-c`).
Контекст — это произвольная метка для группировки секретов, например `myapp.dev`, `stripe-api.prod`, `work.staging`.
### Глобальные параметры
Эти параметры доступны для всех команд:
- `--context`, `-c` — Имя контекста (например, `myapp.dev`, `stripe-api.prod`). Также считывается из переменной окружения `ENVSEC_CONTEXT`
- `--debug`, `-d` — Включить отладочное логирование
- `--json` — Вывод в формате JSON для скриптов
- `--db` — Путь к файлу базы данных SQLite (по умолчанию: `~/.envsec/store.sqlite`). Также считывается из переменной окружения `ENVSEC_DB`
### Пользовательский путь к базе данных
По умолчанию метаданные хранятся в `~/.envsec/store.sqlite`. Вы можете переопределить это с помощью `--db` или переменной окружения `ENVSEC_DB`:```bash
# Use a project-local database
envsec --db ./local-store.sqlite -c myapp.dev list
# Or via environment variable
export ENVSEC_DB=/shared/team/envsec.sqlite
envsec -c myapp.dev list
Флаг --db имеет приоритет над ENVSEC_DB. Варианты использования включают базы данных для отдельных проектов, общие базы данных команды на сетевых дисках, а также CI/CD с эфемерным хранилищем.
Добавить секрет
Сохраните секрет в хранилище учётных данных ОС.
<key>— имя ключа секрета (например,api.key,db.password)--value,-v— значение для сохранения (опустите для интерактивного маскированного запроса)--expires,-e— срок действия (например,30m,2h,7d,4w,3mo,1y)```bash
Store a value inline
envsec -c myapp.dev add api.key --value "sk-abc123"
Or use the short alias
envsec -c myapp.dev add api.key -v "sk-abc123"
Omit --value for an interactive masked prompt
envsec -c myapp.dev add api.key
Set an expiry duration with --expires (-e)
envsec -c myapp.dev add api.key -v "sk-abc123" --expires 30d
Supported duration units: m (minutes), h (hours), d (days), w (weeks), mo (months), y (years)
Combinable: 1y6mo, 2w3d, 1d12h
envsec -c myapp.dev add api.key -v "sk-abc123" -e 6mo
### Получить секрет
Извлеките значение секрета из хранилища учетных данных ОС.
- `<key>` — имя ключа секрета для извлечения
- `--quiet`, `-q` — выводить только исходное значение (без предупреждений и дополнительного вывода)
- `--json` — вывод в формате JSON (включает context, key, value, expires_at)```bash
envsec -c myapp.dev get api.key
# Print only the raw value (no warnings or extra output)
envsec -c myapp.dev get api.key --quiet
envsec -c myapp.dev get api.key -q
Удаление секрета
Удаляет секрет из хранилища учётных данных ОС.
<key>— имя ключа секрета для удаления (необязательно, если используется--all)--yes,-y— пропустить запрос подтверждения--all— удалить все секреты в контексте```bash envsec -c myapp.dev delete api.key
or use the alias
envsec -c myapp.dev del api.key
### Переименование секрета
Переименуйте ключ секрета в том же контексте. Значение и метаданные срока действия сохраняются.
- `<old-key>` — Текущее имя ключа секрета
- `<new-key>` — Новое имя ключа секрета
- `--force`, `-f` — Перезаписать целевой ключ, если он уже существует```bash
# Rename a key
envsec -c myapp.dev rename old.key new.key
# Overwrite target if it already exists
envsec -c myapp.dev rename old.key existing.key --force
Вывод всех секретов в контексте
Выводит все ключи секретов и метаданные в контексте.
--json— вывод в формате JSON```bash envsec -c myapp.dev list
### Список всех контекстов
Выводит список всех доступных контекстов с количеством секретов.
- `--json` — вывод в формате JSON```bash
# Without --context, lists all available contexts with secret counts
envsec list
Поиск секретов
Поиск секретов или контекстов с использованием glob-шаблонов.
<pattern>— Glob-шаблон для поиска (например,api.*,myapp.*)--json— Вывод в формате JSON```bash
Search secrets within a context
envsec -c myapp.dev search "api.*"
Search contexts by pattern (without --context)
envsec search "myapp.*"
### Перемещение секретов между контекстами
Перемещает секреты из одного контекста в другой. Исходные секреты удаляются после перемещения.
- `<pattern>` — glob-шаблон или точный ключ для перемещения (необязательно, если используется `--all`)
- `--to`, `-t` — целевой контекст, в который перемещаются секреты
- `--all` — переместить все секреты из исходного контекста
- `--force`, `-f` — перезаписать существующие секреты в целевом контексте
- `--yes`, `-y` — пропустить запрос подтверждения```bash
# Move a single secret
envsec -c myapp.dev move api.token --to myapp.prod
# Move secrets matching a glob pattern
envsec -c myapp.dev move "redis.*" --to myapp.prod -y
# Move all secrets from one context to another
envsec -c myapp.dev move --all --to myapp.prod -y
# Overwrite existing secrets in the target context
envsec -c myapp.dev move "redis.*" --to myapp.prod --force -y
Копирование секретов между контекстами
Копирует секреты из одного контекста в другой. Исходные секреты остаются нетронутыми.
<pattern>— Glob-шаблон или точный ключ для копирования (необязательно, если используется--all)--to,-t— Целевой контекст для копирования секретов--all— Копировать все секреты из исходного контекста--force,-f— Перезаписать существующие секреты в целевом контексте--yes,-y— Пропустить запрос подтверждения```bash
Copy a single secret
envsec -c myapp.dev copy api.token --to myapp.staging
Copy secrets matching a glob pattern
envsec -c myapp.dev copy "redis.*" --to myapp.staging -y
Copy all secrets from one context to another
envsec -c myapp.dev copy --all --to myapp.staging -y
Overwrite existing secrets in the target context
envsec -c myapp.dev copy "redis.*" --to myapp.staging --force -y
### Выполнить команду с секретами
Выполните команду с подстановкой секретных значений через плейсхолдеры или внедрением их в качестве переменных окружения.
- `<command>` — Команда для выполнения. Используйте плейсхолдеры `{key}` для подстановки секретов
- `--inject`, `-i` — Внедрить все секреты контекста как переменные окружения (`KEY.NAME` → `KEY_NAME`)
- `--save`, `-s` — Сохранить эту команду для последующего использования
- `--name`, `-n` — Имя для сохранённой команды (запрашивается интерактивно, если опущено с `--save`)```bash
# Placeholders {key} are resolved with secret values before execution
envsec -c myapp.dev run 'curl {api.url} -H "Authorization: Bearer {api.token}"'
# Any {dotted.key} in the command string is replaced with its value
envsec -c myapp.prod run 'psql {db.connection_string}'
# Inject ALL context secrets as environment variables (KEY.NAME → KEY_NAME)
envsec -c myapp.dev run --inject 'node server.js'
envsec -c myapp.dev run -i 'docker compose up'
# Combine --inject with placeholders
envsec -c myapp.dev run --inject 'curl {api.url} -H "Authorization: Bearer $API_TOKEN"'
# Save the command for later use with --save (-s) and --name (-n)
envsec -c myapp.dev run --save --name deploy 'kubectl apply -f - <<< {k8s.manifest}'
# If you use --save without --name, you'll be prompted interactively
envsec -c myapp.dev run --save 'psql {db.connection_string}'
Если какой-либо плейсхолдер ссылается на секрет, которого не существует, команда не выполнится, и вы увидите понятную ошибку:``` ❌ Missing secrets in context "myapp.dev":
- api.url
- api.token
Add them with: envsec -c myapp.dev add
### Сохранённые команды
Сохранённые команды находятся в подкоманде `cmd`, что позволяет держать их отдельно от операций с секретами.
#### cmd list
Вывести список всех сохранённых команд.```bash
envsec cmd list
cmd run
Запуск сохранённой команды (используется контекст, с которым она была сохранена).
<name>— имя сохранённой команды для выполнения--override-context,-o— переопределить сохранённый контекст во время выполнения--quiet,-q— подавить информационный вывод (выводить только результат команды)--inject,-i— внедрить все секреты контекста как переменные окружения```bash envsec cmd run deploy
Run quietly (suppress informational output like "Resolved N secret(s)")
envsec cmd run deploy --quiet envsec cmd run deploy -q
Override the context at execution time
envsec cmd run deploy --override-context myapp.prod envsec cmd run deploy -o myapp.prod
Inject all context secrets as env vars when running a saved command
envsec cmd run deploy --inject envsec cmd run deploy -i
#### cmd search
Поиск сохранённых команд по имени или строке команды.
- `<pattern>` — шаблон поиска
- `--name`, `-n` — поиск только по именам команд
- `--command`, `-m` — поиск только по строкам команд```bash
envsec cmd search psql
# Search only by name
envsec cmd search deploy -n
# Search only by command string
envsec cmd search kubectl -m
cmd delete
Удаляет сохранённую команду.
<name>— имя команды для удаления```bash envsec cmd delete deploy
### Создание файла .env
Экспортируйте все секреты из контекста в файл `.env`.
- `--output`, `-o` — путь к выходному файлу (по умолчанию: `.env`)```bash
# Creates .env with all secrets from the context
envsec -c myapp.dev env-file
# Specify a custom output path
envsec -c myapp.dev env-file --output .env.local
Ключи преобразуются в UPPER_SNAKE_CASE (например, api.token → API_TOKEN).
Экспорт секретов как переменных окружения
Вывод операторов export для использования с eval или подключением в shell.
--shell,-s— Синтаксис целевой оболочки:bash(по умолчанию),zsh,fish,powershell--unset,-u— Вывод команд unset/remove вместо export```bash
Output export statements for eval (bash/zsh)
eval $(envsec -c myapp.dev env)
Specify target shell syntax
envsec -c myapp.dev env --shell fish envsec -c myapp.dev env --shell powershell
Output unset commands to clean up exported variables
eval $(envsec -c myapp.dev env --unset)
Combine shell and unset
envsec -c myapp.dev env --unset --shell fish
Поддерживаемые оболочки: `bash` (по умолчанию), `zsh`, `fish`, `powershell`. Ключи преобразуются в `UPPER_SNAKE_CASE` (например, `api.token` → `API_TOKEN`). Вывод идёт в stdout, поэтому его можно передать в `eval` или подключить напрямую — файл на диск не записывается.
### Запуск сеанса оболочки с ограниченным доступом к секретам
Запускает интерактивную подоболочку со всеми секретами из контекста, внедрёнными в качестве
переменных окружения. Когда вы выходите (`exit`), секреты исчезают — очистка не требуется.
- `--shell`, `-s` — Оболочка для запуска (`bash`, `zsh`, `fish`, `powershell`). По умолчанию: автоопределение
- `--no-inherit` — Не наследовать переменные окружения родительского процесса
- `--quiet`, `-q` — Подавить баннер запуска/выхода```bash
envsec -c myapp.dev shell
Features
- Automated Reconnaissance: Automatically gathers subdomains, URLs, and other assets from multiple sources.
- Vulnerability Scanning: Integrates with popular vulnerability scanners to identify potential security issues.
- Customizable Workflows: Allows users to define custom workflows and integrate with their existing tools.
- Reporting: Generates detailed reports in various formats, including HTML, PDF, and JSON.
- Collaboration: Supports team collaboration with shared projects and results.
- Extensibility: Plugin-based architecture allows for easy extension and customization.
Installation
To install reconftw, you can use the following command:
git clone https://github.com/six2dez/reconftw.git
cd reconftw
./install.sh
Usage
To run a basic reconnaissance scan, use the following command:
./reconftw.sh -d example.com
For more advanced usage, refer to the documentation.
License
This project is licensed under the MIT License - see the LICENSE file for details.``` ▶ envsec shell — context: myapp.dev (8 secrets loaded) Type 'exit' or press Ctrl+D to leave the session.
(envsec:myapp.dev) ~ $ echo $DATABASE_URL postgres://user:pass@localhost/mydb
(envsec:myapp.dev) ~ $ exit → Exiting envsec shell — secrets cleared.
🛡️ Возможности
- Обнаружение уязвимостей: Сканирует веб-приложения на наличие распространённых уязвимостей, таких как SQL-инъекции, межсайтовый скриптинг (XSS) и небезопасные конфигурации.
- Автоматизация: Автоматизирует повторяющиеся задачи безопасности, экономя время и снижая риск человеческой ошибки.
- Отчёты: Генерирует подробные отчёты о найденных уязвимостях, включая рекомендации по их устранению.
- Интеграция: Легко интегрируется в существующие конвейеры CI/CD для непрерывного мониторинга безопасности.
- Настраиваемость: Позволяет настраивать параметры сканирования в соответствии с конкретными потребностями вашей организации.
🚀 Быстрый старт
Чтобы начать работу с инструментом, выполните следующие шаги:
- Установка: Установите инструмент с помощью менеджера пакетов или клонируйте репозиторий.
- Конфигурация: Настройте файл конфигурации в соответствии с вашей средой.
- Запуск: Запустите сканирование с помощью предоставленных команд.
- Анализ: Просмотрите сгенерированные отчёты и примите меры по устранению обнаруженных проблем.
📚 Документация
Подробная документация доступна в официальной документации. Она включает в себя:
- Руководство по установке
- Справочник по API
- Примеры использования
- Часто задаваемые вопросы (FAQ)
🤝 Вклад
Мы приветствуем вклад сообщества! Если вы хотите внести свой вклад, пожалуйста, следуйте нашим правилам внесения вклада.
📄 Лицензия
Этот проект распространяется под лицензией MIT. Подробности см. в файле LICENSE.
📬 Контакты
Если у вас есть вопросы или предложения, свяжитесь с нами по адресу [email protected].
Отказ от ответственности: Этот инструмент предназначен только для образовательных целей и тестирования безопасности в авторизованных средах. Используйте его ответственно и в соответствии с действующим законодательством.
# Force a specific shell
envsec -c myapp.dev shell --shell zsh
# Only envsec secrets in env (no parent variables, except PATH)
envsec -c myapp.dev shell --no-inherit
# Suppress the startup/exit banner
envsec -c myapp.dev shell --quiet
```
Переменная `ENVSEC_CONTEXT` всегда устанавливается внутри сеанса, поэтому вы можете
ссылаться на неё в скриптах или настройках приглашения.
### Загрузка секретов из файла .env
Импорт секретов из файла `.env` в контекст.
- `--input`, `-i` — путь к входному файлу `.env` (по умолчанию: `.env`)
- `--force`, `-f` — перезапись существующих секретов без запроса
- `--batch`, `-b` — пакетный режим: отложить сохранение в базе данных до импорта всех секретов```bash
# Import secrets from .env into the context
envsec -c myapp.dev load
# Specify a custom input file
envsec -c myapp.dev load --input .env.local
# Overwrite existing secrets without warning
envsec -c myapp.dev load --force
```
Ключи преобразуются из `UPPER_SNAKE_CASE` в `dotted.lowercase` (например, `API_TOKEN` → `api.token`). Если ключ уже существует, он пропускается с предупреждением, если не указан `--force` (`-f`).
### Обмен секретами (GPG-шифрование)
Зашифруйте все секреты из контекста для члена команды с помощью GPG.
- `--encrypt-to` — ключ получателя GPG (email, ID ключа или отпечаток) для шифрования
- `--output`, `-o` — путь к выходному файлу (по умолчанию: stdout). Используйте `-` для явного указания stdout
- `--json` — использовать формат JSON внутри зашифрованных данных (по умолчанию: формат `.env`)```bash
# Encrypt all secrets from a context for a team member
envsec -c myapp.dev share --encrypt-to [email protected]
# Save encrypted output to a file
envsec -c myapp.dev share --encrypt-to [email protected] -o secrets.enc
# Use JSON format inside the encrypted payload
envsec -c myapp.dev --json share --encrypt-to [email protected] -o secrets.enc
```
Получатель может расшифровать с помощью `gpg --decrypt secrets.enc` и передать результат в `envsec load`. По умолчанию зашифрованная полезная нагрузка использует формат `.env` (`KEY="value"`); с `--json` используется структурированный JSON-объект. Требуется установленный GPG и публичный ключ получателя в вашей связке ключей.
### Проверка секретов на истечение срока
Проверка на истёкшие или истекающие секреты и отслеживаемые экспорты файлов `.env`.
- `--within`, `-w` — Показать секреты, истекающие в течение этого периода (по умолчанию: `30d`). Используйте `0d`, чтобы показать только уже истёкшие
- `--json` — Вывод в формате JSON```bash
# Check for expired or expiring secrets in a context (default window: 30 days)
envsec -c myapp.dev audit
# Specify a custom window
envsec -c myapp.dev audit --within 7d
# Show only already-expired secrets
envsec -c myapp.dev audit --within 0d
# Audit across all contexts (omit --context)
envsec audit
# JSON output
envsec -c myapp.dev audit --json
```
Секреты с установленной длительностью `--expires` через `envsec add` отслеживаются в метаданных. Команда `audit` сканирует секреты, которые уже истекли или истекут в пределах указанного окна. Команды `get` и `list` также выводят предупреждения об истечении срока действия встроенно.
Команда `audit` также отслеживает сгенерированные файлы `.env`. Каждый раз при использовании `env-file` записываются путь вывода, контекст и временная метка. Вывод аудита включает второй раздел со списком этих файлов. Если отслеживаемый файл `.env` больше не существует на диске, audit автоматически удаляет его из метаданных и сообщает об очистке.
### Сгенерировать случайный секрет
Сгенерируйте криптографически безопасный случайный секрет, при необходимости сохраняя его.
- `<key>` — Имя ключа секрета (необязательно; опустите для автономной генерации пароля)
- `--length`, `-l` — Длина сгенерированного секрета (по умолчанию: `32`)
- `--prefix`, `-p` — Префикс для добавления к сгенерированному секрету (например, `sk_`)
- `--expires`, `-e` — Длительность истечения срока действия (например, `30m`, `2h`, `7d`, `4w`, `3mo`, `1y`)
- `--alphanumeric`, `-a` — Использовать только буквенно-цифровые символы `[a-zA-Z0-9]` (по умолчанию)
- `--special`, `-s` — Включить распространённые специальные символы `[a-zA-Z0-9!@#$%^&*]`
- `--all-chars`, `-A` — Использовать все печатные ASCII-символы для максимальной энтропии```bash
# Generate and store a 32-char alphanumeric secret
envsec -c myapp.dev secret api.key
# Custom length and prefix
envsec -c myapp.dev secret api.key --prefix "sk_" --length 48
# Character sets:
# --alphanumeric (-a) [a-zA-Z0-9] (default)
# --special (-s) [a-zA-Z0-9] + !@#$%^&*
# --all-chars (-A) all printable ASCII
envsec -c myapp.dev secret db.password --special --length 64
# With expiry
envsec -c myapp.dev secret api.key --prefix "sk_" -l 48 --expires 90d
# Standalone password generator (no store, just print)
envsec secret --length 32
envsec secret --special --length 64 --prefix "pk_"
```
Когда указаны и контекст, и ключ, сгенерированное значение сохраняется и выводится на печать. Без них исходное значение отправляется в stdout — удобно для передачи в `pbcopy`, `xclip` или другие инструменты.
### Интерактивный TUI
envsec включает полноэкранный терминальный интерфейс для интерактивного управления секретами — не нужно запоминать команды.```bash
# Launch the TUI
envsec tui
# Launch with a pre-selected context
envsec -c myapp.dev tui
```
TUI предоставляет восемь экранов, доступных из главного меню:
- **Contexts** — просмотр всех контекстов, установка активного контекста с помощью `s`, очистка контекста с помощью `x`, просмотр количества секретов, удаление целых контекстов
- **Secrets** — список секретов в таблице, раскрытие значений, добавление или удаление секретов
- **Add Secret** — интерактивная форма с маскированным вводом и необязательной длительностью действия
- **Search** — поиск по glob-шаблону среди секретов или контекстов
- **Saved Commands** — список, просмотр и удаление сохранённых шаблонов команд
- **Audit** — проверка на истёкшие/истекающие секреты, просмотр отслеживаемых экспортов файлов `.env`
- **Import .env** — загрузка секретов из файла `.env` в текущий контекст
- **Export .env** — экспорт секретов в файл `.env` (отслеживается для аудита)
Сочетания клавиш:
| Клавиша | Действие |
|-----|--------|
| `↑` / `↓` | Навигация по пунктам меню и строкам таблицы |
| `Enter` | Выбрать / подтвердить |
| `c` | Открыть представление контекстов (главное меню) |
| `s` | Установить выбранный элемент как активный контекст (представление контекстов) |
| `x` | Очистить активный контекст (представление контекстов) |
| `a` | Добавить новый секрет (представление секретов) |
| `d` | Удалить выбранный элемент |
| `r` | Раскрыть значение секрета (представление деталей) |
| `Esc` | Назад / отмена |
| `q` | Выйти из TUI |
### Диагностика вашей настройки
Запустите проверки работоспособности, чтобы убедиться в корректности установки envsec.
- `--json` — вывод в формате JSON для использования в скриптах```bash
# Run all health checks
envsec doctor
# JSON output for scripting
envsec --json doctor
```
Команда `doctor` проверяет, что ваша установка envsec работает корректно. Она проверяет:
- Поддержку платформы и версию Node.js
- Доступность хранилища учётных данных (macOS Keychain, Linux secret-tool, Windows cmdkey)
- Доступ к связке ключей на чтение и запись
- Путь к базе данных, права доступа и целостность схемы
- Потерянные секреты (метаданные без записи в связке ключей)
- Просроченные секреты
- Переменные окружения (`ENVSEC_DB`, `ENVSEC_CONTEXT`)
- Текущую оболочку
### Автодополнение в оболочке
envsec поддерживает динамическое автодополнение по клавише Tab для bash, zsh и fish. Автодополнение учитывает контекст: оно предлагает ваши фактические имена контекстов, ключи секретов и сохранённые имена команд в реальном времени, запрашивая базу данных метаданных.```bash
# Bash (add to ~/.bashrc)
eval "$(envsec --completions bash)"
# Zsh (add to ~/.zshrc)
eval "$(envsec --completions zsh)"
# Fish (add to ~/.config/fish/config.fish)
envsec --completions fish | source
```
Что заполняется динамически:
- `--context` / `-c` — выводит список всех ваших контекстов
- Аргументы секретных ключей (`get`, `add`, `delete`) — выводит ключи для текущего контекста
- `cmd run` / `cmd delete` — выводит сохранённые имена команд
- `--override-context` / `-o` — выводит контексты для `cmd run`
- Подкоманды, флаги и статические варианты (оболочки и т. д.) также заполняются
## Сравнение
Чем envsec отличается от других инструментов для управления секретами окружения?
| Возможность | envsec | dotenv / dotenvx | 1Password CLI (`op`) |
|---|---|---|---|
| Хранение секретов | Системное хранилище учётных данных ОС (Keychain, Secret Service, Credential Manager) | Файлы `.env` на диске (dotenvx добавляет шифрование) | Облачное хранилище 1Password |
| Шифрование в состоянии покоя | Делегировано ОС (Keychain, GNOME Keyring, DPAPI) | Нет (dotenv) / ECIES для каждого файла (dotenvx) | AES-256 в облаке 1Password |
| Секреты на диске | Никогда — значения попадают напрямую в системное хранилище учётных данных ОС | Всегда — файлы `.env` по умолчанию в открытом виде | Никогда локально (извлекаются во время выполнения из облака) |
| Офлайн-доступ | Полный — секреты хранятся локально в хранилище ОС | Полный — файлы хранятся локально | Требуется сеть (кэшированные элементы доступны офлайн в приложении) |
| Учётная запись / подписка | Нет — бесплатно, с открытым исходным кодом, без регистрации | Бесплатно (dotenv) / бесплатно с открытым исходным кодом (dotenvx) | Платная подписка (от ~$3/мес для частных лиц, ~$8/пользователя/мес для бизнеса) |
| Кроссплатформенность | macOS, Linux, Windows | Любая платформа с Node.js / любая среда выполнения (dotenvx) | macOS, Linux, Windows |
| Организация контекстов / окружений | Контексты (например, `myapp.dev`, `stripe.prod`) | Отдельные файлы `.env` для каждого окружения | Хранилища и элементы |
| Запуск команд с секретами | `envsec run` — подстановка плейсхолдеров + `--inject` переменных окружения | `dotenvx run -- cmd` — внедряет из зашифрованного `.env` | `op run -- cmd` — внедряет через ссылки на секреты |
| Экспорт в файл `.env` | `envsec env-file` (отслеживается для аудита) | Нативный формат — файлы `.env` являются источником истины | `op inject --out-file` |
| Импорт из файла `.env` | `envsec load` (с обнаружением конфликтов) | Н/Д — `.env` является основным хранилищем | Создание элементов вручную |
| Экспорт переменных окружения в оболочку | `eval $(envsec env)` — bash, zsh, fish, powershell | `dotenvx run` или `node -r dotenv/config` | `op run --env-file` |
| Интерактивная сессия оболочки | `envsec shell` — изолированная подоболочка с автоматической очисткой | Не встроено | Не встроено |
| Поиск секретов | Глоб-шаблоны по ключам и контекстам | Не встроено | Фильтрация `op item list --tags/--category` |
| Аудит истечения / ротации | `envsec audit` — истёкшие, истекающие, отслеживаемые файлы `.env` | Не встроено | Watchtower (в приложении, не в CLI) |
| Сохранённые команды | `envsec cmd` — сохранить, вывести список, найти, запустить, удалить | Не встроено | Не встроено |
| Перемещение / копирование секретов | `envsec move` и `envsec copy` между контекстами | Ручное копирование файлов | `op item move` между хранилищами |
| Переименование секретов | `envsec rename` (сохраняет значение и метаданные) | Ручное редактирование файла `.env` | `op item edit` |
| Обмен с GPG-шифрованием | `envsec share --encrypt-to` | Зашифрованные файлы `.env`, закоммиченные в git (dotenvx) | Встроенный обмен хранилищами, подготовка команд |
| Интерактивный TUI | `envsec tui` — полноэкранный терминальный интерфейс | Не встроено | Не встроено |
| Диагностика состояния | `envsec doctor` — проверяет платформу, связку ключей, целостность БД | Не встроено | Не встроено |
| Автодополнение в оболочке | Динамическое (контексты, ключи, команды) для bash, zsh, fish | Не встроено | Статическое дополнение для bash, zsh, fish, powershell |
| SDK / программный доступ | `@envsec/sdk` для Node.js / Bun | `require('dotenv').config()` — основной сценарий использования | SDK 1Password (Node.js, Python, Go и др.) |
| Командная / многопользовательская работа | Обмен через GPG (вручную) | Обмен на основе git с зашифрованным `.env` (dotenvx) | Встроенное управление командой, RBAC, журналы аудита |
<!-- | Интеграция CI/CD | Стандартный CLI — работает везде, где есть Node.js | `dotenvx run` в любом конвейере CI | Сервисные учётные записи, нативные интеграции CI/CD | -->
| Биометрическая аутентификация | Наследует биометрию ОС (например, разблокировка Keychain в macOS) | Нет | Отпечаток пальца / Touch ID через интеграцию с приложением |
| Отслеживание метаданных | SQLite (имена ключей, временные метки — никогда значения) | Нет | Облачная история элементов и журналы аудита |
Короче говоря: dotenv — самый простой подход (файлы на диске), 1Password CLI — самый функциональный для команд с облачной синхронизацией и RBAC, а envsec находится посередине — предлагая нативное шифрование ОС без учётных записей, без облачных зависимостей и рабочий процесс, ориентированный на разработчика, который выходит за рамки возможностей файлов `.env`.
## Как это работает
Секреты хранятся в нативном хранилище учётных данных ОС. Бэкенд выбирается автоматически на основе платформы:
| ОС | Бэкенд | Инструмент / API |
|---------|--------------------------------|-------------------------------------|
| macOS | Keychain | CLI `security` |
| Linux | Secret Service API (D-Bus) | `secret-tool` (libsecret) |
| Windows | Credential Manager | `cmdkey` + PowerShell (advapi32) |
Метаданные (имена ключей, временные метки) хранятся в базе данных SQLite по пути `~/.envsec/store.sqlite` (настраивается через `--db` или `ENVSEC_DB`). Ключи должны содержать хотя бы один разделитель-точку (например, `service.account`), что соответствует структуре служба/учётная запись в хранилище учётных данных.
## Безопасность
envsec построен на простом принципе: ваши секреты должны храниться в вашей ОС, а не в dot-файлах. Каждое проектное решение исходит из этой основы.
### Как envsec защищает ваши секреты
**Нативное шифрование ОС, ноль собственной криптографии.** Значения секретов хранятся напрямую в macOS Keychain, GNOME Keyring / KDE Wallet или Windows Credential Manager. envsec никогда не изобретает собственное шифрование — он делегирует проверенным хранилищам учётных данных, которые уже предоставляет ваша операционная система, защищённым вашим пользовательским сеансом и (в macOS) связкой ключей входа.
**Полная поддержка Unicode.** Значения секретов могут содержать любые символы Unicode, включая эмодзи и буквы с диакритикой. Значения кодируются в base64 перед сохранением в хранилище учётных данных ОС, что позволяет избежать особенностей кодирования, зависящих от платформы (например, CLI `security` в macOS кодирует не-ASCII вывод в hex). Устаревшие секреты в открытом виде читаются прозрачно для обратной совместимости.
**Секреты никогда не попадают на диск в открытом виде.** Значения идут напрямую из вашего терминала в хранилище учётных данных ОС. Они никогда не записываются в конфигурационные файлы, журналы или промежуточное хранилище.
**Никаких секретов в выводе терминала.** Команды `list` и `search` отображают только имена ключей — значения никогда не выводятся. Это защищает секреты от буферов прокрутки, записи экрана и подглядывания через плечо.
**Безопасное выполнение команд.** Команда `run` внедряет секреты как переменные окружения дочернего процесса, а не подставляет их в строку команды. Это означает, что значения секретов не появляются в выводе `ps` или истории оболочки. Если какой-либо упомянутый секрет отсутствует, команда полностью блокируется — никакого частичного выполнения с неполными учётными данными.
**Проверка ввода и предотвращение инъекций.** Имена контекстов проверяются по строгому разрешённому списку (буквенно-цифровые символы, точки, дефисы, подчёркивания) с проверками на обход пути и загрязнение прототипа. Все запросы SQLite используют подготовленные операторы с параметрами привязки, что предотвращает SQL-инъекции. Аргументы PowerShell в Windows экранируются для защиты от инъекций команд.
**Ограничительные права на файлы.** Каталог метаданных (`~/.envsec/`) создаётся с правами `0700`, а база данных SQLite — с `0600`, что ограничивает доступ только владельцем-пользователем.
### Известные ограничения и области для улучшения
Мы верим в честность относительно того, что envsec пока не покрывает. Это реальные компромиссы, а не ошибки — и их понимание помогает принимать взвешенные решения.
**Метаданные видны.** База данных SQLite по пути `~/.envsec/store.sqlite` хранит имена ключей, имена контекстов и временные метки — никогда значения секретов, но достаточно, чтобы раскрыть, *какие* секреты существуют. Сохранённые шаблоны команд (с плейсхолдерами `{key}`) также хранятся там. Если конфиденциальность метаданных для вас важна, убедитесь, что ваш домашний каталог находится на зашифрованном томе.
**Экспорт `env-file` — в открытом виде.** Команда `env-file` записывает значения секретов в файл `.env` на диске. Это по своей сути чувствительно — обращайтесь с выходным файлом соответствующим образом и никогда не коммитьте его в систему контроля версий. Считайте это удобным мостом, а не механизмом хранения.
**Выполнение в оболочке несёт неотъемлемый риск.** Команда `run` передаёт ваш шаблон команды через `/bin/sh` (или `cmd.exe` в Windows). Если сам шаблон поступает из ненадёжного источника, возможна инъекция в оболочку. Запускайте только те шаблоны команд, которые вы написали или которым доверяете.
**Нет контроля доступа между контекстами.** Любой процесс, работающий от имени вашего пользователя ОС, может прочитать все секреты во всех контекстах. envsec полагается на изоляцию пользователей на уровне ОС — он не добавляет собственный уровень авторизации между контекстами.
**Среды Linux без графического интерфейса.** В Linux envsec зависит от активного сеанса D-Bus и демона связки ключей (например, `gnome-keyring-daemon`). В контейнерах или на серверах без графического сеанса связка ключей может быть недоступна или может хранить секреты с более слабой защитой.
**Шифрование зависит от вашей ОС.** envsec не добавляет дополнительного шифрования в состоянии покоя сверх того, что предоставляет нативное хранилище учётных данных. В системах без полнодискового шифрования злоумышленник с физическим доступом потенциально может извлечь секреты из связки ключей. Мы рекомендуем включить полнодисковое шифрование (FileVault, LUKS, BitLocker) для максимальной защиты.
## Разработка
### Предварительные требования
- Node.js >= 22
- pnpm
Пакеты ядра, SDK, CLI и TUI используют Effect 4 и в настоящее время закреплены на
`4.0.0-rc.112`. Держите версии Effect и `@effect/platform-node` согласованными
во всём рабочем пространстве, пока Effect 4 остаётся в статусе кандидата на выпуск.
### Настройка```bash
git clone https://github.com/davidnussio/envsec.git
cd envsec
pnpm install
pnpm run build
```
### Структура проекта```
packages/
cli/ → envsec CLI (published as `envsec`)
sdk/ → Node.js/Bun SDK (published as `@envsec/sdk`)
core/ → Core engine, shared by CLI and SDK (published as `@envsec/core`)
tui/ → Interactive terminal UI (published as `@envsec/tui`)
apps/
website/ → Documentation website
```
### Общие команды```bash
# Build all packages
pnpm run build
# Lint and format check (all packages)
pnpm run check
# Auto-fix lint and formatting
pnpm run fix
# Run package unit and contract tests
pnpm run test:unit
# Run the CLI end-to-end suite with isolated database and credential fixtures
pnpm --filter envsec test
# Release (build + changeset publish)
pnpm run release
```
Изолированный E2E-набор никогда не обращается к нативному хранилищу учётных данных. Чтобы задействовать
реальный адаптер ОС на macOS или Linux, сначала выполните сборку и явно включите его:```bash
ENVSEC_E2E_CLI="$PWD/packages/cli/dist/main.js" \
ENVSEC_E2E_ISOLATED=0 \
pnpm --filter envsec test
```
Нативные E2E-тесты используют выделенные контексты `test.e2e*` и удаляют их после завершения.
### Запуск локально без установки
Создайте временный алиас, чтобы использовать локальную сборку так, как если бы она была установлена глобально:```bash
# Bash / Zsh
alias envsec="node $(pwd)/packages/cli/dist/main.js"
# Fish
alias envsec "node (pwd)/packages/cli/dist/main.js"
```
### Тестирование автодополнений оболочки локально
После сборки и настройки алиаса загрузите автодополнения в текущей сессии:```bash
# Bash
alias envsec="node $(pwd)/packages/cli/dist/main.js"
eval "$(envsec --completions bash)"
# Zsh
alias envsec="node $(pwd)/packages/cli/dist/main.js"
eval "$(envsec --completions zsh)"
# Fish
alias envsec "node (pwd)/packages/cli/dist/main.js"
envsec --completions fish | source
```
Затем нажмите TAB после `envsec -c `, чтобы увидеть свои контексты, или после `envsec -c myapp.dev get `, чтобы увидеть ключи секретов.
### Запуск тестов
Сквозные интеграционные тесты охватывают полный жизненный цикл CLI (add, get, list, search, env-file, load, delete, run, cmd, audit, share, completions).```bash
# Build first
pnpm run build
# macOS / Linux
bash packages/cli/test/e2e-test.sh
# Windows (PowerShell)
pwsh packages/cli/test/e2e-test.ps1
```
CI автоматически запускается при push/PR в `main` через GitHub Actions, выполняя `e2e-test.sh` на macOS и Ubuntu, и `e2e-test.ps1` на Windows.
## Лицензия
MIT