Strengthen backup and secret handling contracts

This commit is contained in:
Mikhail Chusavitin
2026-03-07 22:03:49 +03:00
parent f55bd84668
commit d2e11b8bdd
4 changed files with 88 additions and 3 deletions

View File

@@ -1,6 +1,6 @@
# Contract: Backup Management # Contract: Backup Management
Version: 1.1 Version: 1.2
## Purpose ## Purpose
@@ -26,6 +26,8 @@ Rules:
- Never write backups into the git repository tree. - Never write backups into the git repository tree.
- Backup files must never be staged or committed to git. - Backup files must never be staged or committed to git.
- Every application must have an explicit backup root outside the repository. - 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/<appname>/backups/`. - Default local-app location: store backups next to the user config, for example `~/.config/<appname>/backups/`.
- Default server/centralized location: store backups in an application-owned path outside the repository, for example `/appdata/<appname>/backups/` or `/var/backups/<appname>/`. - Default server/centralized location: store backups in an application-owned path outside the repository, for example `/appdata/<appname>/backups/` or `/var/backups/<appname>/`.
- Keep retention tiers in separate directories: `daily/`, `weekly/`, `monthly/`, `yearly/`. - 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. - On application startup, create a backup immediately if none exists yet for the current period.
- Support scheduled daily backups at a configured local time. - 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, 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. - If backup location, schedule, or retention is configurable, provide safe defaults and an explicit disable switch.
## Restore Readiness ## Restore Readiness

View File

@@ -1,6 +1,6 @@
# Contract: Go Code Style and Project Conventions # Contract: Go Code Style and Project Conventions
Version: 1.0 Version: 1.1
## Logging ## 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. - Never hardcode ports, DSNs, or file paths in application code.
- Provide a `config.example.yaml` committed to the repo. - Provide a `config.example.yaml` committed to the repo.
- The actual `config.yaml` is gitignored. - The actual `config.yaml` is gitignored.
- Secret handling and pre-commit/pre-push leak checks must follow the `secret-management` contract.
## Template / UI Rendering ## Template / UI Rendering

View File

@@ -1,6 +1,6 @@
# Contract: Database Patterns (Go / MySQL / MariaDB) # Contract: Database Patterns (Go / MySQL / MariaDB)
Version: 1.5 Version: 1.6
## MySQL Transaction Cursor Safety (CRITICAL) ## MySQL Transaction Cursor Safety (CRITICAL)
@@ -123,6 +123,7 @@ Rules:
- The operator must know how to restore from that backup before applying the change. - 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. - 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. - 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 ## Migration Policy

View File

@@ -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.