feat(config): validate clients and scope security

This commit is contained in:
2026-09-14 01:07:46 +02:00
parent 5b0c623a8d
commit a3cee2756c
17 changed files with 230 additions and 437 deletions
+8
View File
@@ -7,6 +7,14 @@ git.md rules-git Git operations such as commits, branches, or merges
microsoft.md rules-microsoft Microsoft 365, Azure DevOps, or Teams operations
refactoring.md rules-refactoring refactoring existing code without changing behavior
security.md rules-security any software development task: implementing, modifying, debugging, reviewing, testing, or configuring code, scripts, hooks, or infrastructure
security-auth.md rules-security-auth authentication, authorization, sessions, tokens, permissions, or tenant-boundary work
security-web.md rules-security-web web, browser, frontend, cookie, redirect, or XSS/CSRF work
security-api.md rules-security-api HTTP API, request handling, serialization, or endpoint work
security-data.md rules-security-data database, query, persistence, sensitive-data, or multi-tenant work
security-files.md rules-security-files file, upload, archive, path, process, IPC, or deserialization work
security-network.md rules-security-network network, URL fetch, proxy, outbound request, TLS, or SSRF work
security-crypto.md rules-security-crypto cryptography, secrets, credentials, key, or token work
security-supply-chain.md rules-security-supply-chain dependency, package, plugin, build, deployment, or CI supply-chain work
typescript.md rules-typescript TypeScript or modern ECMAScript implementation work
ui-ux.md rules-ui-ux UI or UX design and interaction decisions
wpf.md rules-wpf WPF, XAML, or MVVM desktop UI work
1 rule_file skill_name trigger
7 microsoft.md rules-microsoft Microsoft 365, Azure DevOps, or Teams operations
8 refactoring.md rules-refactoring refactoring existing code without changing behavior
9 security.md rules-security any software development task: implementing, modifying, debugging, reviewing, testing, or configuring code, scripts, hooks, or infrastructure
10 security-auth.md rules-security-auth authentication, authorization, sessions, tokens, permissions, or tenant-boundary work
11 security-web.md rules-security-web web, browser, frontend, cookie, redirect, or XSS/CSRF work
12 security-api.md rules-security-api HTTP API, request handling, serialization, or endpoint work
13 security-data.md rules-security-data database, query, persistence, sensitive-data, or multi-tenant work
14 security-files.md rules-security-files file, upload, archive, path, process, IPC, or deserialization work
15 security-network.md rules-security-network network, URL fetch, proxy, outbound request, TLS, or SSRF work
16 security-crypto.md rules-security-crypto cryptography, secrets, credentials, key, or token work
17 security-supply-chain.md rules-security-supply-chain dependency, package, plugin, build, deployment, or CI supply-chain work
18 typescript.md rules-typescript TypeScript or modern ECMAScript implementation work
19 ui-ux.md rules-ui-ux UI or UX design and interaction decisions
20 wpf.md rules-wpf WPF, XAML, or MVVM desktop UI work
+1
View File
@@ -8,6 +8,7 @@ status_line = ["model", "reasoning", "project-name", "git-branch", "context-wind
[agents]
enabled = true
max_concurrent_threads_per_session = 5
max_depth = 1
[features]
hooks = true
+5 -7
View File
@@ -1,13 +1,11 @@
# Configuration
Codex receives a generated global `AGENTS.md`, agent TOML files, skills, rule files, and a `config.toml` adapter with workspace sandboxing, interactive approval boundaries, automatic approval review, enabled sub-agents, and a five-thread concurrency limit (`max_concurrent_threads_per_session`, the current canonical key; the legacy `max_threads` alias is not emitted). Claude Code receives a generated global `CLAUDE.md`, agent Markdown files, skills, and `settings.json` with the `auto` permission mode, explicit `Agent` permission, and a five-operation tool/sub-agent concurrency limit. The exact installed locations are resolved from the user profile at install time; no machine-specific absolute path is stored in the repository.
Codex receives a generated global `AGENTS.md`, agent TOML files, skills, rule files, and a `config.toml` adapter. It keeps workspace sandboxing, automatic approval review, `agents.enabled = true`, `agents.max_concurrent_threads_per_session = 5`, and `agents.max_depth = 1`. Claude Code receives a generated global `CLAUDE.md`, agent Markdown files, skills, and `settings.json` with `auto` permissions, explicit `Agent` permission, and five-operation concurrency. Installation resolves user paths at runtime; the repository contains no machine-specific paths.
Claude's rule loading differs from Codex's by design: `general.md` is the only rule shipped as a plain, always-applied file (its text is also embedded directly in `CLAUDE.md`). Every technology- or situation-specific rule in `shared/rules/` is instead generated as a skill under `skills/rules/`, driven by `adapters/claude/rule-skills.tsv` (rule file, skill name, trigger description). Only a skill's name and description are ever permanently in context; Claude loads the full rule text only when it invokes the skill. Codex is unaffected — it keeps receiving every rule as a plain file and is told to load the matching one by path, exactly as before.
Codex keeps rules as files and loads only applicable focused rules. Claude embeds `general.md` and generates the remaining rules as skills from `adapters/claude/rule-skills.tsv`. `security.md` is a short universal baseline; focused security rules load only for authentication, web, API, data, files, network, cryptography, and supply-chain work.
Codex's current configuration schema has no `agents.max_depth` or other agent-recursion-depth key. The only `max_depth`-shaped setting in the schema is `network_proxy.glob_scan_max_depth`, which bounds glob-pattern expansion for the network proxy feature and is unrelated to agents; Claude Code's settings likewise expose no comparable key. The repository does not emit either as an invented key.
`agents.max_depth = 1` limits V1 Codex subagent recursion. `features.multi_agent_v2` is not enabled. If enabled later, V2 takes precedence over `agents.enabled` and ignores `agents.max_depth`.
`[agents].enabled = true` (set explicitly, matching its own documented default) is the current, documented way to enable Codex's multi-agent tools. A separate `[features].multi_agent` toggle exists in the schema but is not set here, since `[agents].enabled` already covers it and setting both would be redundant. `multi_agent_v2` does not appear in the current documented schema at all — it surfaced only in upstream issue titles describing an internal/experimental flag — so it is deliberately not configured.
The build parses TOML with Python's standard-library `tomllib`, validates the emitted Claude settings shape, and uses `codex --strict-config` against an isolated generated configuration when Codex is available. This rejects malformed and unknown Codex configuration keys for the installed CLI version.
Client settings remain thin adapters. Shared semantics remain in `shared/`.
User plugins are managed separately through `adapters/plugins.tsv` and the client-native plugin commands. They are not copied into `generated/` because each client owns its plugin cache and authentication state.
Client settings remain thin adapters. Shared semantics remain in `shared/`. User plugins are managed separately through `adapters/plugins.tsv` and client-native installation commands.
+38 -7
View File
@@ -12,7 +12,7 @@ $pluginEntries = @(Import-Csv -LiteralPath $pluginManifest -Delimiter ([char]9))
if ($pluginEntries.Count -eq 0) { throw 'Plugin manifest must define at least one plugin.' }
$pluginNames = @()
foreach ($pluginEntry in $pluginEntries) {
foreach ($field in @('name','claude_plugin','codex_plugin')) {
foreach ($field in @('name','claude_plugin','codex_method')) {
if ([string]::IsNullOrWhiteSpace($pluginEntry.$field)) { throw "Missing $field for plugin $($pluginEntry.name)." }
}
if ($pluginNames -contains $pluginEntry.name) { throw "Duplicate plugin name in manifest: $($pluginEntry.name)" }
@@ -52,6 +52,32 @@ function Read-Field($path, $name) {
function Quote-Toml($value) {
return ('"' + $value.Replace('\','\\').Replace('"','\"').Replace("`r",'').Replace("`n",'\n') + '"')
}
function Test-CodexSchema($configPath) {
if (-not (Get-Command codex -ErrorAction SilentlyContinue)) {
if ($env:REQUIRE_CODEX_SCHEMA -eq 'true') { throw 'Codex CLI is required for schema validation.' }
Write-Warning 'Codex CLI unavailable; skipped Codex schema validation.'
return
}
$tempHome = Join-Path ([System.IO.Path]::GetTempPath()) ("codex-schema-" + [Guid]::NewGuid())
$previousCodexHome = $env:CODEX_HOME
try {
New-Item $tempHome -ItemType Directory -Force | Out-Null
Copy-Item $configPath (Join-Path $tempHome 'config.toml') -Force
$env:CODEX_HOME = $tempHome
$previousErrorActionPreference = $ErrorActionPreference
try {
$ErrorActionPreference = 'Continue'
$schemaOutput = @(& codex --strict-config --help 2>&1)
$schemaExitCode = $LASTEXITCODE
} finally {
$ErrorActionPreference = $previousErrorActionPreference
}
if ($schemaExitCode -ne 0) { throw "Codex schema validation failed: $configPath`n$($schemaOutput -join [Environment]::NewLine)" }
} finally {
$env:CODEX_HOME = $previousCodexHome
Remove-Item $tempHome -Recurse -Force -ErrorAction SilentlyContinue
}
}
& (Join-Path $root 'shared/hooks/scripts/Test-SessionConfig.ps1') -RepositoryRoot $root
@@ -75,6 +101,14 @@ Detect the languages, frameworks, tools, and change areas from the repository an
Load rule files when their subject applies:
- rules/security-auth.md for authentication, authorization, sessions, tokens, permissions, or tenant boundaries.
- rules/security-web.md for browser, frontend, cookie, redirect, XSS, or CSRF work.
- rules/security-api.md for HTTP APIs, request handling, serialization, or endpoints.
- rules/security-data.md for databases, persistence, sensitive data, or multi-tenancy.
- rules/security-files.md for files, uploads, archives, paths, processes, IPC, or deserialization.
- rules/security-network.md for network access, URLs, TLS, proxies, or SSRF.
- rules/security-crypto.md for cryptography, secrets, credentials, keys, or tokens.
- rules/security-supply-chain.md for dependencies, packages, plugins, builds, deployments, or CI.
- rules/angular.md for Angular work.
- rules/typescript.md for TypeScript work.
- rules/csharp.md for C# or .NET work.
@@ -154,13 +188,10 @@ foreach ($platform in @('windows','linux')) {
}
$tomlPath = Join-Path $output "codex-$platform/config.toml"
$tomlContent = Get-Content -LiteralPath $tomlPath -Raw
if (([regex]::Matches($tomlContent, '(?<!\\)"')).Count % 2 -ne 0) { throw "Generated Codex config.toml has unbalanced quotes: $tomlPath" }
if (([regex]::Matches($tomlContent, '\[')).Count -ne ([regex]::Matches($tomlContent, '\]')).Count) { throw "Generated Codex config.toml has unbalanced brackets: $tomlPath" }
$settingsPath = Join-Path $output "claude-$platform/settings.json"
try { Get-Content -LiteralPath $settingsPath -Raw | ConvertFrom-Json | Out-Null }
catch { throw "Generated Claude settings.json is not valid JSON: $settingsPath" }
& python (Join-Path $root 'scripts/validate-config.py') $tomlPath $settingsPath
if ($LASTEXITCODE -ne 0) { throw "Generated configuration validation failed for $platform." }
Test-CodexSchema $tomlPath
}
$leftoverPlaceholders = @(Get-ChildItem $output -File -Recurse | ForEach-Object {
+19 -12
View File
@@ -84,6 +84,14 @@ Detect the languages, frameworks, tools, and change areas from the repository an
Load rule files when their subject applies:
- rules/security-auth.md for authentication, authorization, sessions, tokens, permissions, or tenant boundaries.
- rules/security-web.md for browser, frontend, cookie, redirect, XSS, or CSRF work.
- rules/security-api.md for HTTP APIs, request handling, serialization, or endpoints.
- rules/security-data.md for databases, persistence, sensitive data, or multi-tenancy.
- rules/security-files.md for files, uploads, archives, paths, processes, IPC, or deserialization.
- rules/security-network.md for network access, URLs, TLS, proxies, or SSRF.
- rules/security-crypto.md for cryptography, secrets, credentials, keys, or tokens.
- rules/security-supply-chain.md for dependencies, packages, plugins, builds, deployments, or CI.
- rules/angular.md for Angular work.
- rules/typescript.md for TypeScript work.
- rules/csharp.md for C# or .NET work.
@@ -180,19 +188,18 @@ for client in codex claude; do
done
toml_path="$output/codex-$platform/config.toml"
quote_count=$(grep -o '"' "$toml_path" | wc -l)
[ $((quote_count % 2)) -eq 0 ] || { printf 'Generated Codex config.toml has unbalanced quotes: %s\n' "$toml_path" >&2; exit 1; }
open_brackets=$(grep -o '\[' "$toml_path" | wc -l)
close_brackets=$(grep -o '\]' "$toml_path" | wc -l)
[ "$open_brackets" -eq "$close_brackets" ] || { printf 'Generated Codex config.toml has unbalanced brackets: %s\n' "$toml_path" >&2; exit 1; }
settings_path="$output/claude-$platform/settings.json"
if command -v jq >/dev/null 2>&1; then
jq empty "$settings_path" >/dev/null 2>&1 || { printf 'Generated Claude settings.json is not valid JSON: %s\n' "$settings_path" >&2; exit 1; }
elif command -v python3 >/dev/null 2>&1 && python3 --version >/dev/null 2>&1; then
# On Windows, `python3` can resolve to a non-functional Microsoft Store app-execution
# alias that still passes `command -v`; probe it with a real invocation before trusting it.
python3 -c 'import json,sys; json.load(open(sys.argv[1], encoding="utf-8"))' "$settings_path" || { printf 'Generated Claude settings.json is not valid JSON: %s\n' "$settings_path" >&2; exit 1; }
python3 "$root/scripts/validate-config.py" "$toml_path" "$settings_path"
if command -v codex >/dev/null; then
schema_home=$(mktemp -d)
cp "$toml_path" "$schema_home/config.toml"
CODEX_HOME="$schema_home" codex --strict-config --help >/dev/null
rm -rf -- "$schema_home"
elif [ "${REQUIRE_CODEX_SCHEMA:-false}" = true ]; then
printf 'Codex CLI is required for schema validation.\n' >&2
exit 1
else
printf 'WARN Codex CLI unavailable; skipped Codex schema validation.\n' >&2
fi
done
+16 -3
View File
@@ -42,9 +42,16 @@ if (Test-Path -LiteralPath $settingsPath) {
}
$configTomlPath = Join-Path $homePath '.codex/config.toml'
if (Test-Path -LiteralPath $configTomlPath) {
$tomlContent = Get-Content -LiteralPath $configTomlPath -Raw
$balanced = (([regex]::Matches($tomlContent, '(?<!\\)"')).Count % 2 -eq 0) -and (([regex]::Matches($tomlContent, '\[')).Count -eq ([regex]::Matches($tomlContent, '\]')).Count)
if ($balanced) { Result 'PASS' 'installed .codex/config.toml looks structurally valid' } else { Result 'FAIL' 'installed .codex/config.toml has unbalanced quotes or brackets' }
$parseResult = & python -c 'import sys,tomllib,pathlib; tomllib.loads(pathlib.Path(sys.argv[1]).read_text(encoding="utf-8-sig"))' $configTomlPath 2>&1
if ($LASTEXITCODE -eq 0) { Result 'PASS' 'installed .codex/config.toml parses as TOML' } else { Result 'FAIL' "installed .codex/config.toml is invalid TOML: $parseResult" }
if (Get-Command codex -ErrorAction SilentlyContinue) {
$previousCodexHome = $env:CODEX_HOME
try {
$env:CODEX_HOME = Split-Path $configTomlPath -Parent
$schemaResult = & codex --strict-config --help 2>&1
if ($LASTEXITCODE -eq 0) { Result 'PASS' 'installed .codex/config.toml matches the installed Codex schema' } else { Result 'FAIL' "installed .codex/config.toml has unsupported Codex settings: $schemaResult" }
} finally { $env:CODEX_HOME = $previousCodexHome }
} else { Result 'WARN' 'Codex CLI unavailable; skipped installed Codex schema validation' }
}
foreach ($destination in @((Join-Path $homePath '.codex'), (Join-Path $homePath '.agents/skills'), (Join-Path $homePath '.claude'))) {
@@ -64,6 +71,12 @@ foreach ($destination in @((Join-Path $homePath '.codex'), (Join-Path $homePath
foreach ($path in @('shared/rules','shared/skills','shared/agents','shared/hooks/scripts')) { if (Test-Path (Join-Path $root $path)) { Result 'PASS' "source $path" } else { Result 'FAIL' "missing $path" } }
foreach ($client in @('codex','claude')) {
$config = if ($client -eq 'codex') { Join-Path $root 'adapters/codex/config/config.toml' } else { Join-Path $root 'adapters/claude/config/settings.json' }
$registered = if ($client -eq 'codex') { (Get-Content $config -Raw) -match '\[\[hooks\.Stop\]\]' } else { ((Get-Content $config -Raw | ConvertFrom-Json).hooks.PSObject.Properties.Name -contains 'Stop') }
if ($registered) { Result 'PASS' "$client Stop hook is registered" } else { Result 'WARN' "$client ships hook utilities, but no Stop hook is registered" }
}
if ($fail) { exit 1 }
Write-Output 'PASS doctor'
exit 0
+6 -6
View File
@@ -55,14 +55,14 @@ if [ -f "$home_path/.claude/settings.json" ]; then
fi
fi
if [ -f "$home_path/.codex/config.toml" ]; then
quote_count=$(grep -o '"' "$home_path/.codex/config.toml" | wc -l)
open_brackets=$(grep -o '\[' "$home_path/.codex/config.toml" | wc -l)
close_brackets=$(grep -o '\]' "$home_path/.codex/config.toml" | wc -l)
if [ $((quote_count % 2)) -eq 0 ] && [ "$open_brackets" -eq "$close_brackets" ]; then
result PASS 'installed .codex/config.toml looks structurally valid'
if python3 -c 'import sys,tomllib,pathlib; tomllib.loads(pathlib.Path(sys.argv[1]).read_text(encoding="utf-8-sig"))' "$home_path/.codex/config.toml"; then
result PASS 'installed .codex/config.toml parses as TOML'
else
result FAIL 'installed .codex/config.toml has unbalanced quotes or brackets'
result FAIL 'installed .codex/config.toml is invalid TOML'
fi
if command -v codex >/dev/null; then
if CODEX_HOME="$home_path/.codex" codex --strict-config --help >/dev/null 2>&1; then result PASS 'installed .codex/config.toml matches the installed Codex schema'; else result FAIL 'installed .codex/config.toml has unsupported Codex settings'; fi
else result WARN 'Codex CLI unavailable; skipped installed Codex schema validation'; fi
fi
for destination in "$home_path/.codex" "$home_path/.agents/skills" "$home_path/.claude"; do
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env python3
"""Validate the generated configuration formats without third-party packages."""
from __future__ import annotations
import json
import sys
import tomllib
from pathlib import Path
CLAUDE_TOP_LEVEL = {"permissions", "env", "statusLine", "hooks"}
CLAUDE_PERMISSION_KEYS = {"defaultMode", "allow", "deny"}
CLAUDE_STATUS_LINE_KEYS = {"type", "command"}
CLAUDE_HOOK_KEYS = {"type", "command", "timeout"}
CLAUDE_PERMISSION_MODES = {"acceptEdits", "auto", "bypassPermissions", "default", "dontAsk", "plan"}
def fail(message: str) -> None:
raise ValueError(message)
def require_keys(value: object, allowed: set[str], label: str) -> dict[str, object]:
if not isinstance(value, dict):
fail(f"{label} must be an object")
unknown = set(value) - allowed
if unknown:
fail(f"{label} has unknown keys: {', '.join(sorted(unknown))}")
return value
def validate_claude(path: Path) -> None:
settings = require_keys(json.loads(path.read_text(encoding="utf-8-sig")), CLAUDE_TOP_LEVEL, str(path))
permissions = require_keys(settings.get("permissions"), CLAUDE_PERMISSION_KEYS, "permissions")
if permissions.get("defaultMode") not in CLAUDE_PERMISSION_MODES:
fail("permissions.defaultMode is unsupported")
for key in ("allow", "deny"):
if not isinstance(permissions.get(key), list) or not all(isinstance(item, str) for item in permissions[key]):
fail(f"permissions.{key} must be an array of strings")
env = settings.get("env")
if not isinstance(env, dict) or not all(isinstance(key, str) and isinstance(value, str) for key, value in env.items()):
fail("env must be an object of string values")
status_line = require_keys(settings.get("statusLine"), CLAUDE_STATUS_LINE_KEYS, "statusLine")
if status_line.get("type") != "command" or not isinstance(status_line.get("command"), str):
fail("statusLine must be a command")
hooks = settings.get("hooks")
if not isinstance(hooks, dict):
fail("hooks must be an object")
for event, matchers in hooks.items():
if not isinstance(event, str) or not isinstance(matchers, list):
fail("hooks must map event names to arrays")
for matcher in matchers:
if not isinstance(matcher, dict) or not isinstance(matcher.get("hooks"), list):
fail(f"hooks.{event} must contain hook arrays")
for hook in matcher["hooks"]:
hook = require_keys(hook, CLAUDE_HOOK_KEYS, f"hooks.{event}")
if hook.get("type") != "command" or not isinstance(hook.get("command"), str) or not isinstance(hook.get("timeout"), int):
fail(f"hooks.{event} contains an unsupported command hook")
def main() -> int:
if len(sys.argv) != 3:
print("usage: validate-config.py <codex-toml> <claude-json>", file=sys.stderr)
return 2
tomllib.loads(Path(sys.argv[1]).read_text(encoding="utf-8-sig"))
validate_claude(Path(sys.argv[2]))
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except (OSError, ValueError, json.JSONDecodeError, tomllib.TOMLDecodeError) as error:
print(f"configuration validation failed: {error}", file=sys.stderr)
raise SystemExit(1)
+7
View File
@@ -0,0 +1,7 @@
# API security
* Authenticate and authorize protected endpoints; validate every request payload and identifier.
* Bound request and response sizes, pagination, query results, and expensive operations.
* Apply rate limits where abuse is plausible and keep administrative endpoints separately protected.
* Return only authorized data and never expose stack traces, internal models, or implementation details in API errors.
* Prefer explicit DTOs and schemas over deserializing arbitrary types or executable objects.
+8
View File
@@ -0,0 +1,8 @@
# Authentication and authorization security
* Use established authentication standards and password hashing; never store plaintext or reversibly encrypted passwords.
* Enforce authorization server-side for every sensitive operation and verify resource ownership and tenant boundaries.
* Use least-privilege roles, short-lived sessions or tokens where supported, and invalidate credentials after sensitive account changes.
* Validate token issuer, audience, signature, and expiry before trusting claims.
* Protect authentication and privileged actions against brute force and privilege escalation.
* Test unauthenticated, unauthorized, cross-user, and cross-tenant access paths.
+6
View File
@@ -0,0 +1,6 @@
# Cryptography and secrets security
* Never implement custom cryptographic primitives or use obsolete algorithms.
* Use established libraries, authenticated encryption, secure randomness, and verified signatures and certificates.
* Treat tokens, private keys, connection strings, and credentials as secrets; keep them out of source, URLs, command lines, logs, fixtures, and frontend code.
* Use environment-appropriate secret storage, separate environments, and rotate compromised credentials.
+7
View File
@@ -0,0 +1,7 @@
# Database and data security
* Use parameterized queries or ORM parameter binding; never concatenate untrusted input into SQL.
* Use least-privilege database accounts and protect connection strings.
* Scope tenant-owned queries explicitly and prevent cross-tenant cache, logging, and diagnostic leakage.
* Collect and retain only necessary sensitive data; encrypt it in transit and at rest where appropriate.
* Avoid raw database errors and use transactions where integrity requires atomicity.
+6
View File
@@ -0,0 +1,6 @@
# File and process security
* Validate filenames, content, sizes, and paths; prevent traversal, zip-slip, and unsafe symbolic-link use.
* Restrict access to intended directories and do not execute uploaded or untrusted files.
* Do not concatenate untrusted input into shell commands; prefer direct APIs and validate process arguments when execution is required.
* Treat local files, IPC, and deserialized input as untrusted at relevant boundaries.
+6
View File
@@ -0,0 +1,6 @@
# Network and SSRF security
* Use HTTPS and never disable certificate or TLS validation.
* Restrict inbound and outbound access to required ports, interfaces, hosts, and protocols.
* Treat user-controlled URLs as dangerous: allowlist schemes and hosts, block localhost, metadata, and internal ranges, and revalidate redirects.
* Set timeouts, response-size limits, bounded retries, and cancellation for remote operations.
+6
View File
@@ -0,0 +1,6 @@
# Supply-chain security
* Keep dependencies minimal, maintained, and from verified sources; respect lockfiles and review identity and compatibility before adding or upgrading packages.
* Pin versions where appropriate and remove unused dependencies.
* Treat plugins, build scripts, CI actions, and generated artifacts as part of the attack surface.
* Use least privilege for build and deployment identities and never expose credentials in pipelines, logs, or artifacts.
+7
View File
@@ -0,0 +1,7 @@
# Web and frontend security
* Escape or sanitize untrusted content; never inject untrusted HTML or bypass framework sanitization.
* Protect state-changing browser requests from CSRF where applicable.
* Use `HttpOnly`, `Secure`, and appropriate `SameSite` cookie settings for sensitive sessions.
* Validate redirect targets, avoid sensitive data in URLs, and use CSP and clickjacking protections where applicable.
* Treat frontend code and browser storage as visible and never rely on client-side checks for authorization.
+9 -402
View File
@@ -1,404 +1,11 @@
# Security Guidelines
# Security baseline
Security is a default requirement for all code, architecture, configuration and infrastructure changes.
Apply this baseline to every code, configuration, infrastructure, or review task.
## Core Principles
* Prefer secure defaults.
* Apply least privilege everywhere.
* Minimize exposed attack surface.
* Treat all external input as untrusted.
* Never trust client-side validation alone.
* Fail securely.
* Prefer deny-by-default over allow-by-default for sensitive operations.
* Keep security controls explicit and auditable.
* Do not weaken security for convenience.
* Do not bypass security mechanisms to make code easier to implement.
* Do not introduce insecure temporary solutions.
* Prefer simple, well-understood security mechanisms over custom cryptography or clever security logic.
## Secrets and Credentials
* Never hardcode passwords, API keys, tokens, connection strings, private keys or secrets.
* Never commit secrets to source control.
* Never log secrets or credentials.
* Never expose secrets in exceptions, diagnostics or UI messages.
* Use secure secret storage appropriate to the environment.
* Prefer short-lived credentials where supported.
* Rotate compromised credentials immediately.
* Do not reuse credentials across environments.
* Keep development, staging and production credentials separate.
* Avoid secrets in URLs, query strings or command-line arguments.
* Do not store secrets in frontend code.
* Do not include real credentials in examples, tests or fixtures.
## Authentication
* Use established authentication standards and framework capabilities.
* Do not implement custom authentication protocols without a strong reason.
* Store passwords only using modern password hashing algorithms designed for password storage.
* Never store plaintext passwords.
* Never use reversible encryption for password storage.
* Support secure session expiration.
* Invalidate sessions or tokens when security-sensitive account state changes.
* Protect authentication endpoints against brute-force abuse where applicable.
* Avoid exposing whether an account exists unless required.
* Require stronger authentication for security-sensitive actions where appropriate.
## Authorization
* Enforce authorization on the server side.
* Never rely on hidden UI elements, disabled buttons or frontend guards as authorization.
* Check authorization for every sensitive operation.
* Prefer explicit permission checks.
* Use least-privilege roles and permissions.
* Avoid broad administrative permissions unless required.
* Prevent horizontal privilege escalation between users or tenants.
* Prevent vertical privilege escalation between permission levels.
* Verify ownership of resources before access or modification.
* Do not trust identifiers supplied by the client as proof of authorization.
## Input Validation
* Validate all input from users, APIs, files, databases, queues, environment variables and external systems.
* Validate type, length, range, format and allowed values.
* Prefer allowlists over denylists.
* Reject unexpected input.
* Normalize input before validation when appropriate.
* Do not rely solely on client-side validation.
* Validate identifiers before using them for resource access.
* Validate uploaded files by content, size and expected type where applicable.
* Do not trust file extensions alone.
## Injection Prevention
* Never concatenate untrusted input into SQL.
* Use parameterized queries or ORM parameter binding.
* Never concatenate untrusted input into shell commands.
* Avoid executing shell commands when a direct API is available.
* Validate and escape command arguments when process execution is required.
* Prevent LDAP, XPath, template and expression injection where applicable.
* Avoid dynamic code execution.
* Avoid `eval`, dynamic compilation and equivalent mechanisms unless strictly required.
* Treat template engines and interpreters as security boundaries.
## Web Security
* Prevent Cross-Site Scripting by using framework escaping and sanitization.
* Never inject untrusted HTML directly.
* Avoid bypassing framework sanitization.
* Protect state-changing browser requests against CSRF where applicable.
* Use secure cookies for sensitive session data.
* Use `HttpOnly` for authentication cookies where possible.
* Use `Secure` cookies in HTTPS environments.
* Configure `SameSite` appropriately.
* Use appropriate Content Security Policy where applicable.
* Avoid leaking sensitive data through referrers or URLs.
* Validate redirect targets to prevent open redirects.
* Protect against clickjacking where applicable.
## API Security
* Authenticate sensitive endpoints.
* Authorize every protected operation.
* Validate all request payloads.
* Apply reasonable request-size limits.
* Apply pagination and bounded queries.
* Apply rate limiting where abuse is possible.
* Avoid exposing internal models directly when this leaks implementation details.
* Return only data the caller is authorized to access.
* Do not expose stack traces or internal exception details.
* Avoid excessive information in error responses.
* Version public APIs intentionally.
* Protect administrative endpoints separately where appropriate.
## Data Protection
* Collect only data that is actually required.
* Minimize storage of sensitive data.
* Classify sensitive data explicitly.
* Encrypt sensitive data in transit.
* Encrypt sensitive data at rest where appropriate.
* Do not implement custom encryption algorithms.
* Use established cryptographic libraries.
* Do not use obsolete cryptographic algorithms.
* Do not use hardcoded encryption keys.
* Use cryptographically secure random number generation for security-sensitive values.
* Avoid exposing personal or sensitive data in logs.
* Delete sensitive data when it is no longer required.
## Cryptography
* Never design custom cryptographic primitives.
* Use current, established cryptographic standards.
* Use authenticated encryption when confidentiality and integrity are required.
* Verify signatures before trusting signed content.
* Validate certificates correctly.
* Never disable certificate validation.
* Never accept all TLS certificates.
* Do not downgrade TLS security.
* Use secure randomness for tokens, nonces, identifiers and keys.
* Never use predictable random generators for security-sensitive values.
## Tokens and Sessions
* Treat tokens as secrets.
* Keep token lifetime as short as practical.
* Validate issuer, audience, signature and expiration where applicable.
* Do not accept unsigned tokens unless explicitly designed and safe.
* Do not trust token contents before validation.
* Avoid storing long-lived access tokens in insecure browser storage.
* Rotate refresh tokens where appropriate.
* Revoke compromised tokens where possible.
* Prevent replay attacks where the protocol requires it.
## File Security
* Validate file names and paths.
* Prevent path traversal.
* Never concatenate untrusted input directly into filesystem paths.
* Restrict file access to intended directories.
* Use generated server-side file names where appropriate.
* Enforce file size limits.
* Validate uploaded content.
* Do not execute uploaded files.
* Store uploads outside executable web roots where applicable.
* Handle archive extraction safely.
* Prevent zip-slip and equivalent path traversal attacks.
* Avoid following untrusted symbolic links where security-sensitive.
## Serialization
* Treat deserialized input as untrusted.
* Avoid insecure polymorphic deserialization.
* Avoid deserializing arbitrary runtime types.
* Use explicit schemas or known DTOs.
* Restrict type resolution.
* Do not deserialize executable objects or behavior.
* Validate deserialized data before use.
* Avoid insecure legacy serializers.
## Database Security
* Use parameterized queries.
* Use least-privilege database accounts.
* Do not use administrative database accounts for normal application traffic.
* Restrict schema modification permissions in runtime accounts.
* Protect connection strings.
* Avoid exposing raw database errors.
* Limit query size and result sets.
* Prevent tenant data leakage.
* Verify tenant boundaries in every relevant query.
* Use transactions where integrity requires atomicity.
## Logging and Monitoring
* Never log secrets.
* Never log passwords.
* Never log authentication tokens.
* Avoid logging sensitive personal data.
* Use structured logging.
* Include security-relevant context without exposing sensitive values.
* Log authentication and authorization failures where appropriate.
* Log suspicious or high-risk actions where appropriate.
* Avoid log injection by treating user input as data.
* Do not let logging failures break critical application behavior.
* Ensure logs have appropriate access controls.
## Error Handling
* Fail securely.
* Do not expose internal stack traces to users.
* Do not reveal implementation details unnecessarily.
* Preserve diagnostic detail internally where safe.
* Avoid different error responses that reveal sensitive existence checks where not required.
* Do not swallow security-relevant exceptions.
* Do not continue execution after critical validation or authorization failures.
## Dependencies
* Keep dependencies minimal.
* Prefer maintained and widely used packages.
* Avoid abandoned packages.
* Avoid unnecessary dependencies for trivial functionality.
* Keep dependencies updated with security patches.
* Review dependency changes before adoption.
* Do not blindly update major versions without compatibility review.
* Remove unused dependencies.
* Treat transitive dependencies as part of the attack surface.
* Verify package identity before installation.
* Avoid untrusted package sources.
* Respect lockfiles.
## Supply Chain Security
* Pin dependency versions where appropriate.
* Protect build and deployment pipelines.
* Do not expose CI/CD credentials.
* Use least privilege for pipeline identities.
* Review third-party actions, plugins and build scripts.
* Avoid executing untrusted build scripts.
* Verify artifacts and sources where practical.
* Keep generated artifacts traceable to source.
* Do not publish secrets in build logs or artifacts.
## Configuration
* Use secure production defaults.
* Do not enable debug mode in production.
* Do not expose development endpoints in production.
* Separate environment-specific configuration.
* Validate security-sensitive configuration at startup.
* Fail startup when mandatory security configuration is missing.
* Do not silently fall back to insecure settings.
* Protect configuration files containing sensitive values.
## Network Security
* Use HTTPS for sensitive or authenticated communication.
* Do not disable TLS validation.
* Restrict outbound network access where practical.
* Restrict inbound services to required ports and interfaces.
* Use timeouts for network operations.
* Limit retries to avoid amplification or denial-of-service behavior.
* Validate remote endpoints where SSRF is possible.
* Do not allow arbitrary user-controlled URLs for privileged server-side requests.
* Block access to internal network ranges when handling untrusted remote URLs where applicable.
## SSRF Prevention
* Treat user-controlled URLs as dangerous.
* Validate schemes.
* Prefer allowlisted hosts.
* Resolve and verify target addresses where necessary.
* Prevent access to localhost, metadata endpoints and internal networks where not explicitly required.
* Revalidate after redirects.
* Limit redirects.
* Apply request timeouts and response-size limits.
## Concurrency and Resource Abuse
* Bound concurrency.
* Avoid unbounded task creation.
* Avoid unbounded queues.
* Limit request sizes.
* Limit collection sizes when processing external input.
* Apply timeouts to external operations.
* Apply cancellation where practical.
* Prevent expensive operations from being triggered repeatedly without limits.
* Protect endpoints against denial-of-service through algorithmic complexity.
* Avoid user-controlled regular expressions that may cause catastrophic backtracking.
## Memory Safety and Resource Management
* Dispose files, streams, sockets and other resources correctly.
* Prevent resource leaks.
* Avoid retaining sensitive data in memory longer than necessary.
* Avoid unsafe code unless explicitly required.
* Review pointer and memory operations carefully.
* Avoid exposing raw memory or buffers across trust boundaries.
* Clear sensitive buffers where warranted.
## Multi-Tenant Systems
* Treat tenant boundaries as security boundaries.
* Scope every tenant-owned query explicitly.
* Never trust tenant identifiers from the client without authorization.
* Prevent cross-tenant cache leakage.
* Prevent cross-tenant logging or diagnostics leakage.
* Keep tenant-specific secrets isolated.
* Test horizontal privilege escalation explicitly.
## Frontend Security
* Assume frontend code and data are visible to the user.
* Never embed secrets in frontend applications.
* Never rely on frontend checks for authorization.
* Treat browser storage as potentially accessible to malicious scripts.
* Avoid storing sensitive long-lived tokens unnecessarily.
* Escape or sanitize untrusted content.
* Do not bypass framework security controls without explicit justification.
## Desktop Application Security
* Treat local files and IPC input as untrusted where applicable.
* Do not assume local users or processes are trusted.
* Avoid storing secrets in plaintext configuration.
* Protect locally cached sensitive data.
* Validate update packages and downloaded executables.
* Do not execute arbitrary files or commands from untrusted input.
* Use least privilege and avoid unnecessary elevation.
## Security-Sensitive Changes
Changes affecting any of the following require additional scrutiny:
* Authentication
* Authorization
* Cryptography
* Secrets
* User permissions
* File access
* Process execution
* Network access
* Input validation
* Serialization
* Database access
* Payment or financial data
* Personal or confidential data
* Admin functionality
* Deployment or infrastructure security
For security-sensitive changes:
* Prefer established framework functionality.
* Review trust boundaries.
* Review failure behavior.
* Review privilege requirements.
* Review input validation.
* Review logging for data leakage.
* Review backward compatibility for security implications.
* Add or update relevant security tests.
## Security Testing
* Test authorization failures.
* Test invalid and malicious input.
* Test boundary values.
* Test unauthenticated access.
* Test unauthorized resource access.
* Test cross-user and cross-tenant access where applicable.
* Test expired and invalid credentials.
* Test malformed payloads.
* Test path traversal where files are involved.
* Test injection risks where interpreters or databases are involved.
* Test rate and resource limits where abuse is realistic.
* Preserve regression tests for discovered security issues.
## Agent Rules
* Never intentionally weaken security controls without explicit user instruction.
* Never disable certificate validation, authentication, authorization, validation or security middleware to solve a problem.
* Never add hardcoded secrets.
* Never expose sensitive data for debugging convenience.
* Never bypass a security check because it blocks implementation.
* Never assume trusted input without a clearly defined trust boundary.
* Never silently choose a less secure implementation because it is easier.
* If a requested change creates a meaningful security risk, clearly identify the risk before proceeding.
* If requirements are ambiguous in a security-sensitive area, ask the user instead of making an autonomous security decision.
## Priority Order
Prioritize security decisions in this order:
* Prevent unauthorized access
* Protect sensitive data
* Preserve integrity
* Minimize privileges
* Minimize attack surface
* Validate trust boundaries
* Maintain availability
* Preserve auditability
* Optimize usability and performance only within acceptable security constraints
Security must not be traded away for convenience without an explicit and informed decision.
* Treat external input as untrusted and validate at trust boundaries.
* Prefer secure defaults, least privilege, explicit authorization, and fail-closed behavior.
* Never hardcode, commit, log, expose, or weaken protections for secrets and credentials.
* Use established framework and platform security mechanisms; do not invent cryptography or bypass validation, authentication, authorization, or TLS checks.
* Keep dependencies minimal and from trusted sources.
* Do not disclose sensitive data or internal implementation details in user-facing errors or diagnostics.
* Load the applicable focused security rule before changing authentication, web/UI, APIs, databases, files, network access, cryptography, secrets, or supply-chain configuration.