Regbot safely applies explainable retention policies to OCI-compatible registries and GitHub Container Registry (GHCR).
It is designed for calendar-versioned container images such as:
v2026.07.20.1
v2026.07.20.1-api
v2026.07.20.1-web
Regbot understands the date, build sequence, and optional monorepo app name. It can keep recent images, remove sufficiently old images, retain the latest builds, and guarantee a minimum number of artifacts per app.
Registry cleanup is deceptively dangerous. Tags may share one digest, multi-platform images form graphs, and signatures or SBOMs may refer to an image. Provider APIs also differ: OCI registries delete manifests by digest, while GitHub deletes package versions by numeric ID.
Regbot uses a fail-closed workflow:
discover → normalize → group → evaluate → enforce safety → plan → apply
- Dry-run is the default.
- Unknown tags and OCI referrers are protected by default.
- Every decision has a stable reason code.
- Deletion plans expire and include a configuration fingerprint.
- Apply rechecks provider preconditions.
- Count and percentage limits stop unexpectedly large deletions.
- Regbot never deletes Cloudflare R2 or S3 objects directly.
Regbot is an early v1 implementation. The configuration and plan formats are
versioned, but releases before v1.0.0 may contain breaking changes.
Regbot releases use Semantic Versioning tags such as v0.1.0. Calendar
versions such as v2026.07.20.1-api describe container images managed by
Regbot; they are not Regbot release versions.
Supported:
- OCI Distribution-compatible registries, including CNCF Distribution 3.x
- GitHub Container Registry organization and user packages
- Calendar tags with optional app suffixes
- One-shot CLI, built-in scheduler, Kubernetes CronJob, GitHub Actions, and optional HTTP mode
Not supported in v1:
- npm, Maven, NuGet, RubyGems, or legacy GitHub Docker Packages
- Docker Hub-specific management APIs
- Direct R2/S3 lifecycle or object deletion
- Cascading deletion of signatures, SBOMs, or attestations
- A web UI or persistent database
Build from source:
go install github.com/restayway/regbot/cmd/regbot@latestOr build the current checkout:
make build
./bin/regbot versionContainer deployments are documented for both
docker run and
Docker Swarm, including mounted configuration,
secret files, scheduling, health checks, and metrics.
Copy the example:
cp examples/regbot.yaml regbot.yaml
export REGBOT_REGISTRY_USERNAME='...'
export REGBOT_REGISTRY_PASSWORD='...'Validate configuration and connectivity:
regbot validate --config regbot.yamlCreate a human-readable plan and save its immutable JSON representation:
regbot plan --config regbot.yaml --out plan.jsonApply that exact plan:
regbot apply --config regbot.yaml --plan plan.jsonFor scheduled execution, regbot run plans and applies only when the
configuration explicitly contains apply: true. Otherwise it remains a dry
run.
For a self-scheduling container, add a top-level schedule block and run:
regbot scheduler --config regbot.yaml --listen 0.0.0.0:8080The scheduler exposes health, readiness, and low-cardinality metrics but no remote run endpoint. Use exactly one scheduler replica.
version: v1
apply: false
registries:
internal:
provider: oci
endpoint: https://registry.example.com
credentials:
username_env: REGBOT_REGISTRY_USERNAME
password_env: REGBOT_REGISTRY_PASSWORD
policies:
production:
targets:
- registry: internal
repositories:
include: ["example-org/*"]
exclude: ["example-org/archive-*"]
tags:
parser: calendar
retention:
keep_newer_than: 168h
delete_older_than: 720h
keep_latest: 5
keep_at_least: 1
group_by: app
protect:
tags: ["latest", "stable", "prod"]
unparsed_tags: true
safety:
max_delete_count: 100
max_delete_percent: 25
require_tagged_artifact: truekeep_newer_than and delete_older_than intentionally have different names:
one protects and the other creates deletion eligibility. keep_latest and
keep_at_least always add protection.
See configuration and policy semantics for the complete contract.
When CNCF Distribution uses R2 through its S3-compatible storage driver, deleting a manifest removes the registry reference. Shared layers remain, and unreferenced blobs occupy storage until Distribution garbage collection runs.
Regbot deliberately does not inspect or delete registry bucket objects. After successful OCI deletion it can send a signed webhook to external automation. That automation should place the registry in its documented maintenance/read-only state, run garbage collection, and restore normal operation. See operations.
One-shot execution is recommended. Optional HTTP mode is available for platforms that need a long-running target:
export REGBOT_RUN_TOKEN='...'
regbot serve --config regbot.yaml \
--listen 127.0.0.1:8080 \
--run-token-env REGBOT_RUN_TOKENIt exposes:
GET /healthzGET /readyzGET /metricsPOST /run
Only low-cardinality Prometheus labels are used. Repository names, tags, digests, and credentials are never metric labels.
Use least-privilege credentials and review a plan before enabling automated apply. For GHCR, the authenticated principal needs read access and package administration/deletion permission. For OCI registries, manifest deletion must be enabled.
See security guidance and report vulnerabilities according to SECURITY.md.
make test
make race
make vet
make buildThe public Go API is documented on pkg.go.dev through the packages under
pkg/. Provider implementations and runtime wiring intentionally remain
internal so their details can evolve without creating accidental compatibility
promises.
Builds use Go 1.26.5 or newer within the 1.26 release line. This minimum patch level includes standard-library security fixes required by Regbot's network surface.
Apache License 2.0. See LICENSE.