From d2e11b8bddef1623e2b3b4df37c67a6b544fc1ee Mon Sep 17 00:00:00 2001 From: Mikhail Chusavitin Date: Sat, 7 Mar 2026 22:03:49 +0300 Subject: [PATCH] Strengthen backup and secret handling contracts --- rules/patterns/backup-management/contract.md | 5 +- rules/patterns/go-code-style/contract.md | 3 +- rules/patterns/go-database/contract.md | 3 +- rules/patterns/secret-management/contract.md | 80 ++++++++++++++++++++ 4 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 rules/patterns/secret-management/contract.md diff --git a/rules/patterns/backup-management/contract.md b/rules/patterns/backup-management/contract.md index dd0d1a1..e9c2ce7 100644 --- a/rules/patterns/backup-management/contract.md +++ b/rules/patterns/backup-management/contract.md @@ -1,6 +1,6 @@ # Contract: Backup Management -Version: 1.1 +Version: 1.2 ## Purpose @@ -26,6 +26,8 @@ Rules: - Never write backups into the git repository tree. - Backup files must never be staged or committed to git. - Every application must have an explicit backup root outside the repository. +- Before creating, rotating, or restoring backups, the application must verify that the backup root resolves outside the git worktree. +- Before creating, rotating, or restoring backups, the application must verify again that the target backup files are not tracked or staged in git. - Default local-app location: store backups next to the user config, for example `~/.config//backups/`. - Default server/centralized location: store backups in an application-owned path outside the repository, for example `/appdata//backups/` or `/var/backups//`. - Keep retention tiers in separate directories: `daily/`, `weekly/`, `monthly/`, `yearly/`. @@ -63,6 +65,7 @@ Rules: - On application startup, create a backup immediately if none exists yet for the current period. - Support scheduled daily backups at a configured local time. - Before migrations or other risky state-changing maintenance steps, trigger a fresh backup from the application-owned backup mechanism. +- Before migrations or other risky state-changing maintenance steps, double-check that backup output is outside the git tree so it cannot be pushed to a remote by accident. - If backup location, schedule, or retention is configurable, provide safe defaults and an explicit disable switch. ## Restore Readiness diff --git a/rules/patterns/go-code-style/contract.md b/rules/patterns/go-code-style/contract.md index e705a0f..f11b9cd 100644 --- a/rules/patterns/go-code-style/contract.md +++ b/rules/patterns/go-code-style/contract.md @@ -1,6 +1,6 @@ # Contract: Go Code Style and Project Conventions -Version: 1.0 +Version: 1.1 ## Logging @@ -64,6 +64,7 @@ Never reverse steps 2 and 5. Never start serving before migrations complete. - Never hardcode ports, DSNs, or file paths in application code. - Provide a `config.example.yaml` committed to the repo. - The actual `config.yaml` is gitignored. +- Secret handling and pre-commit/pre-push leak checks must follow the `secret-management` contract. ## Template / UI Rendering diff --git a/rules/patterns/go-database/contract.md b/rules/patterns/go-database/contract.md index 4809922..5cc0734 100644 --- a/rules/patterns/go-database/contract.md +++ b/rules/patterns/go-database/contract.md @@ -1,6 +1,6 @@ # Contract: Database Patterns (Go / MySQL / MariaDB) -Version: 1.5 +Version: 1.6 ## MySQL Transaction Cursor Safety (CRITICAL) @@ -123,6 +123,7 @@ Rules: - The operator must know how to restore from that backup before applying the change. - If a migration or script is intended for production/staging, the rollout instructions must state the backup step explicitly. - The backup taken before a migration must be triggered by the application's own backup mechanism, not by assuming `mysql`, `mysqldump`, or other DB client tools exist on the user's machine. +- Before a migration starts, double-check that backup output resolves outside the git worktree and is not tracked or staged in git. ## Migration Policy diff --git a/rules/patterns/secret-management/contract.md b/rules/patterns/secret-management/contract.md new file mode 100644 index 0000000..bda389f --- /dev/null +++ b/rules/patterns/secret-management/contract.md @@ -0,0 +1,80 @@ +# Contract: Secret Management + +Version: 1.1 + +## Purpose + +Общие правила, которые предотвращают утечку секретов в git, логи, конфиги, шаблоны и release-артефакты. + +## No Secrets In Git + +Secrets must never be committed to the repository, even temporarily. + +This includes: +- API keys +- access tokens +- passwords +- DSNs with credentials +- private keys +- session secrets +- OAuth client secrets +- `.env` files with real values +- production or staging config files with real credentials + +Rules: +- Real secrets must never appear in tracked files, commit history, tags, release assets, examples, fixtures, tests, or docs. +- `.gitignore` is required for runtime config and local secret files, but `.gitignore` alone is not considered sufficient protection. +- Commit only templates and examples with obvious placeholders, for example `CHANGEME`, `example`, or empty strings. +- Never place secrets in screenshots, pasted logs, SQL dumps, backups, or exported archives that could later be committed. + +## Where Secrets Live + +Rules: +- Store real secrets only in local runtime config, secret stores, environment injection, or deployment-specific configuration outside git. +- Keep committed config files secret-free: `config.example.yaml`, `.env.example`, and similar files must contain placeholders only. +- If a feature requires a new secret, document the config key name and format, not the real value. + +## Required Git Checks + +Before every commit: +- Verify that files with real secrets are gitignored. +- Inspect staged changes for secrets, not just working tree files. +- Run an automated secret scan against staged content using project tooling or a repository-approved scanner. +- If the scan cannot be run, stop and do not commit until an equivalent staged-content check is performed. + +Before every push: +- Scan the commits being pushed for secrets again. +- Refuse the push if any potential secret is detected until it is reviewed and removed. + +High-risk patterns that must be checked explicitly: +- PEM blocks (`BEGIN PRIVATE KEY`, `BEGIN OPENSSH PRIVATE KEY`, `BEGIN RSA PRIVATE KEY`) +- tokens in URLs or DSNs +- `password=`, `token=`, `secret=`, `apikey=`, `api_key=` +- cloud credentials +- webhook secrets +- JWT signing keys + +## Scheduled Security Audit + +Rules: +- Perform a security audit at least once per week. +- At least once per week, scan the git repository for leaked secrets, including current files, staged changes, commit history, and reachable tags. +- Treat weekly secret scanning as mandatory even if pre-commit and pre-push checks already exist. +- If the weekly audit finds a leaked secret, follow the Incident Response rules immediately. + +## Logging and Generated Artifacts + +Rules: +- Do not print secrets into terminal output, structured logs, panic messages, or debug dumps. +- Do not embed secrets into generated backups, exports, support bundles, or crash reports unless the artifact is explicitly treated as secret operational data and guaranteed to stay outside git. +- If secrets must appear in an operational artifact, that artifact inherits the same "never in git" rule as backups. + +## Incident Response + +If a secret is committed or pushed: +- Treat it as compromised immediately. +- Rotate or revoke the secret. +- Remove it from the current tree and from any generated artifacts. +- Remove it from all affected commits and from repository history, not just from the latest revision. +- Inform the user that history cleanup may be required. +- Do not claim safety merely because the repo is private.