Proteggere gli Agenti AI con gli strumenti MCP di Laravel

Dare a un agente AI l'accesso alla tua app tramite MCP è come consegnare a qualcuno un mazzo di chiavi. Se non stabilisci delle regole, potrebbe aprire le porte sbagliate.

Recentemente ho sviluppato degli strumenti MCP per un'app Laravel multi-tenant. Avevo un unico obiettivo: permettere all'agente di gestire l'app senza consentirgli di vedere i dati di qualcun altro.

Il problema con gli strumenti MCP

Ogni strumento MCP è un endpoint. Un agente chiama uno strumento e il tuo server esegue il codice. In un'app multi-tenant, ogni strumento deve rispondere a due domande:

  • Sei autorizzato a farlo?
  • Sei autorizzato a farlo in questa specifica organizzazione?

Se ne trascuri una, causi una fuga di dati.

Perché il multi-tenancy standard fallisce in questo caso

In una normale applicazione web, hai delle sessioni. Usi gli "global scopes" per filtrare i dati in base all'ID dell'organizzazione. Funziona perché la "organizzazione corrente" è sempre presente nella sessione.

Gli strumenti MCP non usano le sessioni. Usano i token. Non c'è un middleware che imposti il contesto del tenant. Se ti affidi a uno scope globale che cerca una sessione, non troverà nulla. Di conseguenza, potrebbe restituire ogni singola riga del tuo database. Questa è una fuga di dati silenziosa.

La soluzione: filtraggio esplicito

Non affidarti mai a uno scope ambientale con l'autenticazione tramite token. Filtra esplicitamente ogni volta.

Ho creato un singolo trait per gestire questa operazione:

trait ResolvesOrgEvents
{
    protected function resolveOrgEvent(Authenticatable $user, string $uuid): ?Event
    {
        if (empty($user->organization_id)) {
            return null;
        }

        return Event::query()
            ->withOrganization($user->organization_id)
            ->where('uuid', $uuid)
            ->first();
    }
}

Questo approccio segue quattro regole:

  • Usa gli UUID: Non usare mai ID auto-incrementanti. Gli agenti non dovrebbero essere in grado di indovinare gli ID cambiando un numero.
  • Unica fonte di verità: Il filtro dell'organizzazione risiede in un unico trait. Ogni strumento lo utilizza.
  • Riutilizza i permessi: Non inventare nuovi permessi per gli agenti. Usa le stesse stringhe di permessi utilizzate dalla tua web app. Questo evita che l'agente abbia più potere dell'utente umano.
  • Segnala gli effetti collaterali: Usa delle annotazioni per indicare se uno strumento è di sola lettura o abilitato alla scrittura.

Testare i confini

Devi testare il percorso negativo. Non limitarti a testare se lo strumento funziona. Testa che un utente dell'Organizzazione A non possa vedere i dati dell'Organizzazione B.

Se un agente tenta di accedere a un UUID di un altro tenant, lo strumento dovrebbe restituire "not found". Non dovrebbe comunicare all'agente che i dati esistono, ma appartengono a qualcun altro.

Tratta ogni strumento AI come un endpoint non attendibile. La disciplina è l'unico modo per mantenere i tuoi dati al sicuro.

Fonte: https://dev.to/nasrulhazim/giving-an-ai-agent-the-keys-without-giving-it-the-building-rbac-org-scoped-mcp-tools-in-laravel-43oi