{
  "name": "Trismag: inspect before the model reads",
  "nodes": [
    {
      "id": "b0449f3f-fa4b-5100-b0bf-6132664c4281",
      "name": "Start here",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        300
      ],
      "parameters": {},
      "onError": "stopWorkflow"
    },
    {
      "id": "441ee5b8-bf48-5301-ab48-e2252477c1db",
      "name": "Fetch example document",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        220,
        300
      ],
      "parameters": {
        "url": "https://trismag.dev/integrations/samples/ordinary.txt",
        "options": {
          "timeout": 10000,
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "response": {
            "response": {
              "responseFormat": "text",
              "outputPropertyName": "data"
            }
          }
        }
      },
      "onError": "stopWorkflow"
    },
    {
      "id": "0ad2e55f-b35d-5efb-837e-2ca2fc1c6bab",
      "name": "Prepare untrusted text",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        440,
        300
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "13399591-4219-51c3-aba4-b4bcbc39799a",
              "name": "text",
              "type": "string",
              "value": "={{ $json.data }}"
            }
          ]
        },
        "options": {}
      },
      "onError": "stopWorkflow"
    },
    {
      "id": "9136bea2-84f5-5806-adf1-14d40282914a",
      "name": "Trismag: check the text",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        660,
        300
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.trismag.dev/v1/triage",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ text: $json.text }) }}",
        "options": {
          "timeout": 10000,
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "response": {
            "response": {
              "responseFormat": "json",
              "fullResponse": true,
              "neverError": false
            }
          }
        }
      },
      "onError": "stopWorkflow"
    },
    {
      "id": "789922ca-aa4f-56ef-88d4-3aefb709c0e6",
      "name": "Only LOW continues",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        880,
        300
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "0ed7100c-21ba-53b0-8d17-645b88d0d457",
              "leftValue": "={{ $json.body?.risk }}",
              "rightValue": "LOW",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            },
            {
              "id": "6e8257af-ca1f-517c-90b3-ec9665ca01a7",
              "leftValue": "={{ $json.statusCode === 200 && $json.body !== null && typeof $json.body === 'object' && !Array.isArray($json.body) && typeof $json.body.rule_weight === 'number' && Number.isFinite($json.body.rule_weight) && $json.body.error === undefined && ($json.body.scan_complete === undefined || $json.body.scan_complete === true) }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "onError": "stopWorkflow"
    },
    {
      "id": "edef6d6b-b135-5c99-826e-03e4ad58d377",
      "name": "RELEASE - no known match (not proof of safety)",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1120,
        180
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "878e11da-6c6c-58f5-9530-72048cb0ffe2",
              "name": "text",
              "type": "string",
              "value": "={{ $('Prepare untrusted text').item.json.text }}"
            },
            {
              "id": "08980120-3eab-5525-b3b8-d9c92622184c",
              "name": "triage_risk",
              "type": "string",
              "value": "={{ $json.body.risk }}"
            }
          ]
        },
        "options": {}
      },
      "onError": "stopWorkflow"
    },
    {
      "id": "dff817d8-fd70-5ae5-b5eb-2f4e0c7b96e2",
      "name": "HOLD - review required",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1120,
        420
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "1a876d4b-f488-5e45-be03-9bec27e4bba8",
              "name": "status",
              "type": "string",
              "value": "held"
            },
            {
              "id": "c9c185da-1cdf-5bb0-a026-31220f574306",
              "name": "reason",
              "type": "string",
              "value": "No usable LOW verdict. Review required."
            }
          ]
        },
        "options": {}
      },
      "onError": "stopWorkflow"
    },
    {
      "id": "8a6eeb0b-b98b-5c78-a20a-a4ece0568220",
      "name": "Read before connecting a model",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        -260
      ],
      "parameters": {
        "width": 650,
        "height": 490,
        "content": "## Trismag: inspect before the model reads\n\n1. In the Trismag HTTP node, select a Header Auth credential: name `Authorization`, value `Bearer YOUR_TRISMAG_KEY`. Store the key in n8n Credentials, never the workflow JSON. Get a key at https://trismag.dev/docs/#get-a-key.\n2. Run the ordinary sample, then replace its URL with https://trismag.dev/integrations/samples/attack.txt to see HOLD. The limitation.txt sample intentionally passes LOW.\n3. Replace the fetch with your content source. Prepare untrusted text must output a `text` string. Connect only RELEASE to your model and use only its `$json.text` as input. Do not reference earlier nodes from the model, attach an alternate source, or let it fetch around this check.\n4. Keep strict LOW plus response validation. Do not enable Continue On Fail, Always Output Data, Ignore Response Code, or redirects. Failures and quota refusals stop the workflow. HOLD has no onward connection.\n5. Saved execution data is disabled, including manual runs. n8n still handles content in memory and may display it during debugging. Review your instance logging, backups and retention before using private content.\n\nCurrent free key: 500 scans/calendar month; 30 requests/minute. Limited free usage continues after September 30, 2026; published limits apply. LOW means no known match, not safe or authorized. Keep restricted permissions and independent action approvals. Setup and test scope: https://trismag.dev/install/"
      },
      "onError": "stopWorkflow"
    }
  ],
  "connections": {
    "Start here": {
      "main": [
        [
          {
            "node": "Fetch example document",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch example document": {
      "main": [
        [
          {
            "node": "Prepare untrusted text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare untrusted text": {
      "main": [
        [
          {
            "node": "Trismag: check the text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Trismag: check the text": {
      "main": [
        [
          {
            "node": "Only LOW continues",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Only LOW continues": {
      "main": [
        [
          {
            "node": "RELEASE - no known match (not proof of safety)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "HOLD - review required",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1",
    "executionTimeout": 60,
    "saveDataErrorExecution": "none",
    "saveDataSuccessExecution": "none",
    "saveManualExecutions": false,
    "saveExecutionProgress": false
  },
  "meta": {
    "templateCredsSetupCompleted": false
  }
}
