This release includes 1 security fix for security teams reviewing exposed deployments.
Topics
+12 more
Affected surfaces
Summary
AI summaryUpdates Full Changelog, Tests, and v1.2.1 across a mixed release.
Full changelog
Community Edition Quotas
Community Edition quotas are now correctly enforced across all resource types. Heartbeats were already limited, but endpoints, TLS certificates, and status pages were not — this is now fixed:
- Endpoints: max 10
- TLS Certificates: max 5 standalone
- Status Pages: max 1 group, 3 components
The /api/v1/edition API now exposes active quotas and current usage. The frontend displays real-time consumption.
TLS Certificate Alerts
Certificate expiry alerts now use contextual severity (warning / critical) based on how close the expiration date is, instead of a fixed level.
Fixes
- Upgrade links in the frontend now point to the internal
/pro-editionroute instead of an external URL.
Breaking Change: Non-Root Container
The Maintenant container now runs as user nobody (UID 65534) instead of root.
This is an important security hardening that eliminates the privilege escalation vector via the Docker socket.
What changed
| Before (v1.2.1) | Now (v1.2.2) |
|---|---|
| Process ran as root inside the container | Process runs as nobody (65534:65534) |
| Docker socket was directly accessible | Docker socket requires group_add to be readable |
| Read-write filesystem | read_only filesystem with tmpfs for /tmp |
Action required
Check the GID of the docker group on your host and update your compose.yml accordingly:
# Find the docker group GID on your host
getent group docker | cut -d: -f3
Then add these directives to your maintenant service:
services:
maintenant:
image: ghcr.io/kolapsis/maintenant:latest
read_only: true
security_opt:
- no-new-privileges:true
group_add:
- "${DOCKER_GID:-983}" # ← docker group GID on your host
tmpfs:
- /tmp:noexec,nosuid,size=64m
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- maintenant-data:/data
The default GID is 983 (common on Arch/systemd). On Ubuntu/Debian it is often 999 or 998. Check with the command above.
Without a correctly configured group_add, Maintenant will not be able to read the Docker socket and container auto-discovery will not work.
Environment variable
You can set DOCKER_GID in a .env file next to your compose.yml:
DOCKER_GID=999
Kubernetes
For Kubernetes deployments, configure runAsUser and runAsGroup in the pod's securityContext:
securityContext:
runAsUser: 65534
runAsGroup: 65534
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
Full Changelog
Features
- Expose quotas in
/api/v1/editionendpoint - Add endpoint quota for Community Edition (max 10)
- Add certificate quota for Community Edition (max 5 standalone)
- Add status page quotas for Community Edition (1 group, 3 components)
- Wire Enterprise unlimited quotas in app initialization
- Add frontend quota awareness UI for Community Edition
Fixes
- Run container as nobody with hardened security defaults
- Change upgrade links from external URL to internal
/pro-editionroute - Use contextual severity for certificate expiry alerts
Tests
- Add coverage for certificate expiry severity logic
Docs
- Align all compose examples and guides with container hardening
Breaking Changes
- Container process now runs as user `nobody` (UID 65534) instead of `root`; requires adding host docker group GID via `group_add` in Docker Compose or setting `runAsUser: 65534` and `runAsGroup: 65534` in Kubernetes.
- Filesystem is read‑only with a tmpfs `/tmp`, removing previous write access.
Security Fixes
- Container runs as non‑root `nobody`, eliminating privilege escalation vector via Docker socket.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
Related context
Related tools
Beta — feedback welcome: [email protected]