| name | sdlc-adversarial-review |
| description | Multi-agent PR review: 3 specialized reviewers (architecture, security, quality) run in parallel, orchestrator synthesizes findings and applies fixes. Includes DORA metrics, SLSA supply chain, AI-assisted review guardrails, threat modeling (STRIDE/ATT&CK), secure code patterns, compliance (SOC2/GDPR/HIPAA), OWASP API Top 10, container/IaC security, policy as code, zero trust, and supply chain security. |
| version | 4.8.0-moderate |
| author | Dinoudon |
| license | MIT |
| platforms | ["linux","macos","windows"] |
| metadata | {"hermes":{"tags":["sdlc","code-review","pr-review","adversarial","multi-agent","security","architecture","dora","slsa","supply-chain","threat-modeling","compliance","owasp-api","zero-trust","policy-as-code"],"related_skills":["sdlc-architecture-design","sdlc-testing-qa","github-code-review","github-pr-workflow"]}} |
Adversarial PR Review
3-agent parallel review system: architecture + security + quality reviewers run in parallel, orchestrator synthesizes and fixes.
When to Use
- Reviews a PR before merging to main
- Wants thorough code review (architecture + security + quality)
- Has significant refactors to validate
- Needs security-sensitive changes reviewed
When NOT to Use
- Trivial changes (typos, comments, version bumps)
- Draft PRs still in progress
- Hotfixes needing immediate merge
Step 0: Automated Pre-Review
Run automated checks first — machines handle mechanical checks, humans handle design/nuance.
semgrep --config=auto --severity=ERROR --severity=WARNING .
gh codeql analyze --language=javascript
trivy fs --scanners vuln,secret,misconfig .
Tool selection matrix:
| Tool | Speed | Depth | Best for |
|---|
| Semgrep | Fast | Medium | Security patterns, code standards, banned APIs |
| CodeQL | Slow | Deep | Cross-function taint analysis, SQLi/XSS/SSRF |
| Trivy | Fast | Medium | Dependency CVEs, exposed secrets, IaC misconfig |
| cosign/Sigstore | Fast | Low | Artifact signature verification, provenance |
SLSA Supply Chain Review (Step 0b)
| SLSA Level | Requirement | Review Action |
|---|
| L0 | No guarantees | Flag as risk — no provenance |
| L1 | Provenance exists | Verify build provenance attestation present |
| L2 | Hosted build platform | Verify builds run on hosted CI (not dev machines) |
| L3 | Hardened builds | Verify isolated, ephemeral build environments |
gh attestation verify <artifact> --owner <org>
syft dir:. -o spdx-json > sbom.spdx.json
grype sbom:sbom.spdx.json
cosign verify --certificate-identity=<workflow> \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com <image>
Supply chain checklist:
Step 1: Spawn 3 Reviewers in Parallel
tasks = [
{
"goal": "Review PR for architecture concerns",
"context": """Focus on (priority order):
1. Design — right abstraction? Right pattern? (Clean/Hexagonal/DDD)
2. Dependencies — point inward? No circular deps?
3. Module boundaries — respected? Interfaces deep (high leverage)?
4. ADRs followed? If new pattern, flag for ADR creation.
5. Architecture fitness functions — would this change break any?
Report findings with severity and suggested fix.""",
"toolsets": ["terminal", "file"]
},
{
"goal": "Review PR for security vulnerabilities",
"context": """Focus on (OWASP Top 10 + supply chain):
1. Injection vectors — SQL, NoSQL, LDAP, OS command
2. Auth issues — broken auth, session management, missing checks
3. Secrets exposure — hardcoded keys, tokens, passwords
4. Input validation — all user input sanitized? SSRF prevention?
5. XSS prevention — output encoding, CSP headers
6. CSRF protection — tokens on state-changing endpoints
7. Rate limiting — on auth and expensive endpoints
8. Dependency vulnerabilities — CVEs in dependencies
9. Supply chain — typosquatting, compromised packages
Report findings with severity and suggested fix.""",
"toolsets": ["terminal", "file"]
},
{
"goal": "Review PR for code quality",
"context": """Focus on (Google review priority order):
1. Functionality — does this do what user needs? Edge cases?
2. Complexity — is code more complex than needed?
3. Tests — present, correct, maintainable? Coverage meets threshold?
4. Naming — clear, descriptive, consistent?
5. Comments — explain WHY, not WHAT
6. Error handling — comprehensive? Graceful degradation?
7. Performance — N+1 queries, unnecessary allocations, blocking I/O?
8. Documentation — API docs, inline docs, README updated for public changes?
9. PR description — clear what/why/how/testing sections?
Report findings with severity and suggested fix.""",
"toolsets": ["terminal", "file"]
}
]
Step 2: Orchestrator Synthesizes
- Collect all 3 review reports
- Deduplicate findings
- Prioritize: critical > high > medium > low
- Cross-reference: architecture finding may explain security finding
- Apply DORA metrics: flag if PR >400 LOC (break up), >1 day open (unblock)
Step 3: Apply Fixes
- If auto-fixable (lint, format, simple refactor) → fix and commit
- If needs human judgment → flag with comment
- If architectural → create issue for follow-up
Step 4: Re-run CI
After fixes, push and verify CI passes. All automated checks must pass before merge.
Review Templates
Architecture Review
- [ ] Follows established patterns (Clean/Hexagonal/DDD)
- [ ] Dependencies point inward
- [ ] Module boundaries respected
- [ ] Interfaces are deep (high leverage)
- [ ] No circular dependencies
- [ ] ADRs followed (or new ADR created)
- [ ] Architecture fitness functions pass
- [ ] C4 model consistency maintained
Security Review
- [ ] No hardcoded secrets (Trivy secrets scan)
- [ ] Input validation on all user input
- [ ] Auth checks on all endpoints
- [ ] SQL injection prevention (parameterized queries)
- [ ] XSS prevention (output encoding)
- [ ] CSRF protection (tokens)
- [ ] Rate limiting on auth/expensive endpoints
- [ ] Dependency vulnerabilities checked (Trivy/Dependabot)
- [ ] No SSRF vectors
- [ ] No path traversal vectors
Quality Review
- [ ] Test coverage meets threshold (>80%)
- [ ] Edge cases tested
- [ ] Error handling comprehensive
- [ ] Naming descriptive and consistent
- [ ] No code duplication
- [ ] Performance considered (no N+1, no blocking I/O)
- [ ] Comments explain WHY, not WHAT
- [ ] PR size <400 LOC (or justified)
- [ ] Documentation updated
- [ ] CHANGELOG entry added (if user-facing change)
DORA Velocity Metrics
| Metric | Elite | High | Medium | Low |
|---|
| PR to first review | <4 hours | <1 day | <1 week | >1 week |
| PR review to merge | <1 day | <3 days | <1 week | >1 week |
| PR size | <400 LOC | <800 LOC | <1500 LOC | >1500 LOC |
| PR lifetime | <1 day | <3 days | <1 week | >1 week |
| Reliability (DORA 2024) | >99.99% | >99.9% | >99% | <99% |
Key findings: Elite performers review in hours. Small batch size enables fastest review. Documentation quality correlates with high performance (DORA 2024). AI for review/testing outperforms AI for code generation alone.
Code Review Culture
Google reviewer priorities (in order):
- Design — right approach? Right abstraction?
- Functionality — does this do what user needs?
- Complexity — more complex than needed?
- Tests — present, correct, maintainable?
- Naming — clear, descriptive
- Comments — explain WHY, not WHAT
- Style — automate this away
- Nit-picks — optional, prefix with "Nit:"
Speed: Respond within 4 hours. Small changes (<200 LOC) review in <1 hour. Never let PR sit >1 business day.
Anti-Patterns:
- Bikeshedding — arguing about trivial things
- Rubber stamping — approving without reading
- Slow reviews — PRs sitting for days
- NIT overload — too many optional comments
- Design-by-committee — conflicting reviewer opinions
PR Template
## What
[1-2 sentence description]
## Why
[Link to issue, business context]
## How
[Technical approach, key decisions]
## Testing
- [ ] Unit tests added/updated
- [ ] Integration tests pass
- [ ] Manual testing done
## Checklist
- [ ] PR <400 LOC (or justified)
- [ ] No hardcoded secrets
- [ ] Error handling comprehensive
- [ ] Comments explain WHY
Multi-Agent Review Architecture
PR opened
│
▼
┌─────────────────────────────────────┐
│ Orchestrator Agent │
│ 1. Run automated checks (Semgrep, │
│ CodeQL, Trivy) │
│ 2. Spawn 3 reviewers in parallel │
│ 3. Collect findings │
│ 4. Deduplicate + prioritize │
│ 5. Apply auto-fixes │
│ 6. Present unified review │
└─────────┬───────────┬───────────┬────┘
│ │ │
┌─────▼──┐ ┌─────▼──┐ ┌─────▼──┐
│ Arch │ │ Sec │ │ Qual │
│ Review │ │ Review │ │ Review │
└────────┘ └────────┘ └────────┘
Stacked Diffs
Instead of one large PR, create chain of small dependent diffs (~100-300 lines each). Each is one logical change, can be reviewed independently. Enables parallel review.
Tools: ghstack (https://github.com/ezyang/ghstack), Graphite (https://graphite.dev/), Sapling (https://sapling-scm.com/)
AI-Assisted Review
AI guardrails (DORA 2024):
- Use AI for: first-pass review, test generation, security pattern detection, docs
- Don't use AI for: final architectural decisions, security-critical approval, blind acceptance
- Track AI suggestion acceptance rate — low = tool mismatch, high = rubber stamping
- All AI-generated code/comments need human approval before merge
- Require human reviewer for security-sensitive changes regardless of AI quality
Pitfalls
- Don't run on every PR — use for significant changes (>100 LOC, security-sensitive)
- Don't auto-fix architecture issues — create issues
- Don't ignore medium/low findings — accumulate into tech debt
- Don't skip re-running CI after fixes
- Don't bikeshed — focus on logic, not style
- Don't rubber stamp — actually read the diff
- Don't let PRs sit — respond within 4 hours
- Don't review for >60 minutes — fatigue degrades quality
- Don't skip automated checks — machines handle mechanical, humans handle design
- Don't mix abstraction levels — architecture in arch review, security in security review
STRIDE Threat Modeling
Systematic threat enumeration using Data Flow Diagrams (DFDs).
DFD Elements
| Element | Symbol | Description |
|---|
| External Entity | Rectangle | Users, external systems, APIs |
| Process | Circle/rounded rect | Code that processes data |
| Data Store | Two parallel lines | Databases, files, caches |
| Data Flow | Arrow | Data movement between elements |
| Trust Boundary | Dashed line | Where privilege levels change |
STRIDE-per-Element Table
| DFD Element | S (Spoofing) | T (Tampering) | R (Repudiation) | I (Info Disclosure) | D (Denial of Service) | E (Elevation of Privilege) |
|---|
| External Entity | ✓ | | ✓ | | | |
| Process | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Data Store | | ✓ | ✓ | ✓ | ✓ | |
| Data Flow | | ✓ | | ✓ | ✓ | |
DREAD Risk Rating
Score each threat 1-10:
| Criterion | 1-3 (Low) | 4-6 (Medium) | 7-10 (High) |
|---|
| Damage | Minor data loss | Service degradation | Complete data loss |
| Reproducibility | Hard, rare conditions | Sometimes | Always |
| Exploitability | Expert required | Advanced user | Any user, browser |
| Affected users | Few/specific | Some users | All users |
| Discoverability | Hard to find | With effort | Obvious |
Risk score = (D + R + E + A + D) / 5
| Score | Priority | Action |
|---|
| 7-10 | Critical | Fix before merge |
| 4-7 | High | Fix within sprint |
| 2-4 | Medium | Track in backlog |
| 1-2 | Low | Accept with documentation |
STRIDE Checklist
OWASP Threat Modeling
Asset Classification
| Asset Type | Examples | Classification |
|---|
| Data | PII, credentials, financial records | Confidentiality + Integrity |
| Services | Auth, payment, notification | Availability + Integrity |
| Infrastructure | Databases, message queues, caches | Availability |
| Code | Source, build artifacts, configs | Integrity |
| Secrets | API keys, encryption keys | Confidentiality |
Threat Agents
| Agent Type | Motivation | Capability |
|---|
| External attacker | Financial gain | Varies — script kiddie to APT |
| Malicious insider | Revenge, financial gain | High — has credentials |
| Compromised service | Lateral movement | Medium — service permissions |
| Supply chain | Backdoor, data exfiltration | High — trusted position |
Attack Surfaces
| Surface | Risk |
|---|
| API endpoints | Injection, broken auth, SSRF |
| Authentication flows | Credential stuffing, session fixation |
| File uploads | Path traversal, malware upload |
| Message queues | Poison messages, replay attacks |
| Webhooks | Forgery, SSRF |
OWASP Deliverable
PASTA vs STRIDE vs OWASP Selection
| Methodology | Best For | Effort | When |
|---|
| STRIDE | Component-level threats | Low-Medium | Every PR touching security boundaries |
| OWASP TM | Full system threat modeling | Medium | New services, major features |
| PASTA | Risk-centric, business-aligned | High | High-risk systems, regulatory requirements |
Secure Code Review Patterns
Cryptography Review
| Use Case | Approved | Banned | Flag |
|---|
| Symmetric encryption | AES-256-GCM, ChaCha20-Poly1305 | DES, 3DES, RC4, AES-CBC (no HMAC) | Non-AEAD mode |
| Asymmetric encryption | RSA-4096, X25519, Ed25519 | RSA-1024, RSA-2048 (new) | Key size < 2048 |
| Hashing | SHA-256, SHA-3, BLAKE2 | MD5, SHA-1 | Any use of MD5/SHA-1 |
| Key derivation | Argon2id, scrypt, PBKDF2 (>600k) | PBKDF2 (<100k), plain hash | Low iteration count |
| TLS | TLS 1.3 (preferred), TLS 1.2 (min) | TLS 1.0/1.1, SSLv3 | Protocol version config |
| Cert validation | Full chain + hostname verification | Disabled validation | verify=False |
Crypto checklist:
cipher = AES.new(key, AES.MODE_ECB)
cipher = AES.new(key, AES.MODE_GCM)
if user_mac == expected_mac:
if hmac.compare_digest(user_mac, expected_mac):
dk = hashlib.pbkdf2_hmac('sha256', password, salt, 1000)
dk = hashlib.pbkdf2_hmac('sha256', password, salt, 600000)
Authentication Flow Review
OAuth2/OIDC checklist:
Session management:
Password handling:
Input Validation
| Layer | Location | Purpose | Technology |
|---|
| L1: Transport | Edge/WAF | Block known patterns | ModSecurity, AWS WAF |
| L2: Schema | API Gateway | Structural validation | JSON Schema, OpenAPI |
| L3: Business | Application | Semantic validation | Custom validators |
| L4: Data | Database | Integrity constraints | CHECK constraints |
Input validation checklist:
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
def validate_url(url):
parsed = urllib.parse.urlparse(url)
if parsed.scheme not in ('https',):
raise ValueError("Only HTTPS allowed")
ip = socket.getaddrinfo(parsed.hostname, None)[0][4][0]
if ipaddress.ip_address(ip).is_private:
raise ValueError("No private IPs allowed")
return url
element.innerHTML = userInput;
element.textContent = userInput;
Object.assign(target, userInput);
const sanitized = JSON.parse(JSON.stringify(userInput));
Object.assign(target, sanitized);
Compliance-Aware Code Review
SOC 2 Type II
| Criteria | Control | Code Review Check |
|---|
| CC6.1 | Logical access | Auth required on all endpoints, RBAC enforced |
| CC6.3 | Access removal | Deprovisioning automated, access revoked on role change |
| CC6.7 | Data transmission | TLS 1.2+ on all connections, mTLS internally |
| CC7.1 | Vulnerability management | Dependency scanning, patching SLAs |
| CC7.2 | Monitoring | Security event logging, SIEM integration |
| CC8.1 | Change management | PR reviews required, CI/CD gates |
SOC 2 checklist:
GDPR
| Right | Article | Endpoint | Review Check |
|---|
| Erasure | Art. 17 | DELETE /users/{id}/personal-data | Cascades to all stores, < 30 days |
| Access | Art. 15 | GET /users/{id}/data-export | All PII, machine-readable |
| Rectification | Art. 16 | PATCH /users/{id}/personal-data | Propagates downstream |
| Portability | Art. 20 | GET /users/{id}/data-portability | JSON/CSV format |
| Restrict | Art. 18 | POST /users/{id}/restrict-processing | PII processing stops |
| Object | Art. 21 | POST /users/{id}/object-processing | Halt profiling/marketing |
class UserDataService:
def erase_user_data(self, user_id: str) -> ErasureResult:
self._verify_data_subject(user_id)
self.db.delete_user(user_id)
self.search_index.remove_user(user_id)
self.cache.invalidate(user_id)
self.analytics.anonymize_user(user_id)
self.email_service.remove_contact(user_id)
self.third_party_processors.request_deletion(user_id)
self.audit_log.record(action="data_erasure", subject_hash=hash(user_id))
return ErasureResult(status="complete",
systems_erased=self._get_erasure_manifest(user_id),
retention_exceptions=self._get_legal_holds(user_id))
GDPR checklist:
HIPAA
| Rule | Requirement | Check |
|---|
| Access Control (§164.312(a)) | Unique user ID, emergency access, auto-logoff, encryption | All 4 implemented |
| Audit Controls (§164.312(b)) | Log all PHI access (who, what, when) | Immutable and complete |
| Transmission Security (§164.312(e)) | Encrypt PHI in transit | TLS 1.2+ mandatory |
| Encryption at Rest | Encrypt PHI | AES-256, KMS managed |
def phi_access_logged(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
current_user = get_authenticated_user()
result = func(*args, **kwargs)
audit_logger.info("phi_access", extra={
"user_id": current_user.id,
"function": func.__name__,
"timestamp": datetime.utcnow().isoformat(),
"fields_accessed": get_phi_field_names(func),
"patient_hash": hashlib.sha256(
kwargs.get("patient_id", "").encode()
).hexdigest()[:16],
})
return result
return wrapper
HIPAA checklist:
Compliance Selection Matrix
| Standard | Applies When | Key Focus |
|---|
| SOC 2 | SaaS/B2B, enterprise sales | Access controls, change management |
| GDPR | EU personal data | Data subject rights, consent, erasure |
| HIPAA | US healthcare (PHI) | PHI access controls, audit logging |
| PCI DSS | Payment card data | Cardholder isolation, encryption |
| ISO 27001 | Info security management | ISMS controls, risk assessment |
AI/ML Model Review
Bias Testing
| Metric | Definition | Threshold |
|---|
| Demographic Parity | Equal prediction rates across groups | < 10% difference |
| Equalized Odds | Equal TPR/FPR across groups | < 5% difference |
| Disparate Impact | 4/5ths rule | Ratio > 0.8 |
Bias checklist:
Prompt Injection Defense
| Vector | Attack | Mitigation |
|---|
| Direct injection | User overrides system prompt | Input/output separation, delimiters |
| Indirect injection | Malicious content in RAG docs | Content sanitization, trust boundaries |
| Jailbreaking | System prompt extraction | Prompt hardening, output filtering |
def safe_llm_call(user_input: str, system_prompt: str) -> str:
sanitized = sanitize_user_input(user_input)
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": f"<user_input>\n{sanitized}\n</user_input>"},
]
response = llm.chat(messages=messages, max_tokens=1000, temperature=0.0)
filtered = filter_pii(response.content)
filtered = filter_system_prompt_leakage(filtered, system_prompt)
return filtered
Prompt injection checklist:
Performance Review Patterns
Complexity Thresholds
| Context | Max Acceptable | Flag |
|---|
| Hot path (API handler) | O(n log n) | O(n²) or worse |
| Background job | O(n²) acceptable | O(n³) or worse |
| Database query | O(n log n) with index | Full table scan >10k rows |
for i, a in enumerate(items):
for j, b in enumerate(items):
if i != j and a == b: ...
seen = set()
for item in items:
if item in seen: ...
seen.add(item)
Complexity checklist:
Memory Leak Patterns
cache = {}
def get_user(user_id):
if user_id not in cache:
cache[user_id] = db.fetch(user_id)
return cache[user_id]
@lru_cache(maxsize=1000)
def get_user(user_id):
return db.fetch(user_id)
Memory checklist:
Concurrency Bugs
if not os.path.exists(path):
with open(path, 'w') as f: f.write(data)
fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
counter = get_counter(); counter += 1; set_counter(counter)
db.execute("UPDATE counters SET value = value + 1 WHERE id = %s", (id,))
Concurrency checklist:
OWASP API Security Top 10 2023
| # | Name | Attack Vector | Fix |
|---|
| API1 | Broken Object Level Auth (BOLA) | Manipulate object IDs | Per-object ownership checks |
| API2 | Broken Authentication | Credential stuffing, token abuse | Rate limiting, short-lived tokens, MFA |
| API3 | Broken Object Property Auth | Mass assignment, excessive data | Explicit allowlist DTOs |
| API4 | Unrestricted Resource Consumption | No rate limits | Rate limiting, pagination caps |
| API5 | Function Level Authorization | Guess admin endpoints | RBAC on every endpoint |
| API6 | Sensitive Business Flows | Bot abuse | CAPTCHA, behavioral analysis |
| API7 | SSRF | Internal service access | URL allowlist, block private IPs |
| API8 | Security Misconfiguration | Verbose errors, CORS | Security headers, strict CORS |
| API9 | Improper Inventory | Shadow APIs | API inventory, deprecate old versions |
| API10 | Unsafe API Consumption | Trusting third-party data | Validate all external responses |
BOLA Mitigation Pattern
@app.get("/orders/{order_id}")
def get_order(order_id: str):
return db.get_order(order_id)
@app.get("/orders/{order_id}")
def get_order(order_id: str, user = Depends(get_current_user)):
order = db.get_order(order_id)
if order.owner_id != user.id and user.role != "admin":
raise HTTPException(status_code=404)
return order
Mass Assignment Prevention
@app.put("/users/me")
def update_user(data: dict, user = Depends(get_current_user)):
db.update_user(user.id, data)
class UserUpdateRequest(BaseModel):
name: str | None = None
email: str | None = None
@app.put("/users/me")
def update_user(data: UserUpdateRequest, user = Depends(get_current_user)):
db.update_user(user.id, data.model_dump(exclude_unset=True))
SSRF Prevention
BLOCKED_CIDRS = [
"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16",
"127.0.0.0/8", "169.254.0.0/16", "::1/128", "fc00::/7",
]
def validate_url(url: str) -> str:
parsed = urlparse(url)
if parsed.scheme not in ("https",):
raise ValueError("Only HTTPS allowed")
ip = socket.getaddrinfo(parsed.hostname, None)[0][4][0]
addr = ipaddress.ip_address(ip)
for cidr in BLOCKED_CIDRS:
if addr in ipaddress.ip_network(cidr):
raise ValueError(f"Blocked: {ip} in {cidr}")
return url
Supply Chain Security
SLSA Levels
| Level | Build | Provenance | Key Guarantee |
|---|
| SLSA 0 | No requirements | None | No guarantees |
| SLSA 1 | Scripted build | Unsigned provenance | Provenance available |
| SLSA 2 | Hosted CI platform | Signed by build service | Tamper resistance |
| SLSA 3 | Hardened, isolated, ephemeral | Non-falsifiable signature | Tamper proof |
Supply Chain Attack Case Studies
SolarWinds (2020): Compromised build system injected backdoor. 18,000+ orgs affected.
- Build system must be isolated from source repo access
- Build process must be reproducible
- Multiple independent build pipelines for critical artifacts
npm attacks: event-stream (2018), ua-parser-js (2021), colors/faker (2022).
- Lockfile committed and verified in CI
- Dependencies pinned by hash
npm audit run in CI with failure on high/critical
- No
preinstall/postinstall from untrusted packages
PyPI attacks: colorama typosquat (2022), dependency confusion, ctx backdoor (2022).
- Internal packages scoped to private registry
pip-audit run in CI
- Hash checking mode (
--require-hashes)
Dependency Verification Checklist
syft dir:. -o spdx-json > sbom.spdx.json
grype sbom:sbom.spdx.json --fail-on high
npm ci --ignore-scripts
npm audit --audit-level=high
LLM/AI Security (OWASP LLM Top 10)
| Rank | Vulnerability | Review Focus |
|---|
| LLM01 | Prompt Injection | Input separation, output filtering |
| LLM02 | Sensitive Info Disclosure | Output filtering, PII detection |
| LLM03 | Supply Chain | Model provenance, data validation |
| LLM04 | Data/Model Poisoning | Data provenance, anomaly detection |
| LLM05 | Improper Output Handling | Output encoding, sandboxing |
| LLM06 | Excessive Agency | Least privilege, human approval |
| LLM07 | System Prompt Leakage | Prompt hardening, output filtering |
| LLM08 | Vector/Embedding Weaknesses | Source trust boundaries |
| LLM09 | Misinformation | Fact-checking, source attribution |
| LLM10 | Unbounded Consumption | Rate limiting, token budgets |
Excessive Agency Defense
FUNCTION_PERMISSIONS = {
"read_user_profile": {"risk": "low", "confirmation": False},
"update_user_email": {"risk": "medium", "confirmation": True},
"delete_user_account": {"risk": "critical", "confirmation": True, "mfa_required": True},
"execute_sql": {"risk": "critical", "disabled": True},
}
async def execute_llm_function(function_name: str, args: dict, user: User):
perms = FUNCTION_PERMISSIONS.get(function_name, {"disabled": True})
if perms.get("disabled"):
raise PermissionError(f"Function {function_name} is disabled")
if perms.get("confirmation"):
return PendingConfirmation(function=function_name, args=args)
return await call_function(function_name, args)
Container Security Scanning
Scanner Comparison
| Feature | Trivy | Grype | Snyk Container |
|---|
| License | Apache 2.0 | Apache 2.0 | Commercial (free tier) |
| Speed | Fast | Fast | Medium |
| Dockerfile lint | Yes | No | Yes |
| Secret scanning | Yes | No | Yes |
| IaC scanning | Yes | No | No |
| Fix guidance | Yes | No | Yes |
| Best for | All-in-one | Fast dep scanning | Developer workflow |
trivy image --severity HIGH,CRITICAL --exit-code 1 myapp:latest
grype myapp:latest --fail-on high
snyk container test myapp:latest --severity-threshold=high
Dockerfile Checklist
trivy config Dockerfile
checkov -f Dockerfile
hadolint Dockerfile
IaC Security Scanning
Scanner Comparison
| Feature | Checkov | tfsec | KICS |
|---|
| Terraform | Excellent | Excellent (dedicated) | Good |
| CloudFormation | Yes | No | Yes |
| Kubernetes | Yes | Limited | Yes |
| Custom rules | Python/Bicep | Go | Rego (OPA) |
| Best for | Multi-platform | Terraform-specific | Multi-platform + OPA |
checkov -d . --framework terraform,kubernetes,cloudformation
tfsec . --minimum-severity HIGH
kics scan -p . --fail-on high
Common IaC Misconfigurations
# BAD: Public S3 bucket
resource "aws_s3_bucket_acl" "data" {
acl = "public-read" # CRITICAL
}
# GOOD: Private with encryption
resource "aws_s3_bucket_public_access_block" "data" {
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
securityContext:
privileged: true
runAsRoot: true
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
IaC checklist:
Secret Detection
Scanner Comparison
| Feature | git-secrets | TruffleHog | detect-secrets |
|---|
| Approach | Pattern (regex) | Pattern + verified | Pattern (plugins) |
| Git integration | Hooks (pre-commit) | Full history scan | Pre-commit hook |
| Verified scanning | No | Yes (checks if live) | No |
| Best for | AWS repos | Comprehensive | Python repos |
git secrets --install && git secrets --register-aws
trufflehog git file://. --only-verified
detect-secrets scan > .secrets.baseline
Secret detection checklist:
Policy as Code
Tool Comparison
| Feature | OPA (Rego) | Kyverno | Sentinel | Cloud Custodian |
|---|
| Language | Rego | YAML | HCL | YAML |
| Platform | Any | Kubernetes only | HashiCorp | AWS/Azure/GCP |
| Learning curve | High | Low | Medium | Low |
| Mutating webhooks | No | Yes | No | No |
| Best for | Complex multi-platform | K8s admission | Terraform governance | Cloud resource hygiene |
# OPA — Deny containers not from approved registry
deny[msg] {
input.request.kind.kind == "Pod"
container := input.request.object.spec.containers[_]
not startswith(container.image, "registry.example.com/")
msg := sprintf("Container '%s' must use approved registry", [container.name])
}
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-resource-limits
spec:
validationFailureAction: Enforce
rules:
- name: check-container-resources
match:
any:
- resources:
kinds: ["Pod"]
validate:
message: "All containers must have CPU and memory limits"
pattern:
spec:
containers:
- resources:
limits:
memory: "?*"
cpu: "?*"
Policy as Code checklist:
Zero Trust Architecture
NIST SP 800-207 Core Tenets
- All data sources and computing services are resources
- All communication secured regardless of network location
- Access granted per-session, not persistent
- Access determined by dynamic policy (identity, device, context)
- Enterprise monitors integrity/security posture of all assets
- Authentication and authorization dynamic and strictly enforced
- Enterprise collects maximum info for trust decisions
Zero Trust Deployment Models
| Model | Description | Complexity |
|---|
| Network-centric | Micro-segmentation, SDN/SDP | Medium |
| Identity-centric | Strong identity + MFA + device trust | Medium |
| Application-centric | Per-app access proxy (BeyondCorp) | High |
| Data-centric | Classification-driven, DLP + encryption | High |
Zero Trust checklist:
SPIFFE/SPIRE Service Identity
SPIFFE ID: spiffe://trust-domain/workload-identifier
| SVID Type | Lifetime | Use Case |
|---|
| X.509 SVID | Hours | mTLS between services |
| JWT SVID | Minutes | API auth, user delegation |
SPIFFE/SPIRE checklist:
mTLS Service Mesh Comparison
| Feature | Istio | Linkerd | Cilium |
|---|
| Data plane | Envoy (C++) | linkerd2-proxy (Rust) | eBPF + Envoy |
| Cert lifetime | 24h, configurable | 24h, configurable | Configurable |
| Auto-mTLS | PeerAuthentication: STRICT | On by default | encryption.enabled: true |
| Policy | AuthorizationPolicy (L4/L7) | ServerAuthorization | CiliumNetworkPolicy (L3-L7) |
| Resource overhead | High (~50MB/pod) | Low (~10MB/pod) | Lowest (eBPF) |
| Best for | Complex policies | Simplicity | Performance-critical |
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mtls:
mode: STRICT
mTLS checklist:
Secret Management
Comparison
| Feature | Vault | AWS Secrets Manager | Sealed Secrets | External Secrets Operator |
|---|
| Dynamic secrets | Yes | No (rotation only) | No | No (syncs) |
| Multi-cloud | Yes | AWS only | Any K8s | Any K8s + any provider |
| GitOps safe | No | No | Yes | Yes |
| Complexity | High | Low | Low | Medium |
| Best for | Dynamic creds, PKI | AWS-native | Simple GitOps | Multi-provider sync |
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "my-app"
vault.hashicorp.com/agent-inject-secret-db-creds: "database/creds/my-role"
Secret management checklist:
Container Runtime Security
Runtime Security Comparison
| Feature | Falco | Sysdig Secure | KubeArmor |
|---|
| Primary function | Detection (alert) | Detection + Response | Enforcement (block) |
| Kernel integration | eBPF / module | eBPF | AppArmor / BPF-LSM / SELinux |
| Enforcement | No (alert only) | Yes (kill, pause, isolate) | Yes (block at kernel) |
| Overhead | Low (2-5% CPU) | Medium (3-7%) | Low (1-3% BPF-LSM) |
| License | Apache 2.0 | Commercial | Apache 2.0 |
| Best for | Detection + audit | Full platform | Active blocking |
- rule: Shell in Container
condition: >
spawned_process and container and
proc.name in (bash, sh, zsh, dash, ksh)
output: "Shell spawned (user=%user.name container=%container.name shell=%proc.name)"
priority: WARNING
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
name: block-shell-in-webapp
spec:
selector:
matchLabels:
app: webapp
process:
matchPaths:
- path: /bin/sh
action: Block
- path: /bin/bash
action: Block
Runtime security checklist:
DevSecOps Pipeline Security Gates
| Phase | Gate | Tools | FAIL Criteria |
|---|
| Plan | Threat Model | STRIDE, OWASP Threat Dragon | Unmitigated HIGH threats |
| Code | Pre-commit | detect-secrets, trufflehog | Any secret in diff |
| Build | SCA + SAST | Trivy, Semgrep, CodeQL | CRITICAL CVE; HIGH+ SAST |
| Test | DAST + IAST | ZAP, Burp Suite | OWASP Top 10 confirmed |
| Deploy | IaC Scan | Checkov, tfsec | Public S3; unencrypted DB; root |
| Operate | Runtime | Falco, Sysdig | Crypto mining; anomalous exec |
FAIL BUILD summary:
NEVER FAIL: INFO severity, low CVEs with no exploit, dev-only dep vulns
ALWAYS FAIL: Secrets in code, CRITICAL CVE with exploit, OWASP Top 10 confirmed,
public storage with sensitive data, root container in prod manifest,
unencrypted PII in IaC, zero-day (EPSS > 0.7)
CONDITIONAL: HIGH without exploit, MEDIUM SAST in non-critical, deprecated API usage
OWASP SAMM Maturity Assessment
5 Business Functions, 15 Practices
| Function | Practices |
|---|
| Governance | Strategy & Metrics, Policy & Compliance, Education & Guidance |
| Design | Threat Assessment, Security Requirements, Security Architecture |
| Implementation | Secure Build, Secure Deployment, Defect Management |
| Verification | Architecture Assessment, Requirements Testing, Security Testing |
| Operations | Incident Management, Environment Management, Operational Management |
Maturity Levels
| Level | Name | Description |
|---|
| 0 | Implicit | No formal practice |
| 1 | Initial | Basic practices in place |
| 2 | Defined | Documented and standardized |
| 3 | Managed | Measured and controlled |
| 4 | Optimized | Continuous improvement |
SAMM checklist:
CSPM (Cloud Security Posture Management)
CSPM vs CWPP vs CNAPP
| Feature | CSPM | CWPP | CNAPP |
|---|
| Focus | Infrastructure misconfig | Runtime workload protection | Unified |
| Scope | Cloud control plane | VMs, containers, serverless | Full cloud-native |
| Detection | Config drift, compliance | Malware, exploits | Both + shift-left |
| Agent | API-based (agentless) | Agent-based | Both |
| Examples | AWS Config, Prisma Cloud | Aqua, Sysdig | Wiz, Orca |
Critical Cloud Misconfigurations
| Misconfig | Risk | Fix |
|---|
| Public S3 bucket | Data exfiltration | Block public access |
| Open Security Group (0.0.0.0/0) | Lateral movement | Restrict to known CIDRs |
| Unencrypted RDS/EBS | Data breach at rest | Enable KMS encryption |
| Over-permissive IAM (:) | Privilege escalation | Least privilege |
| Public IP on DB | Direct DB access | Set false, use bastion |
API Security Testing
Burp Suite BApps for API Testing
Autorize — Authorization testing (BOLA/BFLA)
JSON Web Tokens — JWT manipulation
Active Scan++ — Enhanced scanning
Param Miner — Hidden parameter discovery
InQL — GraphQL testing
Turbo Intruder — High-speed fuzzing
ZAP CI/CD Integration
api-security:
runs-on: ubuntu-latest
steps:
- name: ZAP API Scan
uses: zaproxy/action-api-scan@v0.7.0
with:
target: https://staging.example.com/openapi.json
format: openapi
Sigstore & SBOM
Cosign Usage
cosign sign --yes ghcr.io/org/app@sha256:abc123
cosign verify \
--certificate-identity=user@example.com \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
ghcr.io/org/app@sha256:abc123
cosign attest --predicate sbom.spdx.json --type spdxjson \
ghcr.io/org/app@sha256:abc123
SBOM Tools
| Tool | Format | Strengths |
|---|
| Syft | SPDX, CycloneDX | Fast, accurate, multiple formats |
| Grype | Reads SPDX/CycloneDX | Fast vuln matching, EPSS scoring |
| Trivy | SPDX, CycloneDX | All-in-one (SBOM + vuln + secret) |
syft dir:. -o spdx-json > sbom.spdx.json
grype sbom:sbom.spdx.json --fail-on high
trivy image --format cyclonedx --output sbom.cdx.json ghcr.io/org/app:v1.0
Supply chain security final checklist:
Microservices Security Architecture
Zero Trust Principles
| Principle | Implementation | Review Check |
|---|
| Verify explicitly | Auth every request with strong identity | No implicit trust from network location |
| Least privilege | JIT/JEA access | Services have minimum required permissions |
| Assume breach | Encrypt all, segment networks | Blast radius minimized by design |
Service Identity & mTLS
| Pattern | Mechanism | Trade-off |
|---|
| JWT propagation | Pass JWT through chain | Stateless, token size grows |
| OAuth2 token exchange | Exchange at each hop (RFC 8693) | Secure, adds latency |
| SPIFFE/SPIRE | Workload identity separate from user | Strong, infrastructure overhead |
| OPA/Gatekeeper | Policy eval at each hop | Flexible, management complexity |
Identity propagation checklist:
Network Segmentation
| Layer | Tool | Review Check |
|---|
| K8s NetworkPolicy | Calico, Cilium | Default-deny ingress; explicit allow per service |
| Service mesh authz | Istio AuthorizationPolicy | L7 policies (method, path, headers) |
| Cloud VPC/subnet | AWS VPC, GCP VPC | Separate subnets, no unnecessary peering |
| API Gateway | Kong, Envoy | Rate limiting, auth, WAF at edge |
| Egress controls | Istio ServiceEntry | Only reach required external endpoints |
Network segmentation checklist:
Microservices Security Master Checklist
Authentication & Authorization:
Data Protection:
Observability & Incident Response:
Resilience:
Deployment & Configuration:
Advanced Threat Modeling
Attack Trees
Hierarchical decomposition of attack goals. Root = attacker objective, leaves = exploit steps.
[Root Goal: Steal user data]
├── [AND] Compromise auth layer
│ ├── [OR] Credential stuffing
│ │ ├── Leaked credential databases
│ │ └── Password spray attacks
│ └── [OR] Session hijacking
│ ├── XSS-based cookie theft
│ └── Session fixation
├── [AND] Access data store
│ ├── [OR] SQL injection
│ └── [OR] SSRF to internal DB
└── [AND] Exfiltrate data
├── [OR] DNS tunneling
└── [OR] Encrypted channel to C2
Attack tree workflow:
- Identify root goal from PR context
- Build tree with AND (all required) / OR (any sufficient) gates
- For each leaf, check if PR introduces or mitigates that vector
- Calculate attack cost: sum effort of cheapest OR-path
- Flag if attack cost < defense cost
Attack tree checklist:
Cyber Kill Chain (Lockheed Martin)
| Stage | Description | Code Review Focus | Mitigation |
|---|
| 1. Reconnaissance | Target research | Rate limiting, info leakage | No verbose errors in prod |
| 2. Weaponization | Crafting exploit | Input validation | Schema validation, allowlisting |
| 3. Delivery | Transmitting exploit | Transport security | TLS 1.3, CSP headers |
| 4. Exploitation | Triggering vuln | Surface reduction | Parameterized queries, sandboxing |
| 5. Installation | Persistence | File integrity | Immutable containers, read-only FS |
| 6. C2 | Remote control | Egress monitoring | Network policies, DNS filtering |
| 7. Actions | Data theft | Data protection | Encryption, DLP, audit logging |
Kill chain checklist:
MITRE ATT&CK Mapping
| Tactic ID | Name | Review Focus |
|---|
| TA0001 | Initial Access | Phishing, valid accounts, supply chain |
| TA0002 | Execution | Command injection, deserialization |
| TA0003 | Persistence | Backdoors, scheduled tasks |
| TA0004 | Privilege Escalation | SUID, kernel exploits |
| TA0005 | Defense Evasion | Obfuscation, log deletion |
| TA0006 | Credential Access | Brute force, credential dumping |
| TA0008 | Lateral Movement | Remote services, SSH hijacking |
| TA0010 | Exfiltration | Over C2, DNS, alt protocols |
| TA0040 | Impact | Data destruction, ransomware |
Common technique-to-code mappings:
| Technique ID | Name | Code Pattern to Review |
|---|
| T1059 | Command Interpreter | os.system(), eval(), exec() |
| T1078 | Valid Accounts | Default creds, weak password policy |
| T1190 | Exploit Public-Facing App | SQLi, XSS, SSRF in endpoints |
| T1053 | Scheduled Task | Cron/K8s CronJobs with excessive perms |
| T1071 | App Layer Protocol | DNS tunneling, HTTP beaconing |
| T1486 | Data Encrypted for Impact | Ransomware, backup integrity |
MITRE ATT&CK checklist:
pip install pytm
pytm --dfd diagram ./model.py
pip install threatspec
threatspec init && threatspec report
ISO 27001 for Engineering
ISMS Clauses (4–10)
| Clause | Requirement | Engineering Mapping |
|---|
| 4 | Context | Define in-scope systems, data classification |
| 5 | Leadership | Security policy in repo, CISO sign-off |
| 6 | Planning | Threat model per service, risk register |
| 7 | Support | Security training, tool budgets |
| 8 | Operation | CI/CD security gates, SAST/DAST |
| 9 | Performance | Security metrics, quarterly internal audits |
| 10 | Improvement | Post-incident reviews, maturity progression |
Annex A Engineering Controls (A.8.25–A.8.34)
| Control | Name | Implementation |
|---|
| A.8.25 | Secure dev lifecycle | SAST/DAST in CI, code review required |
| A.8.26 | App security requirements | Security requirements in user stories |
| A.8.27 | Secure architecture | Architecture review, defense-in-depth |
| A.8.28 | Secure coding | Coding standards (CWE Top 25), input validation |
| A.8.29 | Security testing | SAST (Semgrep), DAST (ZAP), SCA (Trivy) |
| A.8.30 | Outsourced dev | Vendor security assessment, code ownership |
| A.8.31 | Separation of envs | No prod data in dev, different access per env |
| A.8.32 | Change management | PR-based, approval gates, rollback |
| A.8.33 | Test information | No real PII/PHI in tests, synthetic data |
| A.8.34 | Test data protection | Automated scrubbing, retention limits |
stages:
pre-commit:
controls: [A.8.28, A.8.25]
checks: [secret-scanning, linting]
pull-request:
controls: [A.8.25, A.8.29, A.8.32]
checks: [code-review (2 approvers), sast, sca]
build:
controls: [A.8.27, A.8.29, A.8.31]
checks: [container-scanning, sbom-generation, image-signing]
deploy:
controls: [A.8.31, A.8.32]
checks: [iac-validation, deployment-approval, rollback-tested]
ISO 27001 Audit Readiness
Risk Assessment (5×5 Matrix)
from enum import IntEnum
class Likelihood(IntEnum):
RARE = 1; UNLIKELY = 2; POSSIBLE = 3; LIKELY = 4; ALMOST_CERTAIN = 5
class Impact(IntEnum):
NEGLIGIBLE = 1; MINOR = 2; MODERATE = 3; MAJOR = 4; CATASTROPHIC = 5
HIPAA Field-Level Encryption
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os
class PHIEncryption:
"""AES-256-GCM field-level encryption for PHI."""
def encrypt_field(self, plaintext: str, field_name: str) -> bytes:
field_key = self._derive_key(self._get_master_key(), field_name)
aesgcm = AESGCM(field_key)
nonce = os.urandom(12)
ciphertext = aesgcm.encrypt(
nonce, plaintext.encode("utf-8"),
field_name.encode("utf-8"),
)
return nonce + ciphertext
def decrypt_field(self, data: bytes, field_name: str) -> str:
nonce, ciphertext = data[:12], data[12:]
field_key = self._derive_key(self._get_master_key(), field_name)
return AESGCM(field_key).decrypt(
nonce, ciphertext, field_name.encode("utf-8")
).decode("utf-8")
def _derive_key(self, master_key: bytes, context: str) -> bytes:
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives import hashes
return HKDF(algorithm=hashes.SHA256(), length=32, salt=None,
info=f"phi-field-{context}".encode()).derive(master_key)
HIPAA Audit Log (Immutable, 6-Year Retention)
class HIPAAAuditLog:
"""Immutable PHI access audit log with integrity chain."""
def record_access(self, user_id, action, resource_type, resource_id,
fields_accessed, purpose, ip_address, success):
event = {
"event_id": generate_ulid(),
"timestamp": datetime.utcnow().isoformat() + "Z",
"user_id": user_id,
"action": action,
"resource_id_hash": hashlib.sha256(resource_id.encode()).hexdigest()[:16],
"fields_accessed": fields_accessed,
"purpose": purpose,
"ip_address": ip_address,
"previous_event_hash": self._previous_hash,
}
event_hash = hashlib.sha256(json.dumps(event, sort_keys=True).encode()).hexdigest()
event["event_hash"] = event_hash
self.storage.append(event)
self._previous_hash = event_hash
return event_hash
def verify_chain_integrity(self) -> bool:
events = self.storage.read_all()
previous_hash = None
for event in events:
if event.get("previous_event_hash") != previous_hash:
return False
stored_hash = event.pop("event_hash")
computed = hashlib.sha256(json.dumps(event, sort_keys=True).encode()).hexdigest()
if computed != stored_hash:
return False
previous_hash = stored_hash
event["event_hash"] = stored_hash
return True
HIPAA Break-Glass Emergency Access
class HIPAAAccessControl:
"""RBAC with MFA and break-glass emergency access."""
FIELD_ACCESS = {
"physician": {"*"},
"nurse": {"demographics", "vitals", "medications", "allergies"},
"pharmacist": {"medications", "allergies", "prescriptions"},
"billing": {"demographics", "insurance", "billing_codes"},
"admin": set(),
"emergency": {"*"},
}
def check_access(self, user, patient_id, fields, purpose):
if not user.mfa_verified:
return AccessDecision(allowed=False, denial="MFA required")
allowed = self.FIELD_ACCESS.get(user.role, set())
unauthorized = [f for f in fields if "*" not in allowed and f not in allowed]
if unauthorized:
return AccessDecision(allowed=False, denial=f"Cannot access: {unauthorized}")
if not self._has_care_relationship(user.id, patient_id):
return AccessDecision(allowed=False, denial="No care relationship")
if user.last_activity < datetime.utcnow() - timedelta(minutes=15):
return AccessDecision(allowed=False, denial="Session expired (15min)")
return AccessDecision(allowed=True)
def activate_break_glass(self, user, reason):
"""Emergency PHI access — auto-expires 4h, reviewed within 24h."""
access = BreakGlassAccess(
user_id=user.id, reason=reason,
started_at=datetime.utcnow(),
expires_at=datetime.utcnow() + timedelta(hours=4),
)
self.alert_security_team(f"BREAK-GLASS: {user.name} — {reason}")
self.scheduler.schedule_revoke(access.access_id, access.expires_at)
return access
GDPR Technical Implementation
Consent Management (TCF 2.0)
Consent Management Platform (CMP):
Purposes (10): Store/access device info, Basic ads, Personalised ads,
Personalised content, Measurement, Improve products, Market research,
Data sharing, Data linking, Precise geolocation
Legal Bases: Consent (Art. 6(1)(a)), Legitimate Interest (Art. 6(1)(f))
Consent string format: TCF v2
Stored: first-party cookie or localStorage
function canProcessData(purposeId, vendorId) {
const consentString = getTCConsentString();
const tcModel = TCString.decode(consentString);
if (!tcModel.purposeConsents.has(purposeId)) return false;
if (!tcModel.vendorConsents.has(vendorId)) return false;
return true;
}
Data Minimization Enforcement
class DataMinimizationValidator:
"""Validate only necessary data collected per Art. 5(1)(c)."""
REQUIRED_PURPOSES = {
"registration": ["email", "name"],
"payment": ["email", "billing_address", "payment_token"],
"analytics": ["session_id", "page_views"],
}
def validate_collection(self, purpose: str, fields: dict) -> list:
findings = []
allowed = self.REQUIRED_PURPOSES.get(purpose, [])
for field_name in fields:
if field_name not in allowed:
findings.append(Finding(
severity="high", article="Art. 5(1)(c)",
description=f"Unnecessary: '{field_name}' for '{purpose}'",
))
return findings
DPIA (Data Protection Impact Assessment)
DPIA required when (Art. 35):
DPIA structure: Processing description → Necessity assessment → Risk assessment → Mitigation measures → DPO consultation → Annual review
BeyondCorp — Google's Zero Trust
Architecture Components
| Component | Function |
|---|
| Device Inventory Service | Tracks all managed devices (serial, owner, patch level, EDR) |
| Access Proxy | Single entry point, TLS termination, auth, policy enforcement |
| Access Control Engine | Central policy evaluation (identity + device trust + context) |
| Continuous Evaluation | Re-evaluate sessions on signal change |
Trust Tiers
| Tier | Device Status | User Auth | Access Level |
|---|
| Full Trust | Managed, patched, encrypted, EDR active | MFA recent (<8h) | All apps |
| Partial Trust | Managed, some drift or off-network | MFA older (>8h) | Most apps, not crown jewels |
| Untrusted | Unmanaged or non-compliant | Basic auth | Public apps only, read-only |
BeyondCorp checklist:
Dockerfile Security Examples
# BAD: Running as root, no multi-stage, unpinned base
FROM node:20
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "server.js"]
# GOOD: Non-root, multi-stage, pinned, minimal
FROM node:20.11-alpine3.19 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --ignore-scripts && npm cache clean --force
COPY . .
RUN npm run build
FROM node:20.11-alpine3.19
RUN addgroup -g 1001 appgroup && adduser -u 1001 -G appgroup -s /bin/sh -D appuser
WORKDIR /app
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]
Kubernetes Security Context Examples
apiVersion: v1
kind: Pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "250m"
Performance Profiling Tools
python -m cProfile -o profile.prof script.py
python -m snakeviz profile.prof
pip install memory_profiler
python -m memory_profiler script.py
py-spy record -o profile.svg -- python script.py
go test -race ./...
jstack <pid> > thread_dump.txt
Cloud Misconfig Detection Scripts
aws s3api list-buckets --query 'Buckets[].Name' --output text | while read bucket; do
acl=$(aws s3api get-bucket-acl --bucket "$bucket" 2>/dev/null)
if echo "$acl" | grep -q "AllUsers"; then
echo "CRITICAL: $bucket is publicly accessible"
fi
done
aws ec2 describe-security-groups \
--filters Name=ip-permission.cidr,Values='0.0.0.0/0' \
--query 'SecurityGroups[*].[GroupId,GroupName]' --output table
Review Metrics
Process metrics:
- Review turnaround time (request to first response)
- Total review cycle time (request to merge)
- PR size distribution (lines changed, files touched)
- Review iteration count (comments-to-merge cycles)
Quality metrics:
- Defect escape rate (post-merge bugs vs during review)
- Comment density (comments per 100 lines changed)
- Post-merge revert rate
Research findings (SmartBear 2024):
- Best defect detection: patches under 400 lines
- Diminishing returns after 200-400 LOC per review
- Review rate >500 LOC/hour drops defect detection
- Sweet spot: 60-90 min review sessions
Related Skills
- sdlc-testing-qa: Test pyramid (unit/integration/e2e), TDD/BDD, property-based testing, mutation testing, contract tes
- sdlc-legal-compliance: Software company legal and compliance: GDPR, SOC 2, CCPA, privacy policy, terms of service, data pro
- sdlc-deployment: Deployment strategies: canary, blue-green, rolling, progressive delivery, feature flags, rollback, d