Platforma Fabrika pro ty, kdo za ni mají ručit

Platforma jen pro vaši firmu, ve vašem vlastním cloudovém účtu. Před každou aplikací jedna vrátnice, přístupy zapsané v kódu a schválené lidmi, nasazování, e-maily i provoz v jedné konzoli. Kód je veřejný, všechno si můžete ověřit.

Přehled v konzoli Fabriky: nasazení, schvalování a chyby napříč firemními aplikacemi

Architektura

Každá firma má vlastní instalaci v cloudovém účtu psaném na firmu. Z internetu se dá dostat jen na proxy.

Internet: prohlížeče, integrace se strojovými klíči, formuláře na vašem webu
Váš cloudový účet (rozložení na Zerops)
Proxy

Jediná cesta do aplikace. Jedna pro každý deployment namespace (aplikace v jednom prostředí), na Cloudflare jeden proxy Worker pro každé prostředí aplikace.

Aplikace

Neveřejné služby bez veřejné adresy.

IAM

Přihlášení přes OIDC i heslem, sessions, role a oprávnění pro každou aplikaci, strojové klíče, audit a log přihlášení, JWKS.

Control

Registr aplikací, prostředí, běhy nasazení, snímky přístupů a schvalování, mailový relay, konzole.

Operations

Příjem chyb (protokol Sentry), releasy a source mapy, kontroly dostupnosti, upozornění přes webhook.

Cesta jednoho požadavku

První návštěva toho dne. Proxy a aplikace sdílejí doménu aplikace, IAM má vlastní.

  1. 01 Prohlížeč → proxy

    https://crm.example.com/ míří na proxy daného namespace.

  2. 02 Proxy

    Smaže příchozí hlavičky X-Fabrika-*, vyžaduje kanonickou cestu a vybere z tabulky hostu právě jeden endpoint. Bez shody, nebo když tabulka chybí či je poškozená: odmítnuto.

  3. 03 Proxy → IAM

    Session není: state a PKCE verifier (v cookie __Host-), přesměrování na IAM. Volání API dostane 401 s adresou přihlášení.

  4. 04 IAM

    Návratová adresa musí být registrovaný origin, jinak 400. Přihlášení přes SSO, heslem, nebo „Pokračovat jako…“.

  5. 05 IAM → proxy

    Jednorázový kód platný dvě minuty, vázaný na session, aplikaci, návratovou adresu a PKCE challenge.

  6. 06 Proxy

    Cookie __Host-px_session jen pro tenhle host, podřízená session v IAM. Žádná sdílená cookie, jedno přihlášení napříč nesouvisejícími doménami.

  7. 07 Proxy → aplikace

    Ověří druh volajícího, akci a pravidla vstupu (Sec-Fetch-Site, Content-Type, povolené originy), odstraní svoje cookies, předá název endpointu a JWT na pět minut, do té doby použitelný znovu.

  8. 08 Aplikace

    Ověří JWT proti JWKS z IAM a otisk pravidel. Na Zerops odmítne požadavky bez tajemství proxy pro danou aplikaci (kromě kontroly dostupnosti).

  9. 09 Aplikace → databáze

    Runtime ověří akci nad objektem, každý dotaz nad tabulkou s rozsahem dostane podmínku rozsahu.

Odhlášení nebo zablokování v IAM ukončí všechny sessions aplikací z toho přihlášení. Vydané tokeny vyprší nejpozději do pěti minut.

Model oprávnění

Aplikace deklarují svoje objekty, akce a role v kódu, podobně jako politiky v IAM velkých cloudů. Kdo jakou roli dostane, rozhodují lidé.

Aplikace deklaruje svůj slovník

Dimenze tvoří hierarchii objektů, akce říkají, co se dá dělat, role jsou balíčky akcí přidělené globálně, nebo nad jedním objektem. Oprávnění se dědí dolů a jen povolují, zakazující pravidla neexistují.

src/vocabulary.ts
export const vocabulary = defineVocabulary({
  app: 'crm',
  dimensions: {
    org: { members: { manage: 'members.manage', list: 'crm.read' } },
    company: { in: 'org' },
    deal: { in: 'company' },
  },
  actions: {
    'crm.read': 'Read companies and deals',
    'deals.write': 'Create deals and move them through the pipeline',
    // …
  },
  roles: {
    sales: {
      grants: ['crm.read', 'deals.write'],
      member: { scope: 'org', assignableBy: ['manager'] },
    },
    // …
  },
})

