MCP en una empresa: el problema no és connectar-lo, és decidir quins permisos donar-li

Anàlisi crítica sobre permisos, abast, auditoria i límits quan connectes agents d'IA a sistemes reals amb MCP.

Cover for MCP en una empresa: el problema no és connectar-lo, és decidir quins permisos donar-li

A l’article anterior sobre MCP vs Skills explicava què és cada cosa i quan té sentit fer servir una o l’altra. Allà ja avançava que la part de seguretat mereixia un article a part. Aquest és aquell article.

El que estic veient a empreses em preocupa. Equips que connecten agents d’IA a bases de dades de producció, a repos de codi, a sistemes de ticketing, a eines d’infraestructura… i quan preguntes “quins permisos té aquest agent”, la resposta acostuma a ser un silenci incòmode o un “els mateixos que l’usuari que el va configurar”. Això és un problema seriós.

Connectar un MCP és fàcil. Decidir què pot fer, què no pot fer, qui ho revisa i què passa quan s’equivoca és el que realment importa. I és el que gairebé ningú està plantejant.


El principi de mínim privilegi aplicat a agents

El principi de mínim privilegi no és nou. Qualsevol enginyer amb experiència en seguretat el coneix: un component del sistema només ha de tenir accés als recursos que necessita estrictament per complir la seva funció. Ni més, ni menys.

Amb agents d’IA connectats via MCP, aquest principi es torna més important i més difícil d’aplicar alhora. Més important perquè l’agent pot prendre decisions impredictibles. Més difícil perquè l’abast del que “necessita” no sempre està clar.

Un agent no és un script. Un script fa exactament el que li programes. Un agent interpreta instruccions i decideix quines eines fer servir i com. Aquesta diferència canvia completament el perfil de risc.

Quan dones a un script accés de lectura a una base de dades, saps exactament quines queries executarà. Quan dones el mateix accés a un agent, no ho saps. Pot decidir fer un SELECT * d’una taula amb dades sensibles perquè li ha semblat rellevant per respondre una pregunta. No per malícia, sinó perquè no té el concepte de “això no ho hauries de veure”.


Casos que t’haurien de treure la son

Llistaré situacions que he vist o que m’han descrit col·legues. Totes reals. Totes prevenibles.

Agent amb accés a la base de dades de producció

El cas clàssic. Algú configura un MCP que connecta l’agent amb PostgreSQL perquè pugui “consultar dades i generar informes”. Li dóna credencials d’un usuari amb permisos amplis perquè “només llegirà”.

El problema: l’agent rep una petició ambigua, construeix una query que fa un full table scan de la taula d’usuaris (amb emails, noms, telèfons), i retorna aquestes dades en una resposta que queda registrada a l’historial del xat. Ara tens dades personals exposades en un sistema que probablement no compleix la política de retenció de dades de la teva empresa.

Variant encara pitjor: li vas donar permisos d’escriptura “per si necessita crear taules temporals”. L’agent interpreta malament una instrucció i executa un UPDATE que no tocava.

Agent que pot crear Pull Requests

Connectar un agent al repo de codi via MCP perquè generi PRs sona productiu. Però si l’agent pot crear PRs directament a la branca principal, sense revisió, estàs delegant control del teu codi a un sistema que no entén el context complet de la teva arquitectura.

He vist agents que generen codi que passa els tests però introdueix dependències insegures, canvia contractes d’API sense avisar, o sobreescriu configuració de seguretat perquè “ha simplificat” el codi.

Agent amb accés a infraestructura

Aquest és el més perillós. Un MCP que connecta l’agent amb Kubernetes, AWS, o la teva eina de CI/CD. “Perquè pugui revisar logs i diagnosticar problemes”. L’agent, intentant resoldre un issue, escala un deployment, canvia una variable d’entorn o reinicia un servei.

