Change Management Policy — BatleHub
This document describes how changes to BatleHub code, configuration, and dependencies are reviewed, approved, and deployed in this project's own repository.
Guidance, not a commitment
Two audiences read this and they need different things from it. If you are looking for evidence against SOC 2 CC8, this is what the project offers — a description of its own practice, not an attestation that it has been verified (see the SOC 2 mapping). If you are running BatleHub, this is a worked example to adapt: your change process is yours, and nothing here binds the project to a release cadence, a review turnaround or a deprecation window.
Scope
This policy covers:
- Source code changes (Rust crates, Vue frontend, CLI)
- Configuration changes (TOML config files, environment variables)
- Dependency updates (Cargo.lock, pnpm-lock.yaml)
- Infrastructure changes (container images, Kubernetes manifests, CI/CD pipelines)
- Database schema changes (migrations in
crates/adapters/migrations/)
Code and Infrastructure Changes
Standard changes (all non-emergency changes)
- Branch — create a feature branch from
main. - Develop — write code locally; run
cargo test --workspaceandcargo clippy --workspace -- -D warningsbefore pushing. - Pull request — open a PR; describe what changed and why. Link to issue or ticket.
- Automated gates (all must pass before merge):
cargo test --workspace— unit + integration testscargo clippy --workspace -- -D warnings— no warningscargo fmt --all --check— formattingcargo audit— no unpatched RUSTSEC advisoriescargo deny check— license, ban, and source policypnpm audit --audit-level high— no high/critical JS CVEsgitleaks— no secrets in difftrivy— no fixable HIGH/CRITICAL in built image
- Peer review — at least one approved review required.
- Merge — squash-merge to
main. - Deploy — CI builds and pushes the image; deployment pipeline applies to staging first, then production.
Emergency changes (P0 incident)
When containment requires an immediate patch to production:
- Implement fix on a branch; at minimum self-review the diff.
- Run
cargo test --workspacelocally — do not skip tests. - Fast-track automated gates (CI still runs; do not bypass).
- Notify the security lead and on-call that an emergency merge is in progress.
- Merge and deploy.
- Open a follow-up PR within 24 hours with a retroactive post-mortem comment.
Configuration Changes
Runtime config (TOML / env vars)
All configuration changes that affect runtime behavior (new registries, RBAC rule changes, rate-limit overrides, IP block additions) must be:
Reviewed — at least one other person must see the diff.
Applied via config reload where possible — use
POST /api/v1/admin/config/reloadto hot-swap the config without a restart. BatleHub logs and stores every reload in theconfig_changestable.Auditable — config change history is queryable:
bashbatlehub admin config changes # or via Admin UI → Config Reload → HistoryReverting — keep the previous config version in version control. Roll back by deploying the prior commit.
Database migrations
SQL migrations live in crates/adapters/migrations/ with sequential numbers. Rules:
- Never modify an existing migration (it may already be applied in production).
- New migrations must be additive where possible (add columns, not drop them).
- All migrations run automatically on server startup via the embedded migrator.
- Test migrations with
task test:pg-cachebefore merging.
Dependency Updates
Routine updates
- Dependabot / Renovate opens PRs automatically for patch and minor bumps.
- Review the changelog for any breaking changes or security implications.
- Verify
cargo auditandcargo deny checkstill pass after the update.
Security patches
When a RUSTSEC advisory is published for a dependency we use:
- BatleHub's CI
back-dep-auditjob will fail within 24 hours of the advisory being published. - Check if the advisory is in the direct or transitive dependency tree:
cargo tree -i <crate>. - Bump the dependency version (or apply a
[patch.crates-io]stub as done forsqlx-macrosandsqlx-mysql). - Verify
cargo auditandcargo deny checkpass locally. - Open and fast-track the PR (standard review still required).
Prohibited operations
| Action | Reason |
|---|---|
features = ["macros"] on sqlx | Pulls in rsa crate (RUSTSEC-2023-0071) |
Default features on aws-sdk-s3 or aws-config | Pulls in legacy rustls (RUSTSEC-2026-0098) |
advisories.ignore or .cargo/audit.toml suppressions | No suppressions policy — fix or patch instead |
--no-verify on commits | Bypasses pre-commit hooks |
These are enforced by cargo deny rules in deny.toml and will fail CI.
RBAC Policy Changes
Changes to per-registry RBAC rules affect what packages users can and cannot download. Before applying:
Use the RBAC simulator to validate the intended effect:
bashbatlehub admin access-check --registry npm --package lodash \ --version 4.17.21 --resource releases:read --role userTest with at least one "deny" case and one "allow" case.
Apply via config reload (changes are logged automatically).
Monitor the audit log for unexpected
deniedevents after applying.
Audit Trail
The following operations are automatically logged in the access_events table (with user identity, IP address, and user-agent):
- Package downloads (allowed and denied)
- Package publishes, yanks, deletes, blocks, unblocks
- Admin token revocations
Config changes are logged in the config_changes table.
To export all audit events for a period:
batlehub admin export-audit-log \
--from 2026-01-01T00:00:00Z --to 2026-03-31T23:59:59Z \
--format csv --output q1-2026-audit.csvAnnual Review
This policy should be reviewed at least annually by the security lead and updated to reflect changes in tooling, team size, or compliance requirements.
Last reviewed: 2026-06-28