[G1-Sync] Manual knowledge update

This commit is contained in:
Antigravity Agent
2026-05-09 21:08:02 +09:00
parent f0befc887a
commit 93ec7e9056
363 changed files with 68333 additions and 64 deletions
@@ -0,0 +1,308 @@
---
id: devsec-pre-commit-security
title: Pre-commit Security — Secret / Lint / 빠른 가드
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [devsecops, pre-commit, hook, vibe-coding]
tech_stack: { language: "Various", applicable_to: ["DevOps"] }
applied_in: []
aliases: [pre-commit, husky, lefthook, lint-staged, gitleaks, secret detection]
---
# Pre-commit Security
> 사고 나기 전에 잡기. **Husky / lefthook / pre-commit framework + lint-staged + gitleaks**. Secret commit 차단 + lint + format. CI 보다 빠른 feedback.
## 📖 핵심 개념
- Pre-commit: commit 전 hook 실행.
- Pre-push: push 전 (더 무거운 검사 가능).
- Lint-staged: 변경 파일만.
- Bypass: --no-verify (긴급).
## 💻 코드 패턴
### Husky (Node 친화)
```bash
yarn add -D husky lint-staged
yarn husky init
```
```jsonc
// package.json
{
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,yaml,md}": ["prettier --write"]
}
}
```
```bash
# .husky/pre-commit
yarn lint-staged
yarn typecheck
```
### Lefthook (Go, 빠름, multi-language)
```yaml
# lefthook.yml
pre-commit:
parallel: true
commands:
lint:
glob: '*.{ts,tsx}'
run: yarn eslint --fix {staged_files}
stage_fixed: true
secrets:
run: gitleaks protect --staged --no-banner
format:
glob: '*.{ts,tsx,json,md}'
run: yarn prettier --write {staged_files}
stage_fixed: true
pre-push:
commands:
typecheck:
run: yarn tsc --noEmit
test:
run: yarn test --run
commit-msg:
commands:
conventional:
run: npx commitlint --edit {1}
```
```bash
lefthook install
```
### pre-commit framework (Python, 다양 hook)
```yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
args: [--maxkb=500]
- id: check-merge-conflict
- id: detect-private-key
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
- repo: https://github.com/returntocorp/semgrep
rev: v1.45.0
hooks:
- id: semgrep
args: [--config=p/secrets, --error]
- repo: local
hooks:
- id: typecheck
name: TypeScript
entry: yarn tsc --noEmit
language: system
pass_filenames: false
```
```bash
pre-commit install
pre-commit run --all-files # 한 번 모든 파일
```
### Secret detection (gitleaks)
```toml
# .gitleaks.toml — 자체 rule
[[rules]]
id = "company-api-key"
description = "Company internal API key"
regex = '''cmp_[a-zA-Z0-9]{32}'''
[allowlist]
paths = [
'''.*\.test\.ts$''',
'''fixtures/.*''',
]
```
```bash
gitleaks detect --source . --verbose
gitleaks protect --staged --verbose # pre-commit
```
### Detect-secrets (Yelp)
```bash
# Baseline 생성 (current secrets)
detect-secrets scan --baseline .secrets.baseline
# Pre-commit
detect-secrets-hook --baseline .secrets.baseline $(git diff --cached --name-only)
```
→ Baseline 으로 false positive 관리.
### Commit message — Conventional Commits
```bash
npm install -D @commitlint/cli @commitlint/config-conventional
```
```js
// commitlint.config.js
module.exports = { extends: ['@commitlint/config-conventional'] };
```
```bash
# .husky/commit-msg
npx --no -- commitlint --edit $1
```
`feat: xxx` / `fix: yyy` 강제. semantic-release 와 결합.
### TypeScript / lint 빠르게
```bash
# 변경 파일만 lint (lint-staged)
yarn lint-staged
# tsc — incremental
tsc --noEmit --incremental --tsBuildInfoFile .tsbuildinfo
```
### Bypass (긴급, 사용 주의)
```bash
git commit --no-verify -m "WIP"
git push --no-verify
```
→ CI 가 second gate.
### Force re-check (skip 한 후)
```yaml
# CI
- name: Pre-commit
run: pre-commit run --all-files
```
→ Bypass 해도 PR 에서 잡힘.
### Husky vs lefthook vs pre-commit
```
Husky:
+ Node 친화, 친숙
- Shell script
Lefthook:
+ 매우 빠름 (Go)
+ 병렬
+ Multi-language
pre-commit (Python):
+ 큰 hook ecosystem
+ 매우 강력 framework
- Python 의존
```
### Skip in CI (이미 fixed)
```yaml
- run: SKIP=eslint pre-commit run --all-files
```
### Secret rotate after leak
```bash
# Force push 로 history 삭제 X — secret 가 git history 에 남음.
# 1. Secret 즉시 rotate (모든 곳)
# 2. .git history 안 secret 도 cleanup
git filter-repo --invert-paths --path file-with-secret # 강력
# 또는 BFG repo-cleaner
# 3. force push (조심) + 모든 사람 re-clone
```
### Large file check
```yaml
- repo: https://github.com/pre-commit/pre-commit-hooks
hooks:
- id: check-added-large-files
args: [--maxkb=500]
```
→ 큰 binary git 안 — Git LFS.
### Private key check
```yaml
- id: detect-private-key
```
→ -----BEGIN RSA PRIVATE KEY----- 자동 검출.
### Branch naming
```bash
# .husky/pre-commit
branch=$(git rev-parse --abbrev-ref HEAD)
if ! [[ "$branch" =~ ^(main|feat|fix|chore)/ ]]; then
echo "Branch must start with feat/, fix/, or chore/"
exit 1
fi
```
### Performance (큰 monorepo)
```bash
# Turborepo + pre-commit
yarn lint-staged # 변경 파일만
turbo run lint --filter='[HEAD^1]' # 변경 package 만
```
### Onboarding 자동
```bash
# postinstall script
"scripts": {
"prepare": "husky install" # auto-install hook
}
```
`npm install` 시 hook 자동 setup.
## 🤔 의사결정 기준
| 상황 | 추천 |
|---|---|
| Node only | Husky + lint-staged |
| Multi-language / monorepo | Lefthook |
| Strong ecosystem | pre-commit framework |
| Secret detection | Gitleaks (강) / Detect-secrets (baseline) |
| Conventional commits | commitlint |
| 빠른 feedback | lint-staged + 작은 hook |
## ❌ 안티패턴
- **모든 hook 동기 + 느림**: 사용자가 bypass.
- **--no-verify 자주**: 의미 잃음.
- **모든 file lint 매 commit**: 큰 repo 느림. lint-staged.
- **Secret 발견 후 history 안 cleanup**: 영원 git history 에.
- **Onboarding 수동 hook install**: 새 dev 가 잊음. prepare script.
- **CI 가 hook 안 검사**: bypass = 통과. CI 가 second gate.
- **Format / lint 가 commit 변경**: stage_fixed.
## 🤖 LLM 활용 힌트
- Husky / lefthook + lint-staged + gitleaks 가 baseline.
- Conventional commit + commitlint.
- Bypass 가능 but CI 가 검사.
## 🔗 관련 문서
- [[DevSec_DAST_SAST]]
- [[DevSec_Supply_Chain]]
- [[DevOps_CI_CD_Pipeline_Patterns]]