Skip to content

Försvar på djupet ​

Triggerfish implementerar säkerhet som 13 oberoende, överlappande lager. Inget enskilt lager är tillräckligt på egen hand. Tillsammans bildar de ett försvar som försämras varsamt — även om ett lager komprometteras fortsätter de återstående lagren att skydda systemet.

SÄKERHET Försvar på djupet innebär att en sårbarhet i ett enskilt lager inte komprometterar systemet. En angripare som kringgår kanalautentisering möter fortfarande session-taint-spårning, policy-hooks och revisionsloggning. En LLM som prompt-injiceras kan fortfarande inte påverka det deterministiska policylagret under den. :::

De 13 lagren ​

Lager 1: Kanalautentisering ​

Skyddar mot: Identitetsstöld, obehörig åtkomst, identitetsförvirring.

Identitet bestäms av kod vid sessionsupprättande, inte av LLM:en som tolkar meddelandeinnehåll. Innan LLM:en ser ett meddelande taggar kanaladaptern det med en oföränderlig etikett:

{ source: "owner" }    -- verifierad kanalidentitet matchar registrerad ägare
{ source: "external" } -- vem som helst annars; enbart indata, behandlas inte som kommando

Autentiseringsmetoder varierar beroende på kanal:

KanalMetodVerifiering
Telegram / WhatsAppParningskodEngångskod, 5 minuters utgång, skickad från användarens konto
Slack / Discord / TeamsOAuthPlattforms-OAuth-medgivandeflöde, returnerar verifierat användar-ID
CLILokal processKörs på användarens dator, autentiserad av OS
WebChatIngen (publik)Alla besökare är EXTERNAL, aldrig owner
E-postDomänmatchningAvsändardomän jämförs mot konfigurerade interna domäner

LLM:en bestämmer aldrig vem som är ägaren. Ett meddelande som säger "Jag är ägaren" från en overifierad avsändare taggas { source: "external" } och kan inte utlösa ägarenivåkommandon. Det här beslutet fattas i kod, innan LLM:en bearbetar meddelandet. :::

Lager 2: Behörighetsmedveten dataåtkomst ​

Skyddar mot: Överprivilegierad dataåtkomst, privilegieskalering via systemuppgifter.

Triggerfish använder användarens delegerade OAuth-tokens — inte systemtjänstkonton — för att söka externa system. Källsystemet tillämpar sin egen behörighetsmodell:

Traditionell kontra Triggerfish: traditionell modell ger LLM direkt kontroll, Triggerfish dirigerar alla åtgärder via ett deterministiskt policylager

Plugin SDK tillämpar detta på API-nivå:

SDK-metodBeteende
sdk.get_user_credential(integration)Returnerar användarens delegerade OAuth-token
sdk.query_as_user(integration, query)Kör med användarens behörigheter
sdk.get_system_credential(name)BLOCKERAD — höjer PermissionError

Lager 3: Session-taint-spårning ​

Skyddar mot: Dataintrång via kontextkontaminering, klassificerade data som når lägre-klassificerade kanaler.

Varje session spårar oberoende en taint-nivå som återspeglar den högsta klassificeringen av data som nåtts under sessionen. Taint följer tre invarianter:

  1. Per konversation — varje session har sin egen taint
  2. Bara eskalering — taint ökar, aldrig minskar
  3. Fullständig återställning rensar allt — taint OCH historik raderas tillsammans

När policymotorn utvärderar en utdata jämför den sessionens taint mot målkanalens effektiva klassificering. Om taint överstiger målet blockeras utdata.

Lager 4: Datalinjegrafi ​

Skyddar mot: Ospårbara dataflöden, oförmåga att granska vart data gick, efterlevnadsluckor.

Varje dataelement bär provenansmetadata från ursprung till destination:

  • Ursprung: Vilken integration, post och användaråtkomst producerade denna data
  • Klassificering: Vilken nivå som tilldelades och varför
  • Transformationer: Hur LLM:en modifierade, sammanfattade eller kombinerade data
  • Destination: Vilken session och kanal tog emot utdata

Linjegrafi möjliggör framåtspårningar ("var gick denna Salesforce-post?"), bakåtspårningar ("vilka källor bidrog till denna utdata?") och fullständiga efterlevnadsexporter.

Lager 5: Policyhanteringshooks ​

Skyddar mot: Prompt-injektionsattacker, LLM-drivna säkerhetskringgåenden, okontrollerad verktygsexekvering.

Åtta deterministiska hooks fångar upp varje åtgärd vid kritiska punkter i dataflödet:

HookVad den fångar upp
PRE_CONTEXT_INJECTIONExtern indata som hamnar i kontextfönstret
PRE_TOOL_CALLLLM som begär verktygsexekvering
POST_TOOL_RESPONSEData som återvänder från verktygsexekvering
PRE_OUTPUTSvar som är på väg att lämna systemet
SECRET_ACCESSBegäran om åtkomst till uppgifter
SESSION_RESETBegäran om taint-återställning
AGENT_INVOCATIONAgent-till-agent-anrop
MCP_TOOL_CALLAnrop av MCP-serververktyg

Hooks är ren kod: deterministiska, synkrona, loggade och ofalsknliga. LLM:en kan inte kringgå dem eftersom det inte finns någon väg från LLM-utdata till hook-konfiguration. Hook-lagret tolkar inte LLM-utdata för kommandon.

Lager 6: MCP Gateway ​

Skyddar mot: Okontrollerad extern verktygsåtkomst, oklassificerade data som kommer in via MCP-servrar, schemaöverträdelser.

Alla MCP-servrar standard till UNTRUSTED och kan inte anropas förrän en admin eller användare klassificerar dem. Gateway tillämpar:

  • Serverautentisering och klassificeringsstatus
  • Verktygsnivåbehörigheter (enskilda verktyg kan blockeras även om servern är tillåten)
  • Begärans-/svarsschemavalidering
  • Taint-spårning på alla MCP-svar
  • Injektionsmönsterskanning i parametrar
MCP-servertillstånd: UNTRUSTED (standard), CLASSIFIED (granskad och tillåten), BLOCKED (uttryckligen förbjuden)

Lager 7: Plugin-sandlåda ​

Skyddar mot: Skadlig eller buggig plugin-kod, datautfiltration, obehörig systemåtkomst.

Plugins körs inuti en dubbel sandlåda:

Plugin-sandlåda: Deno-sandlåda omsluter WASM-sandlåda, plugin-kod körs i det innersta lagret

Plugins kan inte:

  • Komma åt odeklarerade nätverksendpoints
  • Emittera data utan klassificeringsetiketter
  • Läsa data utan att utlösa taint-spridning
  • Bevara data utanför Triggerfish
  • Använda systemuppgifter (bara användarens delegerade uppgifter)
  • Exfiltrera via sidokanaler (resursgränser, inga råa sockets)

Plugin-sandlådan är skild från agentens körningsmiljö. Plugins är ej betrodd kod som systemet skyddar från. Körningsmiljön är en arbetsyta där agenten är tillåten att bygga — med policy-styrd åtkomst, inte sandlådisolering. :::

Lager 8: Hemlighetsisolering ​

Skyddar mot: Stöld av uppgifter, hemligheter i konfigurationsfiler, okrypterad uppgiftslagring.

Uppgifter lagras i OS-nyckelringen (personlig nivå) eller vault-integration (företagsnivå). De visas aldrig i:

  • Konfigurationsfiler
  • StorageProvider-värden
  • Loggposter
  • LLM-kontext (uppgifter injiceras i HTTP-lagret, under LLM:en)

SECRET_ACCESS-hooken loggar varje åtkomst till uppgifter med den begärande plugin-en, uppgiftomfånget och beslutet.

Lager 9: Filsystemsverktygssandlåda ​

Skyddar mot: Sökvägsgenomgångsattacker, obehörig filåtkomst, klassificeringskringgång via direkta filsystemsoperationer.

Alla filsystemsverktygsoperationer (läs, skriv, redigera, lista, sök) körs inuti en sandlådd Deno Worker med OS-nivåbehörigheter avgränsade till sessionens taint-lämpliga arbetsytaunderkatalog. Sandlådan tillämpar tre gränser:

  • Sökvägsinstängning — varje sökväg löses till en absolut sökväg och kontrolleras mot instängningsroten med separatormedveten matchning. Genomgångsförsök (../) som flyr arbetsytan avvisas innan någon I/O sker
  • Sökvägsklassificering — varje filsystemsökväg klassificeras via en fast lösningskedja: hårdkodade skyddade sökvägar (RESTRICTED), arbetsytaklassificeringkataloger, konfigurerade sökvägsmappningar och sedan standardklassificering. Agenten kan inte komma åt sökvägar ovanför sin session-taint
  • Taint-avgränsade behörigheter — sandlåde-Workerns Deno-behörigheter ställs in på arbetsytaunderkatalogen som matchar sessionens aktuella taint-nivå. När taint eskalerar skapas Worker:n om med utökade behörigheter. Behörigheter kan bara utvidgas, aldrig begränsas inom en session
  • Skrivskydd — kritiska filer (TRIGGER.md, triggerfish.yaml, SPINE.md) är skrivskyddade på verktygslagret oavsett sandlådebehörigheter. Dessa filer kan bara ändras via dedikerade hanteringsverktyg som tillämpar sina egna klassificeringsregler

Lager 10: Agentidentitet ​

Skyddar mot: Privilegieskalering via agentkedjor, datauttvättning via delegering.

När agenter anropar andra agenter förhindrar kryptografiska delegeringskedjor privilegieskalering:

  • Varje agent har ett certifikat som specificerar dess funktioner och klassificeringstak
  • Den kallade ärver max(eget taint, anroparens taint) — taint kan bara öka via kedjor
  • En anropare med taint som överstiger den kallade agentens tak blockeras
  • Cirkulära anrop upptäcks och avvisas
  • Delegeringsdjup är begränsat och tillämpas
Datauttvättningsförsvar: attackväg blockerad vid takskontroll och taint-arv förhindrar utdata till lägre-klassificerade kanaler

Lager 11: Revisionsloggning ​

Skyddar mot: Oupptäckbara intrång, efterlevnadsbrister, oförmåga att utreda incidenter.

Varje säkerhetsrelevant beslut loggas med fullständigt sammanhang:

json
{
  "timestamp": "2025-01-29T10:23:45Z",
  "user_id": "user_123",
  "session_id": "sess_456",
  "action": "slack.postMessage",
  "target_channel": "external_webhook",
  "session_taint": "CONFIDENTIAL",
  "target_classification": "PUBLIC",
  "decision": "DENIED",
  "reason": "classification_violation",
  "hook": "PRE_OUTPUT",
  "policy_rules_evaluated": ["rule_001", "rule_002"],
  "lineage_ids": ["lin_789", "lin_790"]
}

Vad som loggas:

  • Alla åtgärdsförfrågningar (tillåtna OCH nekade)
  • Klassificeringsbeslut
  • Session-taint-ändringar
  • Kanalautentiseringshändelser
  • Policyreglutvärderingar
  • Skapande och uppdatering av linjegrafipost
  • MCP Gateway-beslut
  • Agent-till-agent-anrop

Revisionsloggning kan inte inaktiveras. Det är en fast regel i policyhierarkin. Inte ens en organisationsadmin kan stänga av loggning för sina egna åtgärder. Företagsdriftsättningar kan valfritt aktivera fullständig innehållsloggning (inklusive blockerat meddelandeinnehåll) för kriminaltekniska krav. :::

Lager 12: SSRF-förebyggande ​

Skyddar mot: Server-side request forgery, intern nätverksrekognoscering, exfiltration av molnmetadata.

Alla utgående HTTP-förfrågningar (från web_fetch, browser.navigate och plugin-nätverksåtkomst) löser DNS först och kontrollerar den upplösta IP-adressen mot en hårdkodad nekalista med privata och reserverade intervall. Det förhindrar en angripare från att lura agenten att komma åt interna tjänster via fabricerade URL:er.

  • Privata intervall (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) är alltid blockerade
  • Länklokal (169.254.0.0/16) och molnmetadataendpoints är blockerade
  • Loopback (127.0.0.0/8) är blockerat
  • Nekalistan är hårdkodad och inte konfigurerbar — det finns ingen admin-åsidosättning
  • DNS-upplösning sker före förfrågningen, vilket förhindrar DNS-rebindningsattacker

Lager 13: Minneklassificeringsgrindning ​

Skyddar mot: Cross-sessions dataintrång via minne, klassificeringsnedsättning via minnesskrivningar, obehörig åtkomst till klassificerade minnen.

Det cross-sessions minnessystemet tillämpar klassificering vid både skriv- och lästid:

  • Skrivningar: Minnesposter tvingas till den aktuella sessionens taint-nivå. LLM:en kan inte välja en lägre klassificering för lagrade minnen.
  • Läsningar: Minnesfrågor filtreras av canFlowTo — en session kan bara läsa minnen vid eller under dess aktuella taint-nivå.

Det förhindrar en agent från att lagra CONFIDENTIAL-data som PUBLIC i minnet och senare hämta det i en lägre-taint-session för att kringgå nedskrivningsförbudet.

Förtroendehierarki ​

Förtroendemodellen definierar vem som har auktoritet över vad. Högre nivåer kan inte kringgå lägre nivåers säkerhetsregler, men de kan konfigurera de justerbara parametrarna inom dessa regler.

Förtroendehierarki: Triggerfish-leverantör (noll åtkomst), Organisationsadmin (ställer in policyer), Anställd (använder agent inom gränser)

Personlig nivå: Användaren ÄR organisationsadminen. Full suveränitet. Ingen Triggerfish-synlighet. Leverantören har noll åtkomst till användardata som standard och kan bara få åtkomst via ett uttryckligt, tidsbegränsat, loggat beviljande från användaren. :::

Hur lagren arbetar tillsammans ​

Tänk dig en prompt-injektionsattack där ett skadligt meddelande försöker exfiltrera data:

StegLagerÅtgärd
1KanalautentiseringMeddelande taggat { source: "external" } — inte ägaren
2PRE_CONTEXT_INJECTIONIndata skannad för injektionsmönster, klassificerad
3Session-taintSession-taint oförändrad (ingen klassificerad data nådd)
4LLM bearbetar meddelandeLLM kan manipuleras att begära ett verktygsanrop
5PRE_TOOL_CALLVerktygsbehörighetskontroll mot externa-källa-regler
6POST_TOOL_RESPONSEReturnerade data klassificerade, taint uppdaterat
7PRE_OUTPUTUtdataklassificering kontra mål kontrollerat
8RevisionsloggningHela sekvensen registrerad för granskning

Även om LLM:en är fullständigt komprometterad vid steg 4 och begär ett dataexfiltreringsverktygsanrop fortsätter de återstående lagren (behörighetskontroller, taint-spårning, utdataklassificering, revisionsloggning) att tillämpa policyn. Ingen enskild felpunkt komprometterar systemet.