Každý endpoint řekne, co potřebuje

V handleru není žádný kód pro přihlášení. Řádek access vynucuje proxy i runtime a schvalování nasazení ho ukáže člověku, když se změní.

Tabulky mají vlastní pravidla

Každá tabulka určuje akci pro čtení, vkládání, úpravu a mazání a sloupce, které se smí zapisovat. Datová vrstva omezí každý dotaz na rozsah, takže jeden org nepřečte řádky jiného. Tabulku bez rozsahu nebo ruční SQL je nutné deklarovat.

src/deals/endpoints.ts
move: r.mutation({
  input: MoveDeal,
  output: Saved,
  // deals.write on this deal, or on its company or org
  access: { action: 'deals.write', on: 'deal', from: 'id' },
}).handle(async ({ input, ctx }) => {
  // ctx.db.target is already narrowed to the one deal
  // …
})

Role určuje kód, přidělení lidé

Nasazení aktualizuje definice rolí a zachová přidělení. Nová verze tak potichu nepřidá ani nesebere přístup.

Vlastník aplikace spravuje svoje lidi

Vlastník přiděluje role v konzoli, jen lidem, které IAM už zná, a jen ty, jejichž akce sám má. Správce uživatelů jde omezit na jednu aplikaci.

Lidé mimo firmu

Externí role omezená na vlastní data, heslo přes odkaz v e-mailu, česky nebo anglicky.

Strojové klíče

Klíče px_ vázané na jednu aplikaci, vyměňované za krátce platné tokeny. Mají omezenou platnost, oprávnění jdou upravit bez výměny tajemství.

Sdílené odkazy a konektory

Odkazy vázané na jeden objekt a volání mezi aplikacemi jsou deklarované schopnosti. Jdou přes proxy a objeví se ve schvalování.

Auditní log

Přihlášení, odhlášení a změny v IAM (oprávnění, uživatelé, klíče) se zapisují ve stejné transakci. U nasazení, schválení a rozhodnutí o e-mailech zůstává, kdo je udělal.

Obrazovka Lidé v konzoli: vlastník aplikace přiděluje role bez IT
Auditní log v konzoli: přidělená oprávnění, nové klíče a rozhodnutí o přihlášení

Schvalování nasazení

AI agenti mají sklon povolit si to, co je zastavilo. Co nový commit oproti produkci v přístupech rozšiřuje, proto čeká na konkrétního člověka.

Detail schvalování v konzoli: zaparkované nasazení do produkce s řádky, které rozšiřují přístup, a řádky k bližší kontrole

Jak se porovnává

Control zafixuje commit a přečte z něj snímek přístupů, aniž by spustil jeho kód. Každý řádek porovná s cílovým prostředím a označí jako rozšíření, zúžení, nebo beze změny. Čte commit, ne to, co hlásí build, takže ho agent neukecá.

Co snímek obsahuje

Endpointy a kdo je smí volat, role, pravidla tabulek a sloupců, veřejné endpointy, joby, webhooky, konektory, adresy mimo instalaci, odesílatele e-mailů, typy a limity souborů, rate limity, každou SQL migraci s kontrolním součtem.

Co vidí schvalovatel

  • rozšiřuje Role sales získává members.manage
  • rozšiřuje Nový endpoint deals.export pro roli manager
  • bližší kontrola Endpoint deals.export deklaruje ruční SQL (čtení)
  • bližší kontrola Endpoint deals.export volá https://api.partner.example
  • bližší kontrola Job overdue posílá e-maily přes mailový transport instalace
  • zužuje Role sales přichází o deals.write

K bližší kontrole: ruční SQL, tabulky bez rozsahu, nové adresy mimo instalaci, nové konektory, vydávání sdílených odkazů, posílání přes poštu instalace, triggery nebo funkce v migraci.

Pravidla

Zaparkováno, ne zveřejněno

Rozšiřující změna na chráněném prostředí běh zaparkuje a platí původní přístupy. Zamítnutí běh ukončí, zaparkovaný běh jde zrušit.

Zúžení projde

Změna, která přístup jen ubírá, nečeká.

Člověk, ne klíč

Schválení vyžaduje access.approve, které má člověk a používá v konzoli. Strojový klíč schvalovat nemůže, ani ten, který nasazení spustil.

Zastaralé schválení neplatí

Když se produkce změní, zatímco běh čeká, porovná se znovu.

Pro každé prostředí zvlášť