No és ciència-ficció. És el que passa quan dones eines potents a un sistema que optimitza per “resoldre la petició de l’usuari” sense entendre les conseqüències operacionals.


Matriu de permisos: què hauria de poder fer cada eina

Abans de connectar qualsevol MCP, hauries de tenir una matriu clara de permisos. Això no és burocràcia, és higiene bàsica. Una taula com aquesta, adaptada al teu context:

Eina MCPLecturaEscripturaScopeRequereix aprovacióDades sensibles
Base de dades (prod)Només vistes predefinidesNoTaules no-PIINoSí, restringir
Base de dades (staging)Només taules tempSchema específicNoNo
Repositori GitNomés branques feature/Repos no-infraSí (PR review)No
Jira / LinearLectura de ticketsCrear comentarisProjecte específicNoNo
Jira / Linear-Crear/moure ticketsProjecte específicNo
SlackLectura canals públicsEnviar missatgesCanals designatsPossible
AWS / InfraNomés lectura de logsNoRead-only roleNoPossible (logs)
CI/CDVeure estat de pipelinesNo-NoNo
CI/CD-Trigger/retry buildsRepos específicsNo

Si no pots omplir aquesta taula per a cada MCP que tens connectat, tens un problema de governança. No d’IA, de governança.

Algunes regles que aplico sempre:

1. Producció és només lectura, i amb scope limitat. Mai escriptura. Sense excepcions. Si l’agent necessita modificar alguna cosa a producció, genera una proposta que un humà executa.

2. Les dades personals no passen per l’agent. Si una taula té PII (dades personals), l’agent no hauria de poder-hi accedir. Fes servir vistes que emmascarin o excloguin aquests camps.

3. L’escriptura sempre requereix aprovació. Qualsevol acció que modifiqui estat (crear un ticket, enviar un missatge, fer un commit) passa per revisió humana.


Logs i auditoria: què va fer, quan, amb quines dades

Si un agent interactua amb els teus sistemes i no tens logs detallats d’aquesta interacció, estàs volant a cegues. No n’hi ha prou amb saber que “l’agent va fer servir el MCP de base de dades”. Necessites saber:

  • Quina eina MCP va fer servir exactament.
  • Quins paràmetres va enviar (la query, la comanda, el contingut).
  • Quina resposta va rebre (i si contenia dades sensibles).
  • Qui va iniciar la petició (quin usuari va demanar a l’agent que fes allò).
  • Quan va passar.
  • Quant va trigar.

Un exemple d’estructura de log per a auditoria:

{
  "timestamp": "2026-05-18T14:23:45Z",
  "event_type": "mcp_tool_call",
  "agent_id": "support-agent-01",
  "user_id": "user-4521",
  "session_id": "sess-abc123",
  "tool": {
    "name": "database_query",
    "mcp_server": "postgres-readonly",
    "parameters": {
      "query": "SELECT order_id, status, created_at FROM orders WHERE user_id = $1",
      "params": ["user-4521"]
    }
  },
  "result": {
    "status": "success",
    "rows_returned": 3,
    "execution_time_ms": 45,
    "contains_pii": false
  },
  "context": {
    "user_prompt": "¿Cuál es el estado de mis últimos pedidos?",
    "conversation_turn": 2
  }
}

Aquests logs no són opcionals. Són la teva única manera de:

  • Investigar incidències: si alguna cosa surt malament, necessites reconstruir exactament què va fer l’agent.
  • Detectar anomalies: un agent que de sobte fa 500 queries per minut quan el normal són 10 és un senyal d’alerta.
  • Complir regulació: GDPR, SOC2, ISO 27001… tots requereixen traçabilitat d’accés a dades.
  • Millorar el sistema: sense dades d’ús real, no pots optimitzar ni els prompts ni els permisos.

Alertes que hauries de tenir

No n’hi ha prou amb registrar. Necessites alertes actives:

