Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / Operations

Reference

Security.txt and readiness

The security.txt document built from settings, the liveness and readiness probes, their answer contract, and the code that relies on them.

A Cluster ERP server answers three unauthenticated operational routes: /.well-known/security.txt, /health, and /ready. This page describes what each returns, the settings behind them, and the tests and scripts that depend on them. The routes are defined in src/cluster_erp/server/app.py; the document builder is src/cluster_erp/server/security_txt.py. The full list of system routes is in system endpoints.

Scope and source

  • Defined in: src/cluster_erp/server/app.py (security_txt, health, ready) and src/cluster_erp/server/security_txt.py (security_txt_body).
  • Count: three routes, counted from the @app.get decorators at src/cluster_erp/server/app.py:1459-1476.

Security.txt

GET /.well-known/security.txt answers HTTP 404 when no contact is configured, and otherwise a text/plain document (src/cluster_erp/server/app.py:1459-1466). The route is not in the OpenAPI schema (src/cluster_erp/server/app.py:1459).

Field Content Source
Contact security_contact; a value with @ and no scheme becomes a mailto: address. src/cluster_erp/server/security_txt.py:21-25
Expires Now plus security_expires_days, clamped to 1 to 365 days, in UTC. src/cluster_erp/server/security_txt.py:26-30
Preferred-Languages tr, en. src/cluster_erp/server/security_txt.py:31
Policy security_policy_url, only when set. src/cluster_erp/server/security_txt.py:33-34
Canonical public_base_url plus the route path, only when set. src/cluster_erp/server/security_txt.py:35-37
Setting Variable Value Source
security_contact CLUSTER_ERP_SECURITY_CONTACT <value> src/cluster_erp/config/settings.py:296
security_policy_url CLUSTER_ERP_SECURITY_POLICY_URL <value> src/cluster_erp/config/settings.py:297
security_expires_days CLUSTER_ERP_SECURITY_EXPIRES_DAYS <value> src/cluster_erp/config/settings.py:298
public_base_url CLUSTER_ERP_PUBLIC_BASE_URL <value> src/cluster_erp/config/settings.py:292

The module states that an empty or fictional security.txt is worse than none, which is why the route answers 404 without a contact (src/cluster_erp/server/security_txt.py:4-7).

Liveness

GET /health answers {"status": "healthy", "version": <app version>} and touches no backing store, so a database outage never restarts the process through a supervisor (src/cluster_erp/server/app.py:1469-1474).

Readiness

GET /ready asks each backing store SELECT 1 under the deadline readiness_timeout_seconds (src/cluster_erp/server/app.py:1485-1493, src/cluster_erp/config/settings.py:649).

Check Present when Source
database always src/cluster_erp/server/app.py:1495
control_plane multi-tenant mode src/cluster_erp/server/app.py:1496-1498
Outcome Status code Body Source
every check passes 200 {"status": "ready", "checks": {...}} src/cluster_erp/server/app.py:1499-1503
any check fails 503 {"status": "not_ready", "checks": {...}} src/cluster_erp/server/app.py:1499-1503

A failing check is reported as fail and the error goes only to the server log, so the answer never contains a host name or connection string (src/cluster_erp/server/app.py:1477-1493).

Contract tests and consumers

Consumer Use Source
tests/test_readiness_contract.py Checks that /health carries a version and that /ready names every store with only pass or fail. A live test: without a server it fails unless CLUSTER_SKIP_LIVE_TESTS=1 is set. tests/test_readiness_contract.py:1-64
tests/test_security_txt.py Checks the 404 case, the mailto: conversion, the fields, and the one-year ceiling. tests/test_security_txt.py:20-51
deploy/install.sh Polls /ready for up to five minutes before it reports a release as live. deploy/install.sh:247-257
deploy/docker/Dockerfile The container health check calls /ready. deploy/docker/Dockerfile:43-44

Constraints and validation

  • security_expires_days is clamped by the builder, not by the settings validator (src/cluster_erp/server/security_txt.py:27).
  • The readiness deadline is a float number of seconds with the default 2.0 (src/cluster_erp/config/settings.py:649).

Terms introduced

Term Code identifier Definition Turkish term Source
liveness probe /health The route that says whether the process is alive, without touching any store. canlılık yoklaması src/cluster_erp/server/app.py:1469-1474
readiness probe /ready The route /ready that says whether the process may take traffic, by asking each store one question. hazırlık yoklaması src/cluster_erp/server/app.py:1476-1504

Verified against commit 92f8051 on 2026-11-13.

Verified against commit 92f8051 · 2026-11-13