Produkce je chráněná automaticky. Kdo má access.approve, může ochranu pro prostředí přepnout; vypnutí neschválí nic, co už čeká, a zapíše se do auditu.

Bez kontraktu žádné nasazení

Commit bez souboru s kontraktem selže dřív, než se zavolá poskytovatel cloudu.

Nad tímhle mechanismem kontrolujeme změny před spuštěním ještě my v rámci služby. Přehled bezpečnosti →

E-maily přes jeden relay

E-maily aplikací i přihlašovací e-maily platformy jdou přes jeden relay v Controlu. Vidíte, co komu odešlo, a poštu na vybrané domény můžete podržet.

Instalace v Zerops, aplikace na knihovnách Fabriky 0.7 a novějších.

Seznam e-mailů v konzoli se zadrženými zprávami nahoře
Detail e-mailu v konzoli s tlačítky Release a Drop

Aplikace nedrží přístupy k poskytovateli

Jeden transport na instalaci, každé prostředí aplikace má klíč k relayi (hash, 30 dní, obnovuje ho nasazení). Vlastní poskytovatel aplikace je deklarovaný rozšiřující řádek.

Záznam o každé zprávě

Odesílatel, doména příjemce, stav a pokusy, bez duplicit díky idempotency klíči. Obsah se maže po 30 dnech, přihlašovací e-maily hned po odeslání.

Pravidla: projde, počká, zahodí se

Podle odesílatele a domény příjemce, platí nejkonkrétnější pravidlo, bez pravidel projde vše. Typicky test podrží poštu mimo firmu.

Pustit, nebo zahodit v konzoli

Zadržené zprávy nahoře: příjemce, předmět, text, HTML v izolovaném rámu bez skriptů a údaje o přílohách. Pustit, zahodit, nebo zařadit znovu; u rozhodnutí zůstane, kdo ho udělal.

Posílá se z jobů

Z plánovaných jobů, které odesílání deklarují, nikdy z obsluhy požadavku. Opakuje zhruba osm a půl hodiny, přes neidempotentní transport nikdy dvakrát.

Co aplikace umí poslat

HTML i text, přílohy, reply-to, jméno odesílatele, odhlášení jedním klikem (RFC 8058). Resend, nebo SmartEmailing bez příloh a hlaviček pro odhlášení.

Nasazování

Nasazení je opakovatelný běh z přesného commitu, žádné proklikávání cloudové konzole.

Aplikaci popisují dva soubory

fabrika.config.ts říká, kde a na čem běží, včetně tabulky endpointů pro proxy vygenerované z kontraktu. enableSubdomainAccess: false: služba aplikace nikdy nedostane veřejnou adresu.

fabrika.contract.ts říká, co vystavuje a komu: endpointy, jednostránková aplikace, typy a velikost souborů, joby, kontrola dostupnosti. Tenhle soubor čte schvalování.

fabrika.config.ts
target: {
  platform: 'zerops',
  services: () => [
    { hostname: 'appdb', type: 'postgresql:single@18' },
    { hostname: 'appfiles', type: 'object-storage', objectStorageSize: 1 },
    { hostname: 'appapi', type: 'alpine/bun@1.3', enableSubdomainAccess: false },
  ],
  contract: compiled,
  proxy: { upstream: 'appapi:3000', ...contractProxyTable(compiled) },
}

Co spustí nasazení

Push do určené větve, tag podle vzoru, konzole, CLI nebo AI builder. Control si pro prostředí aplikace vezme zámek a zafixuje commit.

Prostředí a tajemství

Každé prostředí má vlastní namespace, tajemství, doménu a přepínač ochrany, každá aplikace vlastní databázi (v nejmenší velikosti schéma). Tajemství jsou v proměnných služeb na Zerops, nebo v trezoru Controlu na Cloudflare. Zpátky se nezobrazí a proměnné platformy nejde přepsat.

Log běhu

Stav, kdo běh spustil (člověk, webhook, klíč, builder), commit, log kroků, release. Nová verze platformy dál provozuje a nasazuje aplikace na knihovnách Fabriky z půl roku před ní.

Běh na Zerops

verify-exposure ukončí běh dřív, než vznikne verze, pokud má některá služba veřejnou subdoménu, a nahlásí to do Operations. Control posílá repozitář z GitHubu do Zerops a nic z něj nespouští.

Všech deset kroků
  1. 01 apply-import
  2. 02 verify-exposure
  3. 03 write-service-env
  4. 04 raise-start-memory
  5. 05 size-database
  6. 06 reserve-version
  7. 07 upload-source
  8. 08 trigger-build
  9. 09 await-version
  10. 10 reconcile-schema
