| Version | Supported |
|---|---|
| Latest | Yes |
Arq Signals enforces its security posture with the same local-first gate pattern as the rest of the Elevarq train. The Go gates + the new security gates share one entrypoint:
scripts/preflight.sh # gofmt + vet + build + test + security
scripts/preflight.sh secrets # gitleaks staged + current-commit
scripts/preflight.sh vuln # govulncheck ./...
scripts/preflight.sh lint # golangci-lint run ./...
scripts/preflight.sh security # secrets + vuln + lintEach gate emits an actionable install hint when its tool is missing and exits 127 (distinct from a real finding's exit 1), so CI / pre-push hooks can distinguish a missing-tool skip from a genuine secret / CVE / lint failure.
The pre-push hook wired via .githooks/pre-push calls
scripts/preflight.sh all, so failing-gate PRs never reach
GitHub.
Tracked under issue #160:
- #161 ✓ — push/PR CI gate runs
preflight.sh secrets+preflight.sh vuln. (lintjoined the gate in #173 once the default-linter baseline was cleaned.) - #173 ✓ —
.golangci.ymlpinned, errcheck idiomatic-Close / Rollback / Encode carve-outs documented in-config, 50-finding baseline cleaned,preflight.sh lintpromoted to a push/PR- required check. - #162 ✓ — nightly evidence in
.github/workflows/nightly-security.yml: full-history Gitleaks, Syft SBOM (SPDX-JSON), Grype against the SBOM, OpenSSF Scorecard. Artefacts upload to the workflow run + Security tab (SARIF). - #163 ✓ — Semgrep (
p/golang+p/security-audit) and OSV-Scanner run aspreflight.sh semgrep/preflight.sh osv, folded into thesecuritybundle. CI runs both on every push/PR alongside the secrets + vuln gates. - #164 ✓ —
preflight.sh kube-lintrunskube-linter+conftestagainst the rendered Helm chart underdeploy/helm/arq-signals. Conftest policies live inpolicy/security.rego(defence-in-depth:automountServiceAccountToken=false, no hostNetwork/PID/IPC, runAsNonRoot, drop all caps, no privilege escalation). - #165 ✓ — release workflow signs the published container
image with cosign (keyless via GitHub Actions OIDC + Sigstore
Fulcio) for both GHCR and Docker Hub. SBOM is re-attested via
cosign attest --type spdxjsonsocosign verify-attestationsucceeds against the workflow OIDC identity. Verification commands live indocs/release-verification.md.
If you discover a security vulnerability in Arq Signals, please report it responsibly:
- Do not open a public GitHub issue
- Email security@elevarq.com with:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- We will acknowledge receipt within 48 hours
- We will provide a fix timeline within 5 business days
Arq Signals enforces read-only access through three independent layers:
- Static linting: All SQL queries are validated at startup. DDL, DML, and dangerous functions cause the process to abort immediately.
- Session-level: Connections use
default_transaction_read_only=on. - Per-query: Each query runs inside
BEGIN ... READ ONLY.
- Passwords are read from file or environment variable at connection time
- Passwords are never cached in memory beyond a single connection attempt
- Passwords are never written to SQLite
- Passwords are never included in snapshot exports
- Password rotation is supported (re-read on each connection)
- The HTTP API binds to a configurable address (default
127.0.0.1:8081) - Arq Signals makes no outbound network connections except to PostgreSQL targets
- No data is sent to external services, AI providers, or analytics platforms
- Snapshots contain only PostgreSQL statistics view data
- No credentials, DSNs, or secrets appear in exports
- SQLite database is stored locally with no remote replication
- Non-root runtime (UID 10001)
- Minimal Alpine base image
- No shell or compilers in production image