0Pricing
SQL Academy · Lezione

Policy di sicurezza a livello di riga

Filtri automaticamente le righe in base all'utente

Policy di sicurezza a livello di riga è una lezione SQL Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento SQL Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso SQL Academy include 4 lezioni in totale.

Che cos'è la sicurezza a livello di riga

La sicurezza a livello di riga (RLS) è una funzionalità di PostgreSQL che consente di controllare quali righe di una tabella un determinato utente o ruolo del database può visualizzare o modificare. Anziché filtrare le righe in ogni query, si definisce una policy una sola volta e PostgreSQL la applica automaticamente a ogni SELECT, INSERT, UPDATE e DELETE.

La si può considerare una clausola WHERE invisibile associata alla tabella stessa anziché a una query specifica.

Abilitazione di RLS su una tabella

RLS è disabilitata per impostazione predefinita. È necessario abilitarla esplicitamente per ogni tabella usando ALTER TABLE ... ENABLE ROW LEVEL SECURITY. Una volta abilitata, qualsiasi ruolo che non sia il proprietario della tabella non vedrà alcuna riga finché non sarà stata creata almeno una policy.

-- Create a sample table
CREATE TABLE orders (
  id        SERIAL PRIMARY KEY,
  owner     TEXT NOT NULL,
  amount    NUMERIC(10,2)
);

-- Enable RLS
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

Creazione della prima policy

Una policy si crea con CREATE POLICY. Le assegni un nome, specifichi la tabella e fornisca un'espressione USING. La clausola USING è un'espressione booleana valutata per ogni riga: all'utente sono visibili solo le righe per le quali l'espressione restituisce TRUE.

-- Allow each user to see only their own orders
CREATE POLICY orders_owner_policy
  ON orders
  FOR SELECT
  USING (owner = current_user);

Le clausole USING e WITH CHECK a confronto

Le policy hanno due clausole di filtro con scopi diversi:

  • USING — filtra le righe nelle operazioni di lettura (SELECT, UPDATE, DELETE). Una riga è visibile solo se USING restituisce TRUE.
  • WITH CHECK — convalida le righe nelle operazioni di scrittura (INSERT, UPDATE). Una scrittura è consentita solo se WITH CHECK restituisce TRUE. Se viene omessa, USING viene riutilizzata per i controlli di scrittura.
-- Allow users to select and insert only their own rows
CREATE POLICY orders_isolation
  ON orders
  FOR ALL
  USING       (owner = current_user)
  WITH CHECK  (owner = current_user);

Ambito della policy: FOR SELECT, INSERT, UPDATE, DELETE

Una singola policy può coprire tutti i comandi (FOR ALL) oppure uno specifico comando. Separare le policy per comando Le offre un controllo granulare, ad esempio consentendo a ogni utente di leggere tutte le righe ma di modificare solo le proprie.

-- Everyone can read all orders
CREATE POLICY read_all_orders
  ON orders
  FOR SELECT
  USING (true);

-- But each user can only update their own orders
CREATE POLICY update_own_orders
  ON orders
  FOR UPDATE
  USING       (owner = current_user)
  WITH CHECK  (owner = current_user);

Utilizzare session_user e current_user

PostgreSQL mette a disposizione funzioni integrate per identificare l'utente attivo all'interno di un'espressione della policy:

  • current_user — il ruolo i cui privilegi sono attualmente attivi (può cambiare dopo SET ROLE).
  • session_user — il ruolo che ha aperto la connessione (non cambia mai durante la sessione).

La maggior parte delle policy RLS si basa su current_user, perché riflette il ruolo effettivo dopo un cambio di ruolo.

-- Inspect the current identity inside a query
SELECT current_user, session_user;

Applicare RLS a ruoli specifici

Per impostazione predefinita, una policy si applica a PUBLIC (tutti i ruoli). È possibile limitarla a un ruolo specifico usando la clausola TO. È utile quando si desidera una policy per gli utenti normali e una diversa per un ruolo amministratore.

-- Policy only for the 'app_user' role
CREATE POLICY app_user_policy
  ON orders
  FOR SELECT
  TO app_user
  USING (owner = current_user);

-- Separate permissive policy for 'admin' role
CREATE POLICY admin_full_access
  ON orders
  FOR ALL
  TO admin
  USING (true)
  WITH CHECK (true);

Policy permissive e restrittive

Più policy sulla stessa tabella possono interagire in due modi:

  • PERMISSIVE (impostazione predefinita) — tutte le policy permissive vengono combinate tramite OR. Una riga è accessibile se una qualsiasi policy permissiva la consente.
  • RESTRICTIVE — le policy restrittive vengono combinate tramite AND con il risultato delle policy permissive. Una riga è accessibile solo se supera la policy restrittiva e almeno una policy permissiva.