Seznam běhů nasazení v konzoli se stavem, autorem a commitem
Detail běhu nasazení s logem kroků

Veřejné formuláře a zabezpečení

Registrace, kontaktní formuláře i webhooky se do interní aplikace dostanou, aniž byste ji otevřeli do internetu. Veřejné endpointy běží na instalacích v Zerops.

01

Veřejný formulář jako samostatná služba

Jen deklarované akce: vložit záznam, číst deklarované tabulky. Úprava záznamu potřebuje jeho ID v podepsaném tokenu.

02

Bez CAPTCHA služby

Proof of work ALTCHA, který aplikace sama vydá i ověří, takže data návštěvníka neopustí instalaci. Volitelně Cloudflare Turnstile.

03

Rate limity

Pro klienta i endpoint, k tomu přibrzděné přihlášení heslem.

Podrobnosti

Výchozí: 10 za minutu na klienta, 100 na endpoint, k tomu limit velikosti požadavku a doby zpracování. Přihlášení heslem je přibrzděné podle účtu, nasazení i klienta. Na Zerops zatím limity podle klienta počítají všechny návštěvníky jako jednoho, dokud platforma nebude věřit adrese klienta z load balanceru.

04

Cross-origin jen z uvedených webů

Endpoint to musí dovolit a přesný origin musí být pro prostředí na seznamu. Prázdný seznam nepustí nic, pokud veřejný endpoint nedeklaruje jakýkoli origin.

05

Odchozí volání jen na deklarované adresy

Nedeklarované adresy mimo instalaci se za běhu odmítnou. Kontrolovaná pojistka, ne sandbox.

06

Ověřené příchozí webhooky

HMAC, basic nebo bearer, s předvolbami pro Slack, Twilio, Stripe, GitHub a Standard Webhooks.

07

Nahrané soubory

První bajty musí odpovídat deklarovanému typu, každý druh souboru má limit velikosti.

08

Bezpečnostní hlavičky u každé odpovědi

CSP, HSTS a další obvyklé hlavičky, CSP se sandboxem u stahovaných souborů, ID požadavku pro dohledání.

Podrobnosti

CSP, HSTS (jeden rok) na https hostech, X-Content-Type-Options: nosniff, Referrer-Policy: no-referrer, Cross-Origin-Opener-Policy, Permissions-Policy. ID požadavku přidělí proxy a aplikace i IAM ho zapisují do logu.

Provoz

Běží ve vaší instalaci, takže hlášení chyb neopouštějí váš účet.

Příjem chyb kompatibilní se Sentry

Fungují existující Sentry SDK. Chyby se seskupují; jde je vyřešit, ignorovat, přiřadit, okomentovat, odložit, sloučit nebo vyřešit v releasu. Vyřešená chyba, která se vrátí, se otevře jako regrese.

Automatická hlášení bez citlivých dat

Neúspěšné požadavky, selhané nebo vynechané joby a pády se hlásí samy. Tajemství, tokeny, autorizační hlavičky, těla požadavků a řádky se vymažou, nebo neposílají.

Releasy a source mapy

Release pro každé nasazení, navázaný na commit. Source mapy se nahrávají s přístupem jen pro daný běh.

Kontroly dostupnosti a upozornění

HTTP kontroly pro každé prostředí aplikace s upozorněním při selhání i obnovení. Nové chyby, regrese, nárůsty a nezdravá telemetrie odcházejí jako webhooky (HTTPS, idempotentně, s opakováním).

Seskupené chyby v konzoli s průběhem v čase
Detail chyby se stack trace dohledaným přes source mapy
Kontroly dostupnosti pro každé prostředí aplikace

Cloud a stack

Každá instalace běží buď na Zerops, nebo na Cloudflare. Celé běhové prostředí aplikací má dnes jen Zerops, proto tam firemní aplikace obvykle dáváme.

Přihlášení, proxy, konzole, nasazování, sběr chyb
Zerops: ano
Cloudflare: ano
Proxy
Zerops: Caddy + autorizační služba v Bunu pro každý namespace
Cloudflare: proxy Worker pro každé prostředí aplikace
Aplikace
Zerops: Bun na Alpine, neveřejná služba
Cloudflare: Workers bez routes, workers.dev vypnuté
Databáze aplikací s pravidly na úrovni řádků
Zerops: PostgreSQL 18
Cloudflare: zatím ne
Joby na pozadí a e-maily
Zerops: ano
Cloudflare: zatím ne
Uložené soubory
Zerops: objektové úložiště kompatibilní s S3
Cloudflare: zatím ne

AWS

Poskytovatele pro AWS kód nemá. Pokud potřebujete AWS, umíme vám tam instalaci nastavit v rámci zavedení.

Jedna aplikace, jeden cloud

Každá aplikace míří na jeden cloud. Přestěhovat ji mezi cloudy za vás platforma neumí.

Stack

Jazyk
všude TypeScript
Runtime a monorepo
Bun 1.3+
Databáze
PostgreSQL (Zerops), D1/SQLite pro služby platformy na Cloudflare
Úložiště
kompatibilní s S3 (objektové úložiště Zerops, R2)
Schémata
zod (API v4)
UI aplikací
React s vlastní sadou komponent
Migrace
čisté SQL, každá služba vlastní svoje schéma

Stavění s AI

Většina aplikací na Fabrice vzniká s AI agentem. Jeho změny jdou stejnou cestou jako změny od člověka.

Lokální builder

Osm vedených fází od zadání po stavbu, s kontrolními body a pravidly aplikace pro Claude Code a Codex. K instalaci v Zerops se připojí, až to člověk schválí, s odvolatelným klíčem pro jednu aplikaci na nejvýš 30 dní.

Úpravy z vlastního Claude nebo ChatGPT

Hotové, celé to ale ještě ověřujeme v produkci; zapíná se pro instalaci, jen na Zerops. Lidé upravují přes MCP, přihlášení proti vašemu IAM a s právy jen na úpravy. Změny jsou commity ve větvi, nasadí se na stage a otevře se pull request; do produkce jen přes merge od člověka a běžné schválení.

Váš tarif AI

Vždy vlastní tarif AI vaší firmy. S výběrem poskytovatele rádi poradíme.

Mantinely v repozitáři

Kontrola kódu odmítne any, přetypování, komentáře potlačující chyby, ruční SQL mimo deklarovanou cestu a přímé čtení proměnných prostředí. Vygenerované testy hlídají oddělení dat a přístup k endpointům.

Co platforma neumí

K aktuální verzi:

Vícefaktorové ověření
Jen přes SSO vašeho poskytovatele identity, k heslu žádné TOTP ani passkeys.
SAML a SCIM
Jen OIDC, jeden poskytovatel identity na instalaci. Odcházející je nutné zablokovat i v IAM.
Zálohy a obnova
Platforma je nedělá, nastavíme je s vámi v rámci služby nástroji cloudu.
Rollback
Příkaz není, nasadí se starší commit přes schválení. Zerops umí přepnout verzi mimo Fabriku.
Upozornění e-mailem
Jen webhooky.
Žádosti o přístup
Nejsou, role přiděluje ten, kdo spravuje lidi aplikace.
Antivirová kontrola nahraných souborů
Kód pro ClamAV existuje, v produkci neověřený, neslibujeme.
Ověření na Zerops
Některé cesty, mezi nimi nahrávání source map, ještě ověřujeme v produkci. Doručování webhooků odolné vůči útokům přes DNS hotové není.
Certifikace
Bez ISO 27001, SOC 2, zveřejněného penetračního testu i SBOM. Kód je veřejný.
Zaručený audit všeho
Změny v IAM jsou transakční a přihlášení se zaloguje dřív, než IAM odpoví. Události z ostatních služeb jen best effort.

Všechny odpovědi pro prověrku dodavatele: Bezpečnostní dotazník →

Open source, a kdybyste odcházeli

Odchodem od nás nepřijdete o nic, na čem stojíte.

github.com/contember/fabrika-platform →
Váš cloudový účet
Všechno běží v něm. My jsme tam správci a přístup nám můžete kdykoli odebrat.
Váš Git
Kód aplikací je obyčejný TypeScript a SQL migrace v GitHubu vaší firmy.
Licence MIT
Platforma na GitHubu, knihovny aplikací na npm jako @fabrika/* s ověřitelným původem, návod k instalaci v CLI.
Co odchod znamená
Provozovat platformu sami nebo s někým jiným, ve stejném účtu. Ne stěhovat se do jiného cloudu.

Projděte si to s naším inženýrem.

Půl hodiny s člověkem, který platformu staví. Vezměte svého poskytovatele identity, cloud, bezpečnostní dotazník nebo repozitář.