Skip to main content

Chapter 13: Security and Performance Constraints


Learning Objectives

By the end of this chapter, you will be able to:

  • Define security constraints for JWT tokens, password hashing, PII handling, authentication, rate limiting, and input validation
  • Define performance constraints for frontend bundles, API latency, database queries, memory usage, and connection pools
  • Create a security and performance constraint document for a project
  • Integrate constraints into CI/CD pipelines as build gates
  • Understand how constraint violations trigger build failure

From Requirements to Constraints

Non-functional requirements (NFRs) from Chapter 11 define what you want: "API should be fast," "passwords should be secure." Constraints define how you achieve it in a way that is enforceable: "JWT access tokens MUST expire within 15 minutes," "Passwords MUST be hashed with bcrypt cost factor ≥12."

The difference: an NFR says "we care about security." A constraint says "here is the exact rule; violate it and the build fails."

Think of it like building codes. The requirement is "buildings must be safe." The constraint is "all electrical wiring must use 12-gauge copper, installed by licensed electricians, inspected before occupancy." The constraint is specific enough to verify.


Security Constraints

Security constraints protect against the vulnerabilities that AI-generated code often introduces: weak authentication, exposed secrets, unvalidated input, and improper data handling.

Real-World Analogy: The Bank Vault

A bank's requirement: "Protect customer assets." The constraints: vault doors must be 18-inch steel; time locks prevent opening outside business hours; two-person rule for access; cameras record all entry. Each constraint is measurable. An auditor can verify compliance. Security constraints in software work the same way: they turn "be secure" into verifiable rules.


Security Constraint 1: JWT Token Policies

The rule: JWT tokens must have bounded lifetime, use strong signing algorithms, and never include sensitive data in payload.

Why it matters: AI often generates JWTs with long expiration (e.g., 30 days), weak algorithms (HS256 with short keys), or sensitive data in the payload. These create significant security risks.

Constraint specification:

## SEC-001: JWT Token Policies

### Access Tokens
- Expiration: MUST NOT exceed 15 minutes
- Signing algorithm: RS256 or ES256 (asymmetric) REQUIRED; HS256 only with 256-bit+ secret
- Payload: MUST NOT include PII beyond user identifier
- Storage: MUST NOT be stored in localStorage; use httpOnly cookies or memory

### Refresh Tokens
- Expiration: MUST NOT exceed 7 days
- Rotation: MUST be invalidated on use (one-time use)
- Storage: httpOnly cookie with Secure, SameSite=Strict

### Violation
- Linter/static analysis flags hardcoded long expiration
- Security review rejects PR with localStorage token storage

Code example (compliant):

// Compliant JWT configuration
const tokenConfig = {
accessToken: {
expiresIn: '15m', // SEC-001: ≤15 min
algorithm: 'RS256', // SEC-001: asymmetric
},
refreshToken: {
expiresIn: '7d', // SEC-001: ≤7 days
rotate: true, // SEC-001: one-time use
},
};

// Payload: only user id, no PII
const payload = { sub: user.id, iat: now(), exp: now() + 15 * 60 };

Code example (violation):

// VIOLATION: 30-day access token, HS256, PII in payload
const token = jwt.sign(
{ userId: user.id, email: user.email }, // PII in payload — VIOLATION
'short-secret', // Weak secret — VIOLATION
{ expiresIn: '30d', algorithm: 'HS256' } // Long expiry, weak algo — VIOLATION
);

Security Constraint 2: Password Hashing Requirements

The rule: Passwords must be hashed with bcrypt (or Argon2), with minimum cost factor. Plain text or weak hashing (MD5, SHA1 alone) is forbidden.

Why it matters: AI sometimes generates MD5 or SHA1 for "simplicity," or bcrypt with cost factor 4 (too weak). Constraint enforces industry standards.

Constraint specification:

## SEC-002: Password Hashing

- Algorithm: bcrypt REQUIRED (Argon2id acceptable alternative)
- Cost factor: bcrypt cost MUST be ≥12 (2^12 iterations)
- Salt: MUST use per-password unique salt (bcrypt handles this)
- Comparison: MUST use constant-time comparison (e.g., crypto.timingSafeEqual)
- Plain text: Passwords MUST NOT be logged, stored, or transmitted in plain text

### Violation
- Build fails if MD5, SHA1, or plain text storage detected
- Code review rejects cost factor < 12

Code example (compliant):

