Lühidalt
Mõlemad lukustavad uue tabeli vaikimisi: Appwrite vastas külalisele ja sisselogitud kasutajale 401, Supabase vastab 401/403, kuni annate tabelile API rollidele grandi. Vahe ilmneb siis, kui reegel on vale või päring ületab kasutajate piiri. Supabase’is andis võõra rea update 200 [] ja lõtv insert-poliitika lasi kasutajal liituda teise ettevõttega; Appwrite’is lõppes iga kasutajapiiri ületamise katse minu käivituses vastusega 401 või 404 ning kasutaja ei saanud oma rida anda kellelegi peale iseenda või kõigi. Appwrite’i serverivõtmetel on skoobid (scopes); Supabase’i secret key jätab iga poliitika vahele.
Olen Denys, full-stack- ja tehisintellekti insener. Enamik rakendusi, mida ehitan või parandan, töötab Supabase’is, ja kliendid, kes alles valivad backendi, küsivad, kuidas Appwrite turvalisuse poolest võrreldes seisab. Funktsioonide nimekirjad sellele ei vasta, nii et saatsin mõlemale samad päringud.
Kuidas testisin. Appwrite 2.3.0, self-hosted Dockeriga 30. oktoobril 2026, REST API kaudu külalisena, kahe sisselogitud kasutajana A ja B ning kahe serverivõtmega. Supabase’i pool on minu käivitus kohalikus stackis (CLI 2.109.1, Postgres 17.6) 24. oktoobril 2026 samade rollidega, täielikult kirjeldatud artiklis Supabase RLS policy näited, testitud API kaudu. Mõlemal küljel väljamõeldud read.
Kuidas Appwrite ja Supabase andmeid kaitsevad?
Supabase kaitseb tabeleid Postgresiga: grant otsustab, kas API rollid tabelini üldse jõuavad, ja reataseme turvalisuse (RLS) poliitikad, mis on kirjutatud SQL-is, otsustavad, milliseid ridu iga päring näeb ja kirjutab. Appwrite hoiab õigused andmete kõrval: tabelil on rollide nimekiri, kellel on lubatud lugeda, luua, uuendada või kustutada, ja kui rea turvalisus (row security) on sees, on igal real oma nimekiri. Appwrite’i õiguste dokumentatsiooni järgi ligipääs ainult antakse, mitte kunagi ei keelata, ja kasutaja vajab seda tabeli või rea tasemel, mitte mõlemal.
Seega ei ole küsimus selles, kumbal on ligipääsukontroll. Mõlemal on. Küsimus on selles, mida kumbki lubab valesti teha.
Mida kumbki uue tabeliga teeb?
| Päring | Appwrite, õigusi pole seadistatud | Supabase, RLS sees, grant puudub (24. okt.) |
|---|---|---|
| Külaline loeb ridu | 401 user_unauthorized |
401 permission denied |
| Sisselogitud kasutaja loeb ridu | 401 user_unauthorized |
403 permission denied |
| Sisselogitud kasutaja lisab rea | 401 No permissions provided for action ‘create’ |
testimata |
Värske tabel on mõlemal suletud. Supabase’is on see uus: pärast 30. oktoobrit 2026 loodud tabelid ei saa Data API granteid enam automaatselt, millest kirjutasin artiklis 30. oktoobri granti muudatus.
Mis juhtub, kui tabel on kõigile avatud?
Need kaks “avatud” seadet ei ole sama asi. Appwrite’is andsin tabelile ühe õiguse, read("any"). Supabase’is on tavaline avatud olek väljalülitatud RLS koos alles jäetud vaikegrantidega.
| Külalise päring | Appwrite, read("any") |
Supabase, RLS väljas, vaikegrandid (24. okt.) |
|---|---|---|
| Loe ridu | 200, mõlemad read |
200, mõlemad read |
| Kustuta rida | 401 |
200, mõlemad read kustutatud |
Appwrite’i “avalik” tähendab ainult lugemist, kui te ei anna ka kirjutamist. Supabase’i tabelit, kus RLS on väljas, saab lugeda ja kirjutada igaüks, kellel on publishable key, mistõttu “RLS disabled in public” on esimene asi, mida kontrollin.
Kuidas töötavad “oma read”?
Appwrite’is lülitasin rea turvalisuse sisse ja andsin tabelile ühe õiguse, create("users"). Kui A lõi rea ilma õigusi nimetamata, seadis Appwrite need ise: read, update ja delete ainult kasutajale A. Supabase’is on sama eesmärk neli poliitikat kujul (select auth.uid()) = user_id.
| Päring | Appwrite (30. okt.) | Supabase (24. okt.) |
|---|---|---|
| Külaline loeb ridu | 200, 0 rida |
401 (anonile granti pole) |
| A loeb ridu | 200, A kaks rida |
200, A kaks rida |
| A loeb B rida | 404 row_not_found |
nimekirjas ei tagastata |
| A uuendab B rida | 401 |
200 [] |
| A kustutab B rea | 401 |
200 [] |
Kumbki ei lekitanud B rida. Erinev on vastus. Supabase filtreerib välja read, mida poliitika peidab, nii et update, mis ei leidnud midagi, on edu nulli reaga; rakendus, mis peab “viga pole” samaks mis “salvestatud”, ütleb kasutajale, et tema muudatus õnnestus. Appwrite keeldub veaga, mida rakendus ei saa märkamata jätta.
Kas kasutaja saab oma andmed kellelegi teisele anda?
Siin läheb genereeritud kood kõige sagedamini valesti, nii et proovisin seda mõlemal.
| A päring | Appwrite | Supabase (24. okt.) |
|---|---|---|
| Loo rida, mida B saab lugeda | 401, Permissions must be one of: any, users, user:A… |
sõltub poliitikast |
| Muuda oma rida nii, et see kuulub B-le | 401, sama teade |
403 täieliku with check-iga; 200 kui with check (true) |
| Loo rida, mida kõik saavad lugeda | 201, ja külaline sai selle seejärel loetleda |
ainult siis, kui poliitika lubab |
Appwrite piirab, mida kasutaja saab anda: ainult rollid, mis tal endal on, ehk any, users, tema enda kasutaja ja tema enda tiimid. See blokeeris käigu “anna minu rida kellelegi teisele” ilma ühegi minu kirjutatud reeglita. See ei takistanud A-l oma rida kõigile avaldamast käsuga read("any"). Kui rida ei tohi kunagi avalik olla, ei tohiks õigusi seadistada klient; looge see serverifunktsioonist.
Supabase’is on tulemus see, mida poliitika ütleb. Täielik with check keeldus liigutamisest vastusega 403; with check (true), mida mõned generaatorid kirjutavad, lasi A-l rea B kontole viia.
Kas kasutaja saab liituda kellegi teise ettevõttega?
Supabase’is on tiimi ligipääs tavaliselt memberships-tabel pluss poliitikad. Minu käivituses lasi insert-poliitika, mida paljud õpetused soovitavad, with check (user_id = auth.uid()), A-l lisada end ettevõttesse 2 vastusega 201 Created ja siis lugeda selle palgaprojekti.
Appwrite’is on tiimid (teams) sisse ehitatud. B lõi tiimi; A proovis end sinna lisada liikmena ja omanikuna. Mõlemad päringud andsid 404 team_not_found: A ei näinud tiimi üldse. Liikmelisuse otsustab server, mitte teie kirjutatud reegel, nii et just see leke ei ole võimalik. Ridade jagamiseks on siiski vaja read("team:…") õigusi ja need seate te ise.
Mida serverivõti avab?
| Võti | Appwrite | Supabase (minu anon vs service role testist) |
|---|---|---|
| Täielik serverivõti | 200, kõik 4 rida mõlemalt kasutajalt |
kõik 3 rida, RLS vahele jäetud |
Kitsa skoobiga võti (users.read) |
401, missing scope rows.read |
skoobiga võtmeid pole |
Supabase’i secret key vastab rollile service_role, millel on BYPASSRLS; mida see avab, on artiklis anon key vs service role key. Appwrite’i võti ignoreerib samuti rea õigusi, aga ainult nende skoopide jaoks, millega see loodi, nii et kasutajate haldamise töö võti ei saa teie tabeleid lugeda. Mis tahes võti brauseri paketis on täielik leke kõigest, milleni see ulatub.
Kaks väiksemat leidu Appwrite’is: külaline ja sisselogitud kasutaja said tabelite nimekirja küsides mõlemad 401 (kutse vajab tables.read, mis on ainult võtmetel), ja read("users") tähendab mis tahes sisselogitud kontot, sama lõks mis auth.uid() is not null Supabase’is, kui registreerimine on avatud.
Kumb on turvalisem?
Kumbki pole vaikimisi turvaline ega ebaturvaline; mõlemad algasid suletuna. Nad erinevad selles, kus viga saab peituda:
| Küsimus | Appwrite | Supabase |
|---|---|---|
| Kus ligipääsureeglid asuvad | Rollinimekirjad tabelitel ja ridadel | SQL-i grandid ja poliitikad |
| Keelatud teise kasutaja kirjutamine | Viga (401 / 404) |
200 nulli reaga update’i ja delete’i puhul |
| Ridade andmine teistele | Ainult rollidele, mis kasutajal on | Mida poliitika lubab |
| Reeglid veeru väärtuste ja MFA taseme järgi | Õigustes pole; vaja serverikoodi | Poliitikas, nt aal2 tundlike ridade jaoks |
| Serverivõtmed | Skoopidega | Secret key jätab kõik poliitikad vahele |
Appwrite’i mudel on kitsam ja minu käivituses keeldus kitsas mudel igast kasutajate-vahelisest trikist, ilma et ma midagi kirjutanuks. Supabase’i mudel on SQL, nii et see suudab väljendada reegleid, mida Appwrite’i õigused ei suuda, näiteks “ainult MFA-ga” või “ainult nende ettevõtete read, kuhu ma kuulun”, ja see suudab väljendada ka vale reegli. Kui teie meeskond poliitikaid ei loe, andestavad Appwrite’i vaikeseaded rohkem. Kui vajate reegleid, mis sõltuvad andmetest, lubab Supabase need kirjutada, ja siis tuleb neid testida; meetod, mida ma kasutan, on artiklis kuidas Supabase’i RLS-i testida.
Kuidas Supabase’i projekti kontrollida?
Tasuta Supabase’i turvakontroll loeb teie projekti ainult lugemisrežiimis ja märgib tabelid, kus RLS on väljas, alati tõesed poliitikad, külaliste kirjutuspoliitikad ja grandid, mis annavad rohkem, kui poliitikad eeldavad. Mida Supabase teie eest kaitseb ja mida jätab teile, on artiklis kas Supabase on turvaline?. Appwrite’i vastet selles pole; Appwrite’is käivitage ülaltoodud päringud kahe kasutajana. Firebase’i puhul tegin sama laadi rünnakuid artiklis Firebase’i turvareeglite näited.
Piirangud. Üks self-hosted Appwrite 2.3.0 sülearvutis ja üks kohalik Supabase’i stack, käivitatud kuue päeva vahega, väljamõeldud read. Appwrite Cloud võib self-hostedist erineda. Storage’it, funktsioone, realtime’i, auth-seadeid ja vastavussertifikaate siin ei võrrelda.
Valite backendi rakendusele privaatsete andmetega?
Vaatan hea meelega koos teiega teie ligipääsumudelit. Müügijututa.
Võtke ühendust