·
76 commits
to 1571cff8cc7f05297df38de700a19336629a66a0
since this release
v0.10.0 — 2026-09-03
Whole-file encryption binds the repository (#79)
- A ciphertext blob sealed in one repo now fails authentication if dropped into
another that merely shares the key.initgenerates a randomrepo_id,
commits it in.repo-enc.yml, and whole-file encryption folds it into the
AEAD's additional-authenticated-data (a v2 envelope, which also authenticates
the envelope header). Repos created before this keep sealing/reading v1
(path-only AAD) unchanged — no migration is forced; opt in with a freshinit
or by addingrepo_idand runningrotate-keys. Don't changerepo_id
once set — existing v2 blobs would stop verifying. - This does not add freshness: rolling a tracked file back to an earlier
ciphertext for the same path still authenticates (no counter on the CLI path).
Newthreat-model.mdT10-CLI row. - Documented the AES-GCM 96-bit-nonce ceiling that keeps it off the default path
(crypto.Defaultis always XChaCha20-Poly1305 for new seals).
CI/CD & supply-chain hardening (#78)
- Every third-party GitHub Action is pinned to a commit SHA;
.github/dependabot.yml
keeps the pins, Go modules, and Docker base images current (the Kubernetes
client stack is its own group — see #86). release.ymlruns with a default-deny token (permissions: {}), and every
released binary now carries a signed SLSA build-provenance attestation
(gh attestation verify …); container images are signed keyless with
cosign and carry provenance + SBOM attestations. An SPDX SBOM of the
module graph is attached to each release. See SECURITY.md → "Verifying a
release".- Dockerfile base images pinned by digest. CI gained advisory
govulncheck+
Trivy scans, runs the race detector on Linux, and fails if the GPG test suite
is silently skipped there.
Controller hardening (Beta → GA, #77)
- Reconcile no longer self-triggers. The reconciler wrote
status.lastSyncTime
on every pass; that write returned through its own watch and re-enqueued the
object, so a steady-stateGitSecretreconciled forever. Status is now written
only when a field other thanlastSyncTimechanges. - Webhook now requires
replicaCount: 1. The serving cert is per-pod and the
ValidatingWebhookConfiguration.caBundleholds one CA; the chart refuses
webhook.enabledwith more than one replica, and the CA injector is
leader-gated. Reconcile HA via leader election is unchanged. - Tighter controller RBAC. Dropped unused verbs (
secrets: delete,
gitsecrets: update/patch); scopedvalidatingwebhookconfigurations
update/patchto the controller's own config by name. NewwatchNamespaces
value confines the cache and Secret RBAC to a fixed namespace list
(--watch-namespaces). - New UPGRADING.md: the
v1alpha1"additive only" compatibility
policy.
Deprecations
git-secret-server(the ESO webhook bridge) is now explicitly deprecated.
It is superseded by the nativeGitSecretCRD +git-secret-controller. The
binary, image, and Helm chart are still published so existing External Secrets
Operator users are not broken, and it receives security fixes only — no new
features. New deployments should use theGitSecretCRD. The chart is marked
deprecated: true.
Docs
- Landing page: corrected the hook-skip note — only
SECRETIZE_SKIP_HOOKS=1
skips hooks; the ambientCIvariable deliberately does not (it previously
impliedCI=1would). Rewrote theGitSecretsection to stand on its own —
no competitor named. disaster-recovery.md/recipient-lifecycle.md: clarified that CRD
recipients removeperforms a rewrap (same content key,encryptedData
untouched), not a content-key rotation — a removed recipient who cached the
content key can still decrypt values that have not since changed. The CLI
git secret removeuserstill forces a fullrotate-keysand is unchanged.threat-model.mdT11 (recipient substitution) reworded "Handled" →
"Partial" —sealer.VerifyRecipientsis a count check, not per-fingerprint
authentication.overview.md: on unseal failure the controller leaves the last-written
targetSecretin place (fail-safe) — documented, with how to force removal.
Verifying this release
gh attestation verify ./git-secret-linux-amd64 --repo OpScaleHub/git-secret
cosign verify \
--certificate-identity-regexp '^https://github.com/OpScaleHub/git-secret/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/opscalehub/git-secret-controller:v0.10.0