keysloth 0.1.1

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.
data/task/task.md ADDED
@@ -0,0 +1,43 @@
1
+ Конечная цель - создать ruby-gem и выложить его в публичный доступ.
2
+
3
+ Задачи, который должен решать ruby-gem:
4
+ - доставать из удаленного репозитория шифрованные файлы
5
+ - расшифровывать их
6
+ - позволять пользователю изменять файлы как обычные файлы в файловой системе
7
+ - шифровать их
8
+ - и выгружать обратно на удаленный репозиторий
9
+
10
+ Решаемая проблема:
11
+ - избавиться от хранения "секретов" напрямую в репозитории
12
+ - при этом инструмент должен помогать доставлять актуальные секреты до всех членов команды
13
+ - и до сборочных нод в рамках CI/CD
14
+ - и делать этот все буквальной одной консольной командой
15
+
16
+ Как я вижу замысел в целом:
17
+ - где-то будет находиться удаленный репозиторий
18
+ - в репозитории - будет определенная ветка
19
+ - в этой ветке лежат в зашифрованном виде "секреты" проекта - файлы с расширением .cer, .p12, .mobileprovisioning и обычные .json файлы
20
+ - шифрование происходит по определенному "паролю"
21
+ - все участники команды получают доступ к репозиторию и пароль, пароль на машинах участников команды лежит в скрытом файле, закрытым .gitignore
22
+ - на сборочной ноде есть сервисный аккаунт с доступом к репозиторию, пароль зашит в переменных окружения
23
+ - любой участник команды или пайплайн сборочной ноды путем указания репозитория, ветки и пароля получает возможность "стянуть" и расшифровать все секреты, при этом в проекте создается определенная папка, которая указана в .gitignore
24
+ - при необходимости внесения изменений в секреты - team lead проекта изменяет файлы (заменяет или подкладывает новые)
25
+ - и затем одной командой с указанием репозитория, ветки и пароля пушит эти изменения в удаленный репозиторий
26
+ - команды вызываются из командной строки (будет использован Makefile)
27
+
28
+ Таким образом получаем:
29
+ - первый контур защиты - к удаленному репозиторию должен быть прямой доступ
30
+ - второй - необходимо знание пароля для расшифровки секретов
31
+ - третий - в удаленном репозитории данные хранятся в шифрованном виде, его утечка не так страшна
32
+ - при этом есть возможность быстрой доствки измененных секретов до команды или сборочных нод
33
+ - система имеет минимальную зависимость от человеческого фактора и требует минимального количества ресурсов devops команды для настройки инструмента
34
+ - инструмент универсален для любых систем CI/CD, будть то jenkins, gitlab runner или что-либо другое
35
+
36
+ Технические ограничения:
37
+ - это должен быть ruby-gem
38
+ - код должен быть читаем и содержать комментарии, достаточные для понимания его сути
39
+ - инструмент должен иметь как минимум три команды
40
+ - первая - для получения, дешифровки и распаковки секретов в дирректорию по определенному пути секретов, в параметрах - адрес репозитория, ветка, пароль и путь до дирректирии, в которую надо распоковать секреты (и которую в случае отсутствия надо создать)
41
+ - вторая - для шифровки и отправки секретов обратно в удаленный репозиторий, параметры все те же
42
+ - третья - help-команда с описанием существующих в инструменте команд
43
+ - все команды публичного интерфейса должны быть покрыты подробными и исчерпывающими комментариями
data/task/test_plan.md ADDED
@@ -0,0 +1,266 @@
1
+ # Test plan: Проверка работы gem KeySloth (шаг за шагом для новичка)
2
+
3
+ ## Цели
4
+ - Подтвердить, что все основные команды работают: `init`, `pull`, `push`, `status`, `validate`, `restore`, `version`, `help`.
5
+ - Проверить успешные и ошибочные сценарии.
6
+ - Пройти путь «с нуля»: установка Ruby/gem, подготовка SSH, тестовый репозиторий, локальная установка и запуск.
7
+
8
+ ## 0. Предпосылки и требования
9
+ - macOS/Linux с установленными:
10
+ - Git: `git --version`
11
+ - OpenSSL: `openssl version`
12
+ - Ruby 2.7+: `ruby -v` (если нет — установите через rbenv/asdf/Homebrew)
13
+ - Bundler/Rake: `gem install bundler rake`
14
+ - SSH доступ к Git-хостингу (GitHub/GitLab). Убедитесь, что ключи работают:
15
+ ```bash
16
+ ssh -T git@github.com # или git@gitlab.com
17
+ ```
18
+
19
+ ## 1. Клонирование проекта и установка зависимостей
20
+ ```bash
21
+ git clone https://github.com/keysloth/keysloth.git # если локально — просто перейдите в папку проекта
22
+ cd keysloth
23
+ bundle install
24
+ ```
25
+
26
+ ## 2. Запуск локальных проверок (по желанию)
27
+ ```bash
28
+ # Тесты
29
+ bundle exec rake spec
30
+
31
+ # Линтинг
32
+ bundle exec rake rubocop
33
+ ```
34
+
35
+ ## 3. Сборка и локальная установка gem
36
+ ```bash
37
+ gem build keysloth.gemspec
38
+ gem install ./keysloth-0.1.1.gem
39
+
40
+ # Проверка установки и базовых команд
41
+ keysloth version
42
+ keysloth help
43
+ ```
44
+
45
+ ### Требования к Git/SSH
46
+ Инструмент использует системный Git и SSH. Убедитесь, что установлены и доступны из PATH:
47
+ ```bash
48
+ git --version
49
+ ssh -V
50
+ ```
51
+
52
+ ## 4. Подготовка тестового удалённого репозитория (SSH)
53
+ Вариант A (GitHub через веб-интерфейс):
54
+ - Создайте приватный репозиторий, например `keysloth-secrets-test`.
55
+ - Выберите «Add a README» при создании, чтобы в репозитории сразу была ветка `main`.
56
+
57
+ Вариант B (через локальный git и push):
58
+ ```bash
59
+ mkdir -p ~/tmp/keysloth-secrets-remote
60
+ cd ~/tmp/keysloth-secrets-remote
61
+ git init
62
+ echo "# secrets" > README.md
63
+ git add README.md
64
+ git commit -m "init"
65
+ git branch -M main
66
+ git remote add origin git@github.com:<YOUR_USER>/keysloth-secrets-test.git
67
+ git push -u origin main
68
+ ```
69
+
70
+ Проверьте доступ по SSH:
71
+ ```bash
72
+ ssh -T git@github.com
73
+ ```
74
+
75
+ ## 5. Подготовка рабочего каталога и начальной конфигурации
76
+ ```bash
77
+ mkdir -p ~/tmp/keysloth-playground
78
+ cd ~/tmp/keysloth-playground
79
+
80
+ # Инициализация проекта под KeySloth (создаст .keyslothrc, директорию секретов, обновит .gitignore)
81
+ keysloth init -r git@github.com:chausovSurfStudio/keysloth-secrets-test.git -b main -d ./secrets
82
+
83
+ # Проверим, что создалось
84
+ cat .keyslothrc
85
+ cat .gitignore
86
+ ```
87
+
88
+ Ожидаемо: `.keyslothrc` содержит `repo_url`, `branch`, `local_path`; в `.gitignore` добавлены `secrets/` и `.keyslothrc`.
89
+
90
+ ## 6. Подготовка тестовых «секретов»
91
+ Создадим набор файлов разных типов, поддерживаемых инструментом:
92
+ ```bash
93
+ mkdir -p secrets/certificates secrets/config
94
+
95
+ # JSON
96
+ cat > secrets/config/app.json << 'JSON'
97
+ {
98
+ "apiKey": "demo-123",
99
+ "endpoint": "https://api.example.com",
100
+ "featureFlags": {"newUI": true}
101
+ }
102
+ JSON
103
+
104
+ # CER (PEM)
105
+ cat > secrets/certificates/dev.cer << 'CER'
106
+ -----BEGIN CERTIFICATE-----
107
+ MIIBkTCB+wI...FAKE...FOR...TEST...
108
+ -----END CERTIFICATE-----
109
+ CER
110
+
111
+ # P12 (минимальный валидный заголовок: первый байт 0x30)
112
+ printf "\x30\x82\x05\x10\x02\x01\x03\x30" > secrets/certificates/dev.p12
113
+
114
+ # Mobile provisioning (XML/plist признак)
115
+ echo '<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"></plist>' > secrets/dev.mobileprovisioning
116
+ ```
117
+
118
+ ## 7. Первая отправка секретов (push)
119
+ ```bash
120
+ export SECRET_PASSWORD="SOME_STRONG_PASSWORD_16+"
121
+
122
+ keysloth push -v \
123
+ -r git@github.com:chausovSurfStudio/keysloth-secrets-test.git \
124
+ -p "$SECRET_PASSWORD" \
125
+ -b main \
126
+ -d ./secrets \
127
+ -m "init secrets"
128
+ ```
129
+
130
+ Ожидаемо: в удалённом репозитории появятся зашифрованные файлы с расширением `.enc`, структура директорий сохранится.
131
+
132
+ Проверьте на хостинге (GitHub/GitLab) наличие `*.enc`.
133
+
134
+ ## 8. Получение секретов (pull)
135
+ Очистим локальные файлы и попробуем скачать и расшифровать:
136
+ ```bash
137
+ rm -rf ./secrets
138
+
139
+ keysloth pull \
140
+ -r git@github.com:chausovSurfStudio/keysloth-secrets-test.git \
141
+ -p "$SECRET_PASSWORD" \
142
+ -b main \
143
+ -d ./secrets
144
+
145
+ # Проверим содержимое
146
+ ls -la ./secrets ./secrets/certificates
147
+ cat ./secrets/config/app.json
148
+ ```
149
+
150
+ Ожидаемо: файлы восстановлены и читаемы.
151
+
152
+ ## 9. Проверка status
153
+ ```bash
154
+ keysloth status -d ./secrets
155
+ ```
156
+ Ожидаемо: отображается список найденных файлов, размеры, список доступных бэкапов (если есть).
157
+
158
+ ## 10. Проверка validate (целостность)
159
+ ```bash
160
+ keysloth validate -d ./secrets
161
+ ```
162
+ Ожидаемо: все файлы «валидны»; завершение с кодом 0.
163
+
164
+ ## 11. Проверка backup и restore
165
+ 1) Сымитируем порчу файла и увидим ошибку в validate:
166
+ ```bash
167
+ truncate -s 0 ./secrets/config/app.json
168
+ keysloth validate -d ./secrets || echo "validate failed (как и ожидалось)"
169
+ ```
170
+
171
+ 2) Посмотрим доступные бэкапы и восстановим:
172
+ ```bash
173
+ keysloth status -d ./secrets # именa бэкапов вида secrets_backup_YYYYMMDD_HHMMSS
174
+
175
+ # Пример восстановления (подставьте своё имя каталога бэкапа из вывода status)
176
+ keysloth restore ./secrets_backup_YYYYMMDD_HHMMSS -d ./secrets
177
+
178
+ keysloth validate -d ./secrets
179
+ ```
180
+
181
+ ## 12. Негативные сценарии (проверка ошибок)
182
+ - Неверный пароль при pull:
183
+ ```bash
184
+ keysloth pull -r git@github.com:chausovSurfStudio/keysloth-secrets-test.git -p WRONGPASS -b main -d ./secrets
185
+ # Ожидаемо: ошибка дешифровки, ненулевой код выхода
186
+ ```
187
+ - Несуществующая ветка:
188
+ ```bash
189
+ keysloth pull -r git@github.com:chausovSurfStudio/keysloth-secrets-test.git -p "$SECRET_PASSWORD" -b no_such_branch -d ./secrets
190
+ # Ожидаемо: ошибка «ветка не найдена»/«не синхронизирована»
191
+ ```
192
+ - Пустая/отсутствующая директория при push:
193
+ ```bash
194
+ keysloth push -r git@github.com:chausovSurfStudio/keysloth-secrets-test.git -p "$SECRET_PASSWORD" -d ./nope
195
+ # Ожидаемо: ошибка файловой системы
196
+ ```
197
+ - Проблемы SSH (нет доступа):
198
+ ```bash
199
+ keysloth pull -r git@github.com:chausovSurfStudio/private_no_access.git -p "$SECRET_PASSWORD"
200
+ # Ожидаемо: ошибка аутентификации/доступа
201
+ ```
202
+
203
+ ## 13. Глобальные флаги логирования
204
+ ```bash
205
+ # Подробный вывод
206
+ keysloth pull -r git@github.com:chausovSurfStudio/keysloth-secrets-test.git -p "$SECRET_PASSWORD" --verbose
207
+
208
+ # Тихий режим (только ошибки)
209
+ keysloth pull -r git@github.com:chausovSurfStudio/keysloth-secrets-test.git -p "$SECRET_PASSWORD" --quiet
210
+ ```
211
+
212
+ ## 14. Работа через .keyslothrc (минимум аргументов)
213
+ После `keysloth init` можно опускать `--repo`, `--branch`, `--path`:
214
+ ```bash
215
+ keysloth pull -p "$SECRET_PASSWORD"
216
+ keysloth push -p "$SECRET_PASSWORD" -m "update via rc"
217
+ ```
218
+
219
+ ## 15. Минимальная проверка в CI/CD (GitHub Actions пример)
220
+ Создайте секреты репозитория: `SSH_PRIVATE_KEY`, `SECRET_PASSWORD`. Затем workflow:
221
+ ```yaml
222
+ name: KeySloth smoke
223
+ on: [workflow_dispatch]
224
+ jobs:
225
+ check:
226
+ runs-on: ubuntu-latest
227
+ steps:
228
+ - uses: actions/checkout@v4
229
+ - name: Setup Ruby
230
+ uses: ruby/setup-ruby@v1
231
+ with:
232
+ ruby-version: '3.2'
233
+ - name: Setup SSH key
234
+ env:
235
+ SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
236
+ run: |
237
+ mkdir -p ~/.ssh
238
+ echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
239
+ chmod 600 ~/.ssh/id_rsa
240
+ ssh-keyscan github.com >> ~/.ssh/known_hosts
241
+ - name: Install KeySloth
242
+ run: gem install keysloth
243
+ - name: Pull secrets
244
+ env:
245
+ SECRET_PASSWORD: ${{ secrets.SECRET_PASSWORD }}
246
+ run: |
247
+ keysloth pull -r git@github.com:<YOUR_USER>/keysloth-secrets-test.git -p "$SECRET_PASSWORD"
248
+ ```
249
+
250
+ ## 16. Завершение и очистка
251
+ ```bash
252
+ # Опционально удалить установленный gem локально
253
+ gem uninstall keysloth -aIx
254
+
255
+ # Удалить рабочие каталоги
256
+ rm -rf ~/tmp/keysloth-playground ~/tmp/keysloth-secrets-remote
257
+ ```
258
+
259
+ ## Чек-лист «что должно сработать»
260
+ - `gem build` и `gem install` проходят без ошибок; `keysloth version`/`help` работают.
261
+ - `push` создаёт `*.enc` в удалённом репозитории; `pull` восстанавливает исходные файлы.
262
+ - `status` показывает файлы и бэкапы; `validate` подтверждает целостность.
263
+ - `restore` возвращает корректные файлы из бэкапа.
264
+ - Негативные сценарии приводят к понятным ошибкам и ненулевому коду выхода.
265
+
266
+
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: keysloth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - KeySloth Team
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-09-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.12'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.50'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.50'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop-performance
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.17'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.17'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.20'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.20'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.22'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.22'
97
+ - !ruby/object:Gem::Dependency
98
+ name: yard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.9'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.9'
111
+ description: "KeySloth - инструмент для безопасного хранения и управления секретами
112
+ (сертификаты, \nключи, конфигурационные файлы) в зашифрованном виде в Git репозиториях.
113
+ \nОбеспечивает простое получение, изменение и отправку секретов с использованием
114
+ \nAES-256-GCM шифрования.\n"
115
+ email:
116
+ - team@keysloth.org
117
+ executables:
118
+ - keysloth
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - ".keyslothrc.example"
123
+ - ".rspec"
124
+ - ".rubocop.yml"
125
+ - ".yardopts"
126
+ - CHANGELOG.md
127
+ - Makefile
128
+ - README.md
129
+ - Rakefile
130
+ - bin/keysloth
131
+ - keysloth.gemspec
132
+ - lib/keysloth.rb
133
+ - lib/keysloth/cli.rb
134
+ - lib/keysloth/config.rb
135
+ - lib/keysloth/crypto.rb
136
+ - lib/keysloth/errors.rb
137
+ - lib/keysloth/file_manager.rb
138
+ - lib/keysloth/git_manager.rb
139
+ - lib/keysloth/logger.rb
140
+ - lib/keysloth/version.rb
141
+ - task/cr.md
142
+ - task/plan.md
143
+ - task/ragged_removing.md
144
+ - task/task.md
145
+ - task/test_plan.md
146
+ homepage: https://github.com/keysloth/keysloth
147
+ licenses:
148
+ - MIT
149
+ metadata:
150
+ allowed_push_host: https://rubygems.org
151
+ homepage_uri: https://github.com/keysloth/keysloth
152
+ source_code_uri: https://github.com/keysloth/keysloth
153
+ changelog_uri: https://github.com/keysloth/keysloth/blob/main/CHANGELOG.md
154
+ rubygems_mfa_required: 'true'
155
+ post_install_message:
156
+ rdoc_options: []
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: 2.7.0
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ requirements: []
170
+ rubygems_version: 3.1.6
171
+ signing_key:
172
+ specification_version: 4
173
+ summary: Ruby gem для управления зашифрованными секретами в Git репозиториях
174
+ test_files: []