Standard propojení ekosystému ONhost E1–E5 (v1, 2026-11-08)
Stav: NÁVRH přijatý arbitrem (vratný, Adrianovo blanket „souhlasím se vším“ ze 7. 11.). Platí pro každý ONhost projekt.
Každý projekt dál funguje samostatně (rozhodnutí 6. 11.): nic z E1–E5 nesmí být podmínkou pro provoz služby.
Vše nové je za příznakem, výchozí stav vypnuto. Referenční implementace: packages/ecosystem-kit (PHP 8.3, bez závislostí).
E1 Identita
- OnPass (
https://onpass.cz, OIDC + PKCE S256, passkeys) je *volitelné* SSO. Lokální účty zůstávají. - Účet se nikdy nepropojí automaticky podle e-mailu; propojení jen po přihlášení k oběma (explicitní souhlas).
- Back-channel logout (OIDC Back-Channel Logout 1.0) – projekt ukončí lokální relaci podle
sid. - Služba↔služba: OAuth 2.0 client credentials, přístupový token max 10 min,
aud= id cílové služby, scope<projekt>:<zdroj>:<read|write>. Žádné sdílené statické klíče mezi projekty. identity_exists≠service_access(README tohoto repa): token scope nikdy nenahrazuje enrollment/tarif.- Příznak:
ONPASS_ENABLED=false. Vlastník: vlákno ONhost ID / OnPass (scope registr, client credentials).
E2 Události a webhooky
- Obálka CloudEvents 1.0, strukturovaný JSON (
application/cloudevents+json), schémaschemas/ecosystem/cloudevent.v1.json. type=cz.onhost.<projekt>.<entita>.<akce>.v<N>(např.cz.onhost.onvet.visit.completed.v1)source=https://<doména projektu>[/cesta],id= UUIDv7,time= RFC 3339 UTC,subject= id zdroje.databez zbytečných osobních údajů; citlivé (zdraví, adopce) jen jako odkaz + scope, nikdy partnerům.- Transactional outbox v každém projektu (zápis události ve stejné DB transakci jako změna).
- Odchozí webhooky podle Standard Webhooks: hlavičky
webhook-id,webhook-timestamp,webhook-signature: v1,<base64 HMAC-SHA256("id.ts.body")>; tajemstvíwhsec_…(≥ 24 B) na odběr, ukázané jednou, uložené šifrovaně; rotace = více podpisů oddělených mezerou. - Příjemce: tolerance ±300 s, idempotence přes
webhook-id, odpověď 2xx do 15 s, práci dělá asynchronně. - Retry: 5 s, 5 min, 30 min, 2 h, 5 h, 10 h, 10 h → dead letter;
410 Gone= endpoint se vypne. - Cílové URL: jen https, port 443, veřejná IP ověřená při každém doručení (SSRF/EgressGuard), bez přesměrování.
- Přechod: sběrnice onhost-hosting (
X-Onhost-Signature: t=,v1=) posílá v přechodu obě hlavičky; kit máLegacyOnhostSignature. Konec přechodu: až všechna vlákna potvrdí příjemwebhook-*. - Katalog událostí projektu:
docs/events.md(typ, schémadata, kdo publikuje, kdo odebírá, osobní údaje ano/ne).
E3 Veřejné API v1
- Prefix
/api/v1, JSON, OpenAPI 3.1 generovaný z kódu (/api/v1/openapi.json), kontrolovaný v lokálním gate (diff proti commitnutému souboru). - Autentizace: osobní tokeny (hash v DB, prefix
<projekt>_pat_) nebo OAuth tokeny OnPass; vždy scope + RBAC + tenant. - Chyby RFC 9457
application/problem+json,type=https://api.onhost.cz/problems/<slug>; cizí tenant = 404. - Rate limit: hlavičky
RateLimit-Policy/RateLimit(IETF httpapi draft) +Retry-Afteru 429. - Stránkování kurzorem (
?cursor=,next_cursor), limit max 100. - Zápisy přijímají
Idempotency-Key(24 h, stejný klíč + jiné tělo = 422). - Zastarávání:
Deprecation+Sunsethlavička min. 6 měsíců předem; breaking change =/api/v2. - Příznak:
API_V1_ENABLED=falsepro nové zápisové endpointy.
E4 MCP server
- Transport Streamable HTTP na
/mcp(jeden POST endpoint, JSON-RPC 2.0), protokol 2025-11-25 (fallback 2025-06-18, 2025-03-26). - Autorizace OAuth 2.1 přes OnPass (MCP authorization spec, Protected Resource Metadata
/.well-known/oauth-protected-resource); dynamická registrace klientů jen pro schválené klienty. - Tenká vrstva nad API v1 (stejné scope, tenant, policy). Nástroje nejdřív jen ke čtení; zápis jen s
allowWritesna serveru + potvrzením uživatele a přes stejný CommandBus/allowlist. - Výstup prochází redakcí (klíče typu secret/token/password/iban…); interní chyby se nevypisují.
- Audit každého volání: nástroj, subjekt, tenant, výsledek, *jména* argumentů (ne hodnoty).
- Příznak
MCP_ENABLED=false. Nástroj bez oprávnění se tváří jako neexistující. - Implementace:
Onhost\EcosystemKit\Mcp\McpServer+Tool.
E5 Health a manifest
GET /health→{"status":"ok|degraded|down","version":"…","checks":{…}}bez interních hostitelů a čísel zákazníků.GET /.well-known/onhost-service.jsonve formátu"schema": "onhost-service/1"(shodný s onhost-hosting #507) podleschemas/ecosystem/onhost-service.v1.json: slug, název, verze, base_url, health, odkaz na OpenAPI a MCP, volitelný issuer OnPass, nabídky (federovaný katalog OnPass), publikované typy událostí.- Čte ho brána
api.onhost.cz(registr služeb), katalog OnPass a status.onhost.cz.
Checklist pro projekt (Definition of Done)
1. E5 manifest + health (může hned, nezávisí na nikom).
2. OpenAPI 3.1 pro existující API, problem+json, RateLimit hlavičky.
3. Outbox + docs/events.md + odchozí webhooky Standard Webhooks.
4. MCP read-only nástroje (2–5 nejužitečnějších dotazů) za MCP_ENABLED=false.
5. OnPass jako volitelné SSO, client credentials pro služba↔služba.
6. Testy: podpis (oficiální vektor), replay, cizí tenant 404, MCP bez scope, redakce. Hlásit OVĚŘENO / NETESTOVÁNO.
Zdroje
CloudEvents 1.0.2 (cloudevents.io), Standard Webhooks spec (standardwebhooks.com), RFC 9457, draft-ietf-httpapi-ratelimit-headers, OpenAPI 3.1, MCP specifikace 2025-11-25 (modelcontextprotocol.io), OAuth 2.1 draft, OIDC Back-Channel Logout 1.0.