Only the latest release line receives security fixes.
| Version | Supported |
|---|---|
| 0.x (latest release) | Yes |
| older tags | No |
Please do not open a public issue for security problems.
Use GitHub's private vulnerability reporting instead: Report a vulnerability — it opens a private thread with the maintainers.
Include what you can: affected endpoint or component, reproduction steps, and impact. You should hear back within a week. Once a fix ships, the advisory is published and credited unless you prefer otherwise.
- Unified GitOps is designed to run on a trusted internal network; treat network exposure and key handling as part of your deployment's threat model.
- Authentication is API keys declared as
api_keysitems in the configuration: each key isrole: admin(everything) or restricted to explicit application ids, and its secret is read from the environment variable the definition names — never from the YAML.UNIFIED_GITOPS_KEY, if set, is one extra admin key. Keys are compared in constant time. With no keys configured at all, authentication is off and every caller is treated as admin — the startup log says so loudly; do not run that way outside local development. /healthz,/readyzand the Swagger UI are always public./metricsis public by default, and its exposition names every application id and its status — a description of what this instance manages. On a shared network, setserver.metrics_require_auth: true.- The configuration API (
config_api.enabled, off by default) makes the configuration directory writable over HTTP for admin keys — the API keys included, which is the same authority as editing the directory the container mounts. With it on, treat every admin key as root on the instance. Two guardrails are enforced before a reload commits: a change that would leave the API with no keys at all is refused, as is one naming a key env var that is not set. All config writes and reloads land in the audit log. - This service writes to production systems. Connector scripts run with the
daemon's privileges and the credentials of their application. Config files, the
connector scripts, and the git projects holding desired state are trusted
input: whoever can push to a desired-state repository can change the systems
its applications point at (at the next sync, or the next check with
auto_sync), though never which systems those are: the address and the credentials live in the configuration, not in the repository. Protect those repositories like production access, give each application a credential with only the permissions its connector needs, and start applications withauto_sync: falseandprune: false. - Credentials are never stored by the service; they are resolved at the start of each run
from environment variables, files, or Vault (KV v2, token or Kubernetes
auth), passed to scripts via their environment, and held only in a short
in-memory resolution cache (
secrets.cache_ttl_seconds, default 60). - There is no rate limiting on authentication attempts — a deliberate trade for the trusted-network posture. Front the service with a proxy if your deployment needs it.