diff --git a/README.md b/README.md index 5b58078..40ce38f 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,50 @@ ![Northwall cover](docs/northwall-cover.svg) -Northwall is an Agentic SOC platform for teams that want multi-agent orchestration using graph-based understanding: custom team of multi-agent specialists, build a knowledge graph, vulnerability analysis & search loops, and GitHub integration. - -If you're looking to build a custom agentic SOC tool / platform for your organization, Northwall would be a good fit to start from; whether it is: -- Multi Agent Orchestration, -- Agentic security operations, -- SOC automation, -- Alert triage, -- Vulnerability / threat investigation, -- Incident response automation, -- Investigation graph, -- Security work item creation, or -- Human-in-the-loop (HITL) security operations. +# Run AppSec missions with specialist AI agents + +Northwall orchestrates specialist AI agents across code, ownership, dependencies, and security context to turn AppSec risk into approved, owner-ready action. + +Most security tools hand leaders another queue. Scanners produce alerts, code review bots produce comments, and engineers still have to answer the hard operational questions: what is reachable, which owner should act, what evidence is strong enough, and what should the remediation work actually say? + +Northwall is an Agentic AppSec Orchestration product. It builds an application knowledge graph first, dispatches a governed team of security agents, runs safe parallel investigation loops, and keeps humans in control before work is sent to owners. + +GitHub is the first execution surface: source context, branch selection, code ownership, dependency evidence, and GitHub issue handoff. The same orchestration pattern is designed to extend to SIEM, EDR, cloud, identity, ticketing, and evidence storage without claiming those connectors as the default path today. + +## Core Flow + +```text +Connect evidence source -> Build graph -> Approve agent mission -> Run parallel specialists -> Send owner handoffs +``` + +- GitHub OAuth for source context and approved remediation handoff +- Repo, branch, package, route, auth, config, ownership, and CI inventory +- AppSec knowledge graph across services, routes, owners, dependencies, controls, and work items +- Specialist agents with named responsibilities before execution starts +- Parallel MoE-style investigation across auth, dependency, ownership, config, CI, and threat context +- Human approval before the mission runs and before work is sent to owners +- Live Socket.IO event stream while agents execute +- Owner handoffs with severity, confidence, evidence, remediation, verification notes, issue body, and labels + +## Why Northwall + +| Alternative | What it gives you | What Northwall adds | +| --- | --- | --- | +| Scanners | Findings, alerts, and severity queues | Governed agentic execution that turns evidence into owner-ready action | +| AI code review bots | Comments on code changes | Application graph context, specialist agents, and approval-gated remediation handoff | +| Manual AppSec triage | Expert judgment, but limited throughput | Parallel specialists that map, triage, verify, and draft work while analysts stay in control | + +## Agent Team + +Northwall plans the mission before execution so reviewers can see the team, task order, evidence goals, and approval notes. + +| Agent | Responsibility | +| --- | --- | +| System Cartographer | Builds the AppSec knowledge graph across repos, routes, packages, owners, controls, and CI. | +| Auth Boundary Agent | Reviews auth, session, tenant, middleware, and permission-sensitive paths. | +| Dependency Analyst | Checks package manifests, lockfiles, dependency exposure, and release risk. | +| CI/Config Analyst | Reviews pipeline, runtime configuration, environment references, and guardrails. | +| Response Handoff Agent | Converts evidence into owner-ready remediation work with verification steps. | +| Human Review Agent | Keeps scope, approval, and risky actions behind explicit analyst control. | ## Demo @@ -21,57 +54,41 @@ If you're looking to build a custom agentic SOC tool / platform for your organiz -### Connect a source +### Connect an evidence source Pick a GitHub repo and branch. Northwall keeps provider tokens server-side. ![Northwall source selection](docs/screenshots/soc-source-selection.png) -### Review the agent plan +### Approve the agent plan -Northwall builds source context first, then shows the investigation graph, agent team, task order, and approval notes before anything runs. +Northwall builds AppSec graph context first, then shows the agent team, task order, evidence goals, and approval notes before anything runs. ![Northwall agent plan](docs/screenshots/agent-plan.png) -### Watch the run +### Watch the mission run -The run log shows what agents are doing, which findings were created, and what evidence was used. +The run log shows which specialist agents are executing, which evidence was used, and which owner handoffs were drafted. -![Northwall live SOC run](docs/screenshots/live-soc-run.png) +![Northwall live AppSec mission](docs/screenshots/live-soc-run.png) ### Send work to owners -Findings are selected by the analyst, previewed as GitHub issues, and sent only after approval. +Handoffs are selected by the analyst, previewed as GitHub issues, and sent only after approval. -![Northwall findings handoff](docs/screenshots/findings-handoff.png) +![Northwall owner handoff](docs/screenshots/findings-handoff.png) ### Mobile sign-in ![Northwall mobile login](docs/screenshots/login-mobile.png) -## Core Flow - -```text -Connect source -> Build context -> Review plan -> Approve run -> Review findings -> Create GitHub issues -``` - -- GitHub OAuth for repo context and issue creation -- Repo, branch, package, route, auth, config, and CI inventory -- Investigation graph across services, routes, owners, dependencies, and work items -- Specialist agents with named responsibilities before the run starts -- Human approval before response actions -- Live Socket.IO event stream while agents work -- Findings with severity, confidence, evidence, owner notes, issue body, and labels - -GitHub is the first connector. The same pattern can extend to SIEM, EDR, cloud, identity, ticketing, and evidence storage. - ## How It Works The backend keeps source and model credentials server-side. When a user connects GitHub, Northwall stores the provider token through encrypted local persistence keyed by `TOKEN_ENCRYPTION_KEY`. The frontend only sees connection metadata: account, scopes, and connection time. -When a run starts, the backend reads the selected repo through the GitHub API and inventories the files that usually matter during response: +When a mission starts, the backend reads the selected repo through the GitHub API and inventories the files that usually matter during AppSec operations: - package manifests and lockfiles - API routes and handlers @@ -80,15 +97,15 @@ When a run starts, the backend reads the selected repo through the GitHub API an - GitHub Actions and CI files - service ownership and work item context -OpenAI GPT-5.5 runs on the backend. It turns the source inventory into an agent plan and owner handoff drafts. The prompts stay defensive: owned systems, concrete evidence, no third-party targets, no destructive actions, no exploit payloads. +OpenAI GPT-5.5 runs on the backend. It turns the source inventory and AppSec graph into an agent plan and owner handoff drafts. The prompts stay defensive: owned systems, static/dependency analysis, concrete evidence, no third-party targets, no destructive actions, no exploit payloads. ## Packages | Package | Role | | --- | --- | -| `@northwall/frontend` | Next.js app, source picker, investigation graph, plan approval, live run, findings table | -| `@northwall/backend` | Hono API, GitHub integration, assessment worker, OpenAI planning, Socket.IO events | -| `@northwall/shared` | Zod schemas for repos, runs, graphs, plans, findings, and issue payloads | +| `@northwall/frontend` | Next.js app, source picker, AppSec graph, agent plan approval, live mission, owner handoff table | +| `@northwall/backend` | Hono API, GitHub integration, mission worker, OpenAI planning, Socket.IO events | +| `@northwall/shared` | Zod schemas for repos, runs, graphs, plans, handoffs, and issue payloads | | `@northwall/agent-runtime` | Agent runtime kept for deeper worker expansion | | `@northwall/agent-control` | Sandbox control service kept for future runtime checks | @@ -171,15 +188,15 @@ Required environment: ## Safety Boundaries -Northwall is for owned systems and authorized security operations work. +Northwall is for owned systems and authorized AppSec work. -It starts with safe triage, static context, dependency context, and owner handoff. It does not run third-party scanning, destructive tests, credential collection, persistence checks, or weaponized exploit output. +It starts with safe source context, dependency context, graph building, agent planning, and owner handoff. It does not run third-party scanning, destructive tests, credential collection, persistence checks, or weaponized exploit output. -The output is plain: what happened, why it matters, what evidence supports it, who owns it, and what work item should be created. +The output is plain: what was found, why it matters, what evidence supports it, who owns it, and what work should be created. ## Work With Us -We build products like this for teams that want agentic security operations without turning the SOC into a black box. +We build products like this for teams that want agentic AppSec execution without turning remediation work into a black box. ![Inferensys](docs/inferensys.svg) diff --git a/package.json b/package.json index 6bc5ed2..a62526c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "northwall", - "description": "Agentic SOC platform for multi-agent security operations, alert triage, investigation graphs, and owner handoff.", + "description": "Agentic AppSec orchestration for specialist security agents, application knowledge graphs, and approved owner handoff.", "private": true, "workspaces": [ "packages/shared", diff --git a/packages/backend/src/services/assessment-manager.ts b/packages/backend/src/services/assessment-manager.ts index 548269b..bc34acc 100644 --- a/packages/backend/src/services/assessment-manager.ts +++ b/packages/backend/src/services/assessment-manager.ts @@ -102,11 +102,11 @@ export class AssessmentManager { } this.setPhase(assessment, "understanding"); - this.emit(id, "understanding_started", "Building investigation context from source, ownership, and security-sensitive surfaces"); + this.emit(id, "understanding_started", "Building AppSec graph context from source, ownership, dependencies, and security-sensitive surfaces"); const token = await this.requireToken(userId); const snapshot = await this.analyzer.analyze(token, assessment.repository, assessment.branch); this.applySnapshot(assessment, snapshot); - this.emit(id, "graph_updated", `Mapped ${snapshot.graph.nodes.length} investigation graph nodes from ${snapshot.inventory.files} files`, { + this.emit(id, "graph_updated", `Mapped ${snapshot.graph.nodes.length} AppSec graph nodes from ${snapshot.inventory.files} files`, { nodes: snapshot.graph.nodes.length, edges: snapshot.graph.edges.length, }); @@ -128,7 +128,7 @@ export class AssessmentManager { }); assessment.plan = plan; this.setPhase(assessment, "plan_ready"); - this.emit(id, "plan_ready", `Response plan ready with ${plan.agents.length} agents and ${plan.tasks.length} tasks`); + this.emit(id, "plan_ready", `Agent plan ready with ${plan.agents.length} specialists and ${plan.tasks.length} tasks`); await this.save(id); return assessment; } @@ -140,7 +140,7 @@ export class AssessmentManager { } this.setPhase(assessment, "approved"); - this.emit(id, "plan_approved", "SOC response plan approved for safe execution"); + this.emit(id, "plan_approved", "AppSec agent plan approved for safe execution"); await this.save(id); return assessment; } @@ -152,7 +152,7 @@ export class AssessmentManager { } this.setPhase(assessment, "running"); - this.emit(id, "run_started", "Starting agentic SOC run"); + this.emit(id, "run_started", "Starting agentic AppSec mission"); for (const agent of assessment.plan.agents) { agent.status = "working"; @@ -195,7 +195,7 @@ export class AssessmentManager { async createIssues(id: string, userId: string, findingIds: string[]): Promise { const assessment = this.requireOwnedAssessment(id, userId); if (assessment.phase !== "findings_ready" && assessment.phase !== "issues_created") { - throw new Error("Issues can only be created after findings are ready."); + throw new Error("Owner handoffs can only be sent after they are ready."); } if (findingIds.length === 0) throw new Error("Select at least one finding."); diff --git a/packages/backend/src/services/github-client.ts b/packages/backend/src/services/github-client.ts index 6026c04..3d7efa5 100644 --- a/packages/backend/src/services/github-client.ts +++ b/packages/backend/src/services/github-client.ts @@ -146,7 +146,7 @@ export class GitHubClient { headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: label, - color: label === "security-operations" || label === "agentic-soc" ? "051914" : label === "security" ? "d73a4a" : "0e8a16", + color: label === "appsec-orchestration" || label === "agentic-appsec" ? "051914" : label === "security" ? "d73a4a" : "0e8a16", }), }); } catch { diff --git a/packages/backend/src/services/mission-manager.ts b/packages/backend/src/services/mission-manager.ts index cfe5b3d..734bc10 100644 --- a/packages/backend/src/services/mission-manager.ts +++ b/packages/backend/src/services/mission-manager.ts @@ -344,7 +344,7 @@ export class MissionManager { const activities = [ { summary: "Confirmed owned application scope and safe AppSec limits", tool: "Read" }, { summary: "Mapped target routes, auth boundaries, packages, and data stores", tool: "Task" }, - { summary: "Prepared an agent assessment strategy with evidence requirements", tool: "Plan" }, + { summary: "Prepared an agent mission strategy with evidence requirements", tool: "Plan" }, ]; for (const activity of activities) { const event: SessionEvent = { @@ -361,7 +361,7 @@ export class MissionManager { } const text = - "I have enough context to plan this as an authorized AppSec assessment. I would map the system first, form a specialist security team, run safe code and dependency checks, verify only approved local routes, and turn high-confidence evidence into a remediation queue."; + "I have enough context to plan this as an authorized AppSec mission. I would map the graph first, form a specialist security team, run safe code and dependency checks, verify only approved local routes, and turn high-confidence evidence into owner handoffs."; const assistant: ChatMessage = { id: `msg-${nanoid(8)}`, sessionId: id, @@ -475,7 +475,7 @@ export class MissionManager { const d = this.missions.get(id); if (!d) return; d.containerStatus = "running"; - d.vncUrl = createDesktopPreviewUrl("Agent desktop live", "Assessment cockpit and local target app running at localhost:3000"); + d.vncUrl = createDesktopPreviewUrl("Agent desktop live", "AppSec mission cockpit and local target app running at localhost:3000"); this.emitEvent(id, "container_running", "Agent VM ready", { vncUrl: d.vncUrl }); this.runSampleExecution(id); }, 900); @@ -517,12 +517,12 @@ export class MissionManager { await fs.mkdir(path.join(workspace, "docs"), { recursive: true }); await fs.writeFile( path.join(workspace, "README.md"), - `# AcmePay AppSec Assessment\n\nAssessment prompt:\n\n${prompt}\n\n## Delivered\n\n- System graph of routes, auth boundaries, dependencies, and data stores\n- Prioritized findings with evidence, owners, and verification steps\n- Safe local probe notes\n- Remediation handoff for engineering review\n`, + `# AcmePay AppSec Mission\n\nMission prompt:\n\n${prompt}\n\n## Delivered\n\n- AppSec graph of routes, auth boundaries, dependencies, and data stores\n- Prioritized owner handoffs with evidence, owners, and verification steps\n- Safe local probe notes\n- Remediation handoff for engineering review\n`, "utf-8", ); await fs.writeFile( - path.join(workspace, "src", "components", "AssessmentCockpit.tsx"), - `export function AssessmentCockpit() {\n return
Northwall assessment cockpit with findings, graph, and remediation queue
;\n}\n`, + path.join(workspace, "src", "components", "MissionCockpit.tsx"), + `export function MissionCockpit() {\n return
Northwall AppSec mission cockpit with handoffs, graph, and remediation queue
;\n}\n`, "utf-8", ); await fs.writeFile( @@ -541,8 +541,8 @@ export class MissionManager { () => this.updateAgent(id, "auth-analyst", "working", "Reviewing session, tenant, and role boundaries"), () => this.completeTask(id, "t3", "auth-analyst", "Verified tenant export finding with safe local fixtures"), () => this.updateAgent(id, "runtime-verifier", "working", "Running approved local probes under scope rate limit"), - () => this.completeTask(id, "t4", "runtime-verifier", "Attached runtime evidence to webhook and session findings"), - () => this.updateAgent(id, "risk-reviewer", "working", "Ranking findings and writing remediation handoff"), + () => this.completeTask(id, "t4", "runtime-verifier", "Attached runtime evidence to webhook and session handoffs"), + () => this.updateAgent(id, "risk-reviewer", "working", "Ranking handoffs and writing remediation guidance"), () => this.completeTask(id, "t5", "risk-reviewer", "Prepared owner-ready remediation queue and verification steps"), () => this.finishSampleMission(id), ]; @@ -602,12 +602,12 @@ export class MissionManager { data.status = "completed"; data.completedAt = Date.now(); data.containerStatus = "running"; - data.vncUrl = createDesktopPreviewUrl("Assessment completed", "Findings, evidence, and remediation notes are ready."); + data.vncUrl = createDesktopPreviewUrl("Mission completed", "Owner handoffs, evidence, and remediation notes are ready."); data.agents = data.agents.map((agent) => ({ ...agent, status: "completed", currentAction: null })); - this.emitEvent(id, "agent_message", "Delivered system graph, evidence-backed findings, and remediation handoff.", { - text: "Delivered system graph, evidence-backed findings, and remediation handoff.", + this.emitEvent(id, "agent_message", "Delivered AppSec graph, evidence-backed handoffs, and remediation guidance.", { + text: "Delivered AppSec graph, evidence-backed handoffs, and remediation guidance.", }, "orchestrator"); - this.emitEvent(id, "session_completed", "Assessment completed"); + this.emitEvent(id, "session_completed", "Mission completed"); this.saveMission(id, true).catch((err) => console.error(`Save failed ${id}:`, err)); } @@ -960,9 +960,9 @@ function createPortfolioPlan(): MissionPlan { const now = Date.now(); return { id: `plan-${nanoid(8)}`, - title: "AcmePay AppSec Assessment", + title: "AcmePay AppSec Mission", objective: - "Map the owned AcmePay SaaS application, run a safe AppSec assessment, and produce evidence-backed findings with remediation steps.", + "Map the owned AcmePay SaaS application, run a safe AppSec mission, and produce evidence-backed owner handoffs with remediation steps.", estimatedComplexity: "complex", createdAt: now, agents: [ @@ -971,7 +971,7 @@ function createPortfolioPlan(): MissionPlan { displayName: "System Cartographer", specialization: "Application graph mapping", description: "Maps routes, services, auth boundaries, data stores, packages, and integrations.", - prompt: "Create a system graph first. Identify trust boundaries and risky paths. Do not run destructive checks.", + prompt: "Create an AppSec graph first. Identify trust boundaries and risky paths. Do not run destructive checks.", tools: ["Read", "Glob", "Grep", "Write"], model: "sonnet", }, @@ -998,7 +998,7 @@ function createPortfolioPlan(): MissionPlan { displayName: "Runtime Verifier", specialization: "Safe local verification", description: "Runs approved local probes against in-scope routes and records runtime evidence.", - prompt: "Verify findings only against approved local targets under rate limits. Stop before side effects.", + prompt: "Verify handoffs only against approved local targets under rate limits. Stop before side effects.", tools: ["Read", "Bash", "Write"], model: "sonnet", }, @@ -1007,7 +1007,7 @@ function createPortfolioPlan(): MissionPlan { displayName: "Risk Reviewer", specialization: "Evidence and remediation triage", description: "Deduplicates weak signals, ranks risk, assigns owners, and writes verification steps.", - prompt: "Turn evidence into a prioritized remediation queue mapped to ASVS, CWE, and owner workflows.", + prompt: "Turn evidence into prioritized owner handoffs mapped to ASVS, CWE, and owner workflows.", tools: ["Read", "Write"], model: "sonnet", }, @@ -1015,7 +1015,7 @@ function createPortfolioPlan(): MissionPlan { tasks: [ { id: "t1", - title: "Map system graph", + title: "Map AppSec graph", description: "Identify routes, services, packages, secrets, data stores, auth flows, and external integrations.", assignee: "system-cartographer", dependencies: [], @@ -1047,8 +1047,8 @@ function createPortfolioPlan(): MissionPlan { }, { id: "t5", - title: "Prioritize remediation queue", - description: "Deduplicate findings, map evidence to ASVS/CWE, assign owners, and write verification steps.", + title: "Prioritize owner handoffs", + description: "Deduplicate handoffs, map evidence to ASVS/CWE, assign owners, and write verification steps.", assignee: "risk-reviewer", dependencies: ["t3", "t4"], status: "pending", @@ -1088,14 +1088,14 @@ function createDesktopPreviewUrl(title: string, subtitle: string): string {

${escapeHtml(subtitle)}

Graph confidence

94%
-

Findings

4
+

Handoffs

4

High confidence

3

Owners

4
-

Live Assessment Preview

-

npm run dev completed. Findings, graph, and remediation queue are visible for review.

+

Live Mission Preview

+

npm run dev completed. Handoffs, graph, and remediation queue are visible for review.

diff --git a/packages/backend/src/services/openai-assessment.ts b/packages/backend/src/services/openai-assessment.ts index 03b6f48..fc411b4 100644 --- a/packages/backend/src/services/openai-assessment.ts +++ b/packages/backend/src/services/openai-assessment.ts @@ -58,9 +58,9 @@ export class OpenAIAssessmentService { if (!this.client) return fallbackPlan(input); const prompt = [ - "You are Northwall, a defensive Agentic SOC planning system for owned environments.", + "You are Northwall, a defensive Agentic AppSec orchestration system for owned environments.", "Return only JSON with keys: summary, agents, tasks, approvalNotes.", - "Treat the GitHub repository as one context source for a security operations run: code ownership, vulnerable paths, response handoff, and evidence.", + "Treat the GitHub repository as the first evidence source for an AppSec mission: code ownership, vulnerable paths, graph context, remediation handoff, and evidence.", "Keep all checks static, dependency, triage, and investigation oriented. Do not include exploit payloads, third-party scanning, credential collection, persistence, or destructive tests.", "Agents need id, name, title, focus, status. Tasks need id, title, agentId, dependsOn, status, evidence.", "", @@ -85,11 +85,11 @@ export class OpenAIAssessmentService { if (!this.client) return fallbackFindings(input); const prompt = [ - "You are Northwall, a defensive Agentic SOC evidence reviewer.", - "Given a repository inventory and investigation graph, produce security-operations findings only when evidence is concrete.", + "You are Northwall, a defensive Agentic AppSec evidence reviewer.", + "Given a repository inventory and AppSec knowledge graph, produce owner handoffs only when evidence is concrete.", "Return only JSON with key findings. Each finding needs id, title, severity, confidence, status, affectedNodes, evidence, impact, remediation, labels, issueTitle, issueBody.", "Evidence items need path, optional line, optional excerpt. Do not reveal secret values; describe config references without copying values.", - "Write findings as owner handoffs for alert triage, threat investigation, response planning, or remediation. Keep human approval in the loop.", + "Write findings as owner handoffs for AppSec triage, specialist investigation, response planning, or remediation. Keep human approval in the loop.", "", JSON.stringify(input, null, 2), ].join("\n"); @@ -111,7 +111,7 @@ export class OpenAIAssessmentService { function normalizePlan(plan: AssessmentPlan, input: PlanningInput): AssessmentPlan { if (!plan.agents?.length || !plan.tasks?.length) return fallbackPlan(input); return { - summary: plan.summary || `Run an Agentic SOC investigation on ${input.repo.fullName}: map context, triage risk, plan response, and prepare owner handoff.`, + summary: plan.summary || `Run an Agentic AppSec mission on ${input.repo.fullName}: map graph context, triage risk, plan specialist work, and prepare owner handoff.`, agents: plan.agents.map((agent) => ({ ...agent, status: agent.status ?? "queued", @@ -142,11 +142,11 @@ function normalizeFindings(findings: VulnerabilityFinding[], input: PlanningInpu function fallbackPlan(input: PlanningInput): AssessmentPlan { return { - summary: `Run an Agentic SOC investigation on ${input.repo.fullName} (${input.branch}): build context, triage risk, review sensitive paths, and prepare owner-ready work items.`, + summary: `Run an Agentic AppSec mission on ${input.repo.fullName} (${input.branch}): build graph context, triage risk, run specialist reviews, and prepare owner-ready work items.`, agents: [ - { id: "cartographer", name: "Rhea", title: "Incident Cartographer", focus: "Map services, owners, auth boundaries, config, CI, and dependency surfaces.", status: "queued" }, - { id: "triage-agent", name: "Kade", title: "Alert Triage Agent", focus: "Separate weak signals from issues that need investigation or owner action.", status: "queued" }, - { id: "threat-investigator", name: "Mira", title: "Threat Investigator", focus: "Review sensitive paths, dependency context, and likely blast radius.", status: "queued" }, + { id: "cartographer", name: "Rhea", title: "System Cartographer", focus: "Map services, owners, auth boundaries, config, CI, and dependency surfaces.", status: "queued" }, + { id: "triage-agent", name: "Kade", title: "AppSec Triage Agent", focus: "Separate weak signals from issues that need investigation or owner action.", status: "queued" }, + { id: "threat-investigator", name: "Mira", title: "Specialist Investigator", focus: "Review sensitive paths, dependency context, and likely blast radius.", status: "queued" }, { id: "handoff-writer", name: "Nova", title: "Response Handoff Writer", focus: "Convert evidence into owner-ready work item drafts with verification steps.", status: "queued" }, ], tasks: [ @@ -156,7 +156,7 @@ function fallbackPlan(input: PlanningInput): AssessmentPlan { { id: "t4", title: "Prepare owner handoff drafts", agentId: "handoff-writer", dependsOn: ["t2", "t3"], status: "queued", evidence: [] }, ], approvalNotes: [ - "Only safe triage, static, dependency, and owner-handoff checks will run.", + "Only safe graph building, static, dependency, and owner-handoff checks will run.", "No third-party hosts, destructive actions, credential collection, or exploit payload output.", "Human approval is required before creating work items.", ], @@ -169,7 +169,7 @@ function fallbackFindings(input: PlanningInput): VulnerabilityFinding[] { if (input.inventory.authFiles.length > 0 && input.inventory.routes.length > 0) { findings.push({ id: "BG-101", - title: "Auth-sensitive route belongs in the SOC response queue", + title: "Auth-sensitive route belongs in the AppSec owner queue", severity: "high", confidence: "medium", status: "open", @@ -180,8 +180,8 @@ function fallbackFindings(input: PlanningInput): VulnerabilityFinding[] { ], impact: "The route and auth-sensitive code sit in the same request path; the owning team should confirm exposure before the case closes.", remediation: "Assign the owner, add tests for cross-tenant access, and verify every route derives tenant/workspace from the authenticated session.", - labels: ["soc", "backend"], - issueTitle: "[Northwall] SOC handoff: review auth-sensitive route ownership", + labels: ["appsec", "backend"], + issueTitle: "[Northwall] AppSec handoff: review auth-sensitive route ownership", issueBody: "", }); } @@ -189,7 +189,7 @@ function fallbackFindings(input: PlanningInput): VulnerabilityFinding[] { if (input.inventory.packageFiles.length > 0) { findings.push({ id: "BG-102", - title: "Dependency signal needs SOC triage before release", + title: "Dependency signal needs AppSec triage before release", severity: input.inventory.dependencies.length > 50 ? "medium" : "low", confidence: "high", status: "open", @@ -197,8 +197,8 @@ function fallbackFindings(input: PlanningInput): VulnerabilityFinding[] { evidence: input.inventory.packageFiles.map((file) => ({ path: file })).slice(0, 4), impact: "Deployable packages should be checked for known advisories and lockfile drift before the change moves into the incident path.", remediation: "Run dependency audit in CI, pin patched versions, and fail builds on known vulnerable production dependencies.", - labels: ["soc", "dependencies"], - issueTitle: "[Northwall] SOC handoff: review production dependency risk", + labels: ["appsec", "dependencies"], + issueTitle: "[Northwall] AppSec handoff: review production dependency risk", issueBody: "", }); } @@ -214,8 +214,8 @@ function fallbackFindings(input: PlanningInput): VulnerabilityFinding[] { evidence: input.inventory.configFiles.map((file) => ({ path: file })).slice(0, 4), impact: "Configuration and environment files define sensitive runtime behavior and can change the response path.", remediation: "Keep example env files value-free, enforce secret scanning in CI, and document required runtime secrets separately.", - labels: ["soc", "config"], - issueTitle: "[Northwall] SOC handoff: review runtime configuration", + labels: ["appsec", "config"], + issueTitle: "[Northwall] AppSec handoff: review runtime configuration", issueBody: "", }); } diff --git a/packages/frontend/src/app/layout.tsx b/packages/frontend/src/app/layout.tsx index d74bbf7..d9ae30f 100644 --- a/packages/frontend/src/app/layout.tsx +++ b/packages/frontend/src/app/layout.tsx @@ -16,9 +16,47 @@ const brandMono = IBM_Plex_Mono({ }); export const metadata: Metadata = { - title: "Northwall — Agentic SOC platform", + title: { + default: "Northwall - Agentic AppSec Orchestration", + template: "%s | Northwall", + }, description: - "Multi-agent security operations for alert triage, investigation graphs, response plans, and remediation work items.", + "Northwall runs AppSec missions with specialist AI agents, parallel MoE orchestration, application security knowledge graphs, human approval gates, and owner-ready remediation handoff.", + keywords: [ + "agentic AppSec orchestration", + "AI application security", + "multi-agent security", + "AppSec knowledge graph", + "parallel security agents", + "MoE agents", + "AI code security", + "application security automation", + "security remediation workflow", + "owner-ready remediation", + "GitHub security review", + "dependency reachability", + "CI/CD security", + "OWASP ASVS", + "CWE", + "CVSS", + "EPSS", + "SBOM", + "SAST", + "SCA", + ], + openGraph: { + title: "Northwall - Agentic AppSec Orchestration", + description: + "Build an AppSec knowledge graph, dispatch parallel specialist AI agents, approve governed missions, and send owner-ready remediation work.", + siteName: "Northwall", + type: "website", + }, + twitter: { + card: "summary", + title: "Northwall - Agentic AppSec Orchestration", + description: + "Specialist AI agents, AppSec knowledge graphs, parallel investigation, human approval, and owner-ready remediation handoff.", + }, icons: [{ rel: "icon", url: "/favicon.svg", type: "image/svg+xml" }], }; diff --git a/packages/frontend/src/app/login/page.tsx b/packages/frontend/src/app/login/page.tsx index 833a1da..6c92c98 100644 --- a/packages/frontend/src/app/login/page.tsx +++ b/packages/frontend/src/app/login/page.tsx @@ -25,14 +25,14 @@ export default async function LoginPage() {

- Agentic SOC, starting with real context. + Agentic AppSec orchestration, starting with real source context.

- Northwall brings agents into security operations: triage alerts, build the investigation graph, draft the response plan, and send the work to the right owner. + Northwall builds an AppSec graph, dispatches specialist agents across code and ownership context, and sends approved remediation work to the right owner.

-
SOC triage
-
Agent graph
+
Agent missions
+
AppSec graph
Owner handoff
@@ -41,7 +41,7 @@ export default async function LoginPage() {

Sign in

- GitHub is the first connector for code context and remediation work items. + GitHub is the first connector for source context and approved remediation work.

diff --git a/packages/frontend/src/app/page.tsx b/packages/frontend/src/app/page.tsx index f092a4a..b5932a5 100644 --- a/packages/frontend/src/app/page.tsx +++ b/packages/frontend/src/app/page.tsx @@ -1,16 +1,290 @@ import Link from "next/link"; -import { ArrowUpRight } from "lucide-react"; +import type { LucideIcon } from "lucide-react"; +import { + ArrowRight, + ArrowUpRight, + Braces, + BrainCircuit, + CheckCircle2, + GitBranch, + LockKeyhole, + Network, + PackageCheck, + Route, + SearchCheck, + Settings2, + ShieldCheck, + Split, + UserCheck, + Workflow, +} from "lucide-react"; import { NorthwallLogo, NorthwallMark } from "@/components/logo"; -const steps = [ - ["01", "Connect source", "GitHub repo, branch, owners, CI, and package context."], - ["02", "Review plan", "Agent team, task order, evidence goals, and approval notes."], - ["03", "Create issues", "Approved findings become owner-ready GitHub work items."], +type Step = { + number: string; + title: string; + body: string; + icon: LucideIcon; +}; + +type Detail = { + title: string; + body: string; + icon?: LucideIcon; +}; + +const steps: Step[] = [ + { + number: "01", + title: "Connect GitHub context", + body: "Start with a repo, branch, owners, routes, packages, auth boundaries, config, and CI/CD evidence.", + icon: GitBranch, + }, + { + number: "02", + title: "Build the AppSec graph", + body: "Map services, files, dependencies, routes, controls, owners, risks, and remediation work as linked context.", + icon: Network, + }, + { + number: "03", + title: "Approve the agent mission", + body: "Review the agent team, task DAG, evidence goals, policy limits, and approval notes before execution starts.", + icon: Workflow, + }, + { + number: "04", + title: "Run parallel specialists", + body: "Dispatch MoE-style agents for auth, dependencies, ownership, config, CI, and threat context in parallel.", + icon: Split, + }, + { + number: "05", + title: "Send owner handoffs", + body: "Turn approved evidence into concise remediation work with owner context, verification steps, and GitHub handoff.", + icon: CheckCircle2, + }, +]; + +const missionMetrics = [ + ["Context", "Repo, branch, owners, routes, packages"], + ["Planner", "Task DAG, approval gates, evidence goals"], + ["Specialists", "Auth, dependency, config, CI/CD, threat"], + ["Output", "Owner handoff with verification steps"], +]; + +const advantages: Detail[] = [ + { + title: "Agentic execution", + body: "Northwall runs governed AppSec missions. It plans work, executes with tools, gathers evidence, and pauses for approval where human judgment matters.", + icon: BrainCircuit, + }, + { + title: "Multi-agent orchestration", + body: "Security work is split across named agents with clear responsibilities, dependencies, task order, and status visible during the run.", + icon: Workflow, + }, + { + title: "Parallel MoE specialists", + body: "The mission planner routes work to focused agents instead of asking one general model to reason through every risk surface sequentially.", + icon: Split, + }, + { + title: "AppSec knowledge graph", + body: "A living graph links code, services, owners, routes, packages, controls, findings, and handoffs so every action has context.", + icon: Network, + }, +]; + +const technicalLayers: Detail[] = [ + { + title: "Graph-first context", + body: "Entity resolution, graph traversal, and relationship-aware retrieval help agents reason about routes, packages, owners, controls, and blast radius together.", + }, + { + title: "MoE-style agent routing", + body: "A planner breaks missions into specialist tracks for authentication, dependency reachability, CI/CD policy, configuration exposure, and owner routing.", + }, + { + title: "Task DAGs and approval gates", + body: "Northwall turns AppSec work into an execution graph with ordered tasks, dependencies, human review points, and auditable decisions.", + }, + { + title: "Evidence-grounded RAG", + body: "Agents should ground reasoning in repo inventory, code paths, package metadata, runtime notes, and prior decisions instead of producing generic advice.", + }, + { + title: "Bounded ReAct-style loops", + body: "Specialists inspect, reason, call tools, summarize evidence, and stop at safe AppSec outputs rather than drifting into open-ended investigation.", + }, + { + title: "Security vocabulary built in", + body: "The workflow can speak in terms of CWE, CVE, CVSS, EPSS, OWASP ASVS, SLSA, OSSF Scorecard, SBOM, SAST, SCA, and dependency reachability.", + }, +]; + +const useCases: Detail[] = [ + { + title: "Auth and tenant-boundary review", + body: "Trace session handling, middleware, role checks, route guards, and permission-sensitive code paths before owners receive remediation work.", + icon: LockKeyhole, + }, + { + title: "Dependency and package exposure", + body: "Connect package findings to lockfiles, reachable code paths, owners, release context, and practical fix guidance.", + icon: PackageCheck, + }, + { + title: "CI/CD and configuration checks", + body: "Review pipeline defaults, secret handling, branch controls, deploy gates, and environment-sensitive configuration with specialist context.", + icon: Settings2, + }, + { + title: "Application route and API context", + body: "Map routes, handlers, edge functions, webhooks, and service boundaries so risk is tied to the system surface security teams care about.", + icon: Route, + }, + { + title: "Owner-ready remediation", + body: "Create handoffs that include evidence, priority, affected area, suggested action, and verification steps for the responsible owner.", + icon: UserCheck, + }, + { + title: "Security leader review", + body: "Give AppSec leaders one place to inspect mission scope, agent behavior, evidence quality, approvals, and handoff status.", + icon: SearchCheck, + }, ]; +const agents: Detail[] = [ + { + title: "System Cartographer", + body: "Builds the AppSec graph across source, routes, packages, owners, controls, and CI/CD context.", + }, + { + title: "Auth Boundary Agent", + body: "Reviews session, tenant, middleware, and permission-sensitive paths with OWASP ASVS-style framing.", + }, + { + title: "Dependency Analyst", + body: "Connects package risk to lockfiles, reachable code paths, release notes, and owner context.", + }, + { + title: "CI/Config Analyst", + body: "Inspects branch rules, workflow defaults, secret handling, deploy gates, and configuration drift.", + }, + { + title: "Threat Context Agent", + body: "Adds CWE, CVE, CVSS, EPSS, exploit maturity, and business exposure context where it is useful.", + }, + { + title: "Response Handoff Agent", + body: "Turns approved evidence into remediation work with owner, priority, rationale, and verification steps.", + }, +]; + +const comparisons = [ + { + alternative: "Scanners", + usefulFor: "Detecting known patterns and producing raw finding queues.", + northwall: "Organizing evidence into graph-backed missions and owner-ready action.", + }, + { + alternative: "AI code review bots", + usefulFor: "Commenting on diffs, pull requests, or narrow code snippets.", + northwall: "Coordinating specialist agents across source, dependencies, owners, controls, and handoff.", + }, + { + alternative: "Ticket queues", + usefulFor: "Tracking work after someone has already translated the risk.", + northwall: "Producing the translation: evidence, owner, action, priority, and verification path.", + }, + { + alternative: "Manual AppSec triage", + usefulFor: "Expert judgment, exception handling, and final approval.", + northwall: "Doing the repeatable investigation work before the reviewer makes the decision.", + }, +]; + +const faqs = [ + { + question: "What is agentic AppSec orchestration?", + answer: + "Agentic AppSec orchestration is a way to run application security work through planned AI missions. The system builds context, assigns work to specialist agents, runs evidence gathering, and keeps humans in control before remediation is sent to owners.", + }, + { + question: "Is Northwall just an AI code review tool?", + answer: + "No. GitHub is the first execution surface, but the product is positioned as an AppSec operations layer. Code review is one input. Northwall also focuses on graph context, owner mapping, dependency context, approval-gated missions, and remediation handoff.", + }, + { + question: "Does Northwall replace SAST, SCA, DAST, or cloud security tools?", + answer: + "No. Northwall is designed to work around those security signals, not replace them. The current product starts with GitHub application context, while SAST, SCA, DAST, SBOM, SIEM, EDR, cloud, Jira, and evidence-store connectors are extension paths.", + }, + { + question: "What are parallel MoE security agents?", + answer: + "MoE means mixture of experts. In Northwall, it means routing a mission to focused security agents such as an auth boundary agent, dependency analyst, CI/config analyst, system cartographer, and response handoff agent instead of relying on one generic agent.", + }, + { + question: "Why does the AppSec knowledge graph matter?", + answer: + "Security findings are easier to act on when they are connected to services, routes, packages, owners, controls, and prior decisions. The graph helps agents and reviewers understand impact, ownership, and remediation sequence.", + }, + { + question: "How does Northwall keep humans in control?", + answer: + "Northwall shows the mission plan before execution, uses approval gates, streams agent activity, and drafts owner handoffs for review. The goal is governed execution, not a black-box security bot.", + }, +]; + +const schema = { + "@context": "https://schema.org", + "@graph": [ + { + "@type": "Organization", + "@id": "https://inferensys.com/#organization", + name: "Inferensys", + url: "https://inferensys.com/", + }, + { + "@type": "SoftwareApplication", + "@id": "https://github.com/Inferensys/northwall#software", + name: "Northwall", + applicationCategory: "SecurityApplication", + operatingSystem: "Web", + publisher: { "@id": "https://inferensys.com/#organization" }, + description: + "Northwall is Agentic AppSec orchestration for security teams. It builds application graph context, dispatches specialist AI agents, and turns approved evidence into owner-ready remediation work.", + featureList: [ + "Agentic AppSec missions", + "AppSec knowledge graph", + "Multi-agent orchestration", + "Parallel MoE security agents", + "Human approval gates", + "Owner-ready remediation handoff", + ], + sameAs: ["https://github.com/Inferensys/northwall"], + }, + { + "@type": "FAQPage", + "@id": "https://github.com/Inferensys/northwall#faq", + mainEntity: faqs.map((faq) => ({ + "@type": "Question", + name: faq.question, + acceptedAnswer: { + "@type": "Answer", + text: faq.answer, + }, + })), + }, + ], +}; + function SignalField() { return ( -
+
{Array.from({ length: 64 }).map((_, index) => { @@ -44,11 +318,35 @@ function SignalField() { ); } +function SectionIntro({ + eyebrow, + title, + body, +}: { + eyebrow: string; + title: string; + body?: string; +}) { + return ( +
+

{eyebrow}

+

+ {title} +

+ {body &&

{body}

} +
+ ); +} + export default function LandingPage() { return (
-
-
+