Skip to content

Autorizace & Role

Tříúrovňová hierarchie adminů

SuperAdmin (globální)
    │   Vidí a spravuje vše — všechny aplikace, uživatele, role

    └── AppAdmin (per-aplikace)
            │   Spravuje role, oprávnění a přiřazení v jedné aplikaci

            └── User (běžný uživatel)
                    Může dělat jen to, co mu role + overrides povolí

SuperAdmin

  • Uložen v tabulce super_admins (pouze email)
  • Bypass všech permission checků — má přístup ke všemu
  • Výjimka: Deaktivovaný účet (users.active = false) blokuje i superadmina při permission checku
  • Spravovat superadminy může jen jiný superadmin
bash
# Přidání superadmina
POST /api/users/superadmins
Authorization: Bearer <superadmin-token>
{ "email": "admin@firma.cz" }

# Seznam superadminů
GET /api/users/superadmins/list

AppAdmin

  • Uložen v tabulce app_admins (email + application_id)
  • Může spravovat pouze svoji aplikaci (role, oprávnění, přiřazení)
  • Nemůže přidávat/odebírat jiné adminy — to je výsada superadmina
  • Může přidat uživatele a přiřadit mu role ve své aplikaci
bash
# Přidání app admina (vyžaduje superadmin)
POST /api/users/admins/apps/:appCode
Authorization: Bearer <superadmin-token>
{ "email": "appadmin@firma.cz" }

# Seznam adminů aplikace
GET /api/users/admins/apps/:appCode

Middleware stack

authorizationMiddleware()

Ověří JWT token a nastaví req.token:

typescript
req.token = {
  email: "uzivatel@firma.cz",
  orgId: "org_abc123",          // jen Zitadel
  roles: { ... },               // jen Zitadel projekt role
  sub: "user_123",
  provider: "zitadel"
}

Vrátí 401 Unauthorized pokud:

  • Chybí Authorization header
  • Token je neplatný, expirovaný nebo od neznámého providera

loadSuperAdminFlag()

Načte superadmin status do req.isSuperAdmin:

typescript
// Nastaví req.isSuperAdmin = true/false
// Na základě SELECT FROM super_admins WHERE email = req.token.email

Musí být zavolán po authorizationMiddleware().

requireSuperAdmin()

Vrátí 403 Forbidden pokud req.isSuperAdmin !== true.

typescript
// Použití v route
router.post('/superadmins',
  authorizationMiddleware(),
  loadSuperAdminFlag(),
  requireSuperAdmin(),
  async (req, res) => { ... }
);

requireAppAdmin()

Ověří, že je uživatel admin dané aplikace (nebo superadmin):

typescript
// Kontroluje req.params.appCode
// SELECT FROM app_admins WHERE email = ? AND app = ?
// SuperAdmin projde automaticky

Vrátí 403 Forbidden pokud uživatel není app admin ani superadmin.

requireInternalApiKey()

Pro service-to-service endpointy — validuje x-internal-api-key header:

typescript
// Porovná s config.internalApiKey
// 401 pokud chybí nebo neodpovídá

Přehled autorizace per endpoint

Bez autentizace

  • GET /api/test, GET /api/version, GET /api/docs
  • POST /api/check, /check/bulk, /check/effective, /check/cache/clear
  • POST /api/zitadel/webhook, GET /api/zitadel/login, /callback

JWT (libovolný přihlášený uživatel)

  • GET /api/profile/me — svůj profil
  • PUT /api/profile/me — úprava svého profilu
  • GET /api/profile/me/admin-status — vlastní admin status
  • GET/PUT /api/profile/me/apps/:appCode — vlastní preference
  • GET/PUT /api/profile/me/push/* — vlastní push subscriptions
  • GET/PUT /api/profile/me/notifications/* — vlastní notifikační preference

JWT + AppAdmin

  • GET/POST /api/applications/:appCode/permissions
  • GET/POST/PUT/DELETE /api/applications/:appCode/roles
  • GET /api/users — seznam uživatelů
  • POST /api/users — vytvoření uživatele
  • GET /api/users/:email — detail uživatele
  • GET/PUT /api/users/:email/apps/:appCode/roles
  • GET/PUT /api/users/:email/apps/:appCode/resources/*
  • GET /api/admin/dashboard/stats — statistiky (jen svá aplikace)

JWT + SuperAdmin

  • GET/POST/PUT/DELETE /api/applications — správa aplikací
  • POST/DELETE /api/users/admins/apps/:appCode/* — správa app adminů
  • GET/POST/DELETE /api/users/superadmins — správa superadminů
  • PATCH /api/users/:email/active — aktivace/deaktivace
  • GET/POST/PUT/DELETE /api/admin/notifications/* — správa notifikačních typů
  • GET/POST/PUT/DELETE /api/admin/brands/* — správa brandů
  • GET /api/admin/dashboard/stats — statistiky (všechny aplikace)
  • GET/POST/PUT /api/zitadel/admin/* — správa Zitadel organizací

x-internal-api-key (service-to-service)

  • POST /api/internal/notifications — odeslání notifikace
  • POST /api/internal/notifications/bulk
  • GET /api/internal/notifications/types
  • GET /api/internal/notifications/log/:email
  • GET/POST/PUT/DELETE /api/internal/notifications/templates/*

Diagram chybových odpovědí

SituaceHTTP kódPopis
Chybí nebo neplatný token401Unauthorized
Platný token, nedostatečná práva403Forbidden
Neplatný API klíč401Unauthorized
Zdroj neexistuje404Not Found
Validační chyba body422Unprocessable Entity
Deaktivovaný uživatel403Forbidden (jen pro admin akce)

Bezpečnostní poznámky

Deaktivovaný uživatel

Deaktivovaný uživatel (active = false) nemůže provádět admin operace — middleware to kontroluje. Při permission checku (/check) je deaktivovaný uživatel vždy denied, i kdyby byl superadmin.

Rotace klíčů

Interní API klíč (internalApiKey) můžete rotovat bez restartu ostatních služeb — pouze API a klientské backend aplikace musí dostat nový klíč současně.

Atrea User API — interní dokumentace