1. 소개
이 Codelab에서는 보안이 별도의 검토 단계가 아닌 일반적인 개발 루프의 일부가 되도록 AI 코딩 에이전트(Antigravity)를 구성합니다. 에이전트에게 계획 → 빨간색 → 녹색 → 리팩터링 주기를 안내하는 에이전트 기술 세트와 git push를 가로채고 CodeMender로 변경된 파일을 스캔하며 발견 사항을 테스트 우선 방식으로 수정하라는 안내와 함께 에이전트에게 다시 전달하는 PreToolUse 후크를 설치합니다.
스킬과 후크는 오픈소스 보안 TDD 에이전트 프레임워크에서 제공됩니다. CodeMender CLI 기본사항에서 빌드한 것과 동일한 ~/codemender-lab 작업공간에 설치합니다.
학습할 내용
- Antigravity가
.agents/에서 작업공간 규칙, 기술, 후크를 검색하는 방법 - 6가지 보안 TDD 기술의 역할과 각 기술이 루프의 어느 단계에 해당하는지
PreToolUse후크가 stdin에서 에이전트의 도구 호출을 수신하고 허용/거부 결정을 반환하는 방법- 보안 게이트 후크(
security_gate_hook.sh)가cm find를 실행하고, 심각도별로 발견 항목을 분류하고, 수정 시도를 추적하고,cm verify로 에스컬레이션하는 방법 - 실제
cm를 가리키기 전에 모의 스캐너를 사용하여 전체 후크 파이프라인을 오프라인으로 확인하는 방법
기본 요건
- CodeMender CLI 기본사항을 완료했습니다. 이 실습은
~/codemender-lab디렉터리에서 계속되며sample_app/,CONTEXT.md, git 기록,~/.codemender/config.yaml를 재사용합니다. - Antigravity가 설치되어 있으며 로컬 폴더를 작업공간으로 열 수 있습니다.
git,jq,bash가 설치되었습니다. 후크 스크립트는 일반 bash이며 macOS의 기본 bash 3.2 및 최신 버전에서 실행됩니다.- Flask가 설치된 CodeMender CLI 기본사항(
~/codemender-lab/.venv)의 Python 가상 환경 - 기본적인 셸 스크립팅 지식
2. Workspace 설정
1단계: 실습 디렉터리로 돌아가기
이 실습의 모든 명령어는 가상 환경이 활성화된 상태에서 ~/codemender-lab에서 실행됩니다.
cd ~/codemender-lab && source .venv/bin/activate
이전 실습의 작업공간이 그대로 유지되고 작업 트리가 정리되었는지 확인합니다.
ls sample_app/data_service.py CONTEXT.md .gitignore
git status --short
git status --short는 아무것도 출력하지 않습니다. 파일이 나열되면 커밋한 후 계속 진행합니다.
2단계: 브랜치 이름 지정 main
보안 게이트는 작업 트리를 origin/main와 비교하여 스캔할 파일을 결정합니다. 이 참조가 없으면 가장 최근 커밋만 포함하는 HEAD~1로 대체됩니다. 브랜치 이름이 main인지 확인합니다.
git branch -M main
3단계: 테스트 모음 진입점 추가
보안 TDD 루프는 수정할 때마다 에이전트에게 python3 -m unittest discover -s tests를 실행하도록 요청하므로 작업공간에 tests/ 디렉터리가 필요합니다. 모음에서 실제로 실행할 수 있도록 하나의 특성화 테스트로 시작합니다.
mkdir -p tests && touch tests/__init__.py
cat << 'EOF' > tests/test_data_service.py
import unittest
from sample_app.data_service import hash_password
class HashPasswordTests(unittest.TestCase):
def test_returns_hex_digest(self):
digest = hash_password("hunter2")
self.assertIsInstance(digest, str)
int(digest, 16) # raises ValueError if not hexadecimal
if __name__ == "__main__":
unittest.main()
EOF
python3 -m unittest discover -s tests
Ran 1 test 및 OK가 표시됩니다.
4단계: .gitignore 확장 및 커밋
이 실습에서 생성하는 런타임 파일을 .gitignore에 추가한 다음 기준을 커밋합니다.
printf '.security-gate/\nusers.db\n*.bak\n' >> .gitignore
git add -A && git commit -m "Add test suite entry point for Secure TDD"
3. 프레임워크 파일 설치
기술, 규칙, 후크, 오프라인 테스트 하네스는 모두 단일 .agents/ 디렉터리에 있습니다. 약 800줄의 bash를 직접 입력하는 대신 프레임워크를 클론하고 해당 디렉터리를 작업공간에 복사합니다.
git clone --depth 1 https://github.com/h3xar0n/secure-tdd-agent-framework.git /tmp/secure-tdd
cp -R /tmp/secure-tdd/.agents ./.agents
rm -rf /tmp/secure-tdd
레이아웃을 확인합니다.
find .agents -type f | sort
.agents/hooks.json
.agents/lib/README.md
.agents/lib/engine_codemender.sh
.agents/lib/engine_semgrep.sh
.agents/lib/gate_common.sh
.agents/rules/secure_tdd_workflow.md
.agents/security_gate_hook.sh
.agents/skills/defensive-developer/SKILL.md
.agents/skills/history-context-seeder/SKILL.md
.agents/skills/local-refactor-scanner/SKILL.md
.agents/skills/security-test-writer/SKILL.md
.agents/skills/skill-evolution-updater/SKILL.md
.agents/skills/threat-model-assessor/SKILL.md
.agents/tests/mocks/cm
.agents/tests/mocks/semgrep
.agents/tests/run_tests.sh
후크 진입점이 실행 가능한지 확인합니다.
chmod +x .agents/security_gate_hook.sh
ls -l .agents/security_gate_hook.sh
이 실습의 나머지 부분에서는 방금 설치한 항목을 하나씩 살펴봅니다.
4. 상시 사용 워크플로 규칙
스킬은 에이전트가 스킬의 설명이 작업과 일치한다고 판단할 때 요청 시 로드됩니다. 에이전트가 올바른 순서로 도달하도록 지시하는 무언가가 있어야 합니다. 이것이 .agents/rules/secure_tdd_workflow.md의 역할입니다. 프런트매터는 trigger: always_on를 설정하므로 규칙이 모든 차례에 삽입됩니다.
---
trigger: always_on
---
# Test-Driven Development with Integrated Security (Secure TDD) Workflow Rule
You MUST strictly follow this 4-phase cyclical workflow for all feature implementations, refactors, and bug fixes:
1. **Phase A (Plan, Scope & Threat Model)**:
- Ingest `CONTEXT.md` to review established project conventions, approved helpers, and trust zones.
- Decompose feature requirements, user stories, and acceptance criteria.
- Invoke the **Threat Model Assessor Skill** to perform a STRIDE evaluation and generate/update `threat_model.md`.
2. **Phase B (Functional & Security Test-First - RED)**:
- Invoke the **Security Test Writer Skill**.
- Author unit and integration tests asserting functional behavior (happy paths, business logic), edge cases, AND security boundaries (rejecting invalid inputs, unauthenticated requests, unauthorized role access).
- Execute the tests and confirm they FAIL for the expected assertion reason (RED).
3. **Phase C (Feature Implementation & Defensive Code - GREEN)**:
- Invoke the **Defensive Developer Skill**.
- Author clean, modular production code strictly required to satisfy the functional tests and security assertions.
- Apply input validation allow-lists, parameterized queries, and least-privilege payload returns.
- Run the tests to confirm they are GREEN.
4. **Phase D (Refactor, Quality & Scan)**:
- Invoke the **Local Refactor & Scanner Skill**.
- Clean up code, eliminate duplication, and verify 100% passing test regressions.
- Run fast deterministic checks (secrets, dependencies, local SAST).
- Conduct a guided AI review to verify architectural boundaries and eliminate logic bypasses.
- Ensure diffs remain small, surgical, and preserve baseline stability.
5. **Continuous Evolution**:
- If a new pattern, helper function, or architectural convention was introduced, invoke the **Skill Evolution Updater Skill** to document the lesson into `CONTEXT.md` or the appropriate `SKILL.md`.
6. **Multi-Finding Remediation Protocol**:
- When resolving multiple findings from a scan or security gate rejection, iterate sequentially one finding at a time:
1. Author one discrete boundary test for the finding (RED).
2. Implement the minimal defensive fix (GREEN).
3. Verify local tests pass before moving to the next finding.
- Avoid applying multi-finding changes in a single unverified edit. Run the full regression test suite only after all individual findings have passed their discrete TDD cycle.
이 규칙은 CodeMender CLI 기본사항에서 만든 CONTEXT.md를 참조합니다. cm fix를 매개변수화된 쿼리 규칙으로 안내한 동일한 파일이 이제 에이전트의 계획을 안내합니다. 이 실습에서는 6번 항목이 가장 중요합니다. 보안 게이트에서 여러 발견 항목이 있는 푸시를 한 번에 거부할 때 에이전트가 따르는 항목입니다.
5. 6가지 상담사 기술
각 기술은 YAML 프런트매터가 있는 SKILL.md가 포함된 디렉터리입니다. 다음 두 필드는 필수입니다.
name: 하이픈으로 연결된 소문자 식별자입니다.description: 스킬의 기능과 사용 시점 에이전트는 전체 기술을 로드할지 결정할 때 이 필드만 읽으므로 아래의 각 설명에는 기술이 적합하지 않은 경우도 설명되어 있습니다.
기술 | 단계 | 목적 |
| A: 계획 | 기능의 범위를 지정하고 STRIDE를 실행하고 |
| B: 빨간색 | 올바른 이유로 실패하는 기능 및 경계 테스트를 작성합니다. |
| C: 녹색 | 안전한 패턴을 사용하여 테스트를 통과하는 최소한의 코드를 작성합니다. |
| D: 리팩터링 | 정리하고 전체 도구 모음을 실행하고 로컬 스캐너를 실행하고 diff를 검토합니다. |
| 연속 |
|
| 온보딩 | 기존 저장소에서 |
전체 콘텐츠는 다음과 같으므로 프런트매터와 안내가 어떻게 결합되는지 확인할 수 있습니다.
1. threat-model-assessor(A단계)
.agents/skills/threat-model-assessor/SKILL.md:
---
name: threat-model-assessor
description: Plans feature architecture, functional requirements, and evaluates STRIDE security boundaries in Phase A Plan. Use when scoping new features or bug fixes, defining user stories and acceptance criteria, identifying trust boundaries, and generating or updating threat_model.md. Do not use for writing test assertions, implementing production code, or running local scanners.
---
# Planning, Requirements & Threat Model Assessor Skill (Phase A: Plan Phase)
## Overview
Decompose feature requirements, establish functional acceptance criteria, and map trust boundaries before any production code is authored. This skill pairs functional engineering scoping with STRIDE threat modeling at the planning stage, establishing the functional and security acceptance criteria consumed by downstream test writers.
## System Sequence
1. **Ingest Context**: Read `CONTEXT.md` to identify existing architecture, trust boundaries, approved libraries, and conventions.
2. **Decompose Requirements**:
- Define user stories, input/output data contracts, and functional acceptance criteria.
- Break complex tasks into bite-sized, testable implementation stages.
3. **Apply STRIDE Threat Modeling**:
- **Spoofing**: Authentication boundaries, session validation, caller identity checks.
- **Tampering**: Input payload validation, integrity checks, parameter tampering.
- **Repudiation**: Audit logging of critical state transitions.
- **Information Disclosure**: Restrict error responses, prevent stack trace leaks, mask PII/secrets.
- **Denial of Service**: Resource limits, payload size constraints, timeout limits.
- **Elevation of Privilege**: Role-Based Access Control (RBAC), caller authorization checks.
4. **Generate/Update `threat_model.md`**:
- Store or update `threat_model.md` at the workspace root with both Functional & Security Acceptance Criteria.
## Target Output Artifact (`threat_model.md`)
```markdown
# Feature Plan & Threat Model: [Feature Name]
## 1. Functional Scope & Requirements
- **Goal**: [Description of feature or bug fix]
- **Deliverables**: [Endpoints, functions, or modules to create/modify]
- **Functional Acceptance Criteria**: [Expected behaviors and outputs]
## 2. Entry Points & Data Inputs
- Endpoint / Input: [Path / Name]
- Format & Constraints: [Schema / Type]
## 3. Trust Boundaries & Access Controls
- Authentication: [Required / Public]
- Authorization Role: [User / Admin]
## 4. STRIDE Threat Matrix & Security Acceptance Criteria
- [STRIDE Category]: [Threat Description] -> [Required Mitigation & Test Assertion]
```
2. security-test-writer(B단계)
.agents/skills/security-test-writer/SKILL.md:
---
name: security-test-writer
description: Authors test-first unit and integration tests covering functional behavior, edge cases, and security boundaries in Phase B RED. Use when creating failing automated tests before writing production code, asserting HTTP status codes and contract responses, establishing boundary limits, or asserting that exploit payloads are rejected cleanly. Do not use for threat modeling during initial planning, writing production feature code, or running refactor sweeps.
---
# QA & Security Test Writer Skill (Phase B: RED Phase)
## Overview
Translate functional requirements and security criteria from `threat_model.md` and `CONTEXT.md` into executable test cases that fail initially (RED), asserting expected business logic, edge-case handling, and security boundaries before production code is authored.
## Three Verification Pillars
1. **Behavior-Driven Outcomes**:
- Assert strictly on API/HTTP outcomes (status codes 200/302 for valid requests, 400/401/403 for invalid/unauthorized, expected JSON responses) rather than mocking internal private methods.
2. **Strict Test Isolation**:
- Ensure test setup and teardown cleanly isolate state (e.g., transaction rollbacks, fresh test contexts) so state never bleeds between test runs.
3. **Integration Over Fragile Mocking**:
- Utilize local test databases or real server contexts rather than fragile fake mocks to verify realistic functional and security behavior.
## Execution Sequence
1. **Consume Requirements & Threat Model**: Read the task scope, `threat_model.md`, and `CONTEXT.md` for functional requirements and security acceptance criteria.
2. **Author Test Cases**:
- **Functional Happy Path**: Test validating standard user workflows and expected output payloads.
- **Functional Edge Cases**: Test missing optional/required parameters, boundary limits, and unexpected data types.
- **Authentication Boundary**: Assert requests without valid credentials return `401 Unauthorized`.
- **Authorization Boundary**: Assert requests with insufficient role/scope return `403 Forbidden`.
- **Input Validation**: Assert malformed, oversized, or un-whitelisted data returns `400 Bad Request`.
- **Exploit Payloads**: Assert dangerous inputs (SQLi, path traversal `../../`, XSS) are rejected cleanly.
3. **Execute & Verify RED**:
- Run the project's test command (e.g., `pytest`, `python3 -m unittest discover -s tests`).
- **Requirement**: Confirm the tests fail due to the expected missing feature logic/boundary assertion and not due to a syntax or import error.
4. **Multi-Finding Handling**:
- When remediating multiple scanner findings, write and verify one boundary test for one finding at a time before proceeding to defensive implementation.
3. defensive-developer(C단계)
.agents/skills/defensive-developer/SKILL.md:
---
name: defensive-developer
description: Implements clean, maintainable production code to deliver features and satisfy functional and security test assertions in Phase C GREEN. Use when writing minimal, modular production code to turn failing RED tests GREEN, applying input validation allow-lists, enforcing explicit caller authorization, and using parameterized sinks and least-privilege payloads. Do not use for authoring initial tests, performing initial threat modeling, or running post-implementation security scans.
---
# Feature Implementation & Defensive Developer Skill (Phase C: GREEN Phase)
## Overview
Implement clean, modular production code that delivers the requested feature or bug fix and satisfies all functional, edge-case, and security assertions from Phase B while adhering to defensive design principles and project conventions in `CONTEXT.md`.
## Three Defensive Pillars
1. **Simple Input Validation**:
- Enforce type, size, and strict allow-list validation on all incoming data.
- Prefer structured parsing libraries (`pydantic`, `urllib.parse`) over complex regex which may be vulnerable to ReDoS.
2. **Explicit Authorization**:
- Validate caller identity and match required permissions before invoking business logic.
3. **Least Privilege & Safe Operations**:
- Parameterize all SQL/database queries.
- Use canonical path checks (`os.path.realpath`) with prefix boundary validation.
- Return only the minimal data payload required by the client.
- Mask credentials, PII, and omit internal stack traces in error messages.
## Execution Sequence
1. **Inspect Failing Tests & Rules**: Review the functional requirements, failing tests from Phase B, and conventions in `CONTEXT.md`.
2. **Author Clean Production Code**:
- Implement the business logic and algorithms required to satisfy the functional feature requirements.
- Apply defensive patterns (e.g. `utils.security.resolve_safe_path`, parameterized SQL statements, `pydantic` schemas).
3. **Confirm GREEN State**:
- Run the project test suite.
- Verify that all functional and security tests pass cleanly without errors.
4. **Multi-Finding Handling**:
- When remediating multiple scanner findings, apply the minimal fix for the current failing boundary test, confirm GREEN, then proceed to the next finding's test-fix cycle.
4. local-refactor-scanner(D단계)
.agents/skills/local-refactor-scanner/SKILL.md:
---
name: local-refactor-scanner
description: Refactors code for quality and maintainability, executes full test suite regression passes, and runs local deterministic security and lint scans in Phase D REFACTOR. Use when cleaning up code structure and eliminating duplication after tests pass, running local linters and fast offline scanners for secrets or dependencies, executing full regression test suites, and performing guided code reviews. Do not use for implementing initial feature logic, writing failing test-first suites, or modifying architectural threat models.
---
# Code Refactoring, Quality & Local Scanner Skill (Phase D: REFACTOR Phase)
## Overview
Refactor implementation for clean code structure, modularity, and maintainability while ensuring 100% passing test regressions and blocking pattern-based security flaws locally prior to commit.
## Verification Guardrails
1. **Code Quality & Refactoring**:
- Clean up boilerplate, eliminate dead code, and centralize common utilities.
- Improve variable naming, modularity, and type annotations without altering verified behavior.
2. **Deterministic Scans (Fast & Offline)**:
- **Secrets**: Check diffs for plaintext credentials, tokens, or private keys.
- **Dependencies**: Flag unpinned dependencies or known CVEs in new packages.
- **Rules-Based SAST**: Run local SAST rules on modified files (`semgrep scan --config auto --json` or `cm find`).
3. **Guided AI Review**:
- Audit architecture and design issues that static tools miss.
- Review business logic and edge cases for bypasses or regression risks.
4. **Small Diffs & Regression QA**:
- Run the complete project test suite to verify zero regressions across existing and new tests.
- Ensure the diff contains only surgical changes directly related to the task scope.
## Execution Sequence
1. Review the git diff of modified files (`git diff`).
2. Refactor code for clarity, maintainability, and helper reuse.
3. Run local linters and security scanners on changed files.
4. Run the full test suite to guarantee 100% passing tests.
5. **Continuous Evolution**: Capture new conventions in `CONTEXT.md` and suggest/apply updates to `SKILL.md` instructions via `skill-evolution-updater` to permanently prevent recurrence of issues.
5. skill-evolution-updater(지속적인 기술 개선)
.agents/skills/skill-evolution-updater/SKILL.md:
---
name: skill-evolution-updater
description: Extracts systemic conventions from resolved bugs, patterns, and refactors to update CONTEXT.md and agent skills for continuous evolution. Use when capturing durable coding rules, architectural conventions, or recurring fix patterns into CONTEXT.md after a task or bug fix, updating skill instructions to prevent recurrence of errors, and logging gate findings to findings-log.ndjson. Do not use for writing feature code, authoring unit tests, or running pre-push scanner pipelines.
---
# Skill & Conventions Evolution Updater (Continuous Evolution)
## Overview
Ensure the development team and agent fleet continuously learn from local fixes, architecture decisions, and refactoring patterns so that systemic quality and security standards are retained permanently.
## Continuous Feedback Mechanism
```
+-----------------------------------------------------------------+
| CONTINUOUS FEEDBACK LOOP |
| |
| 1. Local Fix / Feature Verified (Refactor Phase) |
| v |
| 2. Systemic Lesson Extracted (Best practices & conventions) |
| v |
| 3. Feed Back to Shared Specs (Update SKILL.md/CONTEXT.md) |
| v |
| 4. Context Seeding (All future agents inherit rules upfront) |
+-----------------------------------------------------------------+
```
## Execution Sequence
1. **Analyze Remediation Diff**: Review the code change or bug fix just completed.
2. **Extract the Systemic Rule**:
- Formulate an actionable, project-specific rule.
- Example: *"When implementing redirects, always use `utils.security.safe_redirect()` with allow-listed domains."*
- Example: *"All JSON endpoints must validate request body using Pydantic schemas."*
3. **Update Shared Specifications**:
- **Update `CONTEXT.md`**: Append the rule under `## 4. Continuous Evolution: Auto-Evolved Conventions`.
- **Update Skills (if applicable)**: If a general coding anti-pattern or QA procedure was refined, update the relevant `SKILL.md`.
4. **Persist Insight**: Append the raw structured event to `.security-gate/findings-log.ndjson` for audit traceability.
6. history-context-seeder(온보딩)
.agents/skills/history-context-seeder/SKILL.md:
---
name: history-context-seeder
description: Analyzes repository Git history for past bug fixes, architectural conventions, and security patterns to seed CONTEXT.md on onboarding. Use when first adopting the framework in an existing repository, mining historical commits and bug fixes for recurring risk areas, or populating the initial CONTEXT.md baseline with established conventions and helpers. Do not use for routine feature development, authoring test suites, or running the inner TDD loop on active tasks.
---
# History & Architectural Context Seeder Skill (Repository Onboarding)
## Overview
Analyzes the repository's Git history and past fix commits to extract recurring bug patterns, architectural conventions, and security patterns, seeding `CONTEXT.md` during initial repository onboarding.
## Execution Sequence
1. **Analyze Git Log**:
- Inspect commits touching bug fixes, refactors, and sensitive modules:
`git log --grep="fix\|bug\|refactor\|vuln\|security\|patch" -n 50 --oneline`
2. **Extract Historical Lessons**:
- Identify which files and modules have historically been prone to bugs or regressions.
- Extract past patterns and architectural conventions established by maintainers.
3. **Seed `CONTEXT.md`**:
- Populate `CONTEXT.md` with known architectural risk areas, sensitive directories, approved helpers, and custom project conventions.
CONTEXT.md가 이미 존재하므로 실습에서는 이 기술을 사용하지 않지만, 수년간의 기록이 있고 작성된 규칙이 없는 저장소에 프레임워크를 가져올 때 이 기술을 사용해야 합니다.
6. Antigravity 후크 구성
.agents/hooks.json는 에이전트가 실행하는 터미널 명령어 전에 보안 게이트를 실행하도록 Antigravity에 지시합니다.
{
"security-gate": {
"PreToolUse": [
{
"matcher": "run_command|.*:run_command|run_shell_command|Bash",
"hooks": [
{
"type": "command",
"command": "bash -c 'if [ -x ./security_gate_hook.sh ]; then exec ./security_gate_hook.sh; else exec ./.agents/security_gate_hook.sh; fi'",
"timeout": 120
}
]
}
]
}
}
이 파일에 대한 몇 가지 세부정보는 실행되는 스크립트의 설계를 설명합니다.
matcher은 명령어 텍스트가 아닌 도구 이름에 대한 정규 표현식입니다.PreToolUse는 도구가 실행되기 전에 실행되며, 매처는 어떤 도구를 실행할지 결정합니다.run_command은 Antigravity의 터미널 도구입니다. 다른 대안은 플러그인 네임스페이스 변형과 이러한 파일을 공유하는 다른 에이전트 플랫폼을 다룹니다.git push*와 같은 일치자는 해당 이름의 도구가 없으므로 실행되지 않습니다. 실제 명령어에 대한 필터링은 스크립트 내에서 이루어집니다.- 후크는 stdin에서 도구 호출을 수신합니다. Antigravity는
{"toolCall": {"name": "run_command", "args": {"CommandLine": "git push origin main"}}, ...}과 같은 JSON 페이로드를 파이프합니다. 스크립트는.toolCall.args.CommandLine를 읽고git push가 아닌 모든 항목에 대해 허용 결정과 함께 즉시 종료됩니다. - 작업 디렉터리는
hooks.json를 포함하는 디렉터리이므로 후크는.agents/내에서 시작됩니다.bash -c 'if [ -x ./security_gate_hook.sh ] ...'래퍼는 이 경우와 저장소 루트에서 실행되는 경우를 모두 처리합니다. 그런 다음 스크립트는 작업을 수행하기 전에git rev-parse --show-toplevel로cd합니다. - 스크립트는 JSON을 사용하여 stdout에 응답합니다.
{"decision": "allow"}는 원래 명령어를 실행합니다.{"decision": "deny", "reason": "..."}에서 이를 차단하고 상담사에게 이유를 표시합니다. 프레임워크는 이전 후크 계약과의 호환성을 위해allow_tool불리언도 내보냅니다. - 후크는 동기식으로 실행되며 완료되거나
timeout에 도달할 때까지 에이전트 루프를 차단합니다(초 단위, 생략된 경우 기본값은 30).
-i.bak 형식은 GNU 및 BSD(macOS) sed 모두에서 작동합니다.
sed -i.bak 's/"timeout": 120/"timeout": 900/' .agents/hooks.json && rm .agents/hooks.json.bak
7. 보안 게이트 후크 작동 방식
security_gate_hook.sh는 .agents/lib/에서 세 가지 모듈을 가져오는 얇은 진입점입니다.
모듈 | 역할 |
| 구성 기본값, |
| 1단계. Semgrep을 사용한 선택적 결정론적 스캔 |
| 2단계. |
1단계: 푸시인지 판단하기
진입점은 stdin 페이로드에서 명령어를 추출하고 git commit -m "before git push"와 같은 따옴표로 묶인 텍스트를 무시하면서 일반적인 형식(git -C /repo push, cd x && git push, sudo git push)으로 git push를 인식하는 정규 표현식에 대해 테스트합니다. 푸시가 아닌 모든 항목은 즉시 허용됩니다.
CMD_TO_CHECK=$(printf '%s\n' "$STDIN_INPUT" | jq -r '
.toolCall?.args?.CommandLine? //
.toolCall?.args?.command? //
.tool_input?.command? //
.CommandLine? //
.command? //
empty
')
...
if ! is_git_push_command "$CMD_TO_CHECK"; then
allow
fi
2단계: 스캐너 선택하기
SECURITY_GATE_SCANNER는 파이프라인을 선택합니다. 기본값인 auto은 Semgrep과 CodeMender 중 설치된 것을 순서대로 실행합니다.
case "$SCANNER" in
codemender|cm) run_codemender_gate false ;;
semgrep) run_semgrep_gate false ;;
auto|pipeline|"")
command -v semgrep >/dev/null && run_semgrep_gate true
command -v cm >/dev/null && run_codemender_gate true
allow ;;
esac
1단계에서 파이프라인 모드의 차단 문제를 발견하면 자체적으로 거부하지 않고 2단계에서 선택하는 임시 파일에 기록하므로 CodeMender가 최종 결정을 내립니다.
3단계: CodeMender 단계
engine_codemender.sh의 run_codemender_gate는 다음을 순서대로 실행합니다.
git diff --name-only origin/main를 사용하여 변경된 파일을 찾습니다(HEAD~1로 대체). 변경사항이 없으면 허용됩니다.cm find "$file" -y --bypass-warning로 각 파일을 스캔한 다음cm report --format json로 모든 파일을 다시 가져옵니다.cm report가 실패하거나 잘못된 JSON을 반환하는 경우 이는 스캔 오류이며 정상 결과가 아닙니다.- 상태가
OPEN또는REOPENED이고file_path가 변경된 파일 중 하나로 끝나는 발견 항목을 필터링합니다. CodeMender CLI 기본사항에서 이미 수정하거나 닫은 발견 항목은 무시됩니다. - 각 발견 항목을 분류합니다. 심각도가
SECURITY_GATE_BLOCK_SEVERITY(기본값HIGH) 이상이면 차단됩니다. 이보다 낮으면 권고로 간주되어 로깅 및 출력되지만 푸시가 중지되지는 않습니다. - 차단하는 항목이 없으면 허용합니다. 이전 푸시를 차단한 발견 항목이 이제 사라진 경우 게이트는 이를
FIXED로 로깅하고## 4. Continuous Evolution아래의CONTEXT.md에 규칙을 추가하고 해당 변경사항을 커밋합니다. - 자체 감사 로그를 읽어 차단 발견 항목당 시도 횟수를 계산합니다. 각 거부는 하나의 시도로 간주됩니다. 1회부터
SECURITY_GATE_MAX_RETRIES회(기본값 3)까지의 시도에서 게이트는DENIED_TO_AGENT를 로깅하고 발견 항목을 거부 메시지에 추가합니다. - 예산이 소진된 후 에스컬레이션합니다. 동일한 발견 항목에 대한 네 번째 시도에서 게이트는
cm verify를 실행합니다. 발견 사항을 악용할 수 없는 경우(종료 코드 1 또는 상태DISMISSED) 권고로 다운그레이드됩니다. 확인되거나cm verify가 비정상 종료되면 게이트는BLOCKED를 로깅하고 사람의 검토를 요청하며 거부합니다. - 안내와 함께 거부합니다. 조치 가능한 발견 사항이 남아 있는 경우 게이트는 상담사에게 다음 이유를 반환합니다.
Security Gate blocked push (1 unresolved finding(s)).
Action Required: Execute the Secure TDD Loop sequentially for each finding:
For each finding below (one at a time):
1. Invoke 'security-test-writer' to author one failing boundary test in tests/ (assert RED).
2. Invoke 'defensive-developer' to apply the minimal defensive fix (assert GREEN).
3. Run the local test to confirm it passes before moving to the next finding.
Once all findings are resolved, run the full regression test suite (python3 -m unittest discover -s tests) and retry 'git push'.
Open Findings:
- [80bdddd6-...] (CRITICAL) in /home/you/codemender-lab/sample_app/data_service.py (Attempt 1/3): OS Command Injection in ping_host endpoint
이 단계는 호기심 유발과 기술의 연계입니다. 후크는 cm fix를 호출하지 않습니다. 에이전트가 사용해야 하는 기술의 이름을 지정하고, 에이전트가 테스트 우선 수정을 수행하고, 다음 git push에서 게이트를 다시 실행합니다.
구성 참조
모든 설정은 gate_common.sh에 기본값이 설정된 환경 변수입니다.
변수 | 기본값 | 효과 |
|
|
|
|
| 차단하는 가장 낮은 심각도입니다. |
|
|
|
|
|
|
|
| 거부 프롬프트 및 커밋 메시지에 인용된 테스트 명령어입니다. |
|
| 확인된 규칙을 |
|
| 추가 전용 감사 로그 |
| (비어 있음) | 각 게이트 이벤트를 stdin에서 JSON으로 수신하는 선택적 명령어입니다. |
8. 오프라인에서 후크 확인하기
게이트가 실제 cm에 도달하기 전에 모의로 올바르게 작동하는지 확인합니다. 프레임워크는 허용, 자문, 거부, 오류, 에스컬레이션 경로를 포함하는 가짜 cm 및 semgrep 바이너리가 포함된 테스트 하네스를 제공합니다.
bash .agents/tests/run_tests.sh
실행하는 데 몇 초 정도 걸리며 다음과 같이 종료됩니다.
-- test_pipeline_tools_missing_passes_smoothly
-- test_skills_frontmatter_valid
60 passed, 0 failed
마지막 테스트는 .agents/skills/ 아래에 있는 모든 기술의 프런트매터도 검증하므로 SKILL.md를 수정한 후 다시 실행해야 하는 명령어입니다.
다음으로, 푸시가 아닌 명령어에 대해 Antigravity가 전송하는 내용을 시뮬레이션합니다. 스크립트는 스캐너를 건드리지 않고 allow에 응답해야 합니다.
echo '{"toolCall":{"name":"run_command","args":{"CommandLine":"git status"}}}' \
| bash .agents/security_gate_hook.sh
{"allow_tool": true, "decision": "allow"}
이제 origin/main에 대해 로컬 변경사항이 없는 푸시를 시뮬레이션합니다. 아직 원격이 없으므로 게이트는 HEAD~1로 대체되고 마지막 커밋의 파일을 스캔합니다. 이 단계를 오프라인으로 유지하려면 모의 cm 및 semgrep를 가리킵니다.
echo '{"toolCall":{"name":"run_command","args":{"CommandLine":"git push origin main"}}}' \
| PATH="$PWD/.agents/tests/mocks:$PATH" bash .agents/security_gate_hook.sh
Stage 1: Running Deterministic AST Scan (semgrep) on: sample_app/data_service.py ...
Deterministic scan clean. No AST vulnerabilities found.
Stage 2: Running Semantic Analysis & Verification (CodeMender)...
No blocking vulnerabilities detected. Code verified clean.
{"allow_tool": true, "decision": "allow"}
모의 디렉터리에 가짜 semgrep와 가짜 cm가 포함되어 있으므로 두 단계가 모두 실행되었습니다. 진행 상황 메시지는 stderr로 전송되고 JSON 결정만 stdout으로 전송되므로 Antigravity가 결과를 파싱할 수 있습니다.
마지막으로 프레임워크 파일을 커밋하여 저장소와 함께 이동하도록 합니다.
git add -A && git commit -m "Add Secure TDD skills, rule, and security gate hook"
9. Antigravity에서 작업공간 열기
Antigravity에서 ~/codemender-lab를 폴더로 엽니다. 로드된 에이전트의 문제는 다음과 같습니다.
- 매 턴마다
secure_tdd_workflow규칙 - 주문형으로 제공되는 6가지 기술
run_command에 등록된security-gate후크입니다.
스킬이 표시되는지 빠르게 확인하려면 새 대화에서 에이전트에게 "사용 가능한 Workspace 스킬은 무엇이며 각 스킬은 어떤 역할을 하나요?"라고 물어보세요. 6가지의 이름을 나열해야 합니다.
권한
후크 자체는 에이전트가 아닌 Antigravity에 의해 실행되므로 도구 권한 프롬프트를 거치지 않습니다. 에이전트 자체 명령어는 승인이 필요합니다. 다음 Codelab에서는 테스트 명령어, git 작업, 에이전트가 직접 실행하기로 결정한 cm 명령어에 대한 승인 메시지가 표시됩니다. 요청 시 승인합니다. Antigravity에서 명령어 프리픽스에 대한 결정을 기억하도록 제안하는 경우 이를 수락하면 루프 전체에서 다시 메시지가 표시되지 않습니다.
git push에 어떤 일이 일어나나요?
- 에이전트가
git push origin main를 사용하여 터미널 도구를 호출합니다. - Antigravity는
run_command를hooks.json와 일치시키고 stdin에서 도구 호출을 사용하여security_gate_hook.sh를 실행합니다. - 스크립트는 푸시를 인식하고 변경된 파일을 찾아
cm find로 스캔하고cm report를 읽습니다. - 차단하는 항목이 없으면
{"decision": "allow"}가 출력되고 푸시가 진행됩니다. - 발견 사항이 차단되면
{"decision": "deny", "reason": "..."}가 출력됩니다. 푸시가 실행되지 않고 에이전트가 이유를 확인하며, 상시 사용 설정된 규칙과 명명된 기술이 다음에 수행할 작업을 알려줍니다. 실패한 테스트 1개, 최소 수정 1개, 모음 다시 실행, 다시 푸시.
수고하셨습니다 CodeMender Skills & Hooks for Antigravity Codelab을 완료했습니다. 다음 Codelab에서는 에이전트에 기능 요청을 제공하고 위협 모델부터 게이트를 통과하는 푸시까지 이 루프가 엔드 투 엔드로 실행되는 것을 확인합니다.