{"id":3382,"date":"2026-08-20T16:55:16","date_gmt":"2026-08-20T14:55:16","guid":{"rendered":"https:\/\/darioiannascoli.it\/blog\/plesk-ai-agent-sandboxing-resource-quotas-2026-isolation-cost-attribution\/"},"modified":"2026-08-20T16:55:16","modified_gmt":"2026-08-20T14:55:16","slug":"plesk-ai-agent-sandboxing-resource-quotas-2026-isolation-cost-attribution","status":"publish","type":"post","link":"https:\/\/darioiannascoli.it\/blog\/plesk-ai-agent-sandboxing-resource-quotas-2026-isolation-cost-attribution\/","title":{"rendered":"Come Implementare Plesk AI Agent Sandboxing e Resource Quotas 2026: La Mia Procedura LLM Workload Isolation, Token Cost Attribution e Runaway Process Prevention"},"content":{"rendered":"<p>Quando ho iniziato a gestire workload LLM multi-tenant su Plesk quest&#8217;anno, ho capito subito che l&#8217;isolamento non \u00e8 una questione di buone pratiche\u2014\u00e8 una questione di sopravvivenza operativa. Un singolo agente AI in runaway pu\u00f2 consumare tutti i token di budget di un mese in poche ore, o pi\u00f9 ancora, un agente compromesso pu\u00f2 compromettere l&#8217;intero stack. In questa guida vi mostro come ho configurato sandboxing real, resource quotas e cost attribution su Plesk per proteggere il controllo plane e i tenant.<\/p>\n<h2>Perch\u00e9 Plesk Necessita di AI Sandboxing Oggi<\/h2>\n<p>La situazione \u00e8 cambiata radicalmente. <cite>Pi\u00f9 della met\u00e0 degli agenti AI aziendali gira oggi senza supervisione di sicurezza o logging, mentre 1 su 8 delle violazioni AI riportate coinvolge sistemi agentici<\/cite>. Nel mio ambiente Plesk multi-tenant, questo significa che un agente mal configurato di un tenant pu\u00f2:<\/p>\n<ul>\n<li>Consumare memoria dell&#8217;host e causare OOM-kill dei servizi di altri tenant<\/li>\n<li>Effettuare richieste API illimitate a modelli LLM, spike di costi imprevisti<\/li>\n<li>Esfiltrare dati attraverso canali di rete non controllati (se non bloccati)<\/li>\n<li>Entrare in loop infiniti di ragionamento e autoreplica<\/li>\n<\/ul>\n<p>Ho scoperto che <cite>un sandbox ben progettato consiste di quattro layer: isolamento del calcolo, boundary del filesystem, controlli di rete e limiti di storage<\/cite>. Plesk Control Plane gestisce bene il multi-tenancy a livello di account, ma per i workload AI serve una difesa aggiuntiva.<\/p>\n<h2>Architettura di Isolamento: Container vs MicroVM in Plesk<\/h2>\n<p>All&#8217;inizio, ho provato a eseguire agenti LLM direttamente in PHP\/Node.js LiteSpeed senza isolamento. Non durato pi\u00f9 di 72 ore: un agente entrato in loop con Claude 3 ha mandato 50 GB di log. Serve isolamento vero.<\/p>\n<p>In Plesk, avete due opzioni:<\/p>\n<h3>Approccio 1: Container Docker via Plesk Extension (Standard)<\/h3>\n<p><cite>I container standard condividono il kernel dell&#8217;host e non sono isolamento sufficiente per workload agentici che eseguono codice generato da LLM o chiamano tool esterni<\/cite>. Tuttavia, se combinate container Docker con cgroup limits ristretti, potete ottenere isolamento reasonevole per workload trusted. \u00c8 quello che uso per il 70% dei tenant.<\/p>\n<p><strong>Vantaggi:<\/strong><\/p>\n<ul>\n<li>Density alta su host singolo<\/li>\n<li>Integrazione nativa con Plesk (via Custom Containers o Plesk Extensions)<\/li>\n<li>Startup rapido (&lt;500ms)<\/li>\n<li>Gestione facile di rete e storage<\/li>\n<\/ul>\n<h3>Approccio 2: Firecracker MicroVMs (Massimo Isolamento)<\/h3>\n<p><cite>I tre approcci di isolamento principale sono microVM (Firecracker, Kata Containers), gVisor (kernel user-space), e container hardened. I microVM forniscono l&#8217;isolamento pi\u00f9 forte con kernel dedicati per workload, gVisor offre intercettazione syscall senza VM complete, e container funzionano solo per codice trusted<\/cite>.<\/p>\n<p>Per agenti che eseguono codice non-trusted o fanno tool calling su endpoint esterni, <cite>applicate limiti di risorsa per-sandbox: CPU, memoria, disk quota, larghezza di banda. Usate contesti di esecuzione ephemeral\u2014demolite dopo il completamento di ogni task. Un&#8217;astrazione transazionale di SandboxClaim permette al orchestrator di agenti di richiedere un ambiente di esecuzione senza conoscere i dettagli del backend di isolamento<\/cite>.<\/p>\n<p>Nel mio setup, uso Firecracker per il 30% di tenant che richiedono rigorosit\u00e0 massima. Costano pi\u00f9 CPU, ma il rischio scende praticamente a zero.<\/p>\n<h2>Step 1: Configurare Resource Quotas su Plesk Control Plane<\/h2>\n<p>Cominciate dalla UI di Plesk. Non potete controllare ogni agente senza limiti a livello di tenant.<\/p>\n<h3>Limiti di Memoria e CPU via Plesk API\/CLI<\/h3>\n<p>Accedo all&#8217;account Plesk di un tenant (es: tenant-ai-1) e setto limiti via RPC:<\/p>\n<p><strong>Configurazione Resource Quota (pseudocodice XML-RPC):<\/strong><\/p>\n<p>&#8220;`<br \/>\nplesk bin subscription update tenant-ai-1<br \/>\n  -cpu-limit 2000m<br \/>\n  -memory-limit 4096Mi<br \/>\n  -ephemeral-storage-limit 20Gi<br \/>\n&#8220;`<\/p>\n<p>Se usate Plesk con Docker extension, potete anche limitare a livello di container via docker-compose.yml:<\/p>\n<p>&#8220;`yaml<br \/>\nservices:<br \/>\n  ai-agent:<br \/>\n    image: python:3.11-slim<br \/>\n    entrypoint: [&#8220;python&#8221;, &#8220;-m&#8221;, &#8220;agentic_framework&#8221;]<br \/>\n    resources:<br \/>\n      limits:<br \/>\n        cpus: &#8216;2&#8217;<br \/>\n        memory: 4G<br \/>\n      reservations:<br \/>\n        cpus: &#8216;1&#8217;<br \/>\n        memory: 2G<br \/>\n    ulimits:<br \/>\n      nproc: 512<br \/>\n      nofile: 4096<br \/>\n    environment:<br \/>\n      &#8211; OTEL_SDK_DISABLED=false<br \/>\n      &#8211; TOKEN_BUDGET=100000<br \/>\n&#8220;`<\/p>\n<p><cite>Limiti CPU: prevenite l&#8217;esaurimento del calcolo impostando share CPU massimi e throttling dei processi runaway. Limiti memoria: bloccate memory bomb definendo limiti hard che terminano processi che superano l&#8217;allocazione. Quote disco: bloccate attacchi di storage limitando l&#8217;uso del filesystem e rate-limiting delle operazioni I\/O. Larghezza di banda rete: prevenite esfiltrazioni dati con rate-limiting del traffico outbound e monitoraggio di pattern inusuali<\/cite>.<\/p>\n<h2>Step 2: Implementare Cost Attribution per Token Consumption<\/h2>\n<p>Senza tracking granulare dei token, i costi diventano invisibili. Ho configurato un sistema a tre livelli:<\/p>\n<h3>Livello 1: Tagging di Metadati all&#8217;Ingresso<\/h3>\n<p><cite>Il tagging di metadati \u00e8 il meccanismo che rende l&#8217;attribuzione funciona su scala. Ogni chiamata API LLM dovrebbe portare un set coerente di coppie chiave-valore identificando l&#8217;origine. Il tagging parziale \u00e8 la ragione principale per cui i dati di attribuzione diventano inaffidabili. L&#8217;applicazione principale attacca i tag, ma microservizi interni o job in background no, creando gap che rendono i dati inutili per scopi di governance. Lo standard di tagging dovrebbe essere forzato a livello di infrastruttura attraverso il proxy layer, piuttosto che lasciato ai developer di implementare service per service<\/cite>.<\/p>\n<p>Nel mio proxy LLM in Plesk (che intercepta tutte le richieste a OpenAI\/Anthropic\/Bedrock), aggiungo header standardizzati:<\/p>\n<p>&#8220;`python<br \/>\n# llm_proxy.py &#8211; middleware che corre su Plesk Application Server<br \/>\nimport httpx<br \/>\nfrom datetime import datetime<br \/>\nfrom uuid import uuid4<\/p>\n<p>class LLMProxyMiddleware:<br \/>\n    def __init__(self, app):<br \/>\n        self.app = app<\/p>\n<p>    async def __call__(self, scope, receive, send):<br \/>\n        if scope[&#8216;type&#8217;] != &#8216;http&#8217;:<br \/>\n            await self.app(scope, receive, send)<br \/>\n            return<\/p>\n<p>        # Extract tenant\/user context<br \/>\n        tenant_id = scope[&#8216;headers&#8217;].get(b&#8217;x-plesk-tenant&#8217;, b&#8217;unknown&#8217;).decode()<br \/>\n        user_id = scope[&#8216;headers&#8217;].get(b&#8217;x-plesk-user&#8217;, b&#8217;unknown&#8217;).decode()<br \/>\n        feature_name = scope[&#8216;headers&#8217;].get(b&#8217;x-feature&#8217;, b&#8217;generic-ai&#8217;).decode()<\/p>\n<p>        # Inject consistent tagging<br \/>\n        request_id = str(uuid4())<br \/>\n        trace_context = {<br \/>\n            &#8216;request_id&#8217;: request_id,<br \/>\n            &#8216;tenant_id&#8217;: tenant_id,<br \/>\n            &#8216;user_id&#8217;: user_id,<br \/>\n            &#8216;feature_name&#8217;: feature_name,<br \/>\n            &#8216;timestamp&#8217;: datetime.utcnow().isoformat(),<br \/>\n            &#8216;workload_type&#8217;: &#8216;agentic_ai&#8217;  # or &#8216;rag&#8217;, &#8216;fine_tuning&#8217;<br \/>\n        }<\/p>\n<p>        # Store in context-local for logging<br \/>\n        scope[&#8216;ai_trace&#8217;] = trace_context<\/p>\n<p>        await self.app(scope, receive, send)<br \/>\n&#8220;`<\/p>\n<h3>Livello 2: Logging di Ogni Transazione LLM<\/h3>\n<p><cite>Quattro Layer di Token Importano: Ogni richiesta consuma token di prompt, tool, memoria e risposta. Aggregare in un bucket singolo input\/output nasconde dove lo spend va veramente e previene ottimizzazione mirata<\/cite>.<\/p>\n<p>Ho implementato logging strutturato via OpenTelemetry:<\/p>\n<p>&#8220;`python<br \/>\nimport json<br \/>\nfrom opentelemetry import trace, metrics<br \/>\nfrom opentelemetry.exporter.jaeger.thrift import JaegerExporter<br \/>\nfrom opentelemetry.sdk.trace import TracerProvider<br \/>\nfrom opentelemetry.sdk.trace.export import BatchSpanProcessor<\/p>\n<p>tracer = trace.get_tracer(__name__)<\/p>\n<p>def log_llm_cost(tenant_id, model, prompt_tokens, completion_tokens, cache_read_tokens, cache_creation_tokens):<br \/>\n    &#8220;&#8221;&#8221;Log cost attribution con quattro dimensioni di token&#8221;&#8221;&#8221;<\/p>\n<p>    span = tracer.start_as_current_span(f&#8221;llm.cost.attribution.{model}&#8221;)<br \/>\n    span.set_attribute(&#8220;tenant_id&#8221;, tenant_id)<br \/>\n    span.set_attribute(&#8220;model&#8221;, model)<br \/>\n    span.set_attribute(&#8220;prompt_tokens&#8221;, prompt_tokens)<br \/>\n    span.set_attribute(&#8220;completion_tokens&#8221;, completion_tokens)<br \/>\n    span.set_attribute(&#8220;cache_read_tokens&#8221;, cache_read_tokens)  # Billing ridotto<br \/>\n    span.set_attribute(&#8220;cache_creation_tokens&#8221;, cache_creation_tokens)<\/p>\n<p>    # Calcolo costo netto (assumendo OpenAI Pricing)<br \/>\n    cost = (<br \/>\n        (prompt_tokens * 0.0005) +  # $0.0005 per 1K input<br \/>\n        (completion_tokens * 0.0015) +  # $0.0015 per 1K output<br \/>\n        (cache_read_tokens * 0.00009) +  # 90% sconto su cache read<br \/>\n        (cache_creation_tokens * 0.0005)  # Stesso prezzo di input per cache write<br \/>\n    ) \/ 1000<\/p>\n<p>    span.set_attribute(&#8220;estimated_cost_usd&#8221;, cost)<br \/>\n    span.end()<\/p>\n<p>    # Persistenza in backend di metriche<br \/>\n    return {<br \/>\n        &#8220;tenant_id&#8221;: tenant_id,<br \/>\n        &#8220;model&#8221;: model,<br \/>\n        &#8220;tokens_breakdown&#8221;: {<br \/>\n            &#8220;prompt&#8221;: prompt_tokens,<br \/>\n            &#8220;completion&#8221;: completion_tokens,<br \/>\n            &#8220;cache_read&#8221;: cache_read_tokens,<br \/>\n            &#8220;cache_creation&#8221;: cache_creation_tokens<br \/>\n        },<br \/>\n        &#8220;cost_usd&#8221;: cost<br \/>\n    }<br \/>\n&#8220;`<\/p>\n<h3>Livello 3: Budget Enforcement Automatizzato<\/h3>\n<p><cite>Un sistema di governance a quattro tier forza budget a livello di virtual key, team, customer, e configurazione di provider. Questo non \u00e8 monitoraggio passivo; enforcement attivo di limiti di spend e reiezione di richieste che supererebbero budget configurati. Le virtual key servono come entit\u00e0 primaria di governance, abilitando permessi di accesso per-consumer, budget e rate limit<\/cite>.<\/p>\n<p>Nel mio setup Plesk, ogni tenant riceve una &#8220;virtual key&#8221; con budget giornaliero\/mensile:<\/p>\n<p>&#8220;`python<br \/>\nclass TokenBudgetGate:<br \/>\n    def __init__(self, redis_client, tenant_id, daily_budget_usd=50, monthly_budget_usd=1000):<br \/>\n        self.redis = redis_client<br \/>\n        self.tenant_id = tenant_id<br \/>\n        self.daily_budget = daily_budget_usd<br \/>\n        self.monthly_budget = monthly_budget_usd<\/p>\n<p>    def check_and_debit(self, estimated_cost_usd):<br \/>\n        &#8220;&#8221;&#8221;Verifica budget prima di autorizzare chiamata LLM&#8221;&#8221;&#8221;<br \/>\n        today = datetime.utcnow().date().isoformat()<br \/>\n        month = datetime.utcnow().strftime(&#8216;%Y-%m&#8217;)<\/p>\n<p>        daily_key = f&#8221;tenant:{self.tenant_id}:spend:daily:{today}&#8221;<br \/>\n        monthly_key = f&#8221;tenant:{self.tenant_id}:spend:monthly:{month}&#8221;<\/p>\n<p>        daily_spend = float(self.redis.get(daily_key) or 0)<br \/>\n        monthly_spend = float(self.redis.get(monthly_key) or 0)<\/p>\n<p>        if daily_spend + estimated_cost_usd &gt; self.daily_budget:<br \/>\n            raise BudgetExceededError(<br \/>\n                f&#8221;Daily budget ${self.daily_budget} exceeded. Current: ${daily_spend}, Requested: ${estimated_cost_usd}&#8221;<br \/>\n            )<\/p>\n<p>        if monthly_spend + estimated_cost_usd &gt; self.monthly_budget:<br \/>\n            raise BudgetExceededError(<br \/>\n                f&#8221;Monthly budget ${self.monthly_budget} exceeded. Current: ${monthly_spend}, Requested: ${estimated_cost_usd}&#8221;<br \/>\n            )<\/p>\n<p>        # Debit from budget<br \/>\n        self.redis.incrbyfloat(daily_key, estimated_cost_usd)<br \/>\n        self.redis.incrbyfloat(monthly_key, estimated_cost_usd)<br \/>\n        self.redis.expire(daily_key, 86400)  # TTL 24 ore<\/p>\n<p>        return True<br \/>\n&#8220;`<\/p>\n<h2>Step 3: Prevenire Runaway AI Processes<\/h2>\n<p>Il scenario peggiore \u00e8 un agente che entra in loop infinito di tool calling senza terminarsi mai. Ho implementato tre controlli in cascata:<\/p>\n<h3>Controllo 1: Timeout Globale e Depth Limit<\/h3>\n<p><cite>Nei domini AI, il comportamento runaway si manifesta tipicamente come loop infiniti di ragionamento, uso non autorizzato di tool, o esaurimento di risorse. Prevenire comportamento runaway richiede una strategia di difesa multi-layer: limiti ristretti di iterazione e timeout, circuit breaker basati su risorsa, controllo granulare di accesso ai tool (RBAC), e monitoraggio comportamentale continuo. Il recovery necessita revoca di accesso immediata e capacit\u00e0 di intervento human-in-the-loop (HITL)<\/cite>.<\/p>\n<p>&#8220;`python<br \/>\nfrom tenacity import Retrying, stop_after_attempt, stop_after_delay<\/p>\n<p>class SafeAgentExecutor:<br \/>\n    def __init__(self, agent, max_iterations=10, timeout_seconds=300, max_tokens=50000):<br \/>\n        self.agent = agent<br \/>\n        self.max_iterations = max_iterations<br \/>\n        self.timeout_seconds = timeout_seconds<br \/>\n        self.max_tokens = max_tokens<br \/>\n        self.iteration_count = 0<br \/>\n        self.token_count = 0<\/p>\n<p>    def execute(self, input_prompt):<br \/>\n        try:<br \/>\n            for attempt in Retrying(<br \/>\n                stop=stop_after_attempt(self.max_iterations),<br \/>\n                stop_after_delay=self.timeout_seconds<br \/>\n            ):<br \/>\n                with attempt:<br \/>\n                    self.iteration_count += 1<\/p>\n<p>                    # Controlla se agente \u00e8 entrato in loop<br \/>\n                    if self.iteration_count &gt; self.max_iterations:<br \/>\n                        raise RuntimeError(<br \/>\n                            f&#8221;Max iterations {self.max_iterations} exceeded. Agent may be in infinite loop.&#8221;<br \/>\n                        )<\/p>\n<p>                    # Esegui step agente<br \/>\n                    result = self.agent.agentic_step(input_prompt)<br \/>\n                    self.token_count += result.get(&#8216;tokens_consumed&#8217;, 0)<\/p>\n<p>                    # Controlla token budget<br \/>\n                    if self.token_count &gt; self.max_tokens:<br \/>\n                        raise RuntimeError(<br \/>\n                            f&#8221;Max token budget {self.max_tokens} exceeded. Current: {self.token_count}&#8221;<br \/>\n                        )<\/p>\n<p>                    return result<\/p>\n<p>        except TimeoutError:<br \/>\n            # Timeout triggerato &#8211; termina agente<br \/>\n            self.agent.kill(reason=&#8221;timeout_exceeded&#8221;)<br \/>\n            raise<br \/>\n&#8220;`<\/p>\n<h3>Controllo 2: Network Egress Allowlist Rigoroso<\/h3>\n<p><cite>Un agente sandboxato opera sotto un allowlist strettamente scoped. La guida pratica NVIDIA 2026 specifica controlli basati su HTTP proxy, IP e porta. In pratica, questo significa: definire esattamente quali API esterne l&#8217;agente \u00e8 permesso di chiamare, forzare via un proxy di egress o network policy, e allertare su tutto altro traffico outbound<\/cite>.<\/p>\n<p>Nel mio setup Plesk, uso iptables + custom proxy layer:<\/p>\n<p>&#8220;`bash<br \/>\n# iptables rule: blocca tutto per default, consenti solo allowlist<br \/>\niptables -I FORWARD 1 -i docker0 -o eth0 -j DROP  # Default deny<\/p>\n<p># Allowlist specifico per tenant<br \/>\niptables -I FORWARD 1 -i docker0 -o eth0 -d api.openai.com -j ACCEPT<br \/>\niptables -I FORWARD 1 -i docker0 -o eth0 -d api.anthropic.com -j ACCEPT<br \/>\niptables -I FORWARD 1 -i docker0 -o eth0 -d bedrock-runtime.us-east-1.amazonaws.com -j ACCEPT<\/p>\n<p># Block dataexfiltration su port 22, 25, 3306 (SSH, SMTP, MySQL)<br \/>\niptables -I FORWARD 1 -i docker0 -o eth0 -p tcp &#8211;dport 22 -j DROP<br \/>\niptables -I FORWARD 1 -i docker0 -o eth0 -p tcp &#8211;dport 25 -j DROP<br \/>\niptables -I FORWARD 1 -i docker0 -o eth0 -p tcp &#8211;dport 3306 -j DROP<br \/>\n&#8220;`<\/p>\n<h3>Controllo 3: Circuit Breaker per Anomalie<\/h3>\n<p><cite>I circuit breaker sono trigger automatizzati che fermano l&#8217;esecuzione quando soglie specifiche vengono superate<\/cite>. Implemento uno via Redis:<\/p>\n<p>&#8220;`python<br \/>\nclass AgentCircuitBreaker:<br \/>\n    def __init__(self, redis_client, tenant_id, threshold_cost_usd=100):<br \/>\n        self.redis = redis_client<br \/>\n        self.tenant_id = tenant_id<br \/>\n        self.threshold_cost = threshold_cost_usd<br \/>\n        self.circuit_key = f&#8221;circuit_breaker:{self.tenant_id}&#8221;<\/p>\n<p>    def check_anomaly(self, current_spend_usd, time_window_minutes=5):<br \/>\n        &#8220;&#8221;&#8221;Rileva spike anomali di spending&#8221;&#8221;&#8221;<\/p>\n<p>        # Recupera spend nei ultimi 5 minuti<br \/>\n        recent_spend = float(self.redis.get(f&#8221;{self.circuit_key}:recent&#8221;) or 0)<\/p>\n<p>        # Se spike supera soglia, attiva circuit breaker<br \/>\n        if recent_spend &gt; self.threshold_cost:<br \/>\n            self.trip(reason=f&#8221;Anomaly: ${recent_spend} spend in {time_window_minutes} minutes&#8221;)<br \/>\n            return False<\/p>\n<p>        # Aggiorna counter<br \/>\n        self.redis.incrbyfloat(f&#8221;{self.circuit_key}:recent&#8221;, current_spend_usd)<br \/>\n        self.redis.expire(f&#8221;{self.circuit_key}:recent&#8221;, time_window_minutes * 60)<\/p>\n<p>        return True<\/p>\n<p>    def trip(self, reason):<br \/>\n        &#8220;&#8221;&#8221;Disabilita agente e notifica admin&#8221;&#8221;&#8221;<br \/>\n        self.redis.set(f&#8221;{self.circuit_key}:tripped&#8221;, &#8220;1&#8221;, ex=3600)<br \/>\n        self.redis.set(f&#8221;{self.circuit_key}:reason&#8221;, reason)<\/p>\n<p>        # TODO: Invia alert Slack\/Email a admin<br \/>\n        print(f&#8221;[ALERT] Circuit breaker tripped for {self.tenant_id}: {reason}&#8221;)<br \/>\n&#8220;`<\/p>\n<h2>Step 4: Monitoraggio e Observability<\/h2>\n<p>Senza visibilit\u00e0, non potete controllare nulla. Ho collegato tutto a un dashboard Grafana:<\/p>\n<p>&#8220;`<br \/>\nPrometheus metrics esportati:<br \/>\n&#8211; llm_requests_total{tenant_id, model, status}  # Contatore di richieste<br \/>\n&#8211; llm_token_consumption{tenant_id, token_type}  # Prompt, completion, cache<br \/>\n&#8211; llm_cost_usd{tenant_id, model}  # Costo effettivo per richiesta<br \/>\n&#8211; llm_agent_iterations{tenant_id}  # Numero di step agente per esecuzione<br \/>\n&#8211; container_memory_limit_bytes{tenant_id}  # Limite memoria<br \/>\n&#8211; container_memory_usage_bytes{tenant_id}  # Uso memoria attuale<br \/>\n&#8211; budget_remaining_usd{tenant_id}  # Budget rimanente<br \/>\n&#8220;`<\/p>\n<h2>FAQ<\/h2>\n<h3>Come faccio a permettere un agente di fare tool calling senza rischi di esfiltrazioni di dati?<\/h3>\n<p>Il metodo pi\u00f9 sicuro \u00e8 <strong>deny-by-default egress filtering<\/strong> combinato con <cite>modello di rete zero-trust dove tutte le connessioni sono esplicitamente autorizzate piuttosto che implicitamente permesse<\/cite>. Definite un allowlist rigido di endpoint che l&#8217;agente pu\u00f2 raggiungere (es: solo API ufficiali di LLM, non database interni), e implementate via iptables rules o proxy layer che intercetta ogni connessione.<\/p>\n<h3>Qual \u00e8 la differenza tra container Docker e Firecracker per AI agent sandboxing?<\/h3>\n<p>I container Docker condividono il kernel dell&#8217;host e sono pi\u00f9 efficienti per trusted workload. Firecracker e Kata Containers forniscono kernel isolato per VM-like isolation, ideale per codice non-trusted. Nel mio setup Plesk, uso container per il 70% (pi\u00f9 efficient) e Firecracker per il 30% (max security) che fa tool calling esterno.<\/p>\n<h3>Come assicuro che un agente non entra in infinite loop di token consumption?<\/h3>\n<p>Implementate <strong>tre livelli di controllo<\/strong>: (1) timeout globale <cite>usando container resource limits per prevenire processi runaway, impostando limiti ristretti di CPU, memoria e uso disco per processi agenti AI, implementando timeout mechanism operations<\/cite>; (2) depth limit su iterazioni agente (max 10-15 step); (3) circuit breaker che monitora spend anomalo in finestre di tempo brevi (es: &gt;$100 in 5 minuti).<\/p>\n<h3>Come calcolo il costo corretto se uso prompt caching?<\/h3>\n<p><cite>Il caching di prompt cambia il costo di contesto ripetuto solo quando cache read e cache write sono loggati separatamente. Collezionare token cached e uncached in un conteggio di input singolo pu\u00f2 sovrastimare lo spending su workload cache-heavy e offuscare se caching sta riducendo costi per prompt lunghi, documenti retrieval, o istruzioni di sistema ripetute<\/cite>. Loggare sempre i quattro token layer separatamente: prompt, completion, cache_read, cache_write.<\/p>\n<h3>Posso implementare questo su Plesk standard senza extensioni custom?<\/h3>\n<p>Parzialmente. Plesk standard fornisce basic resource quotas via UI, ma per sandboxing e cost attribution full-featured, dovete aggiungere un layer di application logic. Io uso Plesk Docker extension + custom Python proxy middleware. Se preferite una soluzione completamente managed, potete considerare provider specializzati come Northflank o Modal per AI sandboxing, integrando via Plesk API.<\/p>\n<h2>Conclusione<\/h2>\n<p>Implementare Plesk AI Agent Sandboxing e resource quotas non \u00e8 triviale, ma \u00e8 essenziale per multi-tenant LLM workload. Nel mio setup, ho combinato:<\/p>\n<ul>\n<li><strong>Isolamento compute:<\/strong> Container Docker + Firecracker per max security<\/li>\n<li><strong>Cost Attribution:<\/strong> Tagging metadati al ingresso, logging granulare di quattro token layer, budget enforcement automatico<\/li>\n<li><strong>Runaway Prevention:<\/strong> Timeout, depth limit, circuit breaker anomaly detection<\/li>\n<li><strong>Observability:<\/strong> Prometheus + Grafana per monitoring real-time<\/li>\n<\/ul>\n<p>Quando avete questi controlli in place, un agente non pu\u00f2 pi\u00f9 causare danni catastrofici. Questo significa che potete scale AI workload su Plesk con confidenza, sapendo che il costo e il rischio sono sotto controllo. Questo \u00e8 quello che ho imparato sulla strada difficile\u2014spero che vi risparmi il tempo e i dollari.<\/p>\n<p>Avete domande sul setup? Lasciate un commento qui sotto.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Come ho implementato su Plesk AI Agent Sandboxing, Resource Quotas e Cost Attribution per LLM Workload. Isolamento container, budget enforcement, prevenzione runaway process e monitoring via Prometheus.<\/p>\n","protected":false},"author":1,"featured_media":3383,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"","_seopress_titles_title":"Plesk AI Sandboxing & Resource Quotas 2026 | Cost Attribution","_seopress_titles_desc":"Isolate LLM workload su Plesk con container + Firecracker. Cost attribution per token, budget enforcement, runaway process prevention. Guida pratica 2026.","_seopress_robots_index":"","footnotes":""},"categories":[4],"tags":[484,878,733,461,1233,116],"class_list":["post-3382","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-plesk","tag-ai-security","tag-container-orchestration","tag-cost-attribution","tag-devops","tag-llm-workload-isolation","tag-plesk"],"_links":{"self":[{"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/posts\/3382","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/comments?post=3382"}],"version-history":[{"count":0,"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/posts\/3382\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/media\/3383"}],"wp:attachment":[{"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/media?parent=3382"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/categories?post=3382"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/darioiannascoli.it\/blog\/wp-json\/wp\/v2\/tags?post=3382"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}