alertas_mcp:
  - nombre: "Volumen anómalo de llamadas"
    condicion: "calls_per_minute > 50 para un mismo agent_id"
    severidad: warning

  - nombre: "Acceso a datos sensibles"
    condicion: "result.contains_pii == true"
    severidad: critical

  - nombre: "Error rate elevado"
    condicion: "error_rate > 20% en ventana de 5 minutos"
    severidad: warning

  - nombre: "Tool no autorizado"
    condicion: "tool.name not in allowed_tools[agent_id]"
    severidad: critical

  - nombre: "Latencia excesiva"
    condicion: "execution_time_ms > 10000"
    severidad: info

Human-in-the-loop: quan obligar revisió humana

No tot necessita aprovació humana. Si cada acció de l’agent requereix que algú premi el botó d‘“acceptar”, perds tot el valor de l’automatització. La clau és definir bé la frontera.

La meva regla general: les accions reversibles i de baix impacte poden ser automàtiques. Les accions irreversibles o d’alt impacte requereixen aprovació.

A la pràctica:

Automàtic (sense aprovació)

  • Consultar l’estat d’un ticket.
  • Llegir logs d’un servei.
  • Buscar documentació interna.
  • Generar un esborrany de resposta.
  • Consultar mètriques d’un dashboard.

Requereix aprovació humana

  • Crear o modificar un ticket.
  • Enviar un missatge a un canal de Slack o un email.
  • Crear una Pull Request o fer commit.
  • Modificar qualsevol dada en qualsevol entorn.
  • Executar accions en infraestructura.
  • Accedir a dades que podrien contenir PII.

Requereix aprovació + segona revisió

  • Qualsevol acció a producció que modifiqui estat.
  • Desplegaments.
  • Canvis en configuració de seguretat.
  • Accés a secrets o credencials.

La pregunta no és “confio en la IA”. La pregunta és “si això surt malament, quin és l’impacte i quant tardo a revertir-ho”. Si la resposta és “alt impacte i difícil de revertir”, poses un humà al davant. Sempre.

El flux típic que implemento:

Usuari demana alguna cosa a l'agent
    → Agent decideix quina tool fer servir
    → L'acció requereix aprovació?
        → NO: executar i registrar
        → SÍ: generar proposta
            → Notificar el reviewer (Slack, email, dashboard)
            → Esperar aprovació (amb timeout)
                → Aprovat: executar i registrar
                → Rebutjat: registrar i notificar l'usuari
                → Timeout: registrar com a "no executat"

Implementació pràctica: middleware de permisos

Una forma efectiva d’implementar-ho és amb un middleware que intercepta cada crida MCP abans que arribi al servidor:

class McpPermissionMiddleware:
    def __init__(self, policy: PermissionPolicy, audit_log: AuditLogger):
        self.policy = policy
        self.audit_log = audit_log

    async def intercept(self, tool_call: ToolCall, context: AgentContext) -> ToolResult:
        # 1. Verificar que el agente tiene permiso para usar esta herramienta
        permission = self.policy.check(
            agent_id=context.agent_id,
            tool_name=tool_call.name,
            action_type=tool_call.action_type,
            parameters=tool_call.parameters
        )

        if permission == Permission.DENIED:
            self.audit_log.record_denied(tool_call, context)
            raise PermissionDeniedError(
                f"Agent {context.agent_id} no tiene permiso para {tool_call.name}"
            )

        if permission == Permission.REQUIRES_APPROVAL:
            approval = await self.request_human_approval(tool_call, context)
            if not approval.granted:
                self.audit_log.record_rejected(tool_call, context, approval)
                return ToolResult.rejected("Acción rechazada por reviewer")

        # 2. Ejecutar la llamada
        result = await self.execute_tool(tool_call)

        # 3. Verificar el resultado (¿contiene datos sensibles?)
        if self.policy.requires_pii_check(tool_call.name):
            result = self.sanitize_pii(result)

        # 4. Loguear todo
        self.audit_log.record_execution(tool_call, context, result)

        return result

La política de permisos es defineix en un fitxer de configuració que viu al repo, versionat i revisable:

# mcp-permissions.yaml
agents:
  support-agent:
    allowed_tools:
      - name: "database_query"
        scope: "readonly"
        allowed_tables: ["orders", "products", "order_status"]
        blocked_tables: ["users", "payments", "credentials"]
        max_rows: 100
      - name: "jira_read"
        scope: "project:SUPPORT"
      - name: "jira_comment"
        scope: "project:SUPPORT"
        requires_approval: true
    blocked_tools:
      - "git_*"
      - "infra_*"
      - "deploy_*"

  dev-assistant:
    allowed_tools:
      - name: "git_read"
        scope: "repos:backend-*"
      - name: "git_create_pr"
        scope: "repos:backend-*"
        requires_approval: true
        target_branches_blocked: ["main", "release/*"]
      - name: "database_query"
        scope: "readonly"
        environment: "staging"
    blocked_tools:
      - "infra_*"
      - "deploy_*"

El que ningú t’explica: el problema organitzatiu

La tecnologia és la part fàcil. El realment difícil és el costat organitzatiu:

Qui defineix els permisos. A la majoria d’empreses no hi ha un rol clar que sigui responsable dels permisos dels agents d’IA. No és l’equip de seguretat (no entenen el context d’ús). No és l’equip de producte (no entenen les implicacions tècniques). No és el desenvolupador que configura el MCP (no té visió global).

La meva recomanació: l’equip de plataforma o enginyeria defineix les polítiques base, l’equip de seguretat les revisa, i l’equip de producte defineix els casos d’ús. Tots tres junts.

Qui revisa les aprovacions. Si poses human-in-the-loop però ningú revisa les peticions, l’agent es queda bloquejat i els usuaris es frustren. Necessites un procés clar: qui revisa, en quin horari, amb quin SLA, i què passa quan no hi ha ningú disponible.

Com evolucionen els permisos. Els permisos que defineixes avui no valen per sempre. Els casos d’ús canvien, els equips creixen, els agents es tornen més capaços. Necessites una revisió periòdica. Jo suggereixo trimestral com a mínim.


Checklist abans de connectar un MCP a un sistema real

Abans de donar l’OK a qualsevol integració MCP a la teva empresa, passa per aquesta llista:

  1. Existeix una matriu de permisos documentada per a aquest agent.
  2. L’accés a producció és només de lectura (sense excepcions).
  3. Les dades personals estan excloses o emmascarades.
  4. Hi ha logs d’auditoria per a cada crida MCP.
  5. Hi ha alertes configurades per a anomalies.
  6. Les accions d’escriptura requereixen aprovació humana.
  7. Hi ha un procés clar per revocar permisos d’emergència.
  8. Els permisos estan versionats al repositori.
  9. Hi ha un responsable definit per revisar els permisos periòdicament.
  10. S’ha fet una prova de “què passa si l’agent fa el pitjor possible amb aquests permisos”.

Aquest últim punt és clau. Abans de donar accés, pregunta’t: si aquest agent es torna boig i fa servir tots els permisos que té de la pitjor manera possible, què és el màxim que pot trencar. Si la resposta t’espanta, redueix els permisos.


No és paranoia, és enginyeria

Res del que he descrit aquí és paranoia ni anti-IA. Al contrari: l’única manera que la integració d’agents a empreses escali de forma sostenible és amb controls seriosos. Les empreses que avui estan connectant agents sense governança tindran incidències. Algunes ja les estan tenint.

La IA a l’empresa no és un playground. És infraestructura productiva que interactua amb dades reals, clients reals i diners reals. Tracta-la com a tal.

OshyTech

Enginyeria backend i de dades orientada a sistemes escalables, automatització i IA.

Navegació

Copyright 2026 OshyTech. Tots els drets reservats