import bcrypt from 'bcrypt';

const SALT_ROUNDS = 12; // SEC-002: ≥12

async function hashPassword(plain: string): Promise<string> {
return bcrypt.hash(plain, SALT_ROUNDS);
}

async function verifyPassword(plain: string, hash: string): Promise<boolean> {
return bcrypt.compare(plain, hash); // bcrypt uses constant-time comparison
}

Security Constraint 3: PII Handling Rules

The rule: Personally Identifiable Information (PII) must never appear in logs, error messages, or client responses beyond what is strictly necessary. PII at rest must be encrypted.

Why it matters: AI-generated code often logs request bodies (which may contain passwords, SSNs), includes PII in error messages ("User john@example.com not found"), or returns full user objects when only an ID is needed. These create compliance and privacy risks.

Constraint specification:

## SEC-003: PII Handling

### Logging
- PII MUST NOT appear in log messages (email, name, address, phone, SSN, etc.)
- Use redaction: log "User [REDACTED] failed login" not "User john@example.com failed"
- Request/response logging MUST redact sensitive fields

### Error Messages
- Client-facing errors MUST NOT expose PII
- "Invalid credentials" not "User alice@example.com password incorrect"
- Stack traces MUST NOT be sent to clients in production

### Storage
- PII at rest MUST be encrypted (AES-256 or equivalent)
- Encryption keys MUST NOT be in source code or config files in repo

### Violation
- Log scanning (e.g., grep for email patterns) fails build
- Security review rejects PR with PII in logs

Code example (compliant):

// Compliant: redacted logging
logger.warn('Login failed', { userId: user.id }); // No email in log

// Compliant: generic error to client
res.status(401).json({ error: 'Invalid credentials' });

// VIOLATION: PII in log
logger.warn(`Login failed for ${user.email}`); // SEC-003 violation

Security Constraint 4: Authentication Requirements

The rule: All API endpoints require authentication by default. Exceptions (e.g., login, health check) must be explicitly listed and justified.

Why it matters: AI often forgets to add auth to new endpoints. "Secure by default" means the default is "auth required"; you opt out for specific routes, not opt in.

Constraint specification:

## SEC-004: Authentication Default

- All API endpoints MUST require authentication by default
- Exceptions MUST be explicitly listed in ALLOWED_ANONYMOUS_ROUTES
- Each exception MUST have documented rationale
- Health/readiness endpoints MAY be anonymous

### Allowed Anonymous Routes (example)
| Route | Rationale |
|-------|-----------|
| POST /api/auth/login | Authentication endpoint |
| GET /health | Load balancer health check |
| GET /api/public/announcements | Public content |

### Violation
- Middleware rejects unauthenticated requests unless route in allowlist
- Audit: any new route without auth middleware flagged in PR

Code example (compliant):

// Auth middleware: require auth unless route is in allowlist
const ALLOWED_ANONYMOUS = ['/api/auth/login', '/api/auth/register', '/health'];

app.use((req, res, next) => {
if (ALLOWED_ANONYMOUS.some(r => req.path.startsWith(r))) {
return next();
}
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Authentication required' });
// verify token...
next();
});

Security Constraint 5: Rate Limiting Policies

The rule: All public-facing endpoints must have rate limiting. Authentication endpoints must have stricter limits to prevent brute force.

Why it matters: Without rate limiting, APIs are vulnerable to abuse, DoS, and brute-force attacks. AI rarely adds rate limiting unless explicitly asked.

Constraint specification:

## SEC-005: Rate Limiting

- All endpoints MUST have rate limiting
- Default: 100 requests per minute per IP (or per user when authenticated)
- Auth endpoints (login, register, password reset): 5 requests per minute per IP
- Burst: Allow short burst (e.g., 10 requests in 1 second) then throttle

### Violation
- Deployment blocked if rate limiter not configured
- Load test: verify 429 returned when limit exceeded

Code example (compliant):

import rateLimit from 'express-rate-limit';

// General API: 100/min
const apiLimiter = rateLimit({
windowMs: 60 * 1000,
max: 100,
message: { error: 'Too many requests' },
});

// Auth: 5/min to prevent brute force
const authLimiter = rateLimit({
windowMs: 60 * 1000,
max: 5,
message: { error: 'Too many login attempts' },
});

app.use('/api/', apiLimiter);
app.use('/api/auth/login', authLimiter);

Security Constraint 6: Input Validation Mandates

The rule: All user input must be validated. SQL injection and XSS prevention are mandatory. Use parameterized queries; sanitize output.

Why it matters: AI sometimes generates code with string concatenation in SQL, or renders user input without escaping. These are critical vulnerabilities.

Constraint specification:

## SEC-006: Input Validation

### SQL Injection Prevention
- MUST use parameterized queries or ORM; NEVER string concatenation for SQL
- Pattern: `db.query('SELECT * FROM users WHERE id = $1', [id])`

### XSS Prevention
- All user-supplied output MUST be escaped (or use framework's safe templating)
- Content-Security-Policy header RECOMMENDED

### General Validation
- Validate type, length, format for all inputs
- Reject unknown fields (strict schema validation)
- Use allowlists over blocklists

### Violation
- Static analysis flags string concatenation in SQL
- Security scan fails on unescaped output

Code example (violation):

// VIOLATION: SQL injection
const user = await db.query(`SELECT * FROM users WHERE id = '${req.params.id}'`);

// CORRECT: parameterized
const user = await db.query('SELECT * FROM users WHERE id = $1', [req.params.id]);

Performance Constraints

Performance constraints turn "fast" into measurable limits. They prevent AI from generating code that works in development but fails under load.

Real-World Analogy: The Highway Speed Limit

"You should drive safely" is a requirement. "Maximum 65 mph" is a constraint. The constraint is measurable. Performance constraints do the same: "API should be fast" becomes "p95 latency < 300ms."


Performance Constraint 1: Frontend Bundle Size Limits

The rule: Initial JavaScript bundle must not exceed a defined size (e.g., 250 KB gzipped). Code splitting required for larger applications.

Why it matters: AI often adds entire libraries for one feature, or generates monolithic bundles. Users on slow connections suffer. Constraint forces conscious choices about dependencies and splitting.

Constraint specification:

## PERF-001: Frontend Bundle Size

- Initial bundle (main chunk): MUST NOT exceed 250 KB gzipped
- Route-based code splitting REQUIRED for routes not on critical path
- Lazy load: Heavy libraries (charts, PDF viewers) MUST be lazy-loaded
- Audit: `npm run build` MUST fail if bundle exceeds limit

### Violation
- CI: bundle-size check fails
- Tools: size-limit, bundlesize, or custom script

Enforcement example:

// package.json
{
"scripts": {
"build": "vite build && npm run check-bundle-size",
"check-bundle-size": "node scripts/check-bundle-size.js"
}
}
// scripts/check-bundle-size.js
const fs = require('fs');
const path = require('path');
const gzipSize = require('gzip-size');

const mainChunk = fs.readFileSync(path.join('dist', 'assets', 'index-*.js'));
const size = gzipSize.sync(mainChunk);
const limit = 250 * 1024; // 250 KB

if (size > limit) {
console.error(`Bundle size ${(size/1024).toFixed(1)} KB exceeds limit ${limit/1024} KB`);
process.exit(1);
}

Performance Constraint 2: API Latency Budgets

The rule: API endpoints must meet latency targets: p95 < 300ms, p99 < 500ms for standard endpoints. Slow endpoints require justification.

Why it matters: AI doesn't optimize by default. N+1 queries, synchronous operations, and missing indexes cause production latency. Constraints force measurement and optimization.

Constraint specification:

## PERF-002: API Latency Budgets

- p95 latency: MUST be < 300ms for standard CRUD endpoints
- p99 latency: MUST be < 500ms
- Exceptions: Export, report, or batch endpoints MAY have higher limits (document)
- Measurement: APM or custom middleware; alert on violation

### Violation
- Performance test fails if p95 > 300ms
- Production alert when budget exceeded

Enforcement: Integrate with APM (Datadog, New Relic) or custom middleware that records percentiles and fails performance tests when budgets are exceeded.


Performance Constraint 3: Database Query Limits

The rule: Individual database queries must complete within 100ms. N+1 query patterns are forbidden.

Why it matters: Slow queries are the most common production performance killer. AI often generates N+1 patterns (loop with query per item). Constraint forces batch queries, joins, or eager loading.

Constraint specification:

## PERF-003: Database Query Limits

- Single query: MUST complete in < 100ms (p95)
- N+1 pattern: FORBIDDEN; use batch load, join, or eager loading
- Query count per request: SHOULD NOT exceed 10 for typical endpoints
- Indexes: All WHERE/JOIN columns MUST have indexes

### Violation
- Query logging flags slow queries
- Integration test fails if N+1 detected (e.g., query count > threshold)

Code example (violation):

// VIOLATION: N+1 queries
const orders = await orderRepo.findAll();
for (const order of orders) {
order.items = await itemRepo.findByOrderId(order.id); // N+1!
}

Code example (compliant):

// CORRECT: batch load
const orders = await orderRepo.findAll();
const orderIds = orders.map(o => o.id);
const items = await itemRepo.findByOrderIds(orderIds); // Single query
const itemsByOrder = groupBy(items, 'orderId');
orders.forEach(o => { o.items = itemsByOrder[o.id] || []; });

Performance Constraint 4: Memory Usage Caps

The rule: Process memory must not exceed a defined limit (e.g., 512 MB for API server). Prevents memory leaks and runaway processes.

Why it matters: AI-generated code sometimes has memory leaks (unclosed connections, growing caches). Constraint forces monitoring and limits.

Constraint specification:

## PERF-004: Memory Usage

- Process heap: MUST NOT exceed 512 MB under normal load
- Cache size: MUST have bounded size (LRU or TTL)
- Connection pools: MUST have max size limits

### Violation
- Container memory limit; OOM kill
- Monitoring alert on sustained high memory

Performance Constraint 5: Connection Pool Sizing

The rule: Database and HTTP connection pools must have explicit max size. Prevents connection exhaustion.

Why it matters: Unbounded pools can exhaust database connections. AI often uses default pool sizes without considering concurrency.

Constraint specification:

## PERF-005: Connection Pool Sizing

- Database pool max: MUST be set explicitly; default 10-20 for typical app
- Pool size MUST be < database max_connections / number of app instances
- HTTP client pool: MUST have connection limit

### Violation
- Config review: pool size must be set
- Load test: verify no connection exhaustion under expected load

The Security and Performance Constraint Document

Combine all constraints into a single document:

# Security and Performance Constraints

## Metadata
- Version: 1.0
- Last Updated: 2026-03-09

## Security Constraints

| ID | Rule | Enforcement |
|----|------|-------------|
| SEC-001 | JWT: 15min access, RS256, no PII in payload | Linter, review |
| SEC-002 | bcrypt cost ≥12 | Code review |
| SEC-003 | No PII in logs | Log scan |
| SEC-004 | Auth required by default | Middleware, audit |
| SEC-005 | Rate limiting on all endpoints | Config check |
| SEC-006 | Parameterized queries, input validation | Static analysis |

## Performance Constraints

| ID | Rule | Enforcement |
|----|------|-------------|
| PERF-001 | Bundle < 250 KB gzipped | CI script |
| PERF-002 | API p95 < 300ms | Perf test |
| PERF-003 | Query < 100ms, no N+1 | Query log, test |
| PERF-004 | Memory < 512 MB | Container limit |
| PERF-005 | Connection pool bounded | Config review |

## Detailed Specifications

[Expand each constraint with full rule, rationale, examples]

Tutorial: Create a Security and Performance Constraint Document

Step 1: Choose Your Project

Use your running project (e.g., collaboration platform API) or a hypothetical "Task Management API."

Step 2: Security Constraints

Create specs/constraints/security.md:

  1. SEC-001: JWT policies—set your access/refresh token expiry and algorithm.
  2. SEC-002: Password hashing—bcrypt cost 12.
  3. SEC-003: PII—list which fields are PII; add log redaction rules.
  4. SEC-004: Auth—list ALLOWED_ANONYMOUS routes.
  5. SEC-005: Rate limits—set limits for API and auth endpoints.
  6. SEC-006: Input validation—confirm parameterized queries; add validation library.

Step 3: Performance Constraints

Create specs/constraints/performance.md:

  1. PERF-001: Bundle size—measure current bundle; set limit (e.g., 250 KB).
  2. PERF-002: API latency—set p95/p99 budgets.
  3. PERF-003: Query limits—add query logging; set 100ms threshold.
  4. PERF-004: Memory—set container memory limit.
  5. PERF-005: Connection pool—set pool size in config.

Step 4: Add Enforcement

For each constraint, add at least one enforcement mechanism:

  • CI script: e.g., scripts/check-security.sh that greps for violations
  • Linter rule: e.g., ESLint plugin for no-eval, no-innerHTML
  • Test: e.g., integration test that verifies rate limit returns 429
  • Config: e.g., required env vars for JWT expiry

Step 5: Integrate with CI/CD

Add a constraint-check job to your pipeline:

# .github/workflows/ci.yml
jobs:
constraints:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Security constraint check
run: |
# Fail if SQL string concatenation
if grep -r "db.query.*\${" src/; then exit 1; fi
# Fail if JWT expiry > 15min
if grep -r "expiresIn.*[2-9][0-9]*m\|expiresIn.*[0-9]*h\|expiresIn.*[0-9]*d" src/; then exit 1; fi
- name: Bundle size check
run: npm run check-bundle-size

How Constraints Become CI/CD Gates

Constraints become gates when violation causes build failure. The pipeline must not pass if constraints are violated.

Gate Types

  1. Static analysis: Linter, security scanner (e.g., Semgrep, Snyk) fails on violation.
  2. Unit/integration tests: Test asserts constraint (e.g., "rate limit returns 429").
  3. Custom scripts: Shell script greps for forbidden patterns.
  4. Performance tests: k6, Artillery, or similar—fail if latency budget exceeded.
  5. Deployment: Container resource limits (memory, CPU) enforce PERF-004.

Constraint Violation as Build Failure

The key principle: constraint violation = build failure. No exceptions without documented override.

# Example: constraint check job
- name: Constraint compliance
run: |
./scripts/check-constraints.sh
if [ $? -ne 0 ]; then
echo "Constraint violation. Fix before merging."
exit 1
fi

When the check fails, the developer must fix the violation or document an approved exception (e.g., in COMPLEXITY.md or SECURITY_EXCEPTIONS.md).


Constraint Prioritization: What to Enforce First

Not all constraints can be enforced on day one. Prioritize based on risk and feasibility:

Tier 1: Must Enforce Immediately (Build Failure)

  • SEC-006: SQL injection prevention (parameterized queries)—critical vulnerability
  • SEC-002: Password hashing (bcrypt cost)—critical for auth
  • PERF-001: Bundle size—affects all users

These have clear, automated checks. Add them to CI first.

Tier 2: Enforce via Code Review

  • SEC-001: JWT policies—requires human judgment for some cases
  • SEC-003: PII in logs—hard to automate fully; use grep + review
  • SEC-004: Auth default—middleware can enforce; audit for new routes

Add to PR checklist. Automate where possible.

Tier 3: Monitor in Production

  • PERF-002: API latency—measure in production; alert on violation
  • PERF-003: Query time—log slow queries; optimize iteratively
  • PERF-004: Memory—container limits + monitoring

These are operational constraints. CI can run performance tests, but production monitoring is primary.


Security Constraint Checklist for AI-Generated Code

When reviewing AI-generated code, use this checklist:

ConstraintCheck
SEC-001JWT expiry ≤15min? Algorithm RS256/ES256? No PII in payload?
SEC-002bcrypt? Cost ≥12? No plain text?
SEC-003Any PII in logs? Error messages safe?
SEC-004New endpoint has auth? In allowlist if anonymous?
SEC-005Rate limiter configured? Stricter for auth?
SEC-006Parameterized queries? Input validated? Output escaped?

Run this checklist on every PR that touches auth, API, or data access.


Performance Constraint Checklist

ConstraintCheck
PERF-001Bundle size measured? Under limit?
PERF-002Latency budget defined? Test exists?
PERF-003N+1 avoided? Queries indexed?
PERF-004Memory limit set? Cache bounded?
PERF-005Connection pool configured?

Common AI Security Mistakes and Constraints That Prevent Them

AI MistakeConstraintEnforcement
Long JWT expirySEC-001Linter flags expiresIn: '30d'
Weak password hashSEC-002Reject cost < 12
Logging request bodySEC-003Log scanner flags email/SSN patterns
New route without authSEC-004Middleware + route audit
No rate limitingSEC-005Config check; deploy block
String concat in SQLSEC-006Semgrep, grep, or linter
Huge bundlePERF-001size-limit in CI
N+1 queriesPERF-003Query count test

Try With AI

Prompt 1: Security Audit

"Review this code for security constraint violations: [paste code]. Check against: (1) JWT policies—expiry, algorithm, PII in payload; (2) password hashing—bcrypt cost; (3) PII in logs; (4) SQL injection risk; (5) missing input validation. List each violation with file and line number, and suggest the fix."

Prompt 2: Constraint Document Generation

"Generate a security and performance constraint document for a [Node/Express | Python/FastAPI | etc.] API. Include: JWT policies, password hashing, PII handling, auth default, rate limiting, input validation, bundle size, API latency, database query limits. Use the format from this chapter with ID, rule, rationale, enforcement, and violation consequence."

Prompt 3: CI/CD Gate Design

"I have these constraints: SEC-001 (JWT 15min), SEC-006 (no SQL concatenation), PERF-001 (bundle 250KB). Design CI/CD steps that would fail the build when these are violated. Give me the exact commands or config for [GitHub Actions | GitLab CI | Jenkins]."

Prompt 4: Violation Fix

"This code violates SEC-003 (no PII in logs): [paste logging code]. Rewrite it to redact PII while preserving useful debugging information. What patterns should we use for redaction?"


Practice Exercises

Exercise 1: Security Constraint Audit

Take an existing API (yours or open source). Audit it against SEC-001 through SEC-006. Document every violation. For each, write the constraint that would have prevented it. Create a specs/constraints/security.md for that project.

Expected outcome: A security constraints document and a list of current violations with remediation plan.

Exercise 2: Performance Constraint Implementation

Add enforcement for PERF-001 (bundle size) and PERF-003 (query time) to a project. For bundle size: add a script that fails the build if the main chunk exceeds 250 KB. For query time: add middleware that logs slow queries (>100ms) and fails tests if N+1 is detected (e.g., query count > 10 per request).

Expected outcome: Working CI checks that fail on constraint violation.

Exercise 3: Constraint Document for New Project

Design a new "File Upload API" that accepts user uploads, stores them in S3, and provides download links. Write a complete security and performance constraint document before any code. Include: auth, rate limiting (stricter for upload), input validation (file type, size), PII (filenames might be PII?), and performance (upload timeout, concurrent upload limit). Then implement the API and verify it complies.

Expected outcome: Constraint document and compliant implementation.


Key Takeaways

  1. Security constraints turn "be secure" into verifiable rules: JWT policies, password hashing, PII handling, auth-by-default, rate limiting, input validation.

  2. Performance constraints turn "be fast" into measurable limits: bundle size, API latency budgets, query time, memory caps, connection pool sizing.

  3. Constraint document format includes ID, rule, rationale, enforcement mechanism, and violation consequence. Use consistent IDs (SEC-001, PERF-001) for traceability.

  4. Constraints become CI/CD gates when violation causes build failure. Use static analysis, tests, custom scripts, and performance tests.

  5. Constraint violation = build failure. No silent violations. Exceptions require documented justification and approval.

  6. Enforcement mechanisms must exist for every constraint. Unenforceable constraints will be violated.


Chapter Quiz

  1. What is the difference between a non-functional requirement and a security constraint? Give an example of each for "secure authentication."

  2. List the six security constraints covered in this chapter. For each, give one example of a violation.

  3. Why must JWT access tokens expire within 15 minutes? What attack does this mitigate?

  4. What is the bcrypt cost factor? Why must it be ≥12?

  5. Explain the "auth required by default" constraint. How do you implement it?

  6. What are the five performance constraints? How would you enforce PERF-001 (bundle size)?

  7. How do constraints become CI/CD gates? What happens when a constraint is violated?

  8. Design a rate limiting constraint for a login endpoint. What limit would you set and why?


Appendix: Security and Performance Constraint Quick Reference

Security Constraints (SEC-001 to SEC-006)

IDRuleKey Value
SEC-001JWT: 15min access, RS256, no PIIToken security
SEC-002bcrypt cost ≥12Password protection
SEC-003No PII in logsPrivacy compliance
SEC-004Auth required by defaultSecure by default
SEC-005Rate limitingDoS/brute-force prevention
SEC-006Parameterized queries, validationInjection prevention

Performance Constraints (PERF-001 to PERF-005)

IDRuleKey Value
PERF-001Bundle < 250 KB gzippedFast load
PERF-002API p95 < 300msResponsive API
PERF-003Query < 100ms, no N+1Efficient data access
PERF-004Memory < 512 MBResource bounds
PERF-005Connection pool boundedNo exhaustion

Enforcement Quick Reference

MechanismBest For
LinterCode patterns (SQL concat, long expiry)
Grep/scriptsSimple pattern checks
Integration testRate limit, auth, N+1
Performance testLatency, bundle size
Config reviewPool size, env vars
Code reviewPII, JWT payload, cost factor