AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻譯準備中
Self-hosted, open-source version tracking for Kubernetes, Amazon ECS, AWS Lambda, Nomad, Docker Swarm and Compose. One matrix of services × environments, with upstream releases, drift, end-of-life, vu
翻譯準備中
開發工具Go · templGitHub @pipozzz上線中營運者未確認
試用過了嗎? 點一下就好,不需要登入。
What runs where, on which version: one matrix of service × environment versions across Kubernetes, ECS, Lambda, Nomad, Swarm and Docker
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
What runs where, on which version, in which environment — across Kubernetes, ECS, Lambda, Nomad, Docker Swarm, plain Docker and Linux servers.
Goliash watches what actually runs, builds a service × environment matrix with the running and the newest
upstream version, and tells you when a new release ships or when environments drift apart — staging on 1.5.0 while
prod is still on 1.3.2, or two prod clusters disagreeing.檢視完整 README ↗Goliash watches what actually runs, builds a service × environment matrix with the running and the newest upstream version, and tells you when a new release ships or when environments drift apart — staging on 1.5.0 while prod is still on 1.3.2, or two prod clusters disagreeing.
Documentation: goliash.dev
Status: stable. From 1.0 the REST API, the agent protocol, MCP tools, CLI, configuration and metrics keep working within 1.x; see Versions and compatibility. Security reports: SECURITY.md.
docker run --rm -p 8080:8080 ghcr.io/pipozzz/goliash try
A throwaway server with three weeks of example data: open the link it prints and you are signed in. Nothing is kept when you stop it. Or look around the live demo first, no install. To run it for real, see Getting started.
docker login, pull secrets or the pod's cloud identity), compared with per-service semver policies (track minor only, pin a major, ignore -alpine noise).
Moving tags resolved by digest (1 = 1.27.3). A built-in catalog of popular images, release dates and
release-notes links from GitHub./, and
Search everywhere looks through services, vulnerabilities, packages, pull requests, history and notifications at
once — also for scripts (/api/v1/search) and assistants (the MCP search tool), or hand the words to Goli.
The tiles move with the arrow keys.nginx), Tick all shown and
open the pull requests together: an upgrade campaign in three clicks./goli in Slack, from an alert, or with
goliash ask in a terminal. Claude, OpenAI or a model on your own hardware; off until you choose one.
Try it on the demo.goliash.git.* labels. Each
is previewed first and says why, what it fixes and which licenses it brings. Open one from the service page, the tiles, the
matrix, Updates, Security, the alert or the weekly plan; tick several to open them together, or one per repository;
promote a whole application in one; let a version policy open them by itself. Renovate's and Dependabot's are
linked, not duplicated; reviewers, labels, CI checks and reminders included. You review, GitOps deploys; the
Delivery page measures how long from opening, and from merging, to running.RUN apt-get install -y chromium, +145 MB), a size budget per
service, and images built on an older build of their FROM image than the base has now (docker build --pull
forgotten), with an alert when an image grows a lot.php
lists what runs it at once and announces its next release.latest, a refused registry, no comparable
tag…), with a CSV and a PDF for risk registers and audits (NIS2, DORA, SOC 2, ISO 27001).claude mcp add --transport http goliash https://demo.goliash.dev/mcp.Out of scope: deploying or upgrading services (that is CI's or Renovate's job), CVE scanning, library versions in code.
your network Goliash server
┌────────────────────────────────┐ ┌──────────────────────────────────┐
│ Kubernetes / ECS / Nomad / │ │ ingest → mapping → versions │
│ Swarm ──read-only──► agent ───┼──HTTPS────► │ │ │ │
│ private registries ──► agent │ snapshots │ ▼ ▼ │
└────────────────────────────────┘ │ events, matrix notifier ──► Slack, webhook, e-mail
│ UI, REST API SQLite / Postgres│
└──────────────────────────────────┘
curl -fsSLO https://raw.githubusercontent.com/pipozzz/goliash/main/docker-compose.yml
docker compose up -d
docker compose logs goliash | grep link= # open it to create your account
docker compose exec goliash goliash demo # optional: three weeks of example data
Open the setup link, create your account, then Connect: pick Kubernetes, Docker, Swarm, Nomad, ECS or Compose files, fill in one form, and run the command it shows where the agent can reach your orchestrator. The page follows the agent connecting and its first report.
To watch the Docker host the quickstart runs on, no agent is needed:
docker compose --profile watch-host up -d # adds a read-only docker-socket-proxy
docker compose exec goliash goliash env create -name prod -position 30
docker compose exec goliash goliash target create -env prod -platform docker -name this-host \
-settings '{"docker":{"docker_host":"tcp://socket-proxy:2375"}}'
Ready-made manifests for Kubernetes (Helm), Nomad, Docker Swarm, plain Docker hosts and ECS are in
deploy/. The Helm charts are also published as oci://ghcr.io/pipozzz/charts/goliash and
oci://ghcr.io/pipozzz/charts/goliash-agent.
Without an agent: a target created without an agent (goliash target create without -agent, or "the server
itself" in the UI) is collected by the server, with the same read-only collectors. That suits a self-hosted server
next to what it watches, e.g. the Kubernetes cluster it runs in (helm … --set collectInCluster=true) or a Swarm or
Docker host through a socket proxy. Turn it off with -collect=false.
ghcr.io/pipozzz/goliash and ghcr.io/pipozzz/goliash-agent (linux/amd64, linux/arm64; distroless,
non-root). Images and release archives are signed with cosign (keyless) and come with SPDX SBOMs.make build, or docker build --target server . / --target agent.Notification channel secrets (Slack and webhook URLs, signing secrets) are encrypted at rest with AES-256-GCM. The
key comes from GOLIASH_SECRET_KEY or GOLIASH_SECRET_KEY_FILE (32 bytes, base64 or hex: openssl rand -base64 32);
with SQLite and neither set, the server creates goliash.key next to the database. Back the key up with the
database: without it, channels must be created again. With PostgreSQL, set the key explicitly.
The server keeps its SQLite database in /data (set GOLIASH_DATABASE_URL=postgres://… for PostgreSQL) and
deletes processed snapshots beyond the newest 20 per target every hour (-keep-snapshots); history lives in events.
Releases are published by pushing a v* tag.
Open GOLIASH_PUBLIC_URL (default http://localhost:8080) and sign in with a link from
goliash login-link -email [email protected]. The UI is server-rendered (templ + htmx), works without a build step
and updates live over server-sent events.
| Page | What it is for |
|---|---|
| Matrix | service × environment with versions, replicas, targets, drift badges and the latest upstream; filter (/) and "only with drift"; a time travel timeline to scrub, step or play back deployments; CSV and CycloneDX SBOM export; cards on phones; a first-run checklist when empty |
| Service | where it runs, upstream releases, history, version policy, acknowledgements, "check upstream now"; delete once it runs nowhere |
| Inbox | unmapped workloads with a suggested name; mapping creates a rule for that image; the list of mapping rules |
| Hygiene | moving tags, tags pushed again, untrusted registries and images without a digest, summarised by kind |
| Delivery | versions waiting for the next environment with the releases they bring; deploys and lead times per environment; a printable monthly report per workspace |
| History | every event, filterable by service, environment and type |
| Settings → Agents and targets | agents and targets with collector health; environments (rename, reorder); edit targets; add agents with install commands, rotate or revoke tokens, rename and delete agents, move or delete targets |
| Settings → Notifications | channels (test, edit, delete) and rules (pause, delete) |
| Settings → Workspace settings | invite people, change roles, sign-in links, sign out, remove passwords, API tokens with roles and expiry, the audit log (admins) |
| Settings → Workspaces | one workspace per team or client (organization admins) |
| Account (your avatar) | name, password, and every browser you are signed in on |
bin/goliash login-link -email [email protected] # first user becomes owner; prints a one-time link
bin/goliash user create -email [email protected] -role member
bin/goliash user password -email [email protected] # optional: sign in with a password too
bin/goliash token create -name prometheus # glsh_api_… for /api/v1, /metrics and /mcp (viewer)
goliash user password. Repeated failures pause sign-in for an address for 15 minutes. Turn passwords off with
GOLIASH_PASSWORD_LOGIN=false when everyone uses OIDC. The account page also lists where you are signed in.GOLIASH_SMTP_*); goliash login-link works without it.GOLIASH_OIDC_ISSUER, GOLIASH_OIDC_CLIENT_ID, GOLIASH_OIDC_CLIENT_SECRET, optional GOLIASH_OIDC_NAME
and GOLIASH_OIDC_DOMAINS (people from these e-mail domains are created as viewers on first sign-in; others
need an account). Redirect URI: <public URL>/auth/oidc/callback.GOLIASH_PUBLIC_URL to the address people use; with https:// cookies are marked Secure.Authorization: Bearer glsh_api_…): GET /api/v1/matrix, /services, /environments,
/targets, /events?service=&environment=&type=&before=&limit=, /drifts, /updates, /vulnerabilities,
/inventory?format=json|csv|cyclonedx&environment=&at=; POST /api/v1/acks. The OpenAPI
description is api/public-v1.yaml, also served at /api/v1/openapi.yaml; every response
is tested against it./mcp (Streamable HTTP, API token),
and goliash mcp runs it on stdio for Claude Desktop or Cursor. Tools: matrix, service, drifts, updates, changes,
promotions, delivery, inventory, hygiene, vulnerabilities and acknowledge.bin/goliash matrix # service × environment, latest upstream, drift markers
bin/goliash matrix -at 2026-09-12T14:00 # what ran then (history is kept for 400 days)
bin/goliash inventory -csv # every running container with image and digest, for audits
bin/goliash hygiene # moving tags, retagged images, untrusted registries (GOLIASH_ALLOWED_REGISTRIES)
bin/goliash drift # open drifts
bin/goliash promotions # versions waiting for the next environment, with the releases they bring
bin/goliash delivery # deploys per environment and lead times between environments, last 30 days
bin/goliash events # history: deployed, version_changed, removed, new_release, drift_*
bin/goliash events -env prod -since 2h # what changed before an incident
bin/goliash check # check upstream registries now (the server does it hourly)
bin/goliash service set -name postgres -track minor -pin-major 15
bin/goliash rule create -match image_repo -pattern 'ghcr\.io/acme/pay.*' -service payments
goliash.service / app.kubernetes.io/name (and goliash.env), then rules, then unmapped
workloads wait in the inbox with a suggested name.GOLIASH_CREDENTIAL_<REGISTRY_HOST> (user:password or a
token). Private Amazon ECR repositories go through the ECR API with the agent's AWS credentials (IAM
ecr:ListImages; IRSA, task role or instance profile), where the credential, if set, names an AWS profile.
New services are checked within a minute, then hourly.tag_filter, track (patch/minor/major), pin_major, prerelease. Without a filter,
tags are compared like with like (same -alpine variant, same number of version parts).catalog/images.yaml holds default policies for popular public images
(postgres, redis, nginx, keycloak, traefik, grafana, prometheus, …) and where their release notes live. A service
without its own policy uses the catalog's; additions are welcome as pull requests.github/gitlab, "github": "owner/repo" or "gitlab": "gitlab.com/group/project" in a
service's own policy, or the image's own org.opencontainers.image.source label) or a changelog URL template.
GitLab means gitlab.com and one self-hosted instance in GOLIASH_GITLAB_URL (token: GOLIASH_GITLAB_TOKEN). The label is read from the registry once a
week, so most images built with GitHub Actions get release notes without any setup. Links appear in the UI and in
new-release notifications. Set GOLIASH_GITHUB_TOKEN to raise GitHub's rate limit.env (an environment runs an older version than the one before it), upstream (behind the newest
release by at least the tracked jump), inconsistent (targets of one environment disagree), declared (what runs
differs from what Compose files in Git declare, when an environment has both), (the running release cycle
reaches its end of life within 60 days, from ; turns it
off, for servers without internet access). Drift shows in the UI
at once but is announced () only after it lasts: 7 days, immediately,
15 minutes, 30 minutes. Override per service, e.g. .Each workspace has its own agents, targets, services, history, notifications and API tokens.
bin/goliash workspace create -name "Client A" -slug client-a -envs
bin/goliash user create -email [email protected] -role member -workspace client-a
bin/goliash user grant -email [email protected] -role admin -workspace client-a
bin/goliash matrix -workspace client-a # every command takes -workspace (or GOLIASH_WORKSPACE)
Organization owners and admins reach every workspace and switch between them in the top bar. Everyone else only sees the workspaces they were invited to, as viewer, member or workspace admin; a workspace admin manages the people of that workspace only. Clients of an MSP therefore never see each other.
bin/goliash channel create -type slack -name ops -url https://hooks.slack.com/services/…
bin/goliash channel create -type webhook -name ci -url https://example.com/goliash -secret s3cret
bin/goliash channel create -type discord -name releases -url https://discord.com/api/webhooks/…
bin/goliash channel create -type telegram -name team -token 123456:ABC… -chat-id -1001234567890
bin/goliash channel create -type ntfy -name phone -url https://ntfy.sh/my-goliash
bin/goliash channel create -type email -name oncall -to [email protected] # GOLIASH_SMTP_* or -smtp-addr/-smtp-from
bin/goliash channel test -name ops
bin/goliash notify create -channel ops -events new_release,drift_detected,agent_stale -mode daily -min-jump minor
bin/goliash ack -service postgres -kind release -until-version 17.0 # "we know about 16, quiet until 17"
bin/goliash ack -service web -kind drift -for 336h # quiet for 14 days
Rules match event types and optionally services, owners, environments and the size of a release jump. instant
rules deliver within seconds (items arriving together are batched); daily and weekly rules collect a digest
sent at digest_hour (UTC). A release is announced once per service and version. Failed deliveries are retried
with backoff. Webhook bodies are signed: X-Goliash-Signature: sha256=HMAC(secret, X-Goliash-Timestamp + "." + body).
| Platform | Reads | Needs | Credentials |
|---|---|---|---|
| Kubernetes | Deployments, StatefulSets, DaemonSets, CronJobs and their running pods (watch) | ClusterRole with get, list, watch | in-cluster service account, else kubeconfig (kubeconfig_context optional) |
| ECS | clusters → services → running tasks → task definitions | IAM ecs:List*, ecs:Describe* | default AWS chain; credentials_ref = AWS profile name |
| Nomad | jobs, job versions, allocations | ACL token with list-jobs and read-job | credentials_ref → token, else NOMAD_TOKEN |
| Docker Swarm | services and running tasks | Docker API GET only (docker-socket-proxy) | none |
| Docker | running containers, grouped into Compose services (optionally only some projects); registry digests | Docker API GET on containers and images (docker-socket-proxy) | none |
| Compose files | services and images declared in Compose files, without a Docker engine | an HTTP(S) URL, or for an agent a file in GOLIASH_COMPOSE_DIRS | credentials_ref → bearer token for the URL |
The server only sends a credentials_ref name. The agent resolves it from the environment variable
GOLIASH_CREDENTIAL_<NAME> (upper-cased, non-alphanumerics as _) or the file
$GOLIASH_CREDENTIALS_DIR/<name> (default /etc/goliash-agent/credentials).
The agent registers, follows its configuration (polled every minute with an ETag), sends a heartbeat every minute
and buffers snapshots in -data-dir while the server is unreachable (the oldest are dropped beyond 200).
The protocol is in api/agent-v1.yaml; the server validates every request against it.
| Path | What | License |
|---|---|---|
cmd/goliash | Server binary | AGPL-3.0-only |
cmd/goliash-agent | Agent binary | Apache-2.0 |
internal/agent | Agent loop | Apache-2.0 |
internal/collectors/{kubernetes,ecs,nomad,swarm,docker,compose} | Read-only collectors | Apache-2.0 |
internal/registry | OCI Distribution API client | Apache-2.0 |
internal/pkgscan | Application packages from their manifests (images without an SBOM, Lambda code) | Apache-2.0 |
api/agent-v1.yaml | Agent protocol (OpenAPI 3.0) | Apache-2.0 |
pkg/agentproto | Protocol types and client, generated from the spec | Apache-2.0 |
pkg/buildinfo | Build metadata | Apache-2.0 |
internal/{api,ingest,mapping,versions,notifier,store,ui} | Server | AGPL-3.0-only |
internal/store/migrations/{sqlite,postgres} | Database migrations (goose), embedded in the server | AGPL-3.0-only |
deploy/{helm,nomad,swarm,docker,ecs} | Deployment manifests | AGPL-3.0-only |
Requires Go (version in go.mod) and, for linting, golangci-lint v2.
make build # bin/goliash and bin/goliash-agent
make generate # regenerate pkg/agentproto after editing api/agent-v1.yaml
make test # SQLite; set GOLIASH_TEST_POSTGRES_DSN to also run against PostgreSQL
make lint # license boundary check + golangci-lint
scripts/lab/up.sh # k3s, Swarm and Nomad in Docker with a server and agent; prints a sign-in link
The documentation site lives in website/ (Astro Starlight): cd website && npm install && npm run dev.
The agent and the code it is built from are licensed under Apache-2.0; the server is licensed under AGPL-3.0-only. Each source file states its license in an SPDX header. See LICENSING.md for details.
Contributions are welcome. Please read CONTRIBUTING.md; external contributions require signing the CLA.
GET /metrics (same auth): what runs where (goliash_deployed_version_info), drift
(goliash_outdated, goliash_drift_days), delivery (goliash_deploys, goliash_lead_time_seconds), GitOps
(goliash_gitops_trouble, goliash_pull_requests, goliash_merge_to_running_seconds), image hygiene and the
server's own health. Dashboards for Grafana and
SigNoz, alert rules, and the Helm chart's metrics.*
options are described in Grafana dashboard,
SigNoz dashboard and Metrics and alerts.eol"eol": "none"-eol=falsedrift_detectedenvupstreaminconsistentdeclared"drift_alert_after": {"env": "72h"}