-- Restrictive policy: block access to archived orders for everyone
CREATE POLICY no_archived_rows
  ON orders
  AS RESTRICTIVE
  FOR SELECT
  USING (amount > 0);

Ignorare RLS: BYPASSRLS e proprietari delle tabelle

Il proprietario della tabella e i superuser ignorano RLS per impostazione predefinita e vedono sempre tutte le righe. È possibile assegnare l'attributo BYPASSRLS a un ruolo che necessita di accesso senza restrizioni, senza renderlo superuser. Al contrario, è possibile obbligare il proprietario a rispettare RLS usando FORCE ROW LEVEL SECURITY.

-- Force the table owner to also obey RLS policies
ALTER TABLE orders FORCE ROW LEVEL SECURITY;

-- Grant BYPASSRLS to a trusted service account
ALTER ROLE service_account BYPASSRLS;

Modificare ed eliminare le policy

È possibile aggiornare una policy esistente con ALTER POLICY oppure rimuoverla completamente con DROP POLICY. Eliminare tutte le policy mentre RLS è ancora abilitato significa che nessuna riga sarà accessibile ai ruoli che non sono proprietari. Per rimuovere completamente RLS, disabilitarlo con ALTER TABLE.

-- Rename a policy
ALTER POLICY orders_owner_policy ON orders
  RENAME TO user_isolation_policy;

-- Update the USING expression
ALTER POLICY user_isolation_policy ON orders
  USING (owner = current_user AND amount >= 0);

-- Remove a policy
DROP POLICY admin_full_access ON orders;

-- Disable RLS entirely on the table
ALTER TABLE orders DISABLE ROW LEVEL SECURITY;

Schema reale: isolamento dei dati multi-tenant

Un modello RLS comune nelle applicazioni SaaS multi-tenant consiste nel memorizzare una colonna tenant_id in ogni tabella e nell'usare una variabile a livello di sessione (set_config) per passare l'identificativo del tenant al momento della connessione. La policy confronta quindi il tenant_id di ogni riga con il valore di questa impostazione.

-- Table with tenant isolation column
CREATE TABLE documents (
  id         SERIAL PRIMARY KEY,
  tenant_id  TEXT NOT NULL,
  title      TEXT
);

ALTER TABLE documents ENABLE ROW LEVEL SECURITY;

-- Policy reads the tenant from a session variable
CREATE POLICY tenant_isolation
  ON documents
  FOR ALL
  USING       (tenant_id = current_setting('app.tenant_id'))
  WITH CHECK  (tenant_id = current_setting('app.tenant_id'));

-- Application sets the variable before running queries
SELECT set_config('app.tenant_id', 'tenant_42', true);

-- Now only tenant_42 documents are visible
SELECT * FROM documents;

Verifica delle conoscenze

Verifichi la Sua comprensione delle policy di Row-Level Security in PostgreSQL.

Riepilogo della lezione

In questa lezione ha imparato come Row-Level Security fornisca un filtraggio automatico delle righe, basato su policy, direttamente a livello di database:

  • Abilitare RLS su una tabella con ALTER TABLE ... ENABLE ROW LEVEL SECURITY.
  • Usare CREATE POLICY con una clausola USING per filtrare le righe leggibili e una clausola WITH CHECK per convalidare le righe scritte.
  • Limitare l'ambito delle policy a comandi specifici (SELECT, INSERT, UPDATE, DELETE, ALL) e a ruoli specifici usando la clausola TO.
  • Combinare policy PERMISSIVE (logica OR) e RESTRICTIVE (logica AND) per ottenere un controllo degli accessi a più livelli.
  • I proprietari delle tabelle e i superuser ignorano RLS per impostazione predefinita; usare FORCE ROW LEVEL SECURITY per modificare questo comportamento.
  • Il modello multi-tenant che usa current_setting() è una potente applicazione reale di RLS.

RLS è il modo standard per applicare l'isolamento dei dati in modo pulito e coerente, senza distribuire clausole WHERE in ogni query dell'applicazione.

Domande Frequenti

La lezione «Policy di sicurezza a livello di riga» è gratuita?

Sì — il testo completo di «Policy di sicurezza a livello di riga» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso SQL Academy, passa a CoddyKit PRO. Il corso SQL Academy include 4 lezioni in totale.

Cosa imparerò in «Policy di sicurezza a livello di riga»?

Filtri automaticamente le righe in base all'utente Eserciti SQL Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare SQL Academy?

Non è richiesta alcuna esperienza precedente. SQL Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Policy di sicurezza a livello di riga»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione SQL Academy?

Sì. Ogni lezione SQL Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Ruoli e privilegi
  2. Policy di sicurezza a livello di riga
  3. Permessi a livello di colonna
  4. Verificare gli accessi
← Torna a SQL Academy