A módszerek EU környezetre (GDPR, NIS2, AI Act, DORA) és Supabase alapú, AI asszisztált fejlesztésre vannak lefordítva, a mögöttük álló elvek viszont bármely technológiai környezetben érvényesek. Minden módszernél megvan a lépéssor, az alkalmazási terület, a tipikus hiba és a mai jelentése. A szabályozási részek fejlesztői kontrollokat neveznek meg, jogi értelmezést nem adnak.
A 2026 októberi állapot szerint a NIST SP 800-63B-4 végleges (2025. augusztus). Az OAuth 2.1 még Internet-Draft (16. revízió, 2026. szeptember), a gyakorlatban mégis ez a viszonyítási alap. A NIST FIPS 203, 204 és 205 szabványok 2024 augusztusa óta véglegesek.
Klasszikus gyökerek, mai módszerként
A hatvanas és hetvenes évek biztonsági irodalma ma is élő tudás, mert ugyanazokat a kérdéseket tette fel, amelyeket egy mai Supabase RLS policy megválaszol. Ki az alany, mi az objektum, milyen műveletről van szó, ki dönt, és hogyan bizonyítható, hogy a döntés mindig lefut.
Dennis és Van Horn, capability (1966)
A gondolat. A jogosultság egy nem hamisítható token, amelynek birtoklása maga a jog. A rendszer ilyenkor azt vizsgálja, mit tart a hívó a kezében, és nem azt, hogy kicsoda. Egy capability egyszerre nevezi meg az objektumot és a megengedett műveleteket.
A módszer ma.
- Számba vesszük azokat a műveleteket, ahol a megosztás egyetlen linkkel vagy tokennel történik (meghívó, fájlmegosztás, jelszó visszaállítás, webhook).
- A token kriptográfiailag erős véletlenből készül (legalább 128 bit), soha nem szekvenciális azonosítóból.
- A tokenbe vagy a hozzá tartozó rekordba belekötjük a hatókört (melyik objektum, milyen művelet) és a lejáratot.
- A tokent hash formában tároljuk, mint egy jelszót, így adatbázis szivárgáskor nem használható.
- A token visszavonható (revoked_at oszlop), és lehetőleg egyszer használatos.
import { randomBytes, createHash } from "node:crypto";
export function newCapability() {
const token = randomBytes(32).toString("base64url"); // 256 bit
const tokenHash = createHash("sha256").update(token).digest("hex");
return { token, tokenHash }; // a token megy a linkbe, a hash az adatbázisba
}
Mikor érdemes. Megosztás olyan féllel, akinek nincs fiókja, időkorlátos delegálás, gépek közötti hívás szűk hatókörrel.
Tipikus hiba. A capability szivárog (Referer fejléc, logok, böngésző előzmények), és nincs lejárata. A Supabase storage signed URL is capability, ezért rövid lejárattal érdemes kiadni (percekre, nem hetekre).
Mai kapcsolat. Az OAuth access token, a signed URL, a macaroon és a biscuit token mind capability. LLM ügynököknél a capability szemlélet a legtisztább védelem, az ügynök csak olyan tokent kap, amely egyetlen feladatra, rövid időre szól. Az ügynökök jogosultságkezeléséről az AI ügynökök és vibecoding kézikönyv ír részletesen.
Ware jelentés (1970)
Willis Ware RAND jelentése (Security Controls for Computer Systems) volt az első rendszerszintű felmérés. Fő tanulsága szerint a biztonságot nem lehet utólag ráhegeszteni egy megosztott, több felhasználós rendszerre, mert a hardver, a szoftver, a kommunikáció, a személyzet és a fizikai környezet mind támadási felület. A jelentés már kimondta, hogy a rendszernek a legkevésbé megbízható felhasználóval szemben is védenie kell az adatot.
Mai módszer. Minden új projekt elején egyoldalas lista készül a támadási felületről (kliens, API, adatbázis, storage, edge function, harmadik fél, emberek, CI). Ebből indul a későbbi fenyegetésmodellezés, amelyet a Kiberbiztonság kézikönyv dolgoz fel.
Lampson, Protection (1971), access matrix
A modell. A sorok az alanyok (felhasználók, folyamatok), az oszlopok az objektumok (fájlok, táblák, sorok), a cellákban a jogok állnak (read, write, own). Két tárolási mód létezik. Oszloponként tárolva access control list (ACL), soronként tárolva capability lista lesz belőle.
Lépések.
- A szerepek és az erőforrások táblázata elkészül, mielőtt egyetlen policy születne.
- A cellákba a műveletek kerülnek (select, insert, update, delete), a feltételükkel együtt.
- Minden üres cella tiltás. Ez a fail safe default.
- Az RLS policykat a táblázatból generáljuk vagy azzal vetjük össze, a táblázat pedig verziózva a repóban él, a kód mellett.
| Alany \ Objektum | projects (saját tenant) | projects (más tenant) | invoices | audit_log |
|---|---|---|---|---|
| owner | CRUD | nincs | CRUD | R |
| member | R, U ha szerkesztő | nincs | R | nincs |
| anon | nincs | nincs | nincs | nincs |
| service (cron) | R | R | U (státusz) | I |
Tipikus hiba. A mátrix csak a fejekben él, és a policyk ellentmondanak egymásnak. AI asszisztált fejlesztésnél ez gyakori, mert a kódgeneráló modell táblánként ír policyt, a teljes kép ismerete nélkül.
Anderson jelentés (1972), a referencia monitor
James Anderson USAF jelentése vezette be a referencia monitor fogalmát, amelyhez három követelménynek kell teljesülnie.
- Teljes közvetítés (always invoked). Minden hozzáférés áthalad rajta, nincs megkerülő út.
- Hamisításbiztosság (tamperproof). Az alanyok nem módosíthatják.
- Ellenőrizhetőség (verifiable). Elég kicsi és egyszerű ahhoz, hogy átvizsgálható és tesztelhető legyen.
Supabase fordítás. A Postgres RLS a referencia monitor. Teljes közvetítés akkor van, ha minden táblán be van kapcsolva az RLS, és nincs olyan út (security definer függvény, view, service_role kulcs a kliensben), amely megkerüli. Hamisításbiztosságról akkor beszélhetünk, ha a felhasználó nem tudja módosítani azokat az adatokat, amelyekre a policy épít (például a saját role oszlopát a profiles táblában). Ellenőrizhető a rendszer, ha a policyk rövidek, egy helyen vannak (migrációban), és automatizált teszt fut rájuk.
Bell és LaPadula (1973), titkosság
Szabályok. Az alanyok és az objektumok biztonsági szinttel rendelkeznek (például nyilvános, belső, bizalmas, szigorúan titkos).
- Simple security property (no read up). Alany nem olvashat magasabb szintű objektumot.
- Star property (no write down). Alany nem írhat alacsonyabb szintű objektumba, mert így szivárogtatna.
- Discretionary property. Az access matrix ezen felül is korlátoz.
Mai alkalmazás. A no write down a legtöbbet használt szabály, csak más néven. Bizalmas táblából nem kerülhet adat nyilvános cache-be, analitikába, logba vagy LLM promptba. A szinteket az adatosztályozás adja (lásd lent), a star property-t pedig a pipeline ellenőrzések valósítják meg.
Tipikus hiba. Egy riport view a bizalmas táblából aggregál egy mindenki által olvasható táblába. Ez write down, és senki nem vette észre, mert a view security definer jogokkal fut.
Biba (1977), integritás
A Bell és LaPadula modell tükörképe, integritásra. No read down (megbízható folyamat nem olvas megbízhatatlan inputot ellenőrzés nélkül) és no write up (megbízhatatlan alany nem ír megbízható adatba).
Mai alkalmazás. A prompt injection Biba sértés. Az LLM megbízhatatlan inputot olvas (weboldal, email, feltöltött dokumentum), majd magas integritású műveletet végez (adatbázis írás, email küldés). A módszer szerint az ilyen adatból származó kimenet alacsony integritású, és csak emberi jóváhagyás vagy szigorú validáció után léphet magasabb szintre. Ugyanez igaz a webhookokra, mert aláírás ellenőrzés nélkül a webhook payload nem írhat a fizetési táblába.
Denning lattice model (1976)
Dorothy Denning az információáramlást hálóként (lattice) formalizálta. Minden adat címkét kap, két adat kombinációja a két címke legkisebb felső korlátját kapja. Ebből következik, hogy egy bizalmas és egy nyilvános mezőből számolt érték is bizalmas.
Mai módszer. Az oszlopok címkét kapnak (Postgres COMMENT vagy security label), a származtatott táblák, view-k és exportok címkéje pedig a forrásaik maximuma. Ezt egy egyszerű CI szkript ellenőrizheti a migrációkon.
Saltzer és Schroeder (1975), a nyolc elv
A The Protection of Information in Computer Systems című cikk nyolc tervezési elve ma is a legjobb ellenőrzőlista. Mindegyikhez mai példa és Supabase vonatkozás tartozik.
| Elv | Jelentés | Mai példa | Ellenőrzés |
|---|---|---|---|
| Economy of mechanism | A védelmi mechanizmus kicsi és egyszerű | Egy is_member(tenant_id) függvény minden policyban, nem tíz eltérő join | Policy hossz, ismétlődés a migrációkban |
| Fail safe defaults | A hozzáférés alapja az engedély, nem a kizárás | RLS bekapcsolva, policy nélkül semmi sem látszik | Supabase advisor, rls_enabled minden public táblán |
| Complete mediation | Minden hozzáférés ellenőrzött, cache sem kerülheti meg | Az edge function is a user JWT-vel hív, nem service_role-lal | Kódkeresés service_role kulcsra |
| Open design | A biztonság nem a titkos terven múlik | Az anon kulcs nyilvános, a védelem az RLS-ben van | Kiindulópont, hogy a támadó ismeri az API-t |
| Separation of privilege | Kritikus művelethez több feltétel kell | Kifizetés jóváhagyása két külön felhasználótól | A négy szem elv tesztje |
| Least privilege | Minden alany csak a feladatához szükséges jogot kapja | Cron job saját Postgres role-lal, csak egy táblára | GRANT lista áttekintése |
| Least common mechanism | A több felhasználó által osztott közös mechanizmus minimális | Bérlőnként külön storage prefix, közös cache kulcsban tenant_id | Cache kulcs séma |
| Psychological acceptability | A védelem könnyen, helyesen használható | Passkey a jelszó helyett, értelmes hibaüzenet | Felhasználói teszt, support jegyek |
A cikk két további elvet is említ, amelyeket a szerzők gyengébbnek tartottak. A work factor (a támadás költsége legyen nagyobb a nyereségnél) ma a kriptográfiai paraméterválasztás alapja. A compromise recording (a betörés legyen észlelhető) mai megfelelője az audit log és a riasztás.
Használat. Kódáttekintésnél a nyolc soron végigmegyünk. AI által generált kódnál a fail safe defaults és a complete mediation sérül leggyakrabban, mert a modell a működő demóra optimalizál.
Clark és Wilson (1987), kereskedelmi integritás
A katonai titkossági modellekkel szemben Clark és Wilson a könyvelés világából indult ki.
Fogalmak.
- CDI (constrained data item). Védett adat, például számlaegyenleg.
- UDI (unconstrained data item). Ellenőrizetlen bemenet.
- IVP (integrity verification procedure). Ellenőrzi, hogy a CDI-k konzisztens állapotban vannak.
- TP (transformation procedure). Az egyetlen út, amelyen a CDI módosulhat. Ez a well formed transaction.
- Separation of duty. Ugyanaz a személy nem indíthatja és hagyhatja jóvá ugyanazt a műveletet.
Megvalósítás Postgresben.
- A CDI táblákra a kliens nem kap közvetlen insert, update, delete jogot.
- A módosítás egyetlen jól definiált függvényen (RPC) keresztül történik, amely tranzakcióban ellenőriz és ír.
- Minden TP auditnaplót ír.
- Az IVP egy ütemezett lekérdezés, amely invariánsokat ellenőriz (például hogy a főkönyv kiegyenlített).
-- a kliens nem írhat közvetlenül
revoke insert, update, delete on public.ledger_entries from authenticated;
create or replace function public.approve_payout(p_payout_id uuid)
returns void
language plpgsql
security definer
set search_path = ''
as $$
declare
v_requested_by uuid;
begin
select requested_by into v_requested_by
from public.payouts where id = p_payout_id for update;
if v_requested_by = auth.uid() then
raise exception 'separation of duty: a kérelmező nem hagyhatja jóvá';
end if;
if not public.has_role(auth.uid(), 'finance_approver') then
raise exception 'nincs jogosultság';
end if;
update public.payouts set status = 'approved', approved_by = auth.uid(), approved_at = now()
where id = p_payout_id and status = 'pending';
insert into public.audit_log(actor, action, object_id)
values (auth.uid(), 'payout.approve', p_payout_id);
end;
$$;
revoke execute on function public.approve_payout(uuid) from public, anon;
grant execute on function public.approve_payout(uuid) to authenticated;
Tipikus hiba. A TP létezik, de a táblán közben nyitva maradt egy update policy, így a kliens megkerüli.
Orange Book (TCSEC, 1983), röviden
Az amerikai védelmi minisztérium értékelési kritériumai négy osztályt határoztak meg. D (minimális védelem), C1 és C2 (diszkrecionális védelem, C2-ben már egyéni elszámoltathatóság és audit), B1, B2, B3 (kötelező, címke alapú védelem, egyre szigorúbb architektúrával), A1 (formálisan igazolt terv). Ma a Common Criteria (ISO/IEC 15408) váltotta, de két gondolata maradandó. A trusted computing base legyen minél kisebb, az assurance szintje pedig külön kérdés a funkcionalitástól. Egy rendszer tudhat sokat, és közben mégis alacsony bizonyosságot nyújthat.
Morris és Thompson, Password Security (1979)
A Unix jelszótárolás esettanulmánya három módszert vezetett be, amelyek ma is alapok.
- Só. Minden jelszóhoz egyedi véletlen érték tartozik, így az azonos jelszavak eltérő hasht adnak, és az előre számolt táblák (később rainbow table) használhatatlanok.
- Lassú függvény. A DES alapú crypt szándékosan lassú volt, hogy a próbálgatás drága legyen.
- Jelszóválasztás ösztönzése. A szerzők kimutatták, hogy a felhasználói jelszavak nagy része rövid vagy szótári.
A mai megfelelő az argon2id vagy a bcrypt (lásd lent, a jelszótárolásnál). A tanulmány alapján a só nem titok, a lassúság a védelem lényege, a gyenge jelszavakat pedig a regisztrációkor kell kiszűrni.
Diffie és Hellman (1976), RSA (1977)
A New Directions in Cryptography bevezette a nyilvános kulcsú kriptográfiát és a kulcscserét, amellyel két fél nyilvános csatornán állapít meg közös titkot. Rivest, Shamir és Adleman egy évvel később gyakorlati sémát adott titkosításra és aláírásra.
Mai jelentés fejlesztőnek. A DH ma X25519 formában él (TLS 1.3, Signal, WireGuard). Az RSA még elterjedt, de új rendszerbe aláírásra Ed25519, kulcscserére X25519, hosszabb távra hibrid X25519 plusz ML-KEM a javasolt. RSA-t saját implementációban sosem írunk. A textbook RSA padding nélkül törhető, a PKCS#1 v1.5 titkosítás pedig padding oracle támadásra érzékeny (Bleichenbacher, 1998).
Ross Anderson, Security Engineering, 3. kiadás (2020)
Anderson könyve a biztonságot mérnöki szakterületként írja le, ahol a technika, az emberek és a pénz egyszerre számít.
A négyes keret
| Elem | Kérdés | Supabase projektben |
|---|---|---|
| Policy | Mit kell elérni? | Access matrix, adatosztályozás, megőrzési szabályok |
| Mechanism | Milyen eszközzel? | RLS, Auth, titkosítás, Vault, rate limit |
| Assurance | Mennyire bízhatunk a mechanizmusban? | pgTAP tesztek, két felhasználós teszt, pentest, advisor |
| Incentive | Kinek mi az érdeke? | Ki fizet a betörésért, ki dönt, ki tartja karban |
Használat. Minden biztonsági döntésnél mind a négy elemet leírjuk, és a hiányzó elem mutatja a hiba helyét. Leggyakrabban az assurance hiányzik (van policy, nincs teszt), vagy torz az incentive (a fejlesztő a határidőért felel, a betörésért nem).
Pszichológia
- A felhasználók a legkisebb ellenállás útját választják. Ha a biztonságos út nehezebb, megkerülik.
- A phishing a figyelem kihasználása, nem butaság. Ezért phishing rezisztens hitelesítés kell (passkey), az oktatás egymagában kevés.
- Biztonsági figyelmeztetésből annyi legyen, amennyit az ember komolyan vesz. A túl sok riasztás vakká tesz (alert fatigue).
- A social engineering a helpdesken keresztül, a fiók helyreállításnál éri el a rendszert. A helyreállítási folyamatnak ezért ugyanolyan erősnek kell lennie, mint a belépésnek.
Gazdaságtan
- Externáliák. A szivárgás költségét gyakran a felhasználó viseli, nem a fejlesztő. A GDPR bírság és a NIS2 vezetői felelősség ezt próbálja visszaterhelni.
- Információs aszimmetria. A vevő nem tudja megítélni a biztonságot, ezért a piac a funkciót jutalmazza. Ellenszere a mérhető bizonyíték (tesztek, audit, SBOM).
- Elsőként a piacra. Hálózati hatásnál a gyors indulás győz, a biztonság később jön. Ezért kell a biztonságos alapértelmezés már a sablonokba, mert később nem kerül be.
- Felelősség és döntés egy kézben. Aki a kockázatot vállalja, az döntsön is róla. A kockázatelfogadást írásban, névvel rögzítjük.
Hozzáférés szabályozási modellek
Áttekintés
| Modell | Ki dönt | Erősség | Gyengeség | Tipikus megvalósítás |
|---|---|---|---|---|
| DAC | Az objektum tulajdonosa | Rugalmas, természetes | Szivárgás megosztással, nehéz auditálni | Unix jogok, Google Drive megosztás, owner_id oszlop |
| MAC | A rendszer, címkék alapján | Erős, központi | Merev, drága üzemeltetni | SELinux, Bell és LaPadula, adatosztály címke |
| RBAC | Szerep hozzárendelés | Egyszerű audit, szervezetben jól skálázódik | Szerep robbanás, kontextus nélküli | NIST RBAC, Postgres role, app_role oszlop |
| ABAC | Attribútumokon futó szabály | Finom, kontextusfüggő | Nehéz átlátni és tesztelni | NIST SP 800-162, AWS IAM feltételek, Cedar |
| ReBAC | Kapcsolati gráf | Megosztás, hierarchia természetesen | Gráf bejárás költsége | Google Zanzibar, OpenFGA, SpiceDB |
RBAC a NIST modell szerint
A NIST RBAC (Ferraiolo és Kuhn, 1992, később ANSI INCITS 359) négy szintet ír le. Core RBAC (felhasználó, szerep, jogosultság, session), hierarchikus RBAC (szerepek öröklése), statikus separation of duty (két szerep nem adható ugyanannak a személynek), dinamikus separation of duty (egy sessionben nem aktiválható egyszerre).
Lépések.
- A jogosultság (permission) a legkisebb egység, például invoice.approve.
- A szerep jogosultságok csoportja. A kód mindig jogosultságot ellenőriz, nem szerepet, így a szerepek átszervezése nem igényel kódmódosítást.
- A szerep hozzárendelése bérlőn belül történik (tenant_id, user_id, role).
- A szerep nem a felhasználó által írható táblában tárolódik.
create table public.memberships (
tenant_id uuid not null references public.tenants(id) on delete cascade,
user_id uuid not null references auth.users(id) on delete cascade,
role text not null check (role in ('owner','admin','member','viewer')),
primary key (tenant_id, user_id)
);
create table public.role_permissions (
role text not null,
permission text not null,
primary key (role, permission)
);
create or replace function public.has_permission(p_tenant uuid, p_perm text)
returns boolean
language sql stable security definer set search_path = ''
as $$
select exists (
select 1
from public.memberships m
join public.role_permissions rp on rp.role = m.role
where m.tenant_id = p_tenant
and m.user_id = (select auth.uid())
and rp.permission = p_perm
);
$$;
Tipikus hiba. Szerep robbanás (admin_eu_readonly_finance_v2). Ha húsznál több szerep kell, az az ABAC vagy a ReBAC jele.
ABAC
Az ABAC (NIST SP 800-162, 2014) négy attribútumcsoportot értékel. Alany (osztály, beosztás), erőforrás (adatosztály, tulajdonos), művelet és környezet (idő, IP, eszköz állapota). A szabály logikai kifejezés.
Postgres példa. Bizalmas dokumentumot csak a saját osztály láthat, és csak MFA-val belépett session.
create policy "confidential docs by department with mfa"
on public.documents for select to authenticated
using (
classification <> 'confidential'
or (
department_id = (select public.current_department())
and (select auth.jwt() ->> 'aal') = 'aal2'
)
);
Az aal claim a Supabase JWT-ben jelzi, hogy a session MFA-val emelt szintű (aal2). Ez a legegyszerűbb ABAC környezeti attribútum.
ReBAC és Google Zanzibar (2019)
A Zanzibar cikk (USENIX ATC 2019) a Google egységes jogosultsági rendszerét írja le (Drive, YouTube, Calendar). Alapegysége a relation tuple, olvasva objektum#reláció@alany, például doc:42#viewer@user:anna vagy doc:42#viewer@group:eng#member. A jogosultság egy névtérkonfigurációban leírt szabály, amely relációkat kombinál (a szerkesztő egyben néző is, a mappa nézője a benne lévő dokumentum nézője). A konzisztenciát a zookie token biztosítja, amely megakadályozza, hogy az új tartalmat régi ACL alapján értékelje a rendszer (new enemy problem).
Kis léptékben, Postgresben.
- Egy relation_tuples tábla (object_type, object_id, relation, subject_type, subject_id, subject_relation).
- A szabályok kiértékelése rekurzív CTE-vel vagy előre materializált hozzáférési táblával történik.
- Nagy gráfnál (mély mappahierarchia, sok csoport) dedikált szolgáltatás a jobb választás, például OpenFGA vagy SpiceDB, és az RLS csak a materializált eredményt nézi.
Mikor érdemes. Ha a termékben van megosztás, mappa, csapat, csoporton belüli csoport. Ha csak bérlő és szerep van, az RBAC elég.
Policy as code (OPA, Cedar)
- OPA (Open Policy Agent), Rego nyelv. Általános policy motor Kubernetes admissionhöz, API gatewayhez, CI szabályokhoz. Akkor jó, ha sok különböző rendszer azonos szabályt használ.
- Cedar (AWS, 2023, nyílt forrás). Kifejezetten alkalmazás szintű jogosultságra tervezett, formálisan elemezhető nyelv. A Cedar policy permit és forbid szabályokból áll, a forbid mindig nyer.
permit (
principal,
action == Action::"viewInvoice",
resource
) when { principal.tenant == resource.tenant };
forbid (principal, action, resource)
when { resource.classification == "restricted" && !context.mfa };
Döntési szempont. Ha az adat Postgresben van és a kliens közvetlenül éri el (Supabase), az RLS a referencia monitor, mert csak az biztosít teljes közvetítést. Policy motor akkor kell mellé, ha több szolgáltatás és több adattár osztozik a szabályokon. Ilyenkor a policy a repóban él, verziózott, és tesztek futnak rajta, mint bármely más kódon.
Multi tenant minták összevetése
| Szempont | Közös tábla, tenant_id oszlop | Schema per tenant | Adatbázis per tenant |
|---|---|---|---|
| Elválasztás erőssége | Logikai, az RLS-en múlik | Közepes, search_path és jogok | Erős, fizikai |
| Költség | Alacsony | Közepes | Magas |
| Migráció | Egyszer fut | Bérlőnként fut, lassul | Bérlőnként fut, orkesztrálás kell |
| Bérlők közötti riport | Egyszerű | Nehézkes | Külön ETL |
| Zajos szomszéd | Igen | Igen | Nem |
| Bérlő törlése (GDPR) | Kaszkád törlés, tesztelni kell | drop schema | Adatbázis törlés |
| Supabase illeszkedés | Natív, ez a fő minta | Korlátozott (az API csak kitett sémákat lát) | Projekt ügyfelenként, drága |
| Mikor | SaaS, sok kis bérlő | Kevés, nagyobb bérlő, testreszabott séma | Szabályozott ügyfél, adatrezidencia, szerződéses elvárás |
A közös tábla minta lépései.
- Minden bérlőhöz tartozó táblában tenant_id not null, idegen kulccsal.
- Index a tenant_id-re (és összetett indexek tenant_id első oszloppal).
- Egyetlen segédfüggvény a tagságra, minden policy ezt hívja.
- Az insert és update policy with check része is ellenőrzi a tenant_id-t, különben a felhasználó más bérlőbe írhat.
- Idegen kulcsoknál biztosítani kell, hogy a hivatkozott sor ugyanabban a bérlőben legyen (összetett idegen kulcs a tenant_id, id párra).
-- összetett kulcs, hogy a task csak a saját tenant projectjére mutathasson
alter table public.projects add constraint projects_tenant_id_id_key unique (tenant_id, id);
alter table public.tasks
add constraint tasks_project_same_tenant
foreign key (tenant_id, project_id) references public.projects (tenant_id, id);
A sématervezés tágabb kérdéseit (kényszerek, normalizálás, sémaevolúció) az Adat és adatbázisok kézikönyv tárgyalja.
IDOR és BOLA elkerülése
Az IDOR (insecure direct object reference) és az API-k világában használt BOLA (broken object level authorization, 2019 és 2023 óta az OWASP API Security Top 10 első helye) ugyanaz a hiba. A szerver elfogadja a kliens által küldött azonosítót, és nem ellenőrzi, hogy az objektum a hívóé-e.
Módszer.
- Az objektumszintű ellenőrzés a lekérdezésben történik, nem utána. Supabase-ben ezt az RLS automatikusan adja.
- Saját API-nál minden lekérdezés tartalmazza a hívó kontextusát (where id = $1 and tenant_id = $2).
- A nem kitalálható azonosító (UUID) nem jogosultság, csak nehezíti a felderítést. Az UUIDv7 időrendezett, részben kitalálható, ezért különösen nem védelem.
- Hiány esetén a válasz 404, nem 403, így a létezés sem derül ki.
- A teszt mindig két felhasználóval fut (lásd lent, a kétfelhasználós tesztelésnél).
// rossz: service_role kliens, a felhasználótól jövő id-vel
const { data } = await admin.from("invoices").select("*").eq("id", req.params.id);
// jó: a felhasználó JWT-jével hívunk, az RLS dönt
const supabase = createClient(url, publishableKey, {
global: { headers: { Authorization: req.headers.authorization! } },
});
const { data } = await supabase.from("invoices").select("*").eq("id", req.params.id).maybeSingle();
if (!data) return res.status(404).end();
Rokon hiba a BOPLA (broken object property level authorization), vagyis a mass assignment. A kliens olyan mezőt is küld (role, tenant_id, is_paid), amelyet nem írhatna. Ellenszere az oszlopszintű GRANT vagy egy trigger, amely tiltja az érzékeny oszlop változását.
revoke update on public.profiles from authenticated;
grant update (display_name, avatar_url) on public.profiles to authenticated;
Hitelesítés
NIST SP 800-63B-4, a fejlesztőt érintő változások
A 2025 augusztusában véglegesített negyedik revízió a jelszószabályokat szigorúbb kötelezésekké tette (should helyett shall), és a phishing rezisztenciát állította középpontba.
| Téma | Előírás a 4. revízióban | Mit jelent a kódban |
|---|---|---|
| Minimális hossz | Egyedüli faktorként használt jelszónál legalább 15 karakter, MFA részeként legalább 8 | Regisztrációs validáció, hibaüzenet a hosszra |
| Maximális hossz | Legalább 64 karaktert el kell fogadni | Levágás nélkül, a bcrypt 72 bájtos korlátjára figyelve |
| Összetételi szabály | Tilos (nem kötelezhető kis és nagybetű, szám, speciális karakter) | A regex szabályok törlése |
| Kötelező periodikus csere | Tilos, csere csak kompromittálódás jelére | Nincs 90 napos lejárat |
| Tiltólista | Kötelező ellenőrzés ismert kiszivárgott, gyakori és kontextusfüggő jelszavak ellen | HIBP k-anonymity API vagy helyi lista |
| Karakterkészlet | Unicode és szóköz elfogadása, normalizálás (NFKC vagy NFKD) | Normalizálás hash előtt |
| Jelszó emlékeztető, biztonsági kérdés | Tilos | Nincs anyja leánykori neve mező |
| Beillesztés, jelszókezelő | Engedélyezni kell | A beillesztés nem tiltható |
| Próbálkozás korlátozás | Kötelező rate limit | Fiókonként és IP-nként |
| Szinkronizált passkey | AAL2-n elfogadott (syncable authenticator) | A passkey lehet elsődleges MFA |
| Phishing rezisztencia | AAL2-n ajánlott opció, AAL3-on kötelező | WebAuthn, nem SMS |
| SMS, hangalapú OTP | Korlátozott (restricted) hitelesítő, kockázatelemzés és alternatíva kell | Nem lehet az egyetlen második faktor |
Regisztrációkor.
- A jelszót Unicode NFKC formára normalizáljuk.
- Ellenőrizzük a hosszt (15 vagy 8 karakter, attól függően, van-e kötelező MFA).
- Ellenőrizzük a tiltólistát. A Have I Been Pwned range API a hash első öt hexa karakterét kéri, így a jelszó nem hagyja el a szervert.
- A jelszót argon2id függvénnyel hasheljük.
import { createHash } from "node:crypto";
export async function isPwned(password: string): Promise<boolean> {
const sha1 = createHash("sha1").update(password.normalize("NFKC")).digest("hex").toUpperCase();
const prefix = sha1.slice(0, 5);
const suffix = sha1.slice(5);
const res = await fetch(`https://api.pwnedpasswords.com/range/${prefix}`, {
headers: { "Add-Padding": "true" },
});
const body = await res.text();
return body.split("\n").some((line) => line.startsWith(suffix));
}
A Supabase Auth beállításaiban a leaked password protection kapcsoló ugyanezt végzi (a 2026 októberi állapot szerint a Pro csomagtól, ellenőrizendő), és a minimális hossz is beállítható. Saját kód írása helyett ezt érdemes bekapcsolni.
Jelszótárolás
| Algoritmus | Ajánlott paraméter (OWASP Password Storage Cheat Sheet) | Megjegyzés |
|---|---|---|
| argon2id | m = 19 MiB, t = 2, p = 1 (alternatíva m = 46 MiB, t = 1) | Első választás, memóriaigényes, GPU ellen jó |
| scrypt | N = 2^17, r = 8, p = 1 | Ha argon2 nem elérhető |
| bcrypt | cost legalább 10, inkább 12 | 72 bájtnál levágja a bemenetet, ezért hosszú jelszónál előtte HMAC vagy argon2 |
| PBKDF2 HMAC SHA256 | 600 000 iteráció | Csak ha FIPS megfelelés kell |
| MD5, SHA1, SHA256 egyszerűen | Tilos | Gyors hash, nem jelszóra való |
Lépések.
- A hash idejét a saját szerveren mérjük. Bejelentkezésenként 100 és 500 ms között legyen, terhelés alatt is.
- A hash stringben (PHC formátum) benne van az algoritmus és a paraméter. Ha belépéskor a tárolt paraméter elavult, sikeres ellenőrzés után újrahasheljük (rehash on login).
- Opcionális a pepper, egy szerveroldali titok (KMS-ben), amellyel a hash előtt HMAC számolható. Adatbázis szivárgáskor a hashek pepper nélkül nem támadhatók, de a pepper rotációja nehéz.
- Az összehasonlítás konstans idejű függvénnyel történik (a könyvtárak ezt elvégzik).
import argon2 from "argon2";
const OPTS = { type: argon2.argon2id, memoryCost: 19456, timeCost: 2, parallelism: 1 };
export const hashPassword = (pw: string) => argon2.hash(pw.normalize("NFKC"), OPTS);
export async function verifyPassword(stored: string, pw: string) {
const ok = await argon2.verify(stored, pw.normalize("NFKC"));
const needsRehash = ok && argon2.needsRehash(stored, OPTS);
return { ok, needsRehash };
}
Supabase Auth használatakor a jelszó hashelését (bcrypt) a GoTrue végzi, mellé saját jelszótábla nem kell.
MFA és passkey (WebAuthn)
Az MFA erősségi sorrendje. Első helyen a hardveres biztonsági kulcs és a passkey áll (phishing rezisztens), utána a TOTP alkalmazás, majd a push értesítés számegyeztetéssel, végül az SMS és az email kód. Az MFA fáradtság (push bombázás) ellen számegyeztetés kell.
A passkey bevezetése.
- Szerveroldali könyvtárra építünk (TypeScripthez SimpleWebAuthn), saját implementáció nem készül.
- Regisztrációkor a szerver challenge-et generál (véletlen, egyszer használatos, sessionhöz kötött), a böngésző a navigator.credentials.create hívással kulcspárt hoz létre, a szerver pedig eltárolja a credential id-t és a nyilvános kulcsot.
- Belépéskor új challenge készül, a navigator.credentials.get hívás után a szerver ellenőrzi az aláírást, az origint, az rpId-t és a signCount értéket (szinkronizált passkeynél ez gyakran 0, ami nem hiba).
- A phishing rezisztencia forrása, hogy a böngésző az origint beleírja az aláírt adatba. Hamis domainen a passkey nem használható.
- Felhasználónként legalább két hitelesítő marad meg, és erős helyreállítási út is van.
Tipikus hiba. A passkey mellett megmarad a gyenge helyreállítás (email link, SMS), így a támadó azon jön be. A helyreállítás a leggyengébb láncszem.
A Supabase Auth natívan támogatja a TOTP MFA-t, az újabb verziók a WebAuthn faktort is (a 2026 októberi állapot szerint, a dokumentációban ellenőrizendő). Az aal szint a JWT-ben megjelenik. Kritikus műveletnél (fizetés, adatexport, szerepváltoztatás) az aal2 ellenőrzése RLS-ben vagy RPC-ben történik.
Sessionkezelés
| Elem | Beállítás | Miért |
|---|---|---|
| Cookie HttpOnly | Mindig a session cookie-n | A JavaScript, és így az XSS sem olvassa |
| Secure | Mindig | Csak HTTPS-en megy |
| SameSite | Alapból Lax, admin felületen Strict | CSRF ellen |
| __Host- előtag | __Host-session | Kikényszeríti a Secure, Path=/ és domain nélküli cookie-t |
| Idle timeout | Érzékeny alkalmazásban 15 és 30 perc között | Elhagyott gép |
| Abszolút lejárat | 8 és 24 óra között, vagy hosszabb, ha a kockázat engedi | Ellopott session korlátozása |
| Rotáció | Új session id belépéskor és jogosultság emeléskor | Session fixation ellen |
| Kijelentkezés | Szerveroldali érvénytelenítés, nem csak cookie törlés | Az ellopott token ne éljen tovább |
| Session lista | A felhasználó látja és visszavonhatja | Gyanús eszköz kizárása |
Supabase-ben az access token rövid életű JWT (alapértelmezés szerint egy óra), a refresh token rotálódik, és újrahasználat detektálással rendelkezik. SSR alkalmazásban (Next.js) a @supabase/ssr csomag cookie-ba teszi a sessiont. Szerveroldalon a felhasználót a getUser() vagy a getClaims() hívás ellenőrzi. A getSession() eredményére nem építünk, mert az a cookie tartalmát ellenőrzés nélkül adja vissza.
OAuth 2.0, OAuth 2.1, OIDC, PKCE
Szerepek. Resource owner (felhasználó), client (alkalmazás), authorization server (például Supabase Auth, Entra ID), resource server (API).
Az OAuth 2.1 változásai a 2.0-hoz képest (draft 16, a 2026 októberi állapot szerint).
- A PKCE minden authorization code folyamatnál kötelező, nyilvános és bizalmas kliensnél egyaránt.
- Az implicit grant (token az URL fragmentben) kikerül.
- A resource owner password credentials grant kikerül.
- A redirect URI ellenőrzése teljes egyezéssel történik, wildcard tilos.
- Bearer token nem mehet URL query paraméterben.
- Nyilvános kliens refresh tokenje küldőhöz kötött vagy rotált.
Ezek a 2.0 Security Best Current Practice (RFC 9700, 2025. január) ajánlásai is, így 2.0 alatt is kötelezőnek tekintendők.
A PKCE lépései.
- A kliens generál egy code_verifier értéket (43 és 128 karakter közötti véletlen).
- Kiszámolja a code_challenge = BASE64URL(SHA256(code_verifier)) értéket.
- Az authorize kérésben elküldi a challenge-et és a method=S256 paramétert.
- A token kérésben elküldi a verifiert, a szerver pedig ellenőrzi, hogy a hash egyezik.
- Így egy elfogott authorization code önmagában értéktelen.
const verifier = crypto.getRandomValues(new Uint8Array(32));
const verifierStr = btoa(String.fromCharCode(...verifier)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifierStr));
const challenge = btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
A Supabase JS kliens a flowType pkce értékével ezt elvégzi (az SSR csomagban ez az alapértelmezett).
OIDC. Az OAuth az engedélyezésről szól, az OIDC hitelesítési réteget tesz rá (ID token, userinfo, discovery). Az ID token a kliensnek szól (ki lépett be), az access token az API-nak (mit tehet). ID token nem mehet API hívásban hozzáférési tokenként. Az iss, aud, exp és nonce mezők ellenőrzése kötelező.
Backend for Frontend (BFF). Böngészős alkalmazásnál a legbiztonságosabb minta, ha a tokeneket egy vékony szerveroldali réteg tartja, és a böngésző csak HttpOnly session cookie-t kap. Az IETF OAuth for Browser-Based Apps dokumentuma is ezt ajánlja első helyen.
JWT csapdák
| Csapda | Mi történik | Védelem |
|---|---|---|
| alg none | A token aláírás nélkül is elfogadott | A könyvtár explicit elfogadott algoritmuslistát kap, a fejlécben érkezőt nem fogadjuk el |
| Algoritmus csere (RS256 helyett HS256) | A nyilvános kulccsal mint HMAC titokkal aláírt token átmegy | Kulcsonként rögzített algoritmus |
| Hosszú lejárat | Az ellopott token napokig él, nem vonható vissza | Access token 5 és 60 perc között, refresh token rotációval |
| localStorage tárolás | XSS-sel kiolvasható | HttpOnly cookie vagy BFF |
| Érzékeny adat a payloadban | A JWT csak base64, bárki olvassa | Csak azonosító és claimek, semmi személyes adat |
| kid manipuláció | A kid alapján a szerver tetszőleges fájlt vagy URL-t tölt be kulcsként | A kid csak egy előre ismert JWKS listából jöhet |
| Hiányzó aud ellenőrzés | Más szolgáltatásnak kiadott token itt is átmegy | Az aud és az iss kötelező ellenőrzése |
| Visszavonás hiánya | Kijelentkezés után a token még él | Rövid lejárat, kritikus műveletnél session ellenőrzés az adatbázisban |
A Supabase 2025 óta aszimmetrikus JWT signing kulcsokat kínál (ES256 vagy RS256, JWKS végponttal). Ezekkel az edge function és a saját backend helyben, hálózati hívás nélkül ellenőrizheti a tokent, a kulcs pedig rotálható a régi tokenek azonnali érvénytelenítése nélkül. Új projektben ez a javasolt út a megosztott HS256 titok helyett.
import { createRemoteJWKSet, jwtVerify } from "jose";
const JWKS = createRemoteJWKSet(new URL(`${SUPABASE_URL}/auth/v1/.well-known/jwks.json`));
export async function verify(token: string) {
const { payload } = await jwtVerify(token, JWKS, {
issuer: `${SUPABASE_URL}/auth/v1`,
audience: "authenticated",
algorithms: ["ES256", "RS256"],
});
return payload;
}
API kulcsok
- A formátum felismerhető előtagot kap (például app_live_ és app_test_), így a secret scanner megtalálja, a fejlesztő pedig látja, éles kulcsról van-e szó.
- Legalább 128 bit véletlen, base62 vagy base64url kódolással.
- A kulcsot hash formában tároljuk (SHA-256 elég, mert a kulcs nagy entrópiájú, nem jelszó). Az első néhány karakter azonosításra külön tárolható.
- A kulcs csak létrehozáskor, egyszer jelenik meg.
- Minden kulcsnak van hatóköre (scope), bérlője, lejárata és utolsó használati időpontja.
- Rotáció átfedéssel, az új kulcs már él, mielőtt a régit visszavonjuk.
- Rate limit kulcsonként.
A Supabase 2025-ben új kulcsrendszert vezetett be. Kliensbe a publishable kulcs (sb_publishable_ előtag) való, ez az anon szerepet kapja. Szerveroldalra a secret kulcs (sb_secret_ előtag) tartozik, az RLS-t megkerülő jogokkal, és a böngészőből érkező kérést elutasítja. A régi anon és service_role JWT kulcsok új projektben nem javasoltak, meglévő projektben a migrációt érdemes megtervezni.
Gyakorlati kriptográfia
A fő források Ferguson, Schneier és Kohno Cryptography Engineering (2010) című könyve, valamint Jean-Philippe Aumasson Serious Cryptography második kiadása (2024). Közös tanulságuk szerint a kriptográfiai hibák szinte mindig az illesztésnél születnek (kulcskezelés, nonce, módválasztás, hibaüzenet), és ritkán az algoritmusban.
Mit használjunk, mit ne
| Cél | Javasolt | Kerülendő |
|---|---|---|
| Szimmetrikus titkosítás | AES-256-GCM, ChaCha20-Poly1305, XChaCha20-Poly1305 | AES-ECB, AES-CBC MAC nélkül, DES, 3DES, RC4 |
| Nonce kezelés kevés kontrollal | XChaCha20-Poly1305 (192 bites nonce, véletlen is biztonságos), AES-GCM-SIV | AES-GCM véletlen 96 bites nonce-szal nagy volumenben (2^32 üzenet felett veszélyes) |
| Aláírás | Ed25519, ECDSA P-256 (determinisztikus nonce-szal) | RSA PKCS#1 v1.5 új rendszerben, DSA |
| Kulcscsere | X25519, hibridként X25519MLKEM768 | Statikus RSA kulcscsere, saját DH paraméter |
| Hash | SHA-256, SHA-512, SHA-3, BLAKE2b, BLAKE3 | MD5, SHA-1 |
| MAC | HMAC-SHA256, Poly1305 (AEAD-ben) | Saját hash(kulcs + üzenet) konstrukció (length extension) |
| Kulcsderiválás kulcsból | HKDF | Egyszerű hash |
| Kulcsderiválás jelszóból | argon2id | PBKDF2 alacsony iterációval |
| Véletlen | crypto.getRandomValues, crypto.randomBytes, /dev/urandom | Math.random |
| Könyvtár | libsodium (libsodium-wrappers, sodium-native), Web Crypto, Node crypto | Saját implementáció, elavult könyvtár |
| Transzport | TLS 1.3, legalább TLS 1.2 erős suite-tal | SSL, TLS 1.0, TLS 1.1 |
Három szabály.
- Mindig AEAD (hitelesített titkosítás). Az integritás nélküli titkosítás módosítható.
- A nonce soha nem ismétlődhet ugyanazzal a kulccsal. AES-GCM-nél egyetlen ismétlés a hitelesítés teljes összeomlását okozza.
- A rejtjelezett adathoz associated data formában hozzákötjük a kontextust (rekord id, tenant id, oszlopnév). Így egy titkosított mezőt nem lehet átmásolni egy másik sorba.
import sodium from "libsodium-wrappers";
await sodium.ready;
export function encryptField(plain: string, key: Uint8Array, aad: string) {
const nonce = sodium.randombytes_buf(sodium.crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);
const ct = sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(plain, aad, null, nonce, key);
return { nonce: sodium.to_base64(nonce), ct: sodium.to_base64(ct) };
}
export function decryptField(enc: { nonce: string; ct: string }, key: Uint8Array, aad: string) {
return sodium.to_string(
sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(
null, sodium.from_base64(enc.ct), aad, sodium.from_base64(enc.nonce), key,
),
);
}
// aad példa: `${tenantId}:${tableName}:${rowId}:${column}`
Envelope encryption és KMS
A minta. Az adatot egy adatkulccsal (DEK, data encryption key) titkosítjuk, a DEK-et pedig egy kulcstitkosító kulccsal (KEK), amely a KMS-ben marad, és sosem hagyja el. A DEK titkosított formában az adat mellett tárolódik.
Lépések.
- A KMS-ben (AWS KMS, Google Cloud KMS, Azure Key Vault, HashiCorp Vault Transit) létrehozzuk a KEK-et, bérlőnként vagy adatosztályonként.
- Íráskor a KMS GenerateDataKey hívása visszaad egy nyílt és egy titkosított DEK-et.
- A nyílt DEK-kel helyben AEAD titkosítás történik, utána a nyílt DEK törlődik a memóriából.
- A titkosított DEK, a nonce és a rejtjel kerül az adatbázisba.
- Olvasáskor a KMS Decrypt visszaadja a DEK-et, a visszafejtés helyben történik.
Előnyök. A KEK rotációja csak a DEK-ek újratitkosítását igényli, az adatét nem. A KMS naplózza a hozzáférést. A bérlőnkénti KEK törlése kriptográfiai törlést (crypto shredding) tesz lehetővé, ami a mentésekben lévő másolatokat is olvashatatlanná teszi. GDPR törlési kérelemnél a mentésekre gyakran ez az egyetlen megvalósítható út.
Supabase. A Supabase Vault (pgsodium alapú, ma a vault.secrets tábla és a vault.decrypted_secrets view) titkok tárolására jó, például harmadik féltől kapott API kulcsokhoz. Oszlopszintű titkosításra a pgsodium Transparent Column Encryption funkcióját a Supabase új projektben már nem ajánlja. Érzékeny mezőkhöz az alkalmazásrétegbeli titkosítás (a fenti kódpélda) és egy külső KMS a tisztább út. A Supabase a lemezt AES-256-tal, a forgalmat TLS-sel titkosítja. Ez a GDPR 32. cikke szerinti alapszint, de az adatbázishoz hozzáférő szolgáltatótól és a service_role kulcs birtokosától nem véd.
Kulcsrotáció
| Kulcs típusa | Rotáció | Módszer |
|---|---|---|
| KEK (KMS) | Évente automatikusan | A KMS verziókat tart, a régi verzió visszafejtésre él |
| DEK | Rekordonként vagy időablakonként új | Az envelope minta miatt olcsó |
| JWT signing kulcs | Évente, gyanú esetén azonnal | JWKS-ben átfedéssel, kid alapján |
| API kulcs, harmadik fél | 90 naptól egy évig, gyanúra azonnal | Kettős kulcsos időszak |
| Adatbázis jelszó | Személycserénél, gyanúra | Secret store, újraindítás nélküli betöltés |
| TLS tanúsítvány | Automatikusan (ACME), 2026-tól a CA/B Forum döntése szerint fokozatosan rövidülő élettartammal | Csak automatizálva |
Szabály. Minden kulcs mellett van azonosító (kid, key_version), mert enélkül nem dönthető el, melyik kulccsal kell visszafejteni, és a rotáció lehetetlen.
Post quantum átállás
Állás 2026 októberében.
- FIPS 203 (ML-KEM, Kyber alapú) kulcsbeágyazás. Általános célra a szabványos paraméter az ML-KEM-768.
- FIPS 204 (ML-DSA, Dilithium alapú) aláírás, az általános célú elsődleges választás.
- FIPS 205 (SLH-DSA, SPHINCS+ alapú) hash alapú aláírás, konzervatív tartalék, nagy aláírásmérettel.
- FN-DSA (Falcon alapú) FIPS 206 néven készül.
- A NIST 2025 márciusában a HQC-t választotta tartalék KEM-nek, eltérő matematikai alapon.
- A NIST IR 8547 átállási terve szerint a kvantum sérülékeny algoritmusok (RSA, ECDH, ECDSA a 112 bites biztonsági szinten) 2030 után elavultak, 2035 után tiltottak az amerikai szövetségi rendszerekben. Az EU 2025-ös koordinált ütemterve a kritikus infrastruktúrában 2030-ig várja az átállást.
Harvest now, decrypt later. A támadó ma rögzíti a titkosított forgalmat, és akkor fejti vissza, amikor lesz elég nagy kvantumszámítógép. A hosszú ideig titkos adat (egészségügyi, jogi, pénzügyi, állami) forgalmát ezért már most hibrid kulcscserével kell védeni. Az aláírás kevésbé sürgős, mert a hamisításhoz a kvantumgépnek az aláírás idején kell léteznie.
Fejlesztői teendők.
- Kriptográfiai leltár (cryptographic bill of materials). Hol van RSA, ECDH, ECDSA, milyen könyvtárral, milyen adatot véd, és meddig kell az adatnak titokban maradnia.
- Crypto agility. Az algoritmus konfigurálható, a titkosított adat mellett verziómező áll.
- Hibrid TLS. A hibrid X25519MLKEM768 a Chrome, a Firefox, a Cloudflare és az OpenSSL 3.5 óta alapértelmezett vagy elérhető. Saját szervernél ellenőrizni kell, hogy a TLS könyvtár támogatja.
- Szimmetrikus kriptográfia. Az AES-256, a SHA-256 és az erősebb változatok kvantum ellen is megfelelők, ott a 128 bites kulcsok 256 bitesre emelésén túl nincs teendő.
- Auditált könyvtár. Saját PQC implementáció nem készül. A választás liboqs, a Go és a Node crypto beépített ML-KEM támogatása, a BoringSSL vagy az AWS-LC.
Titokkezelés
Szabályok
- Titok soha nem kerül a repóba, a kliens bundle-be, a logba, a hibajelentésbe vagy az LLM promptba.
- Fejlesztésben .env.local fájl, amely a .gitignore-ban szerepel. Élesben a platform secret store (Vercel environment variables, Supabase edge function secrets, GitHub Actions secrets OIDC-vel, Doppler, Infisical, 1Password, cloud secret manager).
- A NEXT_PUBLIC_, VITE_ és hasonló előtagú változó a böngészőbe kerül. Titok sosem kaphat ilyen előtagot.
- CI-ban hosszú életű felhőkulcs helyett OIDC federáció működik (GitHub Actions és AWS, GCP, Azure között), így nincs tárolt titok.
- Minden titoknak van gazdája, létrehozási dátuma és rotációs ideje.
- Pre-commit hook és CI scan kötelező.
Szivárgás felderítése
| Eszköz | Erősség | Használat |
|---|---|---|
| gitleaks | Gyors, regex és entrópia alapú, pre-commit és CI | gitleaks git --redact, gitleaks protect --staged |
| trufflehog | Több száz detektor, élő ellenőrzés (verified), git történet, S3, Docker image | trufflehog git file://. --only-verified |
| GitHub secret scanning és push protection | Partnerprogram, a szolgáltató automatikusan visszavonhat | A repó beállításaiban kapcsolható be |
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.24.0
hooks:
- id: gitleaks
Teendők kiszivárgott kulcsnál
A lépések sorrendje kötött, mert az idő számít. A nyilvános GitHub repóba került kulcsot automatizált botok perceken belül megtalálják.
- Azonnali visszavonás és rotáció. A szolgáltatónál érvénytelenítjük a kulcsot, újat generálunk, és telepítjük. Ez megelőzi a git történet tisztítását.
- A hatókör felmérése. Mit érhetett el a kulcs (service_role esetén a teljes adatbázist, RLS nélkül).
- A naplók átnézése. A szivárgás pillanatától kezdve szokatlan használatot keresünk a szolgáltató naplóiban (Supabase API logok, felhő audit log, számlázás).
- A git történet tisztítása. git filter-repo vagy BFG, force push, a forkokról és a cache-ekről a GitHub supporttal egyeztetve. A tisztítás nem helyettesíti a rotációt, mert a kulcs már másolódhatott.
- Az incidens rögzítése. Ha személyes adathoz férhettek hozzá, a GDPR 33. cikke szerint 72 órán belül értesíteni kell a felügyeleti hatóságot (Magyarországon a NAIH-ot), hacsak a kockázat nem valószínűtlen. NIS2 hatály alatt jelentős incidensnél 24 órás korai figyelmeztetés kell a CSIRT felé. A döntést a felelős vezető hozza, a fejlesztő a tényeket adja.
- Az okok kezelése. Pre-commit hook, push protection, rövidebb élettartamú kulcs, OIDC.
Az incidenskezelés teljes folyamatát a Kiberbiztonság kézikönyv írja le.
Privacy by Design, Cavoukian hét elve
Ann Cavoukian, Ontario adatvédelmi biztosa a kilencvenes években fogalmazta meg, 2009-ben hét elvként publikálta a gondolatot. A GDPR 25. cikke jogi kötelezettséggé tette.
| Elv | Fejlesztői fordítás | Konkrét kontroll |
|---|---|---|
| 1. Proaktív, nem reaktív, megelőző, nem helyreállító | Adatvédelmi kérdések a tervezésnél, nem a launch előtt | LINDDUN a design reviewban, adatfolyam ábra |
| 2. Adatvédelem mint alapbeállítás | Felhasználói beavatkozás nélkül is védett | Opt-in analitika, privát alapértelmezett profil, minimális mezők |
| 3. Beépített adatvédelem | A rendszer része, nem kiegészítő | RLS, pszeudonim azonosítók, megőrzési job a sémával együtt |
| 4. Teljes funkcionalitás (pozitív összeg) | Nem kell a funkciót feláldozni | Aggregált riport nyers adat helyett, kliensoldali feldolgozás |
| 5. Végponttól végpontig biztonság, teljes életciklus | Gyűjtéstől törlésig | Titkosítás, megőrzési idő, igazolt törlés, mentések kezelése |
| 6. Láthatóság és átláthatóság | Ellenőrizhető, mit csinál a rendszer | A valós működéssel összhangban lévő adatkezelési tájékoztató, audit log |
| 7. A felhasználó tisztelete | Érintett központú | Önkiszolgáló export, törlés, hozzájárulás kezelés, érthető szöveg |
GDPR fejlesztői szemmel
Az 5. cikk elvei és a fejlesztői teendők
| Elv | Kérdés a kódhoz | Teendő |
|---|---|---|
| Jogszerűség, tisztességesség, átláthatóság | Melyik jogalapon gyűjtjük ezt a mezőt? | Mezőszintű jogalap a nyilvántartásban, hozzájárulás esetén consent tábla időbélyeggel és verzióval |
| Célhoz kötöttség | Csak arra használjuk, amire gyűjtöttük? | Új cél (például modell tanítás) új jogalapot és elemzést kér, nem kódmódosítást |
| Adattakarékosság | Kell ez a mező egyáltalán? | Születési dátum helyett nagykorúság jelző, teljes cím helyett irányítószám |
| Pontosság | Javítható az adat? | Felhasználói szerkesztés, forrás frissítése |
| Korlátozott tárolhatóság | Meddig kell? | Megőrzési idő táblánként, automatikus törlés vagy anonimizálás |
| Integritás és bizalmas jelleg | Védett illetéktelen hozzáféréstől? | RLS, titkosítás, hozzáférés naplózás |
| Elszámoltathatóság | Tudjuk bizonyítani? | Migrációk, tesztek, nyilvántartás, DPIA, döntési napló a repóban |
A 25. cikk, beépített és alapértelmezett adatvédelem
Az adatkezelőnek a tervezéskor és a kezelés során is megfelelő technikai és szervezési intézkedéseket kell hoznia (például pszeudonimizálást), és alapértelmezésként csak a célhoz szükséges adatot kezelheti. Fejlesztői fordításban minden új funkció pull requestje rövid adatvédelmi blokkot tartalmaz.
## Adatvédelmi hatás
- Új személyes adat mező: igen/nem, melyik
- Adatosztály: (lásd adatosztályozás)
- Jogalap és cél: hivatkozás a nyilvántartás sorára
- Megőrzés: X nap, utána törlés/anonimizálás
- Ki fér hozzá (RLS policy neve):
- Harmadik félhez kerül-e (LLM, analitika, email):
A 32. cikk, az adatkezelés biztonsága
A cikk kockázatarányos intézkedéseket kér, és négyet név szerint is említ. Ezek fejlesztői megfelelői a következők.
- Pszeudonimizálás és titkosítás. TLS, lemeztitkosítás, érzékeny mezők alkalmazásszintű titkosítása, pszeudonim azonosítók az analitikában.
- Bizalmasság, integritás, rendelkezésre állás, ellenálló képesség. RLS, MFA, mentés, monitorozás.
- Helyreállíthatóság. Point in time recovery (Supabase PITR kiegészítő), tesztelt visszaállítás, dokumentált RTO és RPO.
- Rendszeres tesztelés és értékelés. RLS tesztek a CI-ban, Supabase security advisor, évenkénti pentest vagy legalább automatizált scan.
DPIA, mikor és hogyan
Mikor kötelező (35. cikk és a NAIH listája alapján). Ha az adatkezelés valószínűleg magas kockázattal jár. Jellemző esetek a nagy léptékű különleges adat (egészségügy, biometria), a rendszeres, kiterjedt megfigyelés, a joghatással járó döntést hozó profilalkotás, az új technológia (az AI rendszerek jellemzően ide tartoznak), a sérülékeny érintettek (gyerekek, munkavállalók) és az adatkészletek összekapcsolása. A NAIH közzétette a kötelező DPIA esetek magyar listáját, ezt az adott projektnél ellenőrizni kell.
Lépések.
- Az adatkezelés leírása (cél, adatkörök, érintettek, címzettek, adatfolyam ábra, megőrzés).
- A szükségesség és az arányosság értékelése (jogalap, adattakarékosság, alternatívák).
- A kockázatok azonosítása az érintettek szemszögéből, nem a cégéből. Ehhez a lent ismertetett LINDDUN jól használható.
- Kockázatkezelő intézkedések, maradó kockázat.
- Az adatvédelmi tisztviselő (DPO) véleménye, ha van ilyen.
- Magas maradó kockázatnál előzetes konzultáció a NAIH-hal (36. cikk).
- Felülvizsgálat változáskor.
A fejlesztő az első, a harmadik és a negyedik lépéshez ad érdemi bemenetet (adatfolyam, technikai intézkedések). AI rendszernél az AI Act alapjogi hatásvizsgálata (FRIA, 27. cikk, bizonyos telepítőknek) összevonható a DPIA-val.
Adatkezelési nyilvántartás (30. cikk)
A nyilvántartás táblázatos. A technikai oszlopokat a fejlesztőcsapat tartja naprakészen, lehetőleg a kóddal együtt verziózott, gépileg olvasható formában a repóban, amelyből emberi olvasásra alkalmas változat generálható.
- tevekenyseg: Ügyfélfiók kezelése
cel: Szolgáltatás nyújtása
jogalap: szerződés teljesítése, 6. cikk (1) b)
erintettek: ügyfelek felhasználói
adatkorok: [név, email, cég, belépési napló]
tablak: [public.profiles, auth.users, public.audit_log]
cimzettek: [Supabase (adatfeldolgozó, EU régió), Resend (email), LLM szolgáltató (zero retention)]
harmadik_orszag: USA, adatvédelmi keretrendszer és SCC
megorzes: fiók törlése után 30 nap, napló 1 év
biztonsag: [RLS, MFA adminnak, TLS, titkosított mentés]
Érintetti jogok technikai kiszolgálása
| Jog | Cikk | Technikai megvalósítás | Határidő |
|---|---|---|---|
| Hozzáférés | 15. | Export függvény, amely minden táblából összegyűjti a felhasználó adatait | Egy hónap, indokoltan hosszabbítható |
| Helyesbítés | 16. | Profil szerkesztés, admin felület | Egy hónap |
| Törlés | 17. | Törlési folyamat kaszkáddal, storage fájlokkal, harmadik felekkel | Egy hónap |
| Korlátozás | 18. | restricted jelző, amelyet az RLS és a feldolgozó jobok figyelnek | Egy hónap |
| Adathordozhatóság | 20. | Géppel olvasható export (JSON, CSV) | Egy hónap |
| Tiltakozás | 21. | Marketing és profilalkotás kikapcsolása | Marketingnél haladéktalanul |
| Automatizált döntés | 22. | Emberi felülvizsgálat kérése, magyarázat | Egy hónap |
Az export lépései.
- Adattérkép készül arról, melyik tábla melyik oszlopa köti az adatot a felhasználóhoz.
- Az export egy security definer függvény vagy edge function, amely a hívó saját azonosítójára szűr, és csak a felhasználó saját adatait adja ki (más felhasználók személyes adatait egy közös szálban maszkolni kell).
- A kimenet JSON, egy ZIP-ben a storage fájlokkal, rövid lejáratú signed URL-lel.
- A kérés és a teljesítés naplózva van.
A törlés lépései.
- Táblánként eldöntjük, hogy törlés, anonimizálás vagy jogi kötelezettség miatti megőrzés következik (például számla 8 évig a számviteli törvény szerint).
- Az idegen kulcsoknál az on delete cascade vagy set null tudatos döntés.
- A storage objektumokat külön kell törölni. Az adatbázis kaszkád ezt nem végzi el, és a storage.objects sor törlése sem törli megbízhatóan a fájlt, a Storage API-t kell hívni.
- Harmadik felek (email szolgáltató, analitika, CRM) törlési API-ja.
- A mentésekből nem törlünk egyenként. Dokumentáljuk, hogy a mentés lejár (például 30 nap után), és visszaállításkor a törlési listát újra lefuttatjuk. Envelope encryption esetén a felhasználói kulcs törlése (crypto shredding) a mentésben lévő másolatot is olvashatatlanná teszi.
- Igazolás a kérelmezőnek.
create or replace function public.delete_my_account()
returns void
language plpgsql security definer set search_path = ''
as $$
declare v_uid uuid := (select auth.uid());
begin
if v_uid is null then raise exception 'not authenticated'; end if;
-- jogi kötelezettség miatt megőrzött adat anonimizálása
update public.invoices set customer_name = 'törölt felhasználó', customer_email = null
where user_id = v_uid;
insert into public.deletion_queue(user_id, requested_at) values (v_uid, now());
-- a storage és harmadik fél törlését egy edge function dolgozza fel a queue-ból,
-- végül az auth.users sort az admin API törli, ez kaszkádol a public táblákra
end;
$$;
Adatmegőrzés automatizálása
- Minden személyes adatot tartalmazó táblának van megőrzési szabálya, a táblakommentben vagy egy retention_policies táblában.
- Egy pg_cron job naponta lefut, és törli vagy anonimizálja a lejárt sorokat.
- Nagy táblánál időalapú particionálás segít, a régi partíció egészben eldobható (detach, drop), ami olcsóbb a soronkénti törlésnél.
- A job eredményét (hány sor, melyik tábla) naplózzuk, mert ez az elszámoltathatóság bizonyítéka.
- A logok és az LLM interakciók is személyes adatok, ezekre is megőrzési szabály vonatkozik.
select cron.schedule(
'retention-daily',
'15 3 * * *',
$$
delete from public.audit_log where created_at < now() - interval '365 days';
delete from public.llm_interactions where created_at < now() - interval '30 days';
update public.leads set email = null, phone = null, anonymized_at = now()
where last_contact_at < now() - interval '2 years' and anonymized_at is null;
$$
);
LINDDUN, adatvédelmi fenyegetésmodellezés
A LINDDUN a KU Leuven kutatócsoportjának módszertana, a STRIDE adatvédelmi párja. Betűszava hét fenyegetéskategóriát jelöl.
| Kategória | Jelentés | Példa SaaS-ban | Tipikus ellenszer |
|---|---|---|---|
| Linking | Adatok összekapcsolása ugyanahhoz a személyhez | Analitika és CRM közös azonosítóval | Célonként eltérő pszeudonim azonosító |
| Identifying | Személy azonosítása az adatból | Anonimnak hitt export ritka kombinációkkal | k-anonimitás, aggregálás |
| Non-repudiation | A személy nem tudja letagadni (adatvédelmi kár) | Whistleblower bejelentés aláírva, IP-vel | Anonim csatorna, az IP nem tárolása |
| Detecting | Már a létezés kikövetkeztethető | Elfelejtett jelszónál a válasz elárulja, van-e fiók | Egységes válasz |
| Data disclosure | Felesleges vagy túlzott adatközlés | Teljes profil az API válaszban | Adattakarékos DTO, mezőszintű szűrés |
| Unawareness and unintervenability | Az érintett nem tud róla, nem tud beavatkozni | Rejtett LLM feldolgozás, nincs export | Átláthatóság, önkiszolgáló jogok |
| Non-compliance | Szabályozási, szabályzati eltérés | Nincs megőrzési idő, nincs DPIA | Nyilvántartás, folyamat |
Lépések (a LINDDUN GO gyors kártyás és a LINDDUN PRO rendszerezett változatának közös magja).
- Rendszermodell. Adatfolyam diagram (DFD) készül külső entitásokkal, folyamatokkal, adattárakkal és adatfolyamokkal, jelölve rajta a személyes adatot és a bizalmi határokat.
- Fenyegetések azonosítása. A DFD minden elemén végigmegyünk a hét kategórián. A LINDDUN GO kártyái kérdés formában segítik ezt egy workshopon.
- Dokumentálás. Fenyegetés, érintett elem, forgatókönyv, súlyosság az érintett szemszögéből.
- Priorizálás. Valószínűség és hatás az érintettre.
- Ellenszer választása. Privacy enhancing technology (PET) vagy tervezési változtatás. A LINDDUN megoldási katalógusa stratégiákat ad (minimalizálás, elrejtés, elválasztás, absztrakció, tájékoztatás, kontroll).
- Ellenőrzés és ismétlés minden jelentős változásnál.
AI asszisztált használat. Egy kódgeneráló modell jól tud DFD-t készíteni a kódból (táblák, edge functionök, külső API hívások), és kategóriánként kérdéseket generál. A súlyosság értékelését és a kockázat elfogadását ember végzi.
Pszeudonimizálás, anonimizálás és rokon technikák
Fogalmak
| Technika | GDPR státusz | Visszafordítható | Példa |
|---|---|---|---|
| Pszeudonimizálás | Továbbra is személyes adat (4. cikk 5. pont) | Igen, a kiegészítő információval | Email helyett HMAC(kulcs, email) |
| Anonimizálás | Nem személyes adat, ha valóban nem azonosítható | Nem | Aggregált statisztika, megfelelő k mellett |
| Tokenizáció | A pszeudonimizálás egy formája | Igen, a token vault által | Kártyaszám helyett token (PCI DSS) |
| Titkosítás | Személyes adat marad | Igen, kulccsal | AES-GCM mező |
| Maszkolás | Megjelenítési kontroll | A forrás megmarad | A kártyaszám utolsó négy jegye |
EU Bíróság, 2025. Az EU Bíróság 2025 szeptemberi, EDPS kontra SRB ügyben hozott ítélete szerint a pszeudonimizált adat annál a címzettnél, aki ésszerűen nem tudja újraazonosítani, nem feltétlenül személyes adat. Az adatkezelőnél viszont az marad. Fejlesztői szempontból ebből annyi következik, hogy a kiegészítő információt (kulcs, leképező tábla) szigorúan el kell választani, és dokumentálni kell, ki fér hozzá. A minősítés jogászi feladat.
Pszeudonimizálás helyesen
- Kulcsolt függvény kell (HMAC-SHA256 titkos kulccsal), nem egyszerű hash. Egy email cím SHA-256 hashe szótárral visszafejthető.
- Célonként eltérő kulcs, így az analitikai és a support azonosító nem kapcsolható össze (a Linking ellen).
- A kulcs a KMS-ben vagy a Vaultban van, az analitikai csapat nem fér hozzá.
- Ha visszafordíthatóság kell, tokenizáció leképező táblával, külön jogosultsággal.
import { createHmac } from "node:crypto";
export const pseudonym = (purposeKey: Buffer, email: string) =>
createHmac("sha256", purposeKey).update(email.trim().toLowerCase()).digest("base64url");
k-anonimitás, l-diverzitás, t-közelség
- k-anonimitás (Sweeney, 2002). Minden rekord legalább k-1 másik rekorddal azonos a kvázi azonosítókon (irányítószám, életkor, nem). Sweeney kimutatta, hogy az amerikai lakosság nagy része azonosítható irányítószám, születési dátum és nem alapján.
- l-diverzitás (Machanavajjhala és társai, 2006). Minden k csoporton belül az érzékeny attribútumnak legalább l eltérő értéke van, különben a homogén csoport elárulja (ha például a csoportban mindenkinek ugyanaz a diagnózisa).
- t-közelség (Li és társai, 2007). Az érzékeny érték eloszlása a csoporton belül közel áll a teljes adathalmaz eloszlásához.
Ellenőrzés SQL-lel.
-- legkisebb csoportméret a kvázi azonosítókon
select min(cnt) as k
from (
select left(zip, 2) as zip2, (age / 10) * 10 as age_band, gender, count(*) as cnt
from export_candidates
group by 1, 2, 3
) g;
-- l-diverzitás: csoportonként hány eltérő diagnózis
select left(zip, 2), (age / 10) * 10, gender, count(distinct diagnosis) as l
from export_candidates group by 1, 2, 3
order by l asc limit 10;
Ha k kisebb a vállalt küszöbnél (gyakran 5 vagy 10), általánosítunk (rövidebb irányítószám, szélesebb korcsoport), vagy elhagyjuk a ritka csoportokat.
A differenciális adatvédelem alapjai
Cynthia Dwork és társai (2006) definíciója szerint egy mechanizmus akkor ε differenciálisan privát, ha bármely egy személy hozzáadása vagy elvétele az adathalmazhoz legfeljebb e^ε szorzóval változtatja bármely kimenet valószínűségét. A gyakorlatban zajt adunk az aggregátumhoz.
Laplace mechanizmus számlálásra. Egy count érzékenysége 1 (egy személy legfeljebb eggyel változtatja). A zaj Laplace eloszlású, a skálája 1/ε.
function laplace(scale: number) {
const u = Math.random() - 0.5; // demóhoz; élesben kriptográfiai véletlen és auditált könyvtár
return -scale * Math.sign(u) * Math.log(1 - 2 * Math.abs(u));
}
export const dpCount = (trueCount: number, epsilon: number) =>
Math.max(0, Math.round(trueCount + laplace(1 / epsilon)));
Gyakorlati szabályok.
- Az ε a privacy budget. Minden lekérdezés fogyaszt belőle, az ismételt lekérdezések összeadódnak.
- A tipikus ε érték 0,1 és 1 között szigorú, 1 és 10 között gyakorlati.
- Élesben auditált könyvtár kell (OpenDP, Google differential privacy library), mert a naiv lebegőpontos implementáció szivároghat (Mironov, 2012).
- Nyilvános statisztikánál, telemetriánál és ügyfelek közötti benchmarknál érdemes alkalmazni, egyedi ügyfélriportnál nem.
Maszkolás logban és LLM promptban
Logban.
- Strukturált logolás (JSON) és egy allowlist arról, mely mezők mehetnek ki. A denylist mindig lyukas.
- A redaction a logger szintjén történik (pino redact opció), nem hívásonként.
- Token, jelszó, Authorization fejléc, cookie és teljes request body nem kerül a logba.
- A felhasználó pszeudonim azonosítóval szerepel a logban, nem email címmel.
import pino from "pino";
export const log = pino({
redact: {
paths: ["req.headers.authorization", "req.headers.cookie", "*.password", "*.token", "*.email", "*.phone"],
censor: "[REDACTED]",
},
});
LLM promptban.
- A döntés az adatosztályozáson alapul. Korlátozott (restricted) adat nem mehet külső LLM-hez, a bizalmas csak szerződéses garanciával (DPA, zero data retention, EU adatfeldolgozás, ha elérhető).
- A prompt összeállítása előtt PII felismerés és helyettesítőkre csere történik (Microsoft Presidio, saját regex magyar mintákra, például adóazonosító, TAJ szám, magyar telefonszám formátum, IBAN).
- A helyettesítők egy kérésen belül konzisztensek (SZEMÉLY_1, SZEMÉLY_2), a válaszban a szerver cseréli vissza őket. A leképező tábla nem hagyja el a szervert.
- Csak a feladathoz szükséges mezők kerülnek át (adattakarékosság), a teljes rekord soha.
- Az LLM interakciók rövid megőrzéssel tárolódnak, és szerepelnek a nyilvántartásban.
- A modell kimenete alacsony integritású (Biba), ezért adatbázisba írás előtt sémavalidáción megy át.
const PATTERNS: [RegExp, string][] = [
[/[\w.+-]+@[\w-]+\.[\w.]+/g, "EMAIL"],
[/\b(?:\+36|06)[\s-]?\d{1,2}[\s-]?\d{3}[\s-]?\d{3,4}\b/g, "TELEFON"],
[/\bHU\d{2}(?:\s?\d{4}){6}\b/g, "IBAN"],
[/\b\d{3}[\s-]?\d{3}[\s-]?\d{3}\b/g, "TAJ"],
];
export function maskForLlm(text: string) {
const map = new Map<string, string>();
let i = 0;
let out = text;
for (const [re, label] of PATTERNS) {
out = out.replace(re, (m) => {
const key = `[${label}_${++i}]`;
map.set(key, m);
return key;
});
}
return { masked: out, map }; // a map a szerveren marad
}
A regex alapú maszkolás csak az első réteg. Neveket és szabad szöveges azonosítókat egy NER modell jobban megtalál, a maradék kockázatot pedig a szerződéses kontroll fedi.
Adatosztályozás
Séma
A legtöbb projektben négy szint elég. Több szintet az emberek nem tudnak következetesen alkalmazni.
| Osztály | Definíció | Példa |
|---|---|---|
| Nyilvános | Közzétételre szánt | Marketing szöveg, publikus árlista, blogcikk |
| Belső | Nem titkos, de nem nyilvános | Belső dokumentáció, nem személyes üzleti mutató |
| Bizalmas | Személyes adat, üzleti titok, ügyféladat | Név, email, ügyfélprojekt tartalma, szerződés |
| Korlátozott | Különleges adat, hitelesítési titok, pénzügyi azonosító, súlyos kárt okozó szivárgás | Egészségügyi adat, jelszó hash, API kulcs, bankszámla, személyi igazolvány, TAJ |
Osztályhoz rendelt kontrollok
| Kontroll | Nyilvános | Belső | Bizalmas | Korlátozott |
|---|---|---|---|---|
| Hozzáférés | Bárki | Bejelentkezett munkatárs | RLS, szükséges szerep | RLS, név szerinti jog, aal2 |
| Titkosítás tároláskor | Nem kell | Platform szint | Platform szint, mentések titkosítva | Alkalmazás szint (AEAD, envelope, KMS) |
| Titkosítás átvitelkor | TLS | TLS | TLS 1.2 vagy újabb | TLS 1.3, belső hálózaton is |
| Naplózás | Nem kell | Változás | Írás és tömeges olvasás | Minden hozzáférés |
| Logba kerülhet | Igen | Igen | Pszeudonim formában | Soha |
| Külső LLM | Igen | Igen, DPA mellett | Csak DPA, zero retention, maszkolás | Nem |
| Fejlesztői környezet, seed | Igen | Igen | Szintetikus vagy maszkolt | Csak szintetikus |
| Export | Szabad | Belső | Jóváhagyással, naplózva | Tilos vagy négy szem elv |
| Megőrzés | Korlátlan | Szabályzat szerint | Meghatározott, automatikus törlés | Minimális, automatikus törlés |
| Szivárgás esetén | Nincs teendő | Belső vizsgálat | Incidenskezelés, GDPR értékelés | Incidenskezelés, valószínűleg bejelentés |
Bevezetés
- A címkézés oszlopszinten, a migrációban történik.
- Egy CI szkript ellenőrzi, hogy minden új oszlop kapott címkét.
- A címkéből generálható a nyilvántartás adatkör oszlopa, a log redaction lista és az LLM maszkolási szabály.
comment on column public.customers.email is 'class=confidential;pii=true;retention=account+30d';
comment on column public.customers.tax_id is 'class=restricted;pii=true;encrypt=app';
-- címke nélküli oszlopok listája a CI-ban
select c.table_name, c.column_name
from information_schema.columns c
left join pg_catalog.pg_description d
on d.objoid = (quote_ident(c.table_schema) || '.' || quote_ident(c.table_name))::regclass
and d.objsubid = c.ordinal_position
where c.table_schema = 'public' and (d.description is null or d.description not like 'class=%');
Supabase specifikus minták
Alapszabályok
- Minden public sémabeli táblán be van kapcsolva az RLS, már a létrehozó migrációban.
- A Supabase ma az új tábláknál alapból kéri az RLS-t, SQL migrációban viszont ezt külön meg kell írni.
- A policy mindig szerepre szűkített (to authenticated, to anon), nem a public pszeudo szerepre szól.
- A select, insert, update és delete külön policyt kap. A for all policy kerülendő, mert az insert és update with check feltételét könnyű kifelejteni.
- Az auth.uid() hívás select-be csomagolva szerepel, a policy oszlopai indexeltek.
- A service_role vagy secret kulcs csak szerveroldalon létezik.
RLS minták
Owner minta.
alter table public.notes enable row level security;
create policy "notes owner select" on public.notes
for select to authenticated using ((select auth.uid()) = user_id);
create policy "notes owner insert" on public.notes
for insert to authenticated with check ((select auth.uid()) = user_id);
create policy "notes owner update" on public.notes
for update to authenticated
using ((select auth.uid()) = user_id)
with check ((select auth.uid()) = user_id);
create policy "notes owner delete" on public.notes
for delete to authenticated using ((select auth.uid()) = user_id);
create index on public.notes (user_id);
Tenant minta. A tagságot egy security definer segédfüggvény kérdezi le. Így a memberships táblán futó RLS nem rekurzál, és a lekérdezés egyszer fut.
create or replace function public.user_tenant_ids()
returns setof uuid
language sql stable security definer set search_path = ''
as $$
select tenant_id from public.memberships where user_id = (select auth.uid());
$$;
revoke execute on function public.user_tenant_ids() from public, anon;
grant execute on function public.user_tenant_ids() to authenticated;
create policy "projects tenant select" on public.projects
for select to authenticated
using (tenant_id in (select public.user_tenant_ids()));
create policy "projects tenant insert" on public.projects
for insert to authenticated
with check (tenant_id in (select public.user_tenant_ids()));
Role minta. Bérlőn belüli szerep alapján működik. A szerepet tartalmazó tábla update joga csak az owneré, vagy csak RPC-n keresztül érhető el.
create policy "projects admin delete" on public.projects
for delete to authenticated
using (public.has_permission(tenant_id, 'project.delete'));
Shared minta. Egyedi megosztás egy felhasználóval, a tulajdonos mellett.
create table public.document_shares (
document_id uuid references public.documents(id) on delete cascade,
user_id uuid references auth.users(id) on delete cascade,
permission text check (permission in ('view','edit')),
primary key (document_id, user_id)
);
create or replace function public.can_view_document(p_doc uuid)
returns boolean language sql stable security definer set search_path = ''
as $$
select exists (select 1 from public.documents d where d.id = p_doc and d.owner_id = (select auth.uid()))
or exists (select 1 from public.document_shares s where s.document_id = p_doc and s.user_id = (select auth.uid()));
$$;
create policy "documents view" on public.documents
for select to authenticated using (public.can_view_document(id));
Ha a can_view_document nagy táblán soronként fut, érdemes halmaz alapúra cserélni (id in (select ...)), mert a soronkénti függvényhívás lassú.
Security definer csapdák
| Csapda | Mi a baj | Javítás |
|---|---|---|
| Hiányzó set search_path | Egy támadó által létrehozott azonos nevű objektum (például függvény a public sémában) a tulajdonos jogaival fut le | set search_path = '' és minden objektum sémával minősítve |
| A függvény a public sémában van, és bárki hívhatja | A PostgREST RPC-ként kiteszi, az anon is hívhatja | revoke execute from public, anon, explicit grant, vagy privát séma |
| Paraméterként kapott user_id | A hívó bárki nevében kérdezhet | A függvényen belül mindig auth.uid() |
| Security definer view | A view a létrehozó jogaival fut, megkerüli az RLS-t | Postgres 15 óta with (security_invoker = true) |
| Dinamikus SQL format nélkül | SQL injection tulajdonosi jogokkal | format() %I és %L, vagy paraméterezett execute using |
| Túl széles visszatérés | A függvény teljes sort ad vissza, benne érzékeny oszloppal | Csak a szükséges oszlopok |
create view public.project_overview
with (security_invoker = true)
as select id, tenant_id, name, status from public.projects;
A Supabase security advisor (a Dashboardon, a CLI-ból vagy MCP szerveren keresztül) jelzi a security definer view-kat, a kikapcsolt RLS-t, a módosítható search_path-ot és a kitett auth.users hivatkozást. Minden migráció után érdemes lefuttatni.
service_role és secret kulcs
- Teljes egészében megkerüli az RLS-t. Aki birtokolja, mindent olvas és ír.
- Soha nem kerülhet kliensbe, mobilappba, NEXT_PUBLIC_ változóba, Lovable vagy hasonló eszközzel generált frontendbe.
- Edge functionben elsődlegesen a hívó JWT-jével készül a kliens. A secret kulcs csak indokolt adminisztratív művelethez kell, és akkor is szűkített lekérdezéssel.
- Ha egy háttérjobnak csak egy táblához kell hozzáférnie, saját Postgres role-t és saját kapcsolatot kap, nem service_role-t.
// supabase/functions/x/index.ts
import { createClient } from "jsr:@supabase/supabase-js@2";
Deno.serve(async (req) => {
const supabase = createClient(Deno.env.get("SUPABASE_URL")!, Deno.env.get("SUPABASE_ANON_KEY")!, {
global: { headers: { Authorization: req.headers.get("Authorization")! } },
});
const { data: { user }, error } = await supabase.auth.getUser();
if (error || !user) return new Response("unauthorized", { status: 401 });
// innen minden lekérdezés RLS alatt fut a felhasználó nevében
return new Response("ok");
});
Storage policy
A Storage a storage.objects táblán futó RLS-sel véd. Bevett minta, hogy a fájl útvonalának első szegmense a bérlő vagy a felhasználó azonosítója.
create policy "tenant files read" on storage.objects
for select to authenticated
using (
bucket_id = 'tenant-files'
and (storage.foldername(name))[1]::uuid in (select public.user_tenant_ids())
);
create policy "tenant files upload" on storage.objects
for insert to authenticated
with check (
bucket_id = 'tenant-files'
and (storage.foldername(name))[1]::uuid in (select public.user_tenant_ids())
);
Csapdák. A public bucket policytól függetlenül, URL-lel mindenki számára olvasható, ezért személyes adat sosem kerül public bucketbe. Minden signed URL capability, rövid lejárattal adjuk ki. A bucketen be kell állítani a megengedett MIME típusokat és a maximális fájlméretet. Feltöltött fájlt nem szolgálunk ki ugyanarról az originről, ahol a session cookie él (HTML vagy SVG fájlon keresztüli XSS veszélye miatt).
auth.uid() és auth.jwt()
- Az auth.uid() a JWT sub claimje, anonim hívásnál null. Policyban a null = user_id hamis, ezért anonim hívó semmit sem lát, ami a kívánt viselkedés.
- Az auth.jwt() a teljes claim készlet. Az app_metadata mezőt csak a szerver írhatja, a user_metadata mezőt a felhasználó is módosíthatja. Jogosultság sosem épülhet a user_metadata-ra.
- Egyedi claimekhez (bérlő, szerep) a custom access token hook a tiszta megoldás. A claim a token lejáratáig él, ezért szerep visszavonásakor a régi token még érvényes lehet. Kritikus jognál inkább a táblát érdemes lekérdezni.
RLS teljesítmény
| Technika | Miért gyorsít |
|---|---|
| (select auth.uid()) a nyers auth.uid() helyett | A planner initPlanként egyszer értékeli ki, nem soronként |
| Index a policy oszlopain (user_id, tenant_id) | A szűrés indexet használ |
| Szerep megadása (to authenticated) | Az anon kérésekre a policy ki sem értékelődik |
| Join helyett in (select ...) halmaz | A soronkénti allekérdezés helyett egyszeri halmaz |
| Security definer segédfüggvény a tagsághoz | Elkerüli a memberships táblán futó RLS rekurzióját |
| A kliens is szűr (.eq('tenant_id', x)) | Explicit feltétellel a planner jobb tervet készít |
A mérés az explain analyze futtatásával, a felhasználó szerepében történik.
begin;
set local role authenticated;
set local request.jwt.claims = '{"sub":"11111111-1111-1111-1111-111111111111","role":"authenticated"}';
explain analyze select * from public.projects;
rollback;
Tesztelés két felhasználóval
Minden RLS policy tesztje legalább két felhasználóval, két bérlőben fut. Az első felhasználó látja a sajátját, a másodikét viszont nem látja és nem módosíthatja. Anonim hívó semmit sem lát.
pgTAP az adatbázisban (supabase test db).
begin;
select plan(4);
-- tesztadat két bérlővel
insert into auth.users (id, email) values
('aaaaaaaa-0000-0000-0000-000000000001', '[email protected]'),
('bbbbbbbb-0000-0000-0000-000000000002', '[email protected]');
insert into public.tenants (id, name) values
('10000000-0000-0000-0000-000000000001', 'A kft'),
('20000000-0000-0000-0000-000000000002', 'B kft');
insert into public.memberships values
('10000000-0000-0000-0000-000000000001', 'aaaaaaaa-0000-0000-0000-000000000001', 'owner'),
('20000000-0000-0000-0000-000000000002', 'bbbbbbbb-0000-0000-0000-000000000002', 'owner');
insert into public.projects (tenant_id, name) values
('10000000-0000-0000-0000-000000000001', 'A projekt'),
('20000000-0000-0000-0000-000000000002', 'B projekt');
set local role authenticated;
set local request.jwt.claims = '{"sub":"aaaaaaaa-0000-0000-0000-000000000001","role":"authenticated"}';
select is((select count(*) from public.projects)::int, 1, 'A csak a saját projektjét látja');
select is((select name from public.projects limit 1), 'A projekt', 'A a saját projektjét látja');
select throws_ok(
$$ insert into public.projects (tenant_id, name) values ('20000000-0000-0000-0000-000000000002', 'betörés') $$,
'42501', null, 'A nem írhat B bérlőjébe'
);
set local role anon;
set local request.jwt.claims = '{"role":"anon"}';
select is((select count(*) from public.projects)::int, 0, 'anon semmit sem lát');
select * from finish();
rollback;
Integrációs teszt a kliens felől (Vitest). Két valódi felhasználó a helyi Supabase példányon, a publishable kulccsal. Ez a teszt a teljes láncot ellenőrzi (Auth, PostgREST, RLS, Storage).
import { createClient } from "@supabase/supabase-js";
import { expect, test } from "vitest";
const url = process.env.SUPABASE_URL!;
const key = process.env.SUPABASE_PUBLISHABLE_KEY!;
async function signedIn(email: string, password: string) {
const c = createClient(url, key, { auth: { persistSession: false } });
const { error } = await c.auth.signInWithPassword({ email, password });
if (error) throw error;
return c;
}
test("B nem olvashatja A számláját id alapján (BOLA)", async () => {
const a = await signedIn("[email protected]", process.env.TEST_PW_A!);
const b = await signedIn("[email protected]", process.env.TEST_PW_B!);
const { data: inv } = await a.from("invoices").insert({ amount: 100 }).select("id").single();
const { data } = await b.from("invoices").select("*").eq("id", inv!.id);
expect(data).toEqual([]);
const { data: upd } = await b.from("invoices").update({ amount: 0 }).eq("id", inv!.id).select();
expect(upd).toEqual([]);
});
Az RLS által blokkolt update nem dob hibát, hanem nulla sort érint. Ezért a teszt a visszaadott sorokat vizsgálja, nem a hibát.
Szabályozás fejlesztői szemmel
Az alábbiak technikai kontrollokra fordítják a szabályozást. A hatály és a kötelezettségek megállapítása jogi kérdés, arról szakértő dönt. Az irányítási rendszerek és a megfelelés szervezeti oldalát az Irányítási rendszerek és governance és az ISO megfelelés és audit kézikönyv tárgyalja.
NIS2 (EU 2022/2555) és a magyar átültetés
Magyarországon a 2024. évi LXIX. törvény (kiberbiztonsági törvény) ülteti át. A felügyeletet a Szabályozott Tevékenységek Felügyeleti Hatósága (SZTFH) látja el, az incidensbejelentés a Nemzeti Kibervédelmi Intézet felé történik. Az érintett szervezeteknek regisztrálniuk kell, kiberbiztonsági auditon kell átesniük, és a vezetés személyesen felel.
| NIS2 21. cikk követelmény | Fejlesztői kontroll |
|---|---|
| Kockázatelemzés, szabályzatok | Fenyegetésmodell, access matrix, adatosztályozás |
| Incidenskezelés | Riasztás, runbook, naplók megőrzése, a 24 órás, 72 órás és egy hónapos bejelentési ütem támogatása |
| Üzletmenet folytonosság, mentés | PITR, tesztelt visszaállítás, RTO és RPO |
| Ellátási lánc biztonsága | SBOM, függőség scan, beszállítói értékelés (Supabase, Vercel, LLM szolgáltató) |
| Biztonság a beszerzésben és a fejlesztésben | Secure SDLC, code review, SAST, secret scan |
| Hatékonyság mérése | Advisor riport, sérülékenység lezárási idő |
| Kiberhigiénia, képzés | Fejlesztői biztonsági ellenőrzőlista |
| Kriptográfia | Kriptográfiai szabályzat (a fenti javasolt és kerülendő algoritmusok táblázata alapján), kulcsrotáció |
| HR biztonság, hozzáférés szabályozás, eszközkezelés | Jogosultság kiosztási és visszavonási folyamat belépéskor és kilépéskor |
| MFA, biztonságos kommunikáció | Kötelező MFA admin és fejlesztői fiókokra |
Ezeket akkor is érdemes alkalmazni, ha az ügyfél maga nem tartozik a hatály alá, mert a hatály alá tartozó megrendelők a beszállítóiktól is elvárják (ellátási lánc).
EU AI Act (EU 2024/1689)
Ütemezés. A rendelet 2024. augusztus 1-jén lépett hatályba. A tiltott gyakorlatok és az AI jártassági kötelezettség (4. cikk) 2025. február 2-től, az általános célú modellekre vonatkozó szabályok 2025. augusztus 2-től alkalmazandók. A magas kockázatú rendszerek szabályai eredetileg 2026. augusztus 2-től lennének alkalmazandók. A Bizottság 2025 novemberi digitális omnibusz javaslata ezt a szabványok és útmutatók elkészültéhez kötné, legkésőbb 2027 decemberéig, a termékekbe épített rendszereknél 2028 augusztusáig. A 2026 októberi állapot szerint ez ellenőrizendő, az aktuális helyzetet projektkezdéskor meg kell nézni.
Fejlesztői kontrollok szerepkör szerint.
- Minden AI rendszernél. Annak eldöntése és dokumentálása, hogy a rendszer tiltott, magas kockázatú, átláthatósági kötelezettséggel járó vagy minimális kockázatú kategóriába tartozik.
- Átláthatóság (50. cikk). A chatbot jelzi, hogy gép. A generált szintetikus tartalom géppel olvasható módon jelölt. A deepfake jelölése kötelező.
- Magas kockázatú rendszernél (például HR szűrés, hitelbírálat, oktatási értékelés). Kockázatkezelési rendszer, adatminőség és adatkezelés (10. cikk), műszaki dokumentáció, automatikus naplózás (12. cikk), emberi felügyelet (14. cikk), pontosság, robusztusság és kiberbiztonság (15. cikk, ide tartozik a prompt injection és az adatmérgezés elleni védelem).
- AI jártasság. A rendszert használó munkatársak dokumentált képzése.
A GDPR az AI rendszerre is teljes egészében vonatkozik. A promptban, a RAG indexben, a finomhangoló adatban és a naplóban lévő személyes adat is személyes adat. Az AI irányítási szabványokat (ISO/IEC 42001 és társai) az AI ISO szabványok kézikönyv ismerteti.
DORA (EU 2022/2554), pénzügyi szektor
- január 17-től alkalmazandó bankokra, biztosítókra, befektetési vállalkozásokra, kriptoszolgáltatókra és a kritikus IKT szolgáltatóikra.
| DORA pillér | Fejlesztői következmény |
|---|---|
| IKT kockázatkezelés | Eszközleltár, adatosztályozás, hozzáférés szabályozás, titkosítás, változáskezelés |
| Incidensjelentés | Az osztályozási szempontok szerinti naplózás, a gyors (órás) első bejelentés támogatása |
| Digitális működési ellenálló képesség tesztelése | Sérülékenység vizsgálat, nagyobb intézménynél fenyegetésalapú penetrációs teszt (TLPT) |
| Harmadik fél kockázat | Szerződéses jogok (audit, kilépési stratégia), beszállítói nyilvántartás. Ha a megoldás Supabase-re vagy LLM szolgáltatóra épül, ezeket fel kell tüntetni |
| Információmegosztás | Fenyegetési információk megosztása |
Pénzügyi szolgáltató ügyfélnél a projekt kezdetén tisztázni kell, alkalmazza-e a DORA-t, mert ez a beszállítóválasztást (EU régió, kilépési terv, auditjog) is befolyásolja.
Magyar vonatkozás, NAIH
- A NAIH (Nemzeti Adatvédelmi és Információszabadság Hatóság) a GDPR felügyeleti hatósága. Az incidensbejelentés 72 órán belül az online felületén történik.
- A NAIH közzétette a kötelező DPIA esetek listáját és incidenskezelési ajánlásait, ezeket a projekt indításakor érdemes átnézni.
- Az Infotv. (2011. évi CXII. törvény) a GDPR mellett a nemzeti kiegészítő szabályokat tartalmazza.
- Munkavállalói adatoknál a Munka törvénykönyve és a NAIH munkahelyi adatkezelési tájékoztatója is irányadó (megfigyelés, email ellenőrzés, AI alapú teljesítményértékelés).
- A Cyber Resilience Act (EU 2024/2847) a termékként forgalmazott szoftvernél 2026 szeptemberétől sérülékenységbejelentési, 2027 decemberétől teljes körű biztonsági követelményeket ír elő, ezt a saját termékeknél figyelni kell.
A gyakorlatban
Állandó szabályok
- RLS az első migrációban. Új táblánál a create table, az enable row level security, a négy külön policy és az index egy migrációban születik. Policy nélküli tábla nem kerül élesbe.
- Előbb access matrix, utána policy. Ha a projektben még nincs verziózott hozzáférési mátrix, előbb az készül el, a policyk abból következnek.
- Kliens a felhasználó nevében. Edge functionben és szerveroldali kódban a hívó JWT-jével jön létre a kliens. A secret vagy service_role kulcs használatát a kódban komment indokolja, és a lekérdezés szűkített.
- Titok soha nincs a kliensben, a repóban, a logban vagy a promptban. Ha titok kerül elő a kódban, egy jegyben vagy egy beszélgetésben, a csapat jelzi és rotálja, nem másolja tovább. AI asszisztens promptjába sem kerül titok.
- Security definer csak search_path = '' beállítással, revoke execute from public, anon sorral és auth.uid() alapú belső szűréssel. View-nál security_invoker = true.
- Jogosultság nem a user_metadata-ból. Szerep és bérlő a memberships táblából vagy az app_metadata-ból jön.
- Bevált kriptográfia. libsodium, Web Crypto vagy Node crypto, AEAD, XChaCha20-nál véletlen nonce, kulcsverzió mező. Saját algoritmus, ECB mód és Math.random alapú token nem kerül a kódba, akkor sem, ha egy kódgeneráló modell ilyet javasol.
- A jelszót és a hitelesítést a platformra bízzuk. Supabase Auth, PKCE, leaked password protection, MFA admin szerepre. Ha saját hitelesítés kell, argon2id az OWASP paraméterekkel és a NIST 800-63B-4 szabályai szerint (15 karakter MFA nélkül, nincs összetételi szabály, nincs kötelező csere, van tiltólista).
- Személyes adat előtt adatosztály. Új személyes adat mezőnél a fejlesztő eldönti vagy egyezteti az osztályt, a megőrzési időt és a nyilvántartás jogalap sorát, és mindezt oszlopkommentbe írja.
- LLM hívás előtt maszkolás. Bizalmas adat csak maszkolva, korlátozott adat egyáltalán nem megy külső modellhez. A modell kimenete írás előtt sémavalidáción megy át.
- Kétfelhasználós teszt nélkül nincs kész. Minden RLS változáshoz pgTAP vagy integrációs teszt tartozik, amely A, B és anon szereppel ellenőriz.
- Advisor minden migráció után. A Supabase security és performance advisor minden migráció után lefut, a figyelmeztetések a pull request leírásába kerülnek.
- Szabályozásról tényt, nem jogi véleményt. A fejlesztőcsapat a kontrollokat nevezi meg, és jelzi, ha egy döntés jogászt, DPO-t vagy a felelős vezetőt igényli.
- Éles adatbázison óvatosan. Éles adaton DDL vagy tömeges módosítás csak kifejezett, dokumentált jóváhagyással fut, előtte branchen vagy helyi példányon kipróbálva. AI asszisztált munkánál ez a szabály az asszisztens eszközjogosultságaira is vonatkozik.
Ellenőrzőlista, új tábla vagy funkció
- Az access matrix frissítve
- RLS bekapcsolva, külön select, insert, update, delete policy, to authenticated
- Insert és update policynál with check is
- (select auth.uid()) formában, a policy oszlopain index
- tenant_id not null, összetett idegen kulcs a bérlőn belüli hivatkozásra
- Érzékeny oszlopokra oszlopszintű grant vagy trigger (mass assignment ellen)
- Oszlopkomment adatosztállyal és megőrzéssel
- Megőrzési job vagy dokumentált indok, miért nincs
- Export és törlés folyamat kiterjesztve az új táblára
- pgTAP teszt két felhasználóval és anon szereppel
- Security advisor tiszta
- Adatvédelmi blokk a PR leírásban
Ellenőrzőlista, hitelesítés és session
- PKCE flow, egyező redirect URI lista
- Session cookie HttpOnly, Secure, SameSite, szerveroldalon getUser vagy getClaims
- Rövid access token, rotáló refresh token
- MFA admin és pénzügyi szerepre, kritikus műveletnél aal2 ellenőrzés
- Passkey opció, erős helyreállítás
- Jelszó minimum hossz és tiltólista bekapcsolva, összetételi szabály nincs
- Rate limit belépésre, regisztrációra, jelszó visszaállításra
- Egységes válasz létező és nem létező fióknál
- Aszimmetrikus JWT signing kulcs, JWKS alapú ellenőrzés, aud és iss ellenőrzés
Ellenőrzőlista, kriptográfia és titkok
- AEAD, associated data a kontextussal, kulcsverzió mező
- Kulcs KMS-ben vagy Vaultban, envelope encryption a korlátozott adatra
- Rotációs naptár kulcsonként
- gitleaks pre-commit, push protection, trufflehog a CI-ban
- Nincs titok NEXT_PUBLIC_ vagy VITE_ változóban
- CI felhő hozzáférés OIDC-vel
- Kriptográfiai leltár, PQC hibrid TLS a hosszú titkosságú adatra
Ellenőrzőlista, adatvédelem és szabályozás
- Adatfolyam ábra és LINDDUN áttekintés a jelentős funkcióknál
- DPIA szükségességének vizsgálata (különleges adat, profilalkotás, AI, munkavállalók, nagy lépték)
- Az adatkezelési nyilvántartás technikai oszlopai naprakészek
- Érintetti export és törlés tesztelve, storage és harmadik felek is
- Log redaction allowlist, pszeudonim felhasználói azonosító a logban
- DPA és zero retention az LLM szolgáltatóval, a nyilvántartásban is szerepel
- AI Act kategória dokumentálva, átláthatósági jelzés a felületen
- A NIS2 vagy DORA hatály kérdése tisztázva az ügyféllel, ha releváns
- Incidens runbook (ki dönt, NAIH 72 óra, CSIRT 24 óra, kulcsrotáció lépései)
Kódáttekintési kérdések AI által generált kódhoz
| Kérdés | Mit keresünk |
|---|---|
| Hol dől el, hogy ez az objektum a hívóé? | Ha a válasz a kliens, az BOLA |
| Van-e út, amely megkerüli az RLS-t? | service_role, security definer view, public számára engedélyezett RPC |
| Mi történik, ha a mező hiányzik vagy null? | Fail safe default, null értékű auth.uid() |
| Mit lát a logban egy támadó vagy egy support munkatárs? | Token, email, teljes body |
| Mi kerül a promptba? | Teljes rekord, korlátozott adat, a maszkolás hiánya |
| Mit tesz a rendszer megbízhatatlan inputtal? | Webhook aláírás, LLM kimenet validálás, Biba sértés |
| Hogyan vonható vissza? | Token, kulcs, megosztás, szerep visszavonása és annak azonnali hatása |
| Hol a teszt, amely bizonyítja? | Kétfelhasználós teszt, assurance |
Az AI asszisztált fejlesztés munkarendjét, az ügynökök jogosultságait és a generált kód átvételét az AI ügynökök és vibecoding kézikönyv részletezi, a módszerek történeti hátterét a Papírkorszak módszerei és a Szoftverarchitektúra kézikönyv adja.
Források
- Jack B. Dennis, Earl C. Van Horn, Programming Semantics for Multiprogrammed Computations, Communications of the ACM, 1966.
- Willis H. Ware (szerk.), Security Controls for Computer Systems, RAND, 1970.
- Butler W. Lampson, Protection, Princeton Symposium, 1971.
- James P. Anderson, Computer Security Technology Planning Study, USAF, 1972.
- D. Elliott Bell, Leonard J. LaPadula, Secure Computer Systems, MITRE, 1973.
- Dorothy E. Denning, A Lattice Model of Secure Information Flow, Communications of the ACM, 1976.
- Kenneth J. Biba, Integrity Considerations for Secure Computer Systems, MITRE, 1977.
- Jerome H. Saltzer, Michael D. Schroeder, The Protection of Information in Computer Systems, Proceedings of the IEEE, 1975.
- David D. Clark, David R. Wilson, A Comparison of Commercial and Military Computer Security Policies, IEEE Symposium on Security and Privacy, 1987.
- U.S. Department of Defense, Trusted Computer System Evaluation Criteria (Orange Book), 1983, illetve 1985.
- Robert Morris, Ken Thompson, Password Security, Communications of the ACM, 1979.
- Whitfield Diffie, Martin E. Hellman, New Directions in Cryptography, IEEE Transactions on Information Theory, 1976.
- Ronald L. Rivest, Adi Shamir, Leonard Adleman, A Method for Obtaining Digital Signatures and Public Key Cryptosystems, 1977 (megjelent 1978).
- Daniel Bleichenbacher, Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption Standard PKCS #1, CRYPTO 1998.
- Ross Anderson, Security Engineering, 3. kiadás, Wiley, 2020.
- David Ferraiolo, Richard Kuhn, Role Based Access Controls, NIST, 1992, valamint ANSI INCITS 359.
- NIST SP 800-162, Guide to Attribute Based Access Control (ABAC) Definition and Considerations, 2014.
- Ruoming Pang és társai, Zanzibar, Google's Consistent, Global Authorization System, USENIX ATC 2019.
- Cedar policy language dokumentáció, AWS, 2023.
- NIST SP 800-63B-4, Digital Identity Guidelines, Authentication and Authenticator Management, 2025.
- OWASP Password Storage Cheat Sheet és OWASP API Security Top 10 (2023).
- IETF, The OAuth 2.1 Authorization Framework, Internet-Draft, 16. revízió, 2026.
- IETF RFC 9700, OAuth 2.0 Security Best Current Practice, 2025.
- IETF, OAuth 2.0 for Browser-Based Applications, Internet-Draft.
- Niels Ferguson, Bruce Schneier, Tadayoshi Kohno, Cryptography Engineering, Wiley, 2010.
- Jean-Philippe Aumasson, Serious Cryptography, 2. kiadás, No Starch Press, 2024.
- NIST FIPS 203, 204 és 205, 2024, valamint NIST IR 8547 (a post quantum átállás terve).
- Ann Cavoukian, Privacy by Design, The 7 Foundational Principles, 2009.
- KU Leuven DistriNet, LINDDUN GO és LINDDUN PRO módszertan.
- Latanya Sweeney, k-Anonymity, A Model for Protecting Privacy, 2002.
- Ashwin Machanavajjhala és társai, l-Diversity, Privacy Beyond k-Anonymity, 2006.
- Ninghui Li, Tiancheng Li, Suresh Venkatasubramanian, t-Closeness, Privacy Beyond k-Anonymity and l-Diversity, 2007.
- Cynthia Dwork, Frank McSherry, Kobbi Nissim, Adam Smith, Calibrating Noise to Sensitivity in Private Data Analysis, 2006.
- Ilya Mironov, On Significance of the Least Significant Bits for Differential Privacy, 2012.
- (EU) 2016/679 rendelet (GDPR), (EU) 2022/2555 irányelv (NIS2), (EU) 2022/2554 rendelet (DORA), (EU) 2024/1689 rendelet (AI Act), (EU) 2024/2847 rendelet (Cyber Resilience Act).
- 2024. évi LXIX. törvény (kiberbiztonsági törvény), 2011. évi CXII. törvény (Infotv.), a NAIH kötelező DPIA listája és incidenskezelési ajánlásai.
- Az EU Bíróság 2025 szeptemberi ítélete az EDPS kontra SRB ügyben.
- Supabase dokumentáció (Row Level Security, Auth, Storage, Vault, API kulcsok, JWT signing kulcsok, security advisor), 2026 októberi állapot.
Állapot 2026 októberében. A szöveg szakmai összefoglaló, nem jogi tanácsadás, a szabványok és jogszabályok aktuális szövegét a kiadótól érdemes ellenőrizni.