Skip to content

v0.10.0

Latest

Choose a tag to compare

@AliRezaTaleghani AliRezaTaleghani released this 03 Sep 06:46
· 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. init generates a random repo_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 fresh init
    or by adding repo_id and running rotate-keys. Don't change repo_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).
    New threat-model.md T10-CLI row.
  • Documented the AES-GCM 96-bit-nonce ceiling that keeps it off the default path
    (crypto.Default is 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.yml runs 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-state GitSecret reconciled forever. Status is now written
    only when a field other than lastSyncTime changes.
  • Webhook now requires replicaCount: 1. The serving cert is per-pod and the
    ValidatingWebhookConfiguration.caBundle holds one CA; the chart refuses
    webhook.enabled with 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); scoped validatingwebhookconfigurations
    update/patch to the controller's own config by name. New watchNamespaces
    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 native GitSecret CRD + 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 the GitSecret CRD. The chart is marked
    deprecated: true.

Docs

  • Landing page: corrected the hook-skip note — only SECRETIZE_SKIP_HOOKS=1
    skips hooks; the ambient CI variable deliberately does not (it previously
    implied CI=1 would). Rewrote the GitSecret section to stand on its own —
    no competitor named.
  • disaster-recovery.md / recipient-lifecycle.md: clarified that CRD
    recipients remove performs 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 removeuser still forces a full rotate-keys and is unchanged.
  • threat-model.md T11 (recipient substitution) reworded "Handled" →
    "Partial" — sealer.VerifyRecipients is a count check, not per-fingerprint
    authentication.
  • overview.md: on unseal failure the controller leaves the last-written
    target Secret in 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

See SECURITY.md → Verifying a release.