From ae40997a795f54f118de1b3c70d52bc169d86b74 Mon Sep 17 00:00:00 2001 From: Albert Mavashev Date: Sat, 2 May 2026 19:10:39 -0400 Subject: [PATCH 1/5] docs: add MAINTAINERS.md + README production-deployment / TLS section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two CII Best Practices quick wins ahead of the badge submission. 1. MAINTAINERS.md (new) Lists project lead (Albert Mavashev / @amavashev), contributing organizations (Runcycles, K2nio, Singleton Labs, Anthropic), and triage / review / release SLAs. Answers the CII "Roles document" criterion (Basics) which was previously NEEDS DECISION. Also gives external contributors a clear "who do I talk to" entry point and shows up on the GitHub repo About sidebar. 2. README "Production deployment & TLS" section (new) Documents the recommended deployment topology (TLS-terminating reverse proxy → HTTP cycles-server:7878 → password-protected Redis), names common proxy choices (nginx / Caddy / Traefik / ALB), and explains the rationale for terminating TLS at the ingress layer rather than the app. Adds a network-hardening table covering admin server isolation and required production env vars (REDIS_PASSWORD, ADMIN_API_KEY, WEBHOOK_SECRET_ENCRYPTION_KEY). Answers the CII "TLS for in-transit" Security criterion which was previously NEEDS DECISION. More importantly: it's a real question first-time deployers actually have, and now there's a written answer in the README rather than asking on Discord. Skipped from the original quick-win list: - CONTRIBUTING.md per-repo: GitHub auto-defaults to the org-wide CONTRIBUTING.md at runcycles/.github root. No per-repo file needed — visible at /community page already. - spotbugs-maven-plugin: SpotBugs has a high false-positive rate on Spring code and adds an ongoing CI maintenance tax. CodeQL + JaCoCo's 95% coverage gate already cover the Quality answer defensibly. --- MAINTAINERS.md | 36 ++++++++++++++++++++++++++++++++++++ README.md | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 MAINTAINERS.md diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 0000000..bf98fcf --- /dev/null +++ b/MAINTAINERS.md @@ -0,0 +1,36 @@ +# Maintainers + +This document lists the people responsible for triaging issues, reviewing PRs, and cutting releases for `cycles-server`. + +## Project lead + +- **Albert Mavashev** — [@amavashev](https://github.com/amavashev) — primary committer, release manager + +## Contributing organizations + +The project receives contributions from: + +- [Runcycles](https://github.com/runcycles) +- [K2nio](https://k2n.io) +- Singleton Labs +- [Anthropic](https://www.anthropic.com) (via Claude Code automated PRs and Sonnet/Opus-assisted contributions) + +## Responsibilities + +| Area | Owner | SLA | +|---|---|---| +| Issue triage | Project lead | 5 business days for first response | +| PR review | Project lead | 3 business days for initial review | +| Security disclosures | See [SECURITY.md](https://github.com/runcycles/.github/blob/main/SECURITY.md) | 48h acknowledgment, 5 business days assessment | +| Release cuts | Project lead | Per [CHANGELOG.md](./CHANGELOG.md); patch releases as needed | +| Dependency updates | Dependabot + project lead | Auto-merge on patch updates passing CI; manual review on minor/major | + +## Becoming a maintainer + +We're a small team and add maintainers cautiously. Path is usually: sustained contribution (≥3 substantive PRs) → triage assistance → invitation to commit access. Open a discussion if you're interested. + +## How to reach maintainers + +- **General questions / bug reports**: [GitHub Issues](https://github.com/runcycles/cycles-server/issues) +- **Security disclosures**: see [SECURITY.md](https://github.com/runcycles/.github/blob/main/SECURITY.md) (do **not** open a public issue) +- **Conduct concerns**: see the org-wide [Code of Conduct](https://github.com/runcycles/.github/blob/main/CODE_OF_CONDUCT.md) diff --git a/README.md b/README.md index 51ae860..4462f3b 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,46 @@ ghcr.io/runcycles/cycles-server:latest ghcr.io/runcycles/cycles-server: # e.g. 0.1.25.14 ``` +## Production deployment & TLS + +The Cycles Server listens on HTTP at port 7878 by design — TLS termination is the responsibility of the ingress layer in front of it. The recommended deployment topology: + +``` +client → [TLS-terminating reverse proxy] → cycles-server:7878 (HTTP) + ↓ + redis:6379 (TCP, password-protected) +``` + +### TLS termination + +Use any TLS-terminating proxy in front of cycles-server. Common choices: + +- **nginx** with Let's Encrypt — minimal config, well-documented +- **Caddy** — automatic Let's Encrypt + HTTP/3 +- **Traefik** — natural fit for Docker / Kubernetes +- **AWS ALB / GCP Load Balancer / Cloudflare** — managed TLS at the edge + +The cycles-server itself doesn't need to know it's behind a proxy. Standard `X-Forwarded-For` / `X-Forwarded-Proto` headers are honored by Spring Boot's defaults. + +**Why HTTP at the app layer:** keeps the container minimal (no cert renewal logic in the app), lets ops centralize TLS posture (cipher suites, HSTS, mTLS) at the proxy, and matches how production Spring Boot services are typically deployed. + +### Network hardening + +| Path | Recommendation | +|---|---| +| **Public → reverse proxy** | TLS 1.2+ only, modern cipher suites, HSTS enabled | +| **Reverse proxy → cycles-server** | Same private network or VPC; not exposed publicly | +| **cycles-server → Redis** | Same private network; Redis password set via `REDIS_PASSWORD` env var; for highest assurance, also enable Redis TLS (Redis 6+ supports it natively) | +| **Admin server (port 7979)** | Internal network only — never expose publicly. The admin server is the management plane (tenants, budgets, API keys); compromise here is total. | + +### Required environment variables for production + +- `REDIS_PASSWORD` — never run Redis without one in production +- `ADMIN_API_KEY` — the bootstrap admin key for the admin server (32+ random bytes recommended) +- `WEBHOOK_SECRET_ENCRYPTION_KEY` — encrypts webhook subscriber secrets at rest in Redis (32 bytes, base64) + +See [Configuration](#configuration) below for the full env-var matrix. + ## Testing The test suite is split into four categories, each gated by a surefire tag or Maven profile so PR CI stays fast while heavier suites run on demand or on a schedule. From 21caa18c8aaf894e6676e868694ee8d872c7bd68 Mon Sep 17 00:00:00 2001 From: Albert Mavashev Date: Sat, 2 May 2026 19:13:56 -0400 Subject: [PATCH 2/5] docs(maintainers): correct K2NIO link to GitHub org URL --- MAINTAINERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index bf98fcf..ac34548 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -11,7 +11,7 @@ This document lists the people responsible for triaging issues, reviewing PRs, a The project receives contributions from: - [Runcycles](https://github.com/runcycles) -- [K2nio](https://k2n.io) +- [K2NIO](https://github.com/K2NIO) - Singleton Labs - [Anthropic](https://www.anthropic.com) (via Claude Code automated PRs and Sonnet/Opus-assisted contributions) From a113b0d9fa2586e7568e8ff89467918736910e7b Mon Sep 17 00:00:00 2001 From: Albert Mavashev Date: Sat, 2 May 2026 19:15:23 -0400 Subject: [PATCH 3/5] Update MAINTAINERS.md --- MAINTAINERS.md | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index ac34548..e099452 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -13,7 +13,6 @@ The project receives contributions from: - [Runcycles](https://github.com/runcycles) - [K2NIO](https://github.com/K2NIO) - Singleton Labs -- [Anthropic](https://www.anthropic.com) (via Claude Code automated PRs and Sonnet/Opus-assisted contributions) ## Responsibilities From 03614476952ca3a4e2db14937bf5380052ccf0be Mon Sep 17 00:00:00 2001 From: Albert Mavashev Date: Sat, 2 May 2026 19:23:23 -0400 Subject: [PATCH 4/5] ci: empty commit to re-trigger CI after .github#43 From ef33dd205f01c336d2d126ddc5218e33ef4d4869 Mon Sep 17 00:00:00 2001 From: Albert Mavashev Date: Sat, 2 May 2026 19:24:26 -0400 Subject: [PATCH 5/5] ci: trigger CI re-run with newline addition (verifying .github#43 fix) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4462f3b..dfc6dca 100644 --- a/README.md +++ b/README.md @@ -307,3 +307,4 @@ Full metric inventory, tag semantics, ready-to-paste Prometheus alert rules, SLO - [Deploy the Full Stack](https://runcycles.io/quickstart/deploying-the-full-cycles-stack) — deployment guide with server setup - [Server Configuration Reference](https://runcycles.io/configuration/server-configuration-reference-for-cycles) — all server configuration options - [`cycles-protocol-service/README.md`](cycles-protocol-service/README.md) — core concepts, authentication, error codes, and the Redis data model +