Security
Read-only by design
Section titled “Read-only by design”- Collectors only read. The Kubernetes ClusterRole allows
get,listandwatch; the ECS roleecs:List*,ecs:Describe*andecr:ListImages; Nomad needslist-jobsandread-job; Docker and Swarm go through a docker-socket-proxy that allows onlyGET. Nothing in Goliash creates, changes or deletes anything in your infrastructure. - The agent only connects out. It sends snapshots to the server over HTTPS. The server never connects to the agent, so no inbound port is needed in your network.
- Credentials stay with the agent. The server sends only the name of a credential; the agent resolves it from its own environment or files.
Tokens and sessions
Section titled “Tokens and sessions”- Agent tokens (
glsh_agent_…) and API tokens (glsh_api_…) are shown once and stored as SHA-256 hashes. They carry a checksum, so secret scanners can recognize them. An agent token can only send data and read that agent’s configuration. - Passwords are hashed with argon2id (19 MiB, 2 passes) and must have at least 12 characters. Failed sign-ins are limited per address and per client, answer the same whether or not the account exists, and take the same time.
- Two-factor sign-in with TOTP codes (RFC 6238) is available to everyone and also guards sign-in links; codes cannot be replayed, recovery codes are single-use and stored hashed, the secret is encrypted at rest.
- Passkeys (WebAuthn) sign in without a password and count as two factors: bound to the server’s domain, with user verification on the device. Only public keys are stored; each challenge is answered once within five minutes.
- Owners can require two-factor sign-in for everyone who does not use single sign-on or a passkey.
- Sessions end after 30 days, or 14 days unused (both configurable). Request bodies are capped at 1 MB outside the agent protocol, which has its own limits.
- Sign-in links are single-use and short-lived. Sessions are HttpOnly cookies, marked Secure when
GOLIASH_PUBLIC_URLuseshttps://. Browsers may not send state-changing requests from other origins. - OIDC sign-in uses PKCE, state and nonce.
- Every response carries a strict Content-Security-Policy (only the server’s own scripts, no inline script, no
framing),
X-Frame-Options: DENY,X-Content-Type-Options: nosniff,Referrer-Policy: same-originand, whenGOLIASH_PUBLIC_URLuseshttps://,Strict-Transport-Security.
Secrets at rest
Section titled “Secrets at rest”Notification channel secrets are encrypted with AES-256-GCM and bound to their channel; see Install. Webhook deliveries can be signed with HMAC-SHA256; see Notifications.
Audit log
Section titled “Audit log”Every change to configuration, tokens and roles, and every sign-in, is recorded with who made it. Secrets never appear in the log.
Verify a release
Section titled “Verify a release”Images and the release checksums are signed with cosign in the release workflow, without long-lived keys:
cosign verify ghcr.io/pipozzz/goliash:0.1.0 \ --certificate-identity-regexp '^https://github.com/pipozzz/goliash/' \ --certificate-oidc-issuer https://token.actions.githubusercontent.comFor binaries, download checksums.txt and checksums.txt.sigstore.json from the release, then:
cosign verify-blob checksums.txt --bundle checksums.txt.sigstore.json \ --certificate-identity-regexp '^https://github.com/pipozzz/goliash/' \ --certificate-oidc-issuer https://token.actions.githubusercontent.comsha256sum --ignore-missing -c checksums.txt # macOS: shasum -a 256 --ignore-missing -c checksums.txtEach image and archive comes with an SPDX SBOM.
Reporting a vulnerability
Section titled “Reporting a vulnerability”Please report vulnerabilities privately through GitHub security advisories, not in public issues.