
Зашифрованное CLI-хранилище для заметок, конфигураций, ключей и файлов. Ищите, а не организуйте.
> Это НЕ менеджер паролей. НЕ приложение для заметок. И уж точно НЕ реестр таксономического происхождения аберрантных бентосных глубоководных образцов. Но первые два оно делает лучше любого из них. Шучу (не совсем).
<div align="center">
<img src="https://assets.kitploit.com/production/public/readmes/13610/534f3cc38369a739749d2f98a8e4ec4a1c5df0a0a597aff5295b8cb1e39cc08e.webp" alt="dredge-doge-vs-cheems"/>
[](https://goreportcard.com/report/github.com/DeprecatedLuar/dredge)
[](https://oosmetrics.com/repo/DeprecatedLuar/dredge-cargo)
[](https://go.dev)
<!-- [](https://codecov.io/gh/DeprecatedLuar/dredge-cargo) -->
<div align="center">
[Установка](#install) • [Быстрый старт](#quick-start) • [Возможности](#features) • [Команда link](#link) • [Команды](#commands) • [Как это работает](#how-it-works) • [Безопасность](#security) • [Зачем](#why)
</div>
</div>
<div align="center">
Ищите, не организуйте. **_Заметки, конфиги, ключи, секреты_** — за пять секунд из вашего терминала.
</div>
<div align="center">
<a href="https://github.com/DeprecatedLuar/dredge-cargo/stargazers">
<img src="https://img.shields.io/github/stars/DeprecatedLuar/dredge-cargo?style=for-the-badge&logo=github&color=1f6feb&logoColor=white&labelColor=black"/>
</a>
<a href="https://github.com/deprecatedluar/dredge-cargo/blob/main/LICENSE">
<img src="https://img.shields.io/github/license/DeprecatedLuar/dredge-cargo?style=for-the-badge&color=green&labelColor=black"/>
</a>
<a href="https://github.com/DeprecatedLuar/dredge-cargo/releases">
<img src="https://img.shields.io/github/v/release/DeprecatedLuar/dredge-cargo?style=for-the-badge&color=orange&labelColor=black"/>
</a>
</div>
---
> *"Не беспокойте меня обычным хламом."* — Рыбак
<div align="center">
<!-- демо gif -->
<img src="https://assets.kitploit.com/production/public/readmes/13610/a31d2a13bfbae4b1b41843137d86ddbc2c38b512972389761eab9dfc3ba6023d.gif" alt="dredge demo" width="800"/>
</div>
```bash
go install github.com/DeprecatedLuar/dredge-cargo/cmd/dredge@latest
```
<div align="right">
[другие варианты установки ↓](#install)
</div>
---
<h2 id="features"><img height="44" src="https://assets.kitploit.com/production/public/readmes/13610/5e6da8f5d6e3dc6eb114152fb8cc8ee944547f43aa95f2cbb4b7430fde0c08a0.webp"/> Крутые функции, которых вы ещё не видели</h2>
- **Зашифрованное хранилище** — Клонируйте репозиторий и получите абсолютно непонятную абракадабру. Вы даже не сможете понять, что находится в репозитории без пароля. (Я использовал AES-256-GCM + Argon2id)
- **Мгновенный поиск** — Я сделал собственный алгоритм нечёткого поиска, потому что я ленив и хочу получить нужную запись среди 300 других за миллисекунды, не задумываясь.
- **Храните что угодно** — заметки, скрипты, dot-файлы, изображения, zip-архивы. Если это файл и он существует, его можно сохранить в dredge.
- **Привязка живых файлов** — Отличная функция: создайте симлинк любого элемента на системный путь, чтобы читать и редактировать напрямую или через dredge. Любые изменения синхронизируются в обе стороны с репозиторием.
- **Поддержка Git** — приватный репозиторий, который принадлежит вам. Просто `git clone` его — и ваши данные у вас.
- **Сессионный пароль** — Один запрос на сессию терминала. После этого вы можете использовать dredge без пароля до закрытия терминала. (прочитайте раздел безопасности, чтобы лучше понять)
- **Корзина + отмена** — удалённые элементы попадают в корзину. Так что просто используйте `dredge undo`, если случайно что-то удалили.
---
<h2><img height="32" src="https://assets.kitploit.com/production/public/readmes/13610/21ca061b01116178eca9bbfd0698ebcaf0f63e614165fbc7b904f54508e01836.webp"/> Что хранить в dredge?</h2>
Я не осужу вас. Надоедливые API-ключи, которые показываются только один раз, SSH-конфиги, AI-промпты, пароли, буквально shell-скрипты, которые можно выполнить, шаблоны писем?, dot-файлы (странно, но будет работать нормально), zip-архивы, список фильмов, списки URL для быстрого доступа...
Даже _легальную_ копию 2-й главы «Человека-бензопилы» на японском. (У меня может быть или не быть именно эта копия)
---
<h2 id="install"><img height="32" src="https://assets.kitploit.com/production/public/readmes/13610/db2b1ad73c3323b870934910e70cd8249c788b4ffdfaf79b09c75c05c8741937.webp"/> Установка</h2>
 
### Go
```bash
go install github.com/DeprecatedLuar/dredge-cargo/cmd/dredge@latest
```
Убедитесь, что `$GOPATH/bin` (обычно `~/go/bin`) находится в вашем `PATH`.
### Универсальный
```bash
curl -sSL https://raw.githubusercontent.com/DeprecatedLuar/the-satellite/main/satellite.sh | bash -s -- install DeprecatedLuar/dredge-cargo:dredge
```
<details>
<summary>Другие способы установки</summary>
<br>
**Установка вручную**
1. Загрузите бинарный файл для вашей ОС из [релизов](https://github.com/DeprecatedLuar/dredge-cargo/releases)
2. Сделайте исполняемым: `chmod +x dredge-*`
3. Переместите в PATH: `mv dredge-* ~/.local/bin/dredge`
---
**Из исходного кода**
```bash
git clone https://github.com/DeprecatedLuar/dredge-cargo
cd dredge-cargo
go build -o dredge ./cmd/dredge
mv dredge ~/.local/bin/
```
</details>
---
<h2 id="quick-start"><img height="32" src="https://assets.kitploit.com/production/public/readmes/13610/b937e031192b68639bfed048d771e9881136e1d0915985740574b930022b2926.webp"/> Быстрый старт</h2>
```bash
# Инициализация с существующим git-удалённым репозиторием
dredge init yourusername/vault # сокращение GitHub
# или: dredge init [email protected]:you/vault.git
# Добавьте первый элемент
dredge add "OpenAI Key" -c "sk-..." -t keys api # открывает редактор без флага -c
# Поиск
dredge search openai
# Отправить в git
dredge push
```
<details>
<summary>Использование</summary>
<br>
```bash
# Добавить что угодно
dredge add My SSH Config -t ssh dotfiles --import ~/.ssh/config
dredge add "Master Architect Prompt" --import prompt.md -t ai prompts
dredge add "Watchlist" -c "Dune 2, Oppenheimer..." -t lists
dredge add "project-backup" --import project.tar.gz # бинарные файлы тоже :D
# Поиск — просто введите то, что помните
dredge search prompt
dredge search aws key
dredge search ssh
# Просмотр, редактирование, удаление
dredge view <id>
dredge edit <id>
dredge rm <id>
dredge undo # восстановление
# Результаты поиска пронумерованы — просто введите номер для просмотра
dredge search ssh # показывает: 1. [xKP] SSH Config 2. [mNq] SSH Key
dredge 1 # просмотр напрямую
# Синхронизация с git
dredge push
dredge pull
dredge sync # pull + push
```
</details>
---
<h2 id="how-it-works"><img height="32" src="https://assets.kitploit.com/production/public/readmes/13610/479f1ebf816d929f37e78e3a97679f47640eb18c52a9f1c129745bdffb7df1be.webp"/> Как это работает</h2>
> *"Не могу представить, что там в глубине."* — Смотритель маяка
Итак, резюмирую:
Я остановился на двух основных крипто-технологиях: Argon2id и, конечно, AES-256, а именно вариант GCM.
Argon2id, потому что это РЕКОМЕНДАЦИЯ из RFC 9106 и победитель PHC 2015 года. Вот и всё.
Вариант GCM AES, потому что он делает все зашифрованные данные невозможными для подделки из-за создания отпечатков. Тоже всё.
Пока что я храню всё в виде зашифрованных файлов в `~/.local/share/dredge/`. Этот каталог также является git-репозиторием (по крайней мере пока). Так что `dredge push` коммитит и отправляет всё для резервного копирования. Каждый элемент представляет собой отдельный зашифрованный блоб со случайным трёхсимвольным ID. Я решил, что никакие имена файлов не должны быть раскрыты, поэтому даже если кто-то увидит ваши файлы, они понятия не будут иметь, на что смотрят.
### Конвейер шифрования
```
Ваш пароль
+ 16-байтовая случайная соль ← соль хранится в .dredge-key
→ Argon2id (64 MB памяти · 4 потока · 1 итерация)
→ 32-байтовый мастер-ключ (соль + пароль = настоящий ключ)
Мастер-ключ + содержимое элемента (TOML: заголовок, теги, содержимое)
→ AES-256-GCM с новым случайным 12-байтовым nonce для каждой операции
→ [12B nonce][шифротекст + 16B тег аутентификации]
→ записывается на диск как items/xKP (случайный ID, без расширения)
```
Таким образом, всё ваше хранилище использует один и тот же производный ключ (это означает, что если вы потеряете ключ, вы потеряете данные, пожалуйста, не теряйте ключ). Каждый элемент использует один и тот же ключ, каждый со своим случайным nonce. Если зашифровать одно и то же содержимое дважды, получатся совершенно разные шифротексты.
### Где что находится
```
~/.local/share/dredge/ ← хранилище (git репозиторий)
├── .git/
├── .gitignore ← исключает .spawned/ и links.json
├── .dredge-key ← соль + зашифрованная проверочная строка
├── items/
│ ├── xKP ← зашифрованный элемент
│ ├── mNq ← зашифрованный элемент
│ └── ...
├── .spawned/ ← открытые копии привязанных элементов
└── links.json ← манифест симлинков
```
Итак, все ваши зашифрованные файлы и `.dredge-key` хранятся в git-репозитории, а все текстовые файлы (те, которые вы решили сделать читаемыми для системы) никогда не будут отслеживаться. Так что делайте с ними что хотите.
### Модель сессии
После первой команды в терминале производный 32-байтовый ключ кэшируется в `$XDG_RUNTIME_DIR/dredge/$PPID/.key` (доступ только root).
Все последующие команды dredge в ТОМ ЖЕ терминале используют кэшированный ключ. Это значит, что вас больше не будут запрашивать пароль. Каждый терминал получает свой изолированный каталог на основе PID родительского процесса. Ключ исчезает с диска после закрытия терминала.
<details>
<summary>Более глубокие технические детали</summary>
<br>
**Вывод ключа — Argon2id:** Рекомендованные параметры RFC 9106 (64 MB памяти, 4 потока, 1 итерация). Соль в `.dredge-key` не является секретом, она лишь гарантирует, что подбор вашего пароля перебором будет _очень_ дорогим, даже имея файл. Ваш пароль — это то, что вас защищает, так что вы знаете, что делать.
**Шифр — AES-256-GCM:** По сути, создаёт отпечатки для каждого шифрования. Вы получаете и конфиденциальность, и целостность. При попытке подделки шифротекста дешифрование не даст мусор — оно просто провалится и запросит помощи.
**Проверка пароля:** `.dredge-key` содержит строку `dredge-vault-v1`, зашифрованную вашим мастер-ключом. При каждой новой сессии dredge расшифровывает её, чтобы проверить, правильный ли пароль. Если вы не получите `dredge-vault-v1`, пароль неверный, и операция завершится неудачей примерно за 100 мс, а не обнаружит неверный пароль в середине операции.
**Что кэшируется:** Файл сессии хранит производный 32-байтовый ключ (пароль + соль), а не сам пароль (я не настолько глуп). Таким образом, даже если кто-то прочитает `.key` во время активной сессии, он не сможет восстановить из него ваш пароль.
</details>
---
<h2 id="security"><img height="56" src="https://assets.kitploit.com/production/public/readmes/13610/8dd63d36b5812744ccd584320794a580b7e1ee13ac9d33a1af0fa8ef8e364381.webp"/> Безопасность</h2>
> *"Лучше вернуться с маленьким уловом, чем не вернуться вообще."* — Рыбак
### Модель угроз (я сделал этот раздел с помощью ИИ, но он верен)
**Кто-то клонирует ваш приватный git-репозиторий:**
Они получат зашифрованные блобы и `.dredge-key`. Соль не секретна — её цель сделать предвычисленные атаки непрактичными. Без вашего пароля элементы — непрозрачные бинарные данные. Argon2id делает офлайн-перебор дорогим. Используйте надёжный пароль.
**Кто-то имеет доступ к вашей запущенной сессии:**
Производный ключ живёт в `$XDG_RUNTIME_DIR/dredge/$PPID/.key` на время сессии терминала. Каждый терминал получает свой изолированный каталог — закройте терминал, ключ исчез. Этот путь доступен только пользователю (режим 700) и находится в памяти. Атакующий с доступом к вашему каталогу сессии может расшифровать ваше хранилище. Относитесь к нему как к любым чувствительным учётным данным в вашем домашнем каталоге. Если кто-то имеет root-доступ к вашей машине, ваш ключ dredge — наименьшая из ваших проблем.
**Кто-то имеет физический доступ к вашему выключенному устройству:**
Элементы на диске зашифрованы. Ключ сессии находится в хранилище на базе RAM и не переживает перезагрузку. Привязанные элементы (`.spawned/`) — открытый текст на диске — см. ниже.
### Где существует открытый текст
| Расположение | Когда | Время жизни |
|----------|------|---------|
| Только в RAM | Каждый просмотр, поиск или редактирование | Освобождается при завершении команды |
| `$XDG_RUNTIME_DIR/dredge/$PPID/edit-*.txt` | Только во время `dredge edit` | Удаляется после закрытия редактора |
| `~/.local/share/dredge/.spawned/<id>` | После `dredge link` | До выполнения `dredge unlink` |
Файл `.spawned` — это единственный постоянный открытый текст на диске, и он существует только потому, что вы явно привязали элемент к системному пути. Всё остальное существует только в памяти.
### Оговорки
- **`--password` / `DREDGE_PASSWORD`:** Передача пароля в командной строке раскрывает его в истории оболочки и выводе `ps`. Переменные окружения могут просочиться в дочерние процессы. Избегайте этого в общих средах.
- **`--vault` / `DREDGE_VAULT`:** Переопределение активного хранилища для одной команды без сохранения изменения. Полезно для скриптов, работающих с несколькими хранилищами.
- **Привязанные элементы:** Открытый текст привязанного элемента находится по цели симлинка (например, `~/.ssh/config`). Он не отслеживается git, но находится на диске в открытом виде.
<div align="center">
<img src="https://assets.kitploit.com/production/public/readmes/13610/dcc75e764202f8315a3a56114ee19e79a70acd9dcc1094f70031f022e18ad76d.webp" width="700"/>
</div>
<h2 id="link"><img height="32" src="https://assets.kitploit.com/production/public/readmes/13610/ca14a510c662e4e6a349bbc44aa1eb397d2ded5d06ba7bd7f21f2cca50a0c1bd.webp"/> Команда link</h2>
Привяжите любой сохранённый элемент к пути в вашей файловой системе:
```bash
dredge link <id> ~/.ssh/config
```
Эта команда создаст симлинк по пути `~/.ssh/config`, указывающий на копию открытого текста, которой управляет dredge (файл открывается на диске, чтобы вы могли его использовать). Вы можете редактировать файл напрямую или через `dredge edit` или как вам угодно — все изменения автоматически синхронизируются обратно в зашифрованное хранилище.
**Автоматическое восстановление:** Если вы переименуете симлинк (например, `mv ~/.ssh/config ~/.ssh/config-backup`), dredge обнаружит и будет отслеживать новый путь автоматически. Удалённые симлинки очищаются при запуске сессии.
<div align="center">
<img src="https://assets.kitploit.com/production/public/readmes/13610/474132cd19d95d478c40ab360838423dcfcef2033d09f230a8640051dcd08d8e.gif" alt="dredge link demo" width="800"/>
</div>
На новой машине:
```bash
git clone [email protected]:you/vault.git ~/.local/share/dredge
dredge link <id> ~/.ssh/config
# тот же SSH-конфиг, те же ключи, каждая машина отслеживается git для любых обновлений
```
Это _собственно_ причина, по которой я создал dredge. Мой SSH-конфиг одинаков на каждой машине, но я не мог просто засунуть его в свои dot-файлы.
---
<h2 id="commands"><img height="32" src="https://assets.kitploit.com/production/public/readmes/13610/8c572a94c96ee031536884f6f6d32202d53ca05943b0b1083ed05b86fad3641a.webp"/> Все команды</h2>
<div align="left">
| Команда | Описание | Пример |
|:--------|:------------|:--------|
| `add` / `a` / `new` / `+` | Добавить элемент (открывает редактор, если нет флага -c) | `dredge add "OpenAI Key" -c "sk-..." -t keys` |
| `search` / `s` | Поиск элементов | `dredge search aws key` |
| `list` / `ls` | Список всех элементов | `dredge ls` |
| `view` / `v` | Просмотр элемента | `dredge view xKP` или `dredge 1` |
| `cat` / `c` | Вывод сырого содержимого (для передачи по каналу) | `dredge cat xKP \| bash` |
| `edit` / `e` | Редактирование элемента | `dredge edit xKP` |
| `rm` | Удаление (попадает в корзину) | `dredge rm 1 2 3` |
| `undo` | Восстановление последнего удалённого элемента | `dredge undo` |
| `link` / `ln` | Привязка элемента к системному пути | `dredge link xKP ~/.ssh/config` |
| `unlink` | Удаление привязки | `dredge unlink xKP` |
| `mv` / `rename` | Переименование ID элемента | `dredge mv xKP abc` |
| `export` | Экспорт файлового элемента на диск | `dredge export xKP ./output/` |
| `copy` / `cp` | Копирование содержимого элемента в буфер обмена | `dredge copy xKP` |
| `lock` | Блокировка хранилища (очищает ключ сессии) | `dredge lock` |
| `init` / `use` | Инициализация или активация хранилища | `dredge init ~/vaults/work` |
| `push` / `pull` / `sync` | Синхронизация с git (автоматические коммиты) | `dredge sync` |
| `drop` | Отказ от незакоммиченных изменений | `dredge drop xKP` или `dredge drop --all` |
| `status` | Показать ожидающие изменения | `dredge status` |
| `passwd` | Смена пароля хранилища | `dredge passwd` |
| `update` | Обновление до последней версии | `dredge update` |
</div>
### Синхронизация с Git (от wlad031)
Синхронизация с Git использует обычный `git` и работает с любым удалённым репозиторием (GitHub/GitLab/Gitea и т.д.).
`dredge init` принимает опциональный git-remote. Если его опустить, dredge инициализирует локальный git-репозиторий (без удалённого).
**Поведение авто-коммита:** `push`, `pull` и `sync` сохраняют синхронизированные незакоммиченные изменения в коммите перед согласованием с удалённым репозиторием. Если вам нужно отменить локальные изменения, чтобы приоритизировать версию с удалённого репозитория, используйте `dredge drop`.
**Автоматическое сохранение истории:** `push` и `sync` применяют политику из `dredge.toml`. Метаданные элементов и бинарное хранилище имеют независимые лимиты на количество версий на элемент и зашифрованные байты, в то время как `history.deleted.retain_for` контролирует, как долго удалённые ID остаются восстанавливаемыми. Если политика ничего не удаляет, Dredge выполняет обычный push. Если требуется уплотнение, Dredge проверяет историю замещения и использует точный force-with-lease; одновременное обновление с удалённого репозитория безопасно останавливается, а не перезаписывается. `pull` никогда не уплотняет и не force-пушит.
Просмотрите сохранённую историю с помощью `dredge history`, `dredge history deleted` или `dredge history <id>`. Восстановите удалённый зашифрованный элемент с помощью `dredge history restore <id>`. Смена пароля не перешифровывает исторические блобы, поэтому восстановленные версии, созданные под старым паролем, могут не расшифроваться текущим паролем.
Допустимые форматы удалённого репозитория:
```bash
# Сокращение GitHub (разворачивается в https://github.com/<владелец>/<репозиторий>.git)
dredge init owner/repo
# HTTPS
dredge init https://github.com/owner/repo.git
dredge init https://gitlab.com/group/repo.git
# SSH (в стиле scp)
dredge init [email protected]:owner/repo.git
dredge init [email protected]:group/repo.git
# SSH URL
dredge init ssh://[email protected]/owner/repo.git
# Локальный путь к удалённому репозиторию (продвинутый)
dredge init /srv/git/dredge-vault.git
```
- Dredge не создаёт удалённые репозитории за вас.
- Если `origin` не настроен, `dredge push`/`pull`/`sync` выдадут ошибку с подсказкой.
- Если у вас уже установлен git-remote, `dredge init` не будет его перезаписывать.
---
<h2 id="why"><img height="32" src="https://assets.kitploit.com/production/public/readmes/13610/b68b7786d5870a11a1d49137213cb61e51a25165c205d3a99298d7a27a616242.webp"/> Зачем</h2>
<img src="https://assets.kitploit.com/production/public/readmes/13610/23c3be123dc3423443be52804789e0647f1aaa477647cc9945dad19e4fe789a2.webp" alt="dredge logo" align="right" width="200"/>
> *"Я коллекционер — многих вещей: искусства и артефактов, сокровищ и истин… и диковинок, занимающих периферию желания."* — Коллекционер
Умственное напряжение от сохранения чего-то и незнания, где это найти, когда оно понадобится.
Меня бесило, что важные вещи (и неважные тоже, просто вещи в целом) разбросаны повсюду; мне приходилось заходить в почтовый ящик, созданный 6 лет назад, потому что он был привязан к какому-то случайному сервису, к которому мне срочно понадобился доступ безо всякой причины… В любом случае, я понял, что многие инструменты, несмотря на свои фишки, пересекаются в очень важном аспекте — хранении информации, поэтому я сделал инструмент, специализирующийся именно на _этом_ пересечении, и оставляет инструменты делать то, что они умеют лучше всего.
Я ленив, поэтому хотел что-то, что просто работает и читает мои мысли, не требует усилий для добавления записи или извлечения её из базы знаний.
Я как-то скачал [jrnl](https://jrnl.sh), и мне очень понравилась идея, но не понравилась реализация из-за странных параметров; у него буквально не было разделения на элементы, а поиск находил *всё*. Dredge — это то, что я на самом деле хотел. (так что да, по сути личный инструмент)
<div align="center">
<img src="https://assets.kitploit.com/production/public/readmes/13610/90f2f36bb0ca104704eb98c1ad2711f7c53b008a66ddfc4334e4503986e515b7.webp" width="600"/>
</div>
---
<h2><img height="32" src="https://assets.kitploit.com/production/public/readmes/13610/dee19080cbb4c8dc2511711c86f32617b12ee55e34ffc08658215533f7420640.webp"/> Участники</h2>
Большое спасибо ребятам, которые внесли вклад в dredge:
<table>
<tr>
<td align="center">
<a href="https://github.com/timcondit"><img src="https://assets.kitploit.com/production/public/readmes/13610/5c0d0e21e68f12b1687cb275ffdfa6b84b6b825998061fb623d88640fcd20f10.jpg" width="48" /><br/>timcondit</a>
</td>
<td align="center">
<a href="https://github.com/wlad031"><img src="https://assets.kitploit.com/production/public/readmes/13610/84d9b6594e04f211f09cbf1b128c591c80ac702807a91a75a5973a4bd384c238.jpg" width="48" /><br/>wlad031</a>
</td>
</tr>
</table>
---
<div align="center">
---
[Read more](https://github.com/deprecatedluar/dredge-cargo)