zaterdag 6 februari 2016

Toegangscontrole (2) - RLS

Naast de mogelijkheden om databeheerders op basis van een rol toegang te geven tot database tabellen, is het aanvullend mogelijk de toegang te verfijnen naar bepaalde records. Hiervoor wordt gebruik gemaakt van Row Level Security functionaliteit, sinds kort beschikbaar in  PostgreSQL.


Zo is voor DEMO de autorisatie uitgewerkt:



Hoe werkt het?

Alle datamodellen die een rol spelen bij de informatie uitwisseling met derden  (IMWA, INSPIRE, BGT, ..) eisen dat bij ieder object een bronhouder wordt aangegeven. Dit wordt in een attribuut naamruimte, namespace, of bronhouder vastgelegd. Dit attribuut bevat een bronhouderscode waarmee via-via te achterhalen is wie de bronhouder is.

Het ligt voor de hand dit attribuut in DEMO dan ook zo dicht mogelijk bij de bron op te nemen in objecttabellen, zoals DAMO dat ook beoogd heeft.

CREATE TABLE oppervlaktewaterlichaam
(
  ..
  naamruimte varchar,
  ..
)
WITH (
  OIDS=FALSE
);
ALTER TABLE oppervlaktewaterlichaam OWNER TO postgres;

De superuser (postgres) wordt standaard eigenaar van iedere nieuwe tabel en krijgt alle rechten op de tabel. De superuser geeft, tenzij anders bepaald, iedere tabel vrij om te mogen raadplegen, en geeft het recht tot gegevensbeheer aan de PostgreSQL Group Role  die bij het informatiedomein hoort waar de tabel onderdeel van uitmaakt. Bijvoorbeeld de bovenstaande tabel oppervlaktewaterlichaam dat hoort bij het informatiemodel Water (IMWA).

GRANT SELECT ON oppervlaktewaterlichaam TO PUBLIC;
GRANT INSERT, UPDATE, DELETE ON public.oppervlaktewaterlichaam TO NSIMWA;

(Note: Er zijn nog andere tabellen met identieke gegevens voor andere domeinen zoals oppervlaktewaterlichaam voor de  Kaderrichtlijn Water (KRW), De toegangscontrole voor die tabellen is vergelijkbaar geconfigureerd).

Hiermee kan iedere gegevensbeheerder die lid is van de groep nsIMWA alle data in de tabel bewerken. Daarmee is de autorisatie echter niet afdoende geregeld. De tabel bevat weliswaar één objecttype van één informatiedomein (bijvoorbeeld oppervlaktewaterlichamen van nsIMWA), maar de tabel bevat mogelijk ook objecten van andere bronhouders (met een andere bronhouderscode). De gegevensbeheerder moet wel de objecten van de eigen organisatie onderhouden, maar niet die van een ander.

Om deze scheiding te kunnen maken moet eerst een verband gelegd kunnen worden tussen het informatiedomein en de bronhouderscode voor dat domein van de eigen organisatie. Dit gebeurt in een KV-store, een simpele tabel met sleutel-waarde kolommen, De KV-store is een tabel die typisch voor 1001 dingen gebruikt wordt en in veel systemen voorkomt.

Dan komt nu het Row Level Security (RLS) onderdeel. Met onderstaande twee regels wordt:
  • RLS geactiveerd voor deze tabel,
  • wordt het informatiedomein voor deze tabel achterhaald,
  • worden indirect alle rechten aan de juiste groep gebruikers toegekend.

ALTER TABLE public.oppervlaktewaterlichaam ENABLE ROW LEVEL SECURITY;
CREATE POLICY user_mod ON public.oppervlaktewaterlichaam FOR ALL USING (true) WITH CHECK (naamruimte = (SELECT value FROM public.kvstore WHERE key = 'nsIMWA')::varchar);

Het inlezen en beheren van de data van de overige bronhouders kan via een superuser verlopen, die sowieso alle rechten op de tabel blijft houden, of via het instellen van extra policies.

Nog één opmerking:
Het bovenstaande verhaal is alleen van toepassing op het schema waarin data wordt beheerd (public). Let er op dat in bovenstaande code soms een kwalificatie public staat en soms niet. Dat is iedere keer zeer bewust gedaan, daarover later meer.

Voilà, uitdaging van autorisatie aangegaan en zonder veel toeters en bellen kunnen invullen.


Geen opmerkingen:

Een reactie posten