Skip to content
Agentmart
Submit a tool

V08-security

Skill by HwangTaehyun

IndexedMIT
Write a review

Chalk Labs

Need help deploying V08-security?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/hwangtaehyun-v08-security

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

The publisher has not written a description yet.

Use cases: security

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions: not checked yet.

What's inside

Skill name
V08-security
Description
None
License
MIT
Instructions
237 lines in SKILL.md · view on GitHub

Agent Skills spec issues

  • missing YAML frontmatter
  • name: missing
  • description: missing

Files (1)

  • SKILL.md

SKILL.md (first lines)

# V08 — security

> **Owner**: `hooks/validators/security.py` (Tier 2/3, configurable, full check set) + `hooks/security_hook.py` (Tier 1, zero-dep, regex-only, sub-100ms gate). Phase38 (A3 audit) put the SECRET_REGEXES + path-classification primitives in `lib/secret_regexes.py` so both tiers share one source of truth.
> **Tier**: 1 (PostToolUse, regex-only) for the fastest secret pass + Tier 2/3 (full V08) for everything else.
> **File patterns**: empty (matches every file). The exclusion logic lives in `lib/secret_regexes.is_excluded_path` so test fixtures, vendor, etc. are skipped.

## Rules

| Rule ID | Severity | When |
|---|---|---|
| `V08-HARDCODED-SECRET` | error | A literal value matches a high-confidence credential pattern (`AKIA[0-9A-Z]{16}`, `ghp_[A-Za-z0-9]{36}`, `sk_live_`, `xoxb-`, plus an 8+ character `password=...` literal that is not a `${VAR}` / `{{ env.X }}` template). |
| `V08-CORS-WILDCARD` | error | Go: `AllowAllOrigins: true`, `cors.Config{AllowOrigins:["*"]}`, raw header `Access-Control-Allow-Origin: *`. |
| `V08-PHI-LOGGING` | warning | Go: `log.Info().Str("email", x)`, `zerolog .Str()` / `.Msg()` with PHI fields. JS: `console.log(email)` or template literals containing PHI fields (`patient_name`, `ssn`, `dob`, etc.). HIPAA risk. PHI field set is configurable via `security.phi_fields` in `.verifiers/config.yaml`. |
| `V08-PHI-CHECK-ENABLED` | (gate) | Whole PHI rule is gated by `security.phi_check_enabled` config (default `true`). Non-medical projects can disable. |
| `V08-NO-GITIGNORE` | error | `.gitignore` does not exist at project root. |
| `V08-GITIGNORE-MISSING` | error | `.gitignore` exists but is missing one or more entries from `security.required_gitignore` (default `[".env", "*.pem", "*.key", ".env.local", "*.p12"]`). |

## Why this verifier exists

V08 is the highest-priority validator in the registry (`get_all_validators()` lists it first) because the failure modes are unrecoverable:

1. **Hardcoded secret in commit history.** Even if removed in the next commit, the credential is permanently leaked — rotate-or-die. Tier 1 must catch this *before* the Edit lands on disk.
2. **Wildcard CORS.** `Allow-Origin: *` lets every domain read auth-cookied responses. The fix is "name your origins"; the failure mode is "every cross-site request can be a CSRF + data-exfil".
3. **PHI in logs.** Logs go to centralized aggregators, retention systems, error trackers. PHI written to a log is PHI in a long-tail of systems the team didn't audit. HIPAA fines + breach notification obligations follow.
4. **Untracked `.env`.** The single most common secret leak path: `.env` exists locally, has secrets, and no `.gitignore` rule excludes it. One `git add .` ships it to the remote.

V08 + Tier 1 form a defense-in-depth: Tier 1 (regex-only, no yaml import, sub-100ms) catches the most common 7 patterns *on the Edit*, blocking the file from settling on disk in many cases. V08 (full set, slower) runs in Tier 2/3 to catch everything else.

## Design rationale

- **Two-tier split is load-bearing.** Tier 1 must be *fast and zero-dep* — it runs on every Edit/Write before the tool returns. If V08 (yaml-loading, multi-helper) ran there, it would blow the 100ms budget. Phase38's `lib/secret_regexes.py` extraction lets both tiers share regexes without coupling Tier 1 to yaml.
- **High-confidence patterns are `error`.** `AKIA[0-9A-Z]{16}` is AWS's own format; a literal match is virtually never a false positive. Same for `ghp_*36-char`, `sk_live_*`. The `password=...` 8+char regex is fuzzier — Tier 1's regex excludes `${...}` and `{{ ... }}` (template-engine vars) to keep false-positive rate manageable.
- **PHI list is configurable, default opinionated.** Default `phi_fields` is medical-domain (`patient_name`, `ssn`, `dob`, `mrn`, ...). Non-medical projects set `security.phi_check_enabled: false` or override `security.phi_fields: ["customer_email", ...]`. Empty list = use defaults (Phase19 SecurityConfig semantics).
- **Path exclusion is anchored, not substring (Phase21+, P2-3).** Pre-Phase21, `EXCLUDE_PATHS = ["mock", ...]` excluded `mockingbird/Real.go` because it contained `mock`. Now `EXCLUDE_DIRS = frozenset({"mock", "mocks", ...})` is matched on `Path.parts`. False-positive class closed.
- **`.gitignore` rules are structural, not stylistic.** Missing `.env` from gitignore = direct secret leak. The required set is small + opinionated; project override is a flat list, not a merge.

## How it checks (implementation)

### Tier 1 — `hooks/security_hook.py` (zero-dep gate)

```python
def main():
    cap = 10 * 1_048_576
    raw = sys.stdin.read(cap + 1)
    if len(raw) > cap:
        # Phase38b: silent-pass on truncated input is wrong for a security gate
        print(json.dumps({"decision": "block", "reason": "stdin truncated"}))
        return
    input_data = json.loads(raw)
    if input_data.get("tool_name") not in ("Edit", "Write", "MultiEdit"):
        return  # only inspect file-modifying tools

    file_path = input_data["tool_input"]["file_path"]
    if _is_excluded_path(file_path):     # delegates to lib/secret_regexes
        return

    findings = check_secrets(file_path)
    if findings:
        # Block the tool: Claude sees the reason and self-corrects on next Edit
        print(json.dumps({"decision": "block", "reason": ..., "additionalContext": ...}))
```

`check_secrets` reads the file, scans line-by-line with `SECRET_REGEXES`, returns a list of `{file, line, rule, message, fix}` dicts. No yaml, no ProjectContext, no logger — Tier 1's whole runtime is < 100 ms.

### Tier 2/3 — `hooks/validators/security.py`

```python
def validate_file(self, ctx, file_path):
    sec_cfg = ctx.config.security
    phi_fields = sec_cfg.phi_fields or PHI_FIELDS
    return self._check_single_file(
        file_path,
        phi_fields=phi_fields,
        phi_enabled=sec_cfg.phi_check_enabled,
    )

def validate_project(self, ctx):
    sec_cfg = ctx.config.security
    return self._check_project_wide(
        ctx,
        phi_fields=sec_cfg.phi_fields or PHI_FIELDS,
        phi_enabled=sec_cfg.phi_check_enabled,
        required_gitignore=sec_cfg.required_gitignore or REQUIRED_GITIGNORE,
    )
```

#### `_check_single_file(file_path, phi_fields, phi_enabled)`

```python
findings: list[Finding] = []
findings.extend(self._check_secrets(file_path))
findings.extend(self._check_cors(file_path))
if phi_enabled:
    findings.extend(self._check_phi_logging(file_path, phi_fields=phi_fields))
return findings
```

#### `_check_secrets(file_path)` — V08-HARDCODED-SECRET

Same regex set as Tier 1, but applied to the file already on disk. Imports from `lib.secret_regexes`:

```python
from lib.secret_regexes import SECRET_REGEXES, is_excluded_path

if is_excluded_path(file_path):
    return []
content = Path(file_path).read_text(errors="replace")
for line_num, line in enumerate(content.splitlines(), 1):
    for pattern, desc in SECRET_REGEXES:
        if re.search(pattern, line):
            yield Finding(
                severity="error",
                rule="V08-HARDCODED-SECRET",
                message=f"{desc} detected in source",
                fix=f"Remove the hardcoded secret at {file_path}:{line_num}. "
                    "Move to env via APP_*, reference via ${{VAR}}.",
                ...
            )
            break  # one finding per line is enough
```

From HwangTaehyun/verifiers, MIT.

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Apr 29, 2026 (6 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get V08-security running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying V08-security?

CallGet help
Cite this page

V08-security skill. Agent Mart. https://agentmart.dev/skills/hwangtaehyun-v08-security (last updated 2026-10-24)