appsec-tool-kit 0.1.0__tar.gz
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.
- appsec_tool_kit-0.1.0/.github/workflows/tests.yml +27 -0
- appsec_tool_kit-0.1.0/.gitignore +10 -0
- appsec_tool_kit-0.1.0/.python-version +1 -0
- appsec_tool_kit-0.1.0/PKG-INFO +255 -0
- appsec_tool_kit-0.1.0/README.md +246 -0
- appsec_tool_kit-0.1.0/appsec_kit/__init__.py +0 -0
- appsec_tool_kit-0.1.0/appsec_kit/cli.py +135 -0
- appsec_tool_kit-0.1.0/appsec_kit/detector.py +16 -0
- appsec_tool_kit-0.1.0/appsec_kit/templates/__init__.py +0 -0
- appsec_tool_kit-0.1.0/appsec_kit/templates/node_templates.py +124 -0
- appsec_tool_kit-0.1.0/appsec_kit/templates/python_templates.py +127 -0
- appsec_tool_kit-0.1.0/appsec_kit/versions.py +6 -0
- appsec_tool_kit-0.1.0/appsec_kit/writer.py +65 -0
- appsec_tool_kit-0.1.0/pyproject.toml +25 -0
- appsec_tool_kit-0.1.0/tests/__init__.py +0 -0
- appsec_tool_kit-0.1.0/tests/test_detector.py +36 -0
- appsec_tool_kit-0.1.0/tests/test_templates.py +213 -0
- appsec_tool_kit-0.1.0/tests/test_versions.py +23 -0
- appsec_tool_kit-0.1.0/tests/test_writer.py +151 -0
- appsec_tool_kit-0.1.0/uv.lock +154 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, master]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: pytest
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
|
|
23
|
+
- uses: astral-sh/setup-uv@v5
|
|
24
|
+
|
|
25
|
+
- run: uv sync --group dev
|
|
26
|
+
|
|
27
|
+
- run: uv run pytest --tb=short
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: appsec-tool-kit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Interactive CLI to configure security tools for CI/CD pipelines
|
|
5
|
+
Requires-Python: >=3.12
|
|
6
|
+
Requires-Dist: questionary>=2.0
|
|
7
|
+
Requires-Dist: rich>=13.0
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
|
|
10
|
+
# AppSec Kit
|
|
11
|
+
|
|
12
|
+
CLI interativo que configura ferramentas de segurança para esteiras CI/CD com um único comando. Roda no projeto do dev e gera os arquivos prontos para uso.
|
|
13
|
+
|
|
14
|
+
**Suporte:** Python · Node.js · GitHub Actions
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## O que ele instala
|
|
19
|
+
|
|
20
|
+
| Camada | Python | Node.js |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| SAST | Bandit | Semgrep |
|
|
23
|
+
| Dependency scanning | pip-audit | npm audit |
|
|
24
|
+
| Secret scanning | Gitleaks + detect-secrets | Gitleaks + detect-secrets |
|
|
25
|
+
| Pre-commit hooks | pre-commit | pre-commit |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Pré-requisitos
|
|
30
|
+
|
|
31
|
+
- Python 3.12+
|
|
32
|
+
- [uv](https://docs.astral.sh/uv/) ou pip
|
|
33
|
+
- Git inicializado no projeto-alvo (`git init`)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Instalação
|
|
38
|
+
|
|
39
|
+
### Via uv (recomendado)
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
uv tool install appsec-tool-kit
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Via pip
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install appsec-tool-kit
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Direto do repositório (desenvolvimento)
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
git clone https://github.com/seu-usuario/appsec-tool-kit.git
|
|
55
|
+
cd appsec-tool-kit
|
|
56
|
+
uv sync
|
|
57
|
+
uv run appsec-kit
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Tutorial passo a passo
|
|
63
|
+
|
|
64
|
+
### Passo 1 — Acesse o diretório do seu projeto
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cd /caminho/do/seu/projeto
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
> O kit detecta automaticamente o tipo de projeto pelo conteúdo do diretório.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
### Passo 2 — Execute o wizard
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
appsec-kit
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Você verá a tela inicial:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
╭──────────────────────────────────────────────────────╮
|
|
84
|
+
│ AppSec Kit – Security toolkit for CI/CD pipelines │
|
|
85
|
+
╰──────────────────────────────────────────────────────╯
|
|
86
|
+
|
|
87
|
+
Detected: Python project
|
|
88
|
+
|
|
89
|
+
? Project type:
|
|
90
|
+
> Python
|
|
91
|
+
Node.js
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### Passo 3 — Confirme o tipo de projeto
|
|
97
|
+
|
|
98
|
+
O kit detecta automaticamente se é **Python** ou **Node.js** pelo conteúdo do diretório:
|
|
99
|
+
|
|
100
|
+
- Python → presença de `pyproject.toml`, `requirements.txt`, `setup.py` ou `Pipfile`
|
|
101
|
+
- Node.js → presença de `package.json`
|
|
102
|
+
|
|
103
|
+
Confirme ou altere com as setas e pressione `Enter`.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
### Passo 4 — Confirme o diretório-alvo
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
? Target directory: [.]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Pressione `Enter` para usar o diretório atual ou informe outro caminho:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
? Target directory: ../meu-outro-projeto
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
### Passo 5 — Selecione as camadas de segurança
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
? Security layers to configure:
|
|
125
|
+
> [x] SAST (Static Analysis)
|
|
126
|
+
[x] Dependency Scanning
|
|
127
|
+
[x] Secret Scanning
|
|
128
|
+
[x] Pre-commit Hooks
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Use `Espaço` para marcar/desmarcar, `Enter` para confirmar.
|
|
132
|
+
Por padrão todas as camadas ficam selecionadas.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
### Passo 6 — Aguarde a geração dos arquivos
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
✓ .github/workflows/security.yml (created)
|
|
140
|
+
✓ .pre-commit-config.yaml (created)
|
|
141
|
+
↻ pyproject.toml (updated)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### Passo 7 — Siga as instruções pós-instalação
|
|
147
|
+
|
|
148
|
+
O wizard exibe os próximos passos automaticamente:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
╭─ Next steps ──────────────────────────────────────────╮
|
|
152
|
+
│ pip install pre-commit detect-secrets │
|
|
153
|
+
│ detect-secrets scan > .secrets.baseline │
|
|
154
|
+
│ pre-commit install │
|
|
155
|
+
│ │
|
|
156
|
+
│ # Commit e push para ativar o GitHub Actions: │
|
|
157
|
+
│ git add .github/ .pre-commit-config.yaml │
|
|
158
|
+
│ git commit -m "chore: add appsec security config" │
|
|
159
|
+
│ git push │
|
|
160
|
+
╰───────────────────────────────────────────────────────╯
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Execute esses comandos na ordem.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## O que é gerado
|
|
168
|
+
|
|
169
|
+
### `.github/workflows/security.yml`
|
|
170
|
+
|
|
171
|
+
Workflow do GitHub Actions com jobs separados por camada:
|
|
172
|
+
|
|
173
|
+
- **SAST** — análise estática roda a cada push/PR
|
|
174
|
+
- **Dependency scan** — verifica vulnerabilidades nas dependências
|
|
175
|
+
- **Secret scanning** — Gitleaks varre o histórico git em busca de segredos expostos
|
|
176
|
+
|
|
177
|
+
O workflow é acionado em push e pull requests para `main` e `master`.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
### `.pre-commit-config.yaml`
|
|
182
|
+
|
|
183
|
+
Hooks que rodam localmente antes de cada commit:
|
|
184
|
+
|
|
185
|
+
**Python:**
|
|
186
|
+
```yaml
|
|
187
|
+
repos:
|
|
188
|
+
- repo: https://github.com/PyCQA/bandit # SAST
|
|
189
|
+
- repo: https://github.com/Yelp/detect-secrets # secrets
|
|
190
|
+
- repo: https://github.com/pypa/pip-audit # dependências
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Node.js:**
|
|
194
|
+
```yaml
|
|
195
|
+
repos:
|
|
196
|
+
- repo: https://github.com/Yelp/detect-secrets # secrets
|
|
197
|
+
- repo: https://github.com/gitleaks/gitleaks # secrets
|
|
198
|
+
- repo: local # npm audit
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
### `pyproject.toml` (apenas Python)
|
|
204
|
+
|
|
205
|
+
Adiciona configuração do Bandit ao arquivo existente:
|
|
206
|
+
|
|
207
|
+
```toml
|
|
208
|
+
[tool.bandit]
|
|
209
|
+
exclude_dirs = ["tests", "venv", ".venv"]
|
|
210
|
+
skips = []
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Casos de uso comuns
|
|
216
|
+
|
|
217
|
+
### Só quero pre-commit, sem CI
|
|
218
|
+
|
|
219
|
+
Execute o wizard e desmarque as camadas SAST, Dependency Scanning e Secret Scanning. Mantenha apenas **Pre-commit Hooks** selecionado.
|
|
220
|
+
|
|
221
|
+
### Só quero o GitHub Actions, sem pre-commit
|
|
222
|
+
|
|
223
|
+
Desmarque **Pre-commit Hooks** e mantenha as outras camadas.
|
|
224
|
+
|
|
225
|
+
### Projeto já tem `.pre-commit-config.yaml`
|
|
226
|
+
|
|
227
|
+
O kit sobrescreve o arquivo com status `(updated)`. Faça backup antes se necessário:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
cp .pre-commit-config.yaml .pre-commit-config.yaml.bak
|
|
231
|
+
appsec-kit
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Atualizando versões dos hooks
|
|
237
|
+
|
|
238
|
+
As versões dos hooks pre-commit ficam fixadas em `.pre-commit-config.yaml`. Para atualizar todas para o latest:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
pre-commit autoupdate
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Ferramentas utilizadas
|
|
247
|
+
|
|
248
|
+
| Ferramenta | Finalidade | Docs |
|
|
249
|
+
|---|---|---|
|
|
250
|
+
| [Bandit](https://bandit.readthedocs.io/) | SAST para Python | bandit.readthedocs.io |
|
|
251
|
+
| [Semgrep](https://semgrep.dev/) | SAST para JavaScript/TypeScript | semgrep.dev |
|
|
252
|
+
| [pip-audit](https://pypi.org/project/pip-audit/) | CVEs em dependências Python | pypi.org/project/pip-audit |
|
|
253
|
+
| [detect-secrets](https://github.com/Yelp/detect-secrets) | Detecção de segredos | github.com/Yelp/detect-secrets |
|
|
254
|
+
| [Gitleaks](https://gitleaks.io/) | Varredura de segredos no histórico git | gitleaks.io |
|
|
255
|
+
| [pre-commit](https://pre-commit.com/) | Framework de git hooks | pre-commit.com |
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# AppSec Kit
|
|
2
|
+
|
|
3
|
+
CLI interativo que configura ferramentas de segurança para esteiras CI/CD com um único comando. Roda no projeto do dev e gera os arquivos prontos para uso.
|
|
4
|
+
|
|
5
|
+
**Suporte:** Python · Node.js · GitHub Actions
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## O que ele instala
|
|
10
|
+
|
|
11
|
+
| Camada | Python | Node.js |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| SAST | Bandit | Semgrep |
|
|
14
|
+
| Dependency scanning | pip-audit | npm audit |
|
|
15
|
+
| Secret scanning | Gitleaks + detect-secrets | Gitleaks + detect-secrets |
|
|
16
|
+
| Pre-commit hooks | pre-commit | pre-commit |
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Pré-requisitos
|
|
21
|
+
|
|
22
|
+
- Python 3.12+
|
|
23
|
+
- [uv](https://docs.astral.sh/uv/) ou pip
|
|
24
|
+
- Git inicializado no projeto-alvo (`git init`)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Instalação
|
|
29
|
+
|
|
30
|
+
### Via uv (recomendado)
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
uv tool install appsec-tool-kit
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Via pip
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install appsec-tool-kit
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Direto do repositório (desenvolvimento)
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git clone https://github.com/seu-usuario/appsec-tool-kit.git
|
|
46
|
+
cd appsec-tool-kit
|
|
47
|
+
uv sync
|
|
48
|
+
uv run appsec-kit
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Tutorial passo a passo
|
|
54
|
+
|
|
55
|
+
### Passo 1 — Acesse o diretório do seu projeto
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
cd /caminho/do/seu/projeto
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
> O kit detecta automaticamente o tipo de projeto pelo conteúdo do diretório.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### Passo 2 — Execute o wizard
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
appsec-kit
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Você verá a tela inicial:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
╭──────────────────────────────────────────────────────╮
|
|
75
|
+
│ AppSec Kit – Security toolkit for CI/CD pipelines │
|
|
76
|
+
╰──────────────────────────────────────────────────────╯
|
|
77
|
+
|
|
78
|
+
Detected: Python project
|
|
79
|
+
|
|
80
|
+
? Project type:
|
|
81
|
+
> Python
|
|
82
|
+
Node.js
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### Passo 3 — Confirme o tipo de projeto
|
|
88
|
+
|
|
89
|
+
O kit detecta automaticamente se é **Python** ou **Node.js** pelo conteúdo do diretório:
|
|
90
|
+
|
|
91
|
+
- Python → presença de `pyproject.toml`, `requirements.txt`, `setup.py` ou `Pipfile`
|
|
92
|
+
- Node.js → presença de `package.json`
|
|
93
|
+
|
|
94
|
+
Confirme ou altere com as setas e pressione `Enter`.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
### Passo 4 — Confirme o diretório-alvo
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
? Target directory: [.]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Pressione `Enter` para usar o diretório atual ou informe outro caminho:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
? Target directory: ../meu-outro-projeto
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
### Passo 5 — Selecione as camadas de segurança
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
? Security layers to configure:
|
|
116
|
+
> [x] SAST (Static Analysis)
|
|
117
|
+
[x] Dependency Scanning
|
|
118
|
+
[x] Secret Scanning
|
|
119
|
+
[x] Pre-commit Hooks
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Use `Espaço` para marcar/desmarcar, `Enter` para confirmar.
|
|
123
|
+
Por padrão todas as camadas ficam selecionadas.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### Passo 6 — Aguarde a geração dos arquivos
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
✓ .github/workflows/security.yml (created)
|
|
131
|
+
✓ .pre-commit-config.yaml (created)
|
|
132
|
+
↻ pyproject.toml (updated)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### Passo 7 — Siga as instruções pós-instalação
|
|
138
|
+
|
|
139
|
+
O wizard exibe os próximos passos automaticamente:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
╭─ Next steps ──────────────────────────────────────────╮
|
|
143
|
+
│ pip install pre-commit detect-secrets │
|
|
144
|
+
│ detect-secrets scan > .secrets.baseline │
|
|
145
|
+
│ pre-commit install │
|
|
146
|
+
│ │
|
|
147
|
+
│ # Commit e push para ativar o GitHub Actions: │
|
|
148
|
+
│ git add .github/ .pre-commit-config.yaml │
|
|
149
|
+
│ git commit -m "chore: add appsec security config" │
|
|
150
|
+
│ git push │
|
|
151
|
+
╰───────────────────────────────────────────────────────╯
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Execute esses comandos na ordem.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## O que é gerado
|
|
159
|
+
|
|
160
|
+
### `.github/workflows/security.yml`
|
|
161
|
+
|
|
162
|
+
Workflow do GitHub Actions com jobs separados por camada:
|
|
163
|
+
|
|
164
|
+
- **SAST** — análise estática roda a cada push/PR
|
|
165
|
+
- **Dependency scan** — verifica vulnerabilidades nas dependências
|
|
166
|
+
- **Secret scanning** — Gitleaks varre o histórico git em busca de segredos expostos
|
|
167
|
+
|
|
168
|
+
O workflow é acionado em push e pull requests para `main` e `master`.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
### `.pre-commit-config.yaml`
|
|
173
|
+
|
|
174
|
+
Hooks que rodam localmente antes de cada commit:
|
|
175
|
+
|
|
176
|
+
**Python:**
|
|
177
|
+
```yaml
|
|
178
|
+
repos:
|
|
179
|
+
- repo: https://github.com/PyCQA/bandit # SAST
|
|
180
|
+
- repo: https://github.com/Yelp/detect-secrets # secrets
|
|
181
|
+
- repo: https://github.com/pypa/pip-audit # dependências
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Node.js:**
|
|
185
|
+
```yaml
|
|
186
|
+
repos:
|
|
187
|
+
- repo: https://github.com/Yelp/detect-secrets # secrets
|
|
188
|
+
- repo: https://github.com/gitleaks/gitleaks # secrets
|
|
189
|
+
- repo: local # npm audit
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### `pyproject.toml` (apenas Python)
|
|
195
|
+
|
|
196
|
+
Adiciona configuração do Bandit ao arquivo existente:
|
|
197
|
+
|
|
198
|
+
```toml
|
|
199
|
+
[tool.bandit]
|
|
200
|
+
exclude_dirs = ["tests", "venv", ".venv"]
|
|
201
|
+
skips = []
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Casos de uso comuns
|
|
207
|
+
|
|
208
|
+
### Só quero pre-commit, sem CI
|
|
209
|
+
|
|
210
|
+
Execute o wizard e desmarque as camadas SAST, Dependency Scanning e Secret Scanning. Mantenha apenas **Pre-commit Hooks** selecionado.
|
|
211
|
+
|
|
212
|
+
### Só quero o GitHub Actions, sem pre-commit
|
|
213
|
+
|
|
214
|
+
Desmarque **Pre-commit Hooks** e mantenha as outras camadas.
|
|
215
|
+
|
|
216
|
+
### Projeto já tem `.pre-commit-config.yaml`
|
|
217
|
+
|
|
218
|
+
O kit sobrescreve o arquivo com status `(updated)`. Faça backup antes se necessário:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
cp .pre-commit-config.yaml .pre-commit-config.yaml.bak
|
|
222
|
+
appsec-kit
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Atualizando versões dos hooks
|
|
228
|
+
|
|
229
|
+
As versões dos hooks pre-commit ficam fixadas em `.pre-commit-config.yaml`. Para atualizar todas para o latest:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
pre-commit autoupdate
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Ferramentas utilizadas
|
|
238
|
+
|
|
239
|
+
| Ferramenta | Finalidade | Docs |
|
|
240
|
+
|---|---|---|
|
|
241
|
+
| [Bandit](https://bandit.readthedocs.io/) | SAST para Python | bandit.readthedocs.io |
|
|
242
|
+
| [Semgrep](https://semgrep.dev/) | SAST para JavaScript/TypeScript | semgrep.dev |
|
|
243
|
+
| [pip-audit](https://pypi.org/project/pip-audit/) | CVEs em dependências Python | pypi.org/project/pip-audit |
|
|
244
|
+
| [detect-secrets](https://github.com/Yelp/detect-secrets) | Detecção de segredos | github.com/Yelp/detect-secrets |
|
|
245
|
+
| [Gitleaks](https://gitleaks.io/) | Varredura de segredos no histórico git | gitleaks.io |
|
|
246
|
+
| [pre-commit](https://pre-commit.com/) | Framework de git hooks | pre-commit.com |
|
|
File without changes
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import questionary
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
from rich.panel import Panel
|
|
7
|
+
|
|
8
|
+
from .detector import detect_project_type
|
|
9
|
+
from .versions import CI_LAYERS
|
|
10
|
+
from .writer import write_configs
|
|
11
|
+
|
|
12
|
+
console = Console()
|
|
13
|
+
|
|
14
|
+
_LAYER_CHOICES = [
|
|
15
|
+
("SAST (Static Analysis)", "sast"),
|
|
16
|
+
("Dependency Scanning", "deps"),
|
|
17
|
+
("Secret Scanning", "secrets"),
|
|
18
|
+
("Pre-commit Hooks", "precommit"),
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
_STYLE = questionary.Style([
|
|
22
|
+
("qmark", "fg:cyan bold"),
|
|
23
|
+
("question", "bold"),
|
|
24
|
+
("answer", "fg:cyan bold"),
|
|
25
|
+
("pointer", "fg:cyan bold"),
|
|
26
|
+
("highlighted", "fg:cyan bold"),
|
|
27
|
+
("selected", "fg:green"),
|
|
28
|
+
("instruction", "fg:default dim"),
|
|
29
|
+
])
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _print_next_steps(lang: str, layers: list[str]) -> None:
|
|
33
|
+
lines: list[str] = []
|
|
34
|
+
|
|
35
|
+
if "precommit" in layers:
|
|
36
|
+
lines += [
|
|
37
|
+
"pip install pre-commit detect-secrets",
|
|
38
|
+
"detect-secrets scan > .secrets.baseline",
|
|
39
|
+
"pre-commit install",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
if lang == "node" and "sast" in layers:
|
|
43
|
+
lines += [
|
|
44
|
+
"",
|
|
45
|
+
"# SEMGREP_APP_TOKEN (free) removes API rate limits in CI:",
|
|
46
|
+
"# 1. Create account at https://semgrep.dev",
|
|
47
|
+
"# 2. Go to Settings → Tokens → Create token",
|
|
48
|
+
"# 3. Add to GitHub: Settings → Secrets → SEMGREP_APP_TOKEN",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
if any(layer in layers for layer in CI_LAYERS) or "precommit" in layers:
|
|
52
|
+
lines += [
|
|
53
|
+
"",
|
|
54
|
+
"# Commit and push to activate GitHub Actions:",
|
|
55
|
+
"git add .github/ .pre-commit-config.yaml",
|
|
56
|
+
'git commit -m "chore: add appsec security configuration"',
|
|
57
|
+
"git push",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
if lines:
|
|
61
|
+
text = "\n".join(
|
|
62
|
+
f" {line}" if line and not line.startswith("#") else line for line in lines
|
|
63
|
+
)
|
|
64
|
+
console.print(Panel(
|
|
65
|
+
text,
|
|
66
|
+
title="[bold green]Next steps[/bold green]",
|
|
67
|
+
border_style="green",
|
|
68
|
+
padding=(0, 1),
|
|
69
|
+
))
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def run() -> None:
|
|
73
|
+
console.print()
|
|
74
|
+
console.print(Panel.fit(
|
|
75
|
+
"[bold cyan]AppSec Kit[/bold cyan] [dim]– Security toolkit for CI/CD pipelines[/dim]",
|
|
76
|
+
border_style="cyan",
|
|
77
|
+
padding=(0, 2),
|
|
78
|
+
))
|
|
79
|
+
console.print()
|
|
80
|
+
|
|
81
|
+
detected = detect_project_type()
|
|
82
|
+
default_project = {"python": "Python", "node": "Node.js"}.get(detected or "", "Python")
|
|
83
|
+
|
|
84
|
+
if detected:
|
|
85
|
+
console.print(f"[dim]Detected:[/dim] [bold]{default_project}[/bold] project\n")
|
|
86
|
+
|
|
87
|
+
project_type = questionary.select(
|
|
88
|
+
"Project type:",
|
|
89
|
+
choices=["Python", "Node.js"],
|
|
90
|
+
default=default_project,
|
|
91
|
+
style=_STYLE,
|
|
92
|
+
).ask()
|
|
93
|
+
|
|
94
|
+
if not project_type:
|
|
95
|
+
sys.exit(0)
|
|
96
|
+
|
|
97
|
+
target_dir = questionary.text(
|
|
98
|
+
"Target directory:",
|
|
99
|
+
default=".",
|
|
100
|
+
style=_STYLE,
|
|
101
|
+
).ask()
|
|
102
|
+
|
|
103
|
+
if target_dir is None:
|
|
104
|
+
sys.exit(0)
|
|
105
|
+
|
|
106
|
+
target_path = Path(target_dir).expanduser().resolve()
|
|
107
|
+
if not target_path.is_dir():
|
|
108
|
+
console.print(f"[red]Error:[/red] '{target_dir}' is not a valid directory.")
|
|
109
|
+
sys.exit(1)
|
|
110
|
+
|
|
111
|
+
selected_layers = questionary.checkbox(
|
|
112
|
+
"Security layers to configure:",
|
|
113
|
+
choices=[
|
|
114
|
+
questionary.Choice(label, value=key, checked=True)
|
|
115
|
+
for label, key in _LAYER_CHOICES
|
|
116
|
+
],
|
|
117
|
+
style=_STYLE,
|
|
118
|
+
).ask()
|
|
119
|
+
|
|
120
|
+
if not selected_layers:
|
|
121
|
+
console.print("[yellow]No layers selected. Exiting.[/yellow]")
|
|
122
|
+
sys.exit(0)
|
|
123
|
+
|
|
124
|
+
lang = "python" if project_type == "Python" else "node"
|
|
125
|
+
|
|
126
|
+
console.print()
|
|
127
|
+
results = write_configs(target_path, lang, selected_layers)
|
|
128
|
+
|
|
129
|
+
for rel_path, status in results:
|
|
130
|
+
color = "green" if status == "created" else "yellow"
|
|
131
|
+
icon = "✓" if status == "created" else "↻"
|
|
132
|
+
console.print(f" [{color}]{icon}[/{color}] {rel_path} [dim]({status})[/dim]")
|
|
133
|
+
|
|
134
|
+
console.print()
|
|
135
|
+
_print_next_steps(lang, selected_layers)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
_PYTHON_MARKERS = ("pyproject.toml", "setup.py", "requirements.txt", "Pipfile")
|
|
4
|
+
_NODE_MARKERS = ("package.json",)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def detect_project_type(path: Path | None = None) -> str | None:
|
|
8
|
+
"""Return 'python', 'node', or None when both or neither are detected."""
|
|
9
|
+
target = path or Path.cwd()
|
|
10
|
+
has_python = any((target / f).exists() for f in _PYTHON_MARKERS)
|
|
11
|
+
has_node = any((target / f).exists() for f in _NODE_MARKERS)
|
|
12
|
+
if has_python and not has_node:
|
|
13
|
+
return "python"
|
|
14
|
+
if has_node and not has_python:
|
|
15
|
+
return "node"
|
|
16
|
+
return None
|
|
File without changes
|