Remediate security vulnerability with n8n and Port AI
Security teams often struggle to quickly understand the full context of vulnerabilities when they're detected. Raw vulnerability data from scanners like Snyk lacks critical operational context: which services are affected, who owns them, what environments are impacted, and what dependencies exist.
This guide demonstrates how to use Port as a context lake to enrich n8n workflows with comprehensive service metadata. When a vulnerability is detected, n8n queries Port's AI agent to retrieve contextual information about affected services, ownership, environments, and dependencies. This enriched context enables two powerful workflows:
- Targeted Slack notifications โ Send vulnerability alerts directly to owning teams with full context
- AI-powered remediation โ Route vulnerabilities to coding agents with complete service context for automated fixes
Common use casesโ
- Contextual vulnerability alerts โ Enrich security notifications with service ownership, dependencies, and environment information
- Automated remediation routing โ Route vulnerabilities to appropriate teams or AI agents based on service context
- Incident management โ Provide operational context for security incidents, outages, or deployment events
Prerequisitesโ
Before you begin, ensure you have:
- Completed the onboarding process
- A Port account with AI agents feature enabled
- Security vulnerabilities synced into Port (e.g., via Snyk, Wiz, or SonarQube)
- You have completed the setup in the Set up Port's n8n custom node guide
- You have completed the setup in the Trigger Claude Code from Port guide (Optional)
- Slack workspace and developer token (for the notification workflow)
- OpenAI API key (for AI remediation workflow)
Set up the Port context retriever agentโ
The context retriever agent is an AI agent that uses Port's catalog as a knowledge base to provide contextual enrichment for any entity or event. It analyzes inputs (like vulnerability details) and returns structured information about affected services, owners, environments, scorecards, dependencies and more.
Create the context retriever agentโ
-
Go to the AI Agents page of your portal
-
Click on
+ AI Agent -
Toggle
Json modeon -
Copy and paste the following JSON schema
Context Retriever Agent (Click to expand)
{
"identifier": "context_retriever_agent",
"title": "Context Retriever Agent",
"icon": "Details",
"team": [],
"properties": {
"description": "AI agent that provides contextual enrichment for any entity or event using the Port catalog as a knowledge base",
"status": "active",
"prompt": "You are an assistant that provides **contextual enrichment** for any entity or event using the **Port catalog** as a knowledge base. Your goal is to retrieve relevant context that helps downstream systems, agents, or security teams understand how a given entity fits within the broader ecosystem.\n\nYou will receive an input describing an **entity or event**.\nAnalyze the input and use the Port catalog to return structured contextual information.\n\n**Example inputs include:**\n\n* A detected security vulnerability\n* An active incident or outage\n* A new deployment or release event\n* A system health anomaly\n\n---\n\n### **For each input, provide the following:**\n\n1. Affected service(s) or component(s)\n2. Ownership or responsible team(s)\n3. Related environments or deployment targets\n4. Dependencies or linked entities in the Port catalog (e.g., repositories, cloud resources, deployments, last X pull requests, or microservices)\n5. Relevant scorecards the define and track engineering standards, KPIs, and quality metrics\n6. Any additional metadata or relationships that provide useful operational context\n\n---\n\n### **Output Format**\n\nReturn the result as **structured JSON** with the following keys:\n\n`identifier`, `title`, `related_services`, `owners`, `environments`, `dependencies`, `scorecards` and `notes`.\n\n**Example output:**\n\n```json\n{\n \"identifier\": \"INC-1023\",\n \"title\": \"Database connection timeout in payments service\",\n \"related_services\": [\"payments-api\", \"orders-api\"],\n \"owners\": [\"payments-team\"],\n \"environments\": [\"production\"],\n \"dependencies\": [\"postgres-cluster-prod\", \"redis-cache\"],\n \"scorecards\": [\"production-readiness not met\", \"code maturity passed\"],\n \"notes\": \"The issue affects all payment operations in production. Linked to previous incident INC-1009.\"\n}\n```\n\nIf a field cannot be determined, return it as an empty string or an empty list.",
"execution_mode": "Automatic",
"tools": [
"^(list|get|search|track|describe)_.*"
]
},
"relations": {}
} -
Click
Createto save the agent
Import the n8n workflow templateโ
-
Open your n8n instance
-
Click on Workflows โ Import from File or Import from URL
-
Copy the workflow JSON from the template below
n8n Workflow Template (Click to expand)
{
"name": "AI-Assisted Vulnerability Remediation",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "security/vulnerability_detected",
"options": {}
},
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
-1200,
96
],
"webhookDescription": "Triggered when a new vulnerability is detected",
"id": "da38b906-9eda-4157-891e-13f828cb9b5c",
"webhookId": "67326f7b-22c3-46c0-9f9f-805fc1401647"
},
{
"parameters": {
"resource": "chat",
"model": "gpt-4o-mini",
"prompt": {
"messages": [
{
"content": "=You are a cybersecurity assistant. Given the following vulnerability details, summarize the issue, assess impact, and generate a clear remediation plan.\n\nVulnerability:{{ $('Webhook Trigger').item.json.body.vulnerability_id }}\nDescription: {{ $('Webhook Trigger').item.json.body.description }}\nSeverity: {{ $('Webhook Trigger').item.json.body.severity }}\n\nContext: {{ $json.result.message }}\n\nYour response must be a single valid JSON object only, without any code block formatting, markdown, explanations, or extra text. \nDo not include ```json or ``` or any surrounding characters โ just raw JSON.\n\nRequired output schema:\n{\n \"summary\": \"\",\n \"impact\": \"\",\n \"remediation_plan\": \"\",\n \"is_fixable\": boolean true or false\n}"
}
]
},
"options": {},
"requestOptions": {}
},
"name": "OpenAI Remediation Plan",
"type": "n8n-nodes-base.openAi",
"typeVersion": 1,
"position": [
-96,
96
],
"id": "b72c278e-6aaa-4b51-873c-921c0d4d0dab",
"credentials": {
"openAiApi": {
"id": "jsaQyiVUkiZdKJuz",
"name": "OpenAi account"
}
}
},
{
"parameters": {
"channel": "#security-updates",
"text": "=โ ๏ธ *AI Remediation Workflow Error*\nNode: {{$node.name}}\nError: {{$error.message}}",
"otherOptions": {},
"attachments": []
},
"name": "Error Alert Slack",
"type": "n8n-nodes-base.slack",
"typeVersion": 1,
"position": [
-384,
320
],
"id": "f8f1726a-df54-48d4-adb7-005a49bfa541",
"credentials": {
"slackApi": {
"id": "GoOLAtWBRwTADKc8",
"name": "Slack account"
}
}
},
{
"parameters": {},
"name": "Error Trigger",
"type": "n8n-nodes-base.errorTrigger",
"typeVersion": 1,
"position": [
-848,
320
],
"id": "a7cf6d6c-e1eb-4d90-afd0-e714d92c7a54"
},
{
"parameters": {
"channel": "#security-updates",
"text": "={{ \n`๐จ *Vulnerability Alert*\n\n*ID:* ${$('Webhook Trigger').item.json.body.vulnerability_id}\n*Severity:* ${$('Webhook Trigger').item.json.body.severity}\n*Summary:* ${$node[\"OpenAI Remediation Plan\"].json[\"message\"][\"content\"].parseJson().summary}\n*Impact:* ${$node[\"OpenAI Remediation Plan\"].json[\"message\"][\"content\"].parseJson().impact}\n*Remediation Plan:* ${$node[\"OpenAI Remediation Plan\"].json[\"message\"][\"content\"].parseJson().remediation_plan}\n\n_Workflow: AI-Assisted Remediation_`\n}}\n",
"otherOptions": {},
"attachments": []
},
"name": "Send Slack Message",
"type": "n8n-nodes-base.slack",
"typeVersion": 1,
"position": [
800,
112
],
"id": "8bfb94df-43ca-42f8-8b81-aad696ec540d",
"credentials": {
"slackApi": {
"id": "GoOLAtWBRwTADKc8",
"name": "Slack account"
}
}
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json.message.content.parseJson().is_fixable }}",
"value2": "={{ true }}"
}
]
}
},
"name": "Is Fixable?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
208,
96
],
"id": "7493e053-5178-48f4-bbef-71daecaa399f"
},
{
"parameters": {
"method": "POST",
"url": "https://api.getport.io/v1/actions/run_claude_code_demo/runs",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ {\n properties: {\n service: \"port-labs/port-product-experiments\",\n prompt: \"Generate a code fix for the security vulnerability based on the AI-provided summary \" + $json.message.content.parseJson().summary + \".\\n\\nHere is the information about the security vulnerability remediation plan:\\n\" + $json.message.content.parseJson().remediation_plan + \"\\n\\nAfter generating the code, open a PR with a description summarizing what was fixed and why.\"\n }\n} }}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
496,
-128
],
"id": "ad946b73-bc0d-4caf-8907-99d6cd6d2671",
"name": "Trigger Claude Code",
"credentials": {
"httpBearerAuth": {
"id": "w6HyPPyI9LWW6Xgl",
"name": "Bearer Auth account"
}
}
},
{
"parameters": {
"agentIdentifier": "context_retriever_agent",
"prompt": "=You are an assistant that provides contextual enrichment for vulnerabilities using the Port catalog as a knowledge base. A new security vulnerability has been detected.\nVulnerability Details:\n- Identifier:{{ $('Webhook Trigger').item.json.body.vulnerability_id }}\n- Description:{{ $('Webhook Trigger').item.json.body.description }}\n- Severity:{{ $('Webhook Trigger').item.json.body.severity }}\n\nUsing the Port catalog (which stores data about services, components, environments, owners, and relationships), return relevant contextual information that will help downstream AI agents or security teams understand how this vulnerability relates to other entities. Specifically, retrieve:\n1. The affected service(s) or components linked to this vulnerability\n2. Ownership or responsible team(s)\n3. Related environments or deployment targets\n4. Dependencies or linked entities in the Port catalog (for example, linked repositories, cloud resources, or microservices)\n5. Any additional metadata that can help prioritize or triage this vulnerability.\n\nFormat the response as structured JSON with the following keys: `identifier`, `title`, `related_services`, `owners`, `environments`, `dependencies`, and `notes`.",
"labels": "{\n \"source\": \"n8n-workflow\",\n \"use_case\": \"vulnerability-context-enrichment\"\n }",
"model": "gpt-5"
},
"type": "CUSTOM.portIo",
"typeVersion": 1,
"position": [
-816,
96
],
"id": "ad298688-35d1-4278-9e1d-fca3856eb02d",
"name": "Get Context From Port",
"credentials": {
"portIoApi": {
"id": "a9s5zHKi57ADlTON",
"name": "Port.io account"
}
}
},
{
"parameters": {
"operation": "getInvocation",
"invocationId": "={{ $json.invocationIdentifier }}"
},
"type": "CUSTOM.portIo",
"typeVersion": 1,
"position": [
-464,
96
],
"id": "f80eed76-7b4d-4b1e-a69d-cad360241c13",
"name": "Process Port AI Response",
"credentials": {
"portIoApi": {
"id": "a9s5zHKi57ADlTON",
"name": "Port.io account"
}
}
}
],
"pinData": {},
"connections": {
"Webhook Trigger": {
"main": [
[
{
"node": "Get Context From Port",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Remediation Plan": {
"main": [
[
{
"node": "Is Fixable?",
"type": "main",
"index": 0
}
]
]
},
"Error Trigger": {
"main": [
[
{
"node": "Error Alert Slack",
"type": "main",
"index": 0
}
]
]
},
"Is Fixable?": {
"main": [
[
{
"node": "Trigger Claude Code",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Slack Message",
"type": "main",
"index": 0
}
]
]
},
"Trigger Claude Code": {
"main": [
[
{
"node": "Send Slack Message",
"type": "main",
"index": 0
}
]
]
},
"Get Context From Port": {
"main": [
[
{
"node": "Process Port AI Response",
"type": "main",
"index": 0
}
]
]
},
"Process Port AI Response": {
"main": [
[
{
"node": "OpenAI Remediation Plan",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "f66b4056-cdfe-42b0-b3ed-5c20b289d5fb",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "e9a36cfd74df34fd103d5f6c7fed0e3d25bfc51a5d136cd0fb7eba9c77b96ae3"
},
"id": "eNhr3iawT6LAYacO",
"tags": []
} -
After importing, configure the following credentials in n8n:
- Port.io credentials โ Use the Port.io credential you created during node installation (contains your Client ID and Client Secret)
- Slack credentials โ Add your Slack API token
- OpenAI credentials โ Add your OpenAI API key
Configure the workflowโ
The workflow consists of several key nodes:
- Webhook Trigger โ Receives vulnerability alerts from Snyk or other security scanners
- Get Context From Port โ Uses Port's custom node to invoke the context retriever agent and retrieve service metadata
- Process Port AI Response โ Uses Port's custom node to get the full AI response with context (handles async invocation automatically)
- OpenAI Remediation Plan โ Generates a remediation plan using the enriched context from Port
- Is Fixable? โ Routes to either automated fix or notification based on the remediation plan
- Trigger Claude Code โ (Optional) Triggers automated code fix via Port action
- Send Slack Message โ Sends notification to Slack with context
- Error Trigger and Error Alert Slack โ Handle workflow errors gracefully
Workflow patternsโ
The n8n workflow demonstrates two primary patterns for using Port as a context lake:
Pattern 1: Targeted Slack notificationsโ
When a vulnerability is detected, the workflow:
- Receives the vulnerability alert via webhook
- Queries Port's context retriever agent to get:
- Affected services
- Owning teams
- Related environments
- Dependencies
- Sends a targeted Slack notification to the owning team with full context
This ensures security alerts reach the right people with all the information they need to prioritize and respond.
Pattern 2: AI-powered remediationโ
For fixable vulnerabilities, the workflow:
- Retrieves context from Port (same as Pattern 1)
- Generates a remediation plan using OpenAI with the enriched context
- Routes to Claude Code (or another coding agent) to automatically generate a fix
- Opens a pull request with the fix
The Port context ensures the AI agent understands the service architecture, dependencies, and best practices before generating code.
Test the workflowโ
Test with a sample vulnerabilityโ
-
Trigger the webhook with a sample payload:
{
"vulnerability_id": "CVE-2025-10023",
"description": "Buffer overflow in crypto library 2.1.4",
"severity": "high"
} -
Verify Port context retrieval โ Check that the "Get Context From Port" and "Process Port AI Response" nodes successfully retrieve:
- Related services
- Ownership information
- Environment details
- Dependencies
-
Check Slack notification โ Verify the notification includes:
-
Vulnerability details
-
Service context from Port
-
Remediation plan
-
-
Verify AI remediation (if applicable) โ Confirm that fixable vulnerabilities trigger the coding agent with proper context
Related resourcesโ
- Remediate vulnerabilities with AI โ Use Port AI agents to automatically enrich and fix vulnerabilities
- Trigger Claude Code from Port โ Set up Claude Code integration with Port
- Set up the Task Manager AI agent โ Create an AI agent to manage and prioritize development tasks