Git-backed Versioning
With Git versioning on, every connection / environment / flow / template / secret-reference change is committed to a local git repository and (optionally) pushed to a remote. You get an audit trail, one-call config rollback, and branch-based staging.
Step 1 — Pick a LocalPath
Section titled “Step 1 — Pick a LocalPath”The working tree where commits are written. Three hard requirements, each enforced at startup:
- Owned by the service user. libgit2 refuses a working tree owned by a different OS user (its
safe.directoryequivalent). Running aszenvara, the repo must be owned byzenvara. - Writable under systemd hardening. With
ProtectSystem=strict, the path must sit under aReadWritePathsentry. The data dir (/var/lib/zenvara) already qualifies. - Outside
Storage.Directory. A nested path logs an overlap warning — keep it in a sibling directory.
install -d -o zenvara -g zenvara /var/lib/zenvara-versions
[Service]ReadWritePaths=/var/lib/zenvara-versions# then: systemctl daemon-reloadStep 2 — Use a token, not a password
Section titled “Step 2 — Use a token, not a password”libgit2 push/clone with an interactive account password trips server-side bot protection (e.g. Bitbucket’s CAPTCHA lockout) and will lock the account. Create an HTTP access token or a dedicated service account with repository write, and put those in Remote.Username / Remote.Password. Leave Remote.Url empty for local-only versioning.
Step 3 — Seed the repository before first start
Section titled “Step 3 — Seed the repository before first start”Pre-create the working tree so the platform simply opens it:
cd /var/lib/zenvara-versionssudo -u zenvara git init -b main .sudo -u zenvara git -c user.email=ops@example.com -c user.name=Zenvara \ commit --allow-empty -m "Initialize git-backed config versioning"sudo -u zenvara git remote add origin https://git.example.com/scm/team/zenvara-config.gitIf the remote already has a main branch with history, skip the manual init — the platform clones it on first start.
Step 4 — Configure and restart
Section titled “Step 4 — Configure and restart”Git: Enabled: true LocalPath: "/var/lib/zenvara-versions" # owned by service user, outside Storage.Directory BaselineOnEnable: false # best-effort startup storage→git baseline Remote: Url: "https://git.example.com/scm/team/zenvara-config.git" Branch: main AutoPush: true Username: "zenvara-ci" # service account or token owner Password: "<http-access-token>" # NOT a personal account password CommitIdentity: Name: "Zenvara" Email: "ops@example.com"After systemctl restart zenvara, the log shows Opening existing git config repository at <LocalPath>. Verify end to end by editing any entity: a commit Update entity: <name> appears in the repo and, with AutoPush, lands on the remote.
Branch staging
Section titled “Branch staging”URLs carry the branch as a path segment: /api/v1/main/flows/... runs against production, /api/v1/staging/flows/... against the staging branch. Stage a change on a branch, validate it, then promote — the production flows are untouched until promotion. On git-disabled installs, the live alias resolves to the production branch so the same URLs work.
Multi-instance config sync
Section titled “Multi-instance config sync”With git versioning plus a shared remote, Git.Sync.Enabled: true makes an instance:
- fetch the remote,
- reverse-sync changed config into storage,
- invalidate caches.
Trigger it via PollInterval and/or the POST /api/v1/platform/git/sync HMAC webhook. The same remote keeps multiple instances in sync, with ConflictPolicy: manual | remote | local.