AI-powered autonomous penetration testing system (Go backend + Next.js frontend)
This repository is the English port of Autumn-27/ARTEX. It includes English interface text, backend messages, agent prompts, documentation, bundled skills, and screenshots.
Build from this repository to use the English edition. Upstream demos, published Docker images, and prebuilt releases are maintained separately and may still contain the original interface.
🌐 Online demo: artex-demo.vercel.app
The images below are fresh page screenshots of the local English interface in demo mode. Demo records are simulated. The public upstream demo is maintained separately and may use another language.
| Dashboard: overview, token usage, activity | Tasks |
|---|---|
| Task execution: sessions and tool calls | Exploration graph (zoomed for readable labels) |
|---|---|
| Findings | Assets |
|---|---|
| Asset coverage: force layout, tested highlights, expandable nodes |
|---|
| Traffic recordings | Human-in-the-loop chat |
|---|---|
| Agent management | LLM profiles |
|---|---|
| Interception approvals | Backend logs |
|---|---|
Additional English interface captures:
| Skills | Tools |
|---|---|
| MCP connections | System settings |
|---|---|
| Notifications | Approval history |
|---|---|
| Asset blocking | Asset synchronization |
|---|---|
| Workspace | Tool executions |
|---|---|
| LLM recordings | Notification delivery history |
|---|---|
Reproduce these captures against the local demo with scripts/capture_english_screenshots.py (requires Playwright). The script also checks visible text on every captured page and a mobile viewport. Run python3 scripts/check_english.py to audit repository text and filenames; CI runs the same check.
Expand global Approval history, task-level Interception approvals, or approval cards in chat to inspect details. The layout references AegisHook’s approval detail component, using ARTEX components and themes.
Import assets directly from ScopeSentry without collecting them again:
- Enter the ScopeSentry address and API key on Asset sync.
- Select projects or tasks and the asset types to import: domains, subdomains, IPs, ports, sites, endpoints, and more.
- Import and assign assets through company scopes. They become available in ARTEX's shared asset graph immediately.
Requires PostgreSQL. Autonomous exploration also requires an LLM, configured with ANTHROPIC_API_KEY, OPENAI_API_KEY, or the UI.
git clone https://github.com/RikunjSindhwad/ARTEX.git
cd ARTEX
./install.shChoose Local build for this fork’s English source. Docker uses the separately published upstream image. The script detects or installs Docker and offers two deployment modes:
- Docker: enter a PostgreSQL password, or accept a generated one. The script writes
.envand runsdocker compose up -d. - Local build: connect to an existing database or start PostgreSQL in Docker, generate
config.json, build a binary with the embedded frontend, and run it.
Open http://localhost:8787. On first use, /setup lets you set the administrator password.
git clone https://github.com/RikunjSindhwad/ARTEX.git
cd ARTEX
cp .env.example .env # Set POSTGRES_PASSWORD and optionally ANTHROPIC_API_KEY
docker compose up -d # Pull autumn27/artex and PostgreSQL
# Open http://localhost:8787The image includes common tools such as ripgrep, curl, vim, npm, and nmap. Bind mounts preserve ./skills and ./data.
Remote MCP connections support http (Streamable HTTP) and legacy sse in System settings. Legacy SSE servers usually open an event stream with GET /sse and accept JSON-RPC at the returned /message?sessionId=... endpoint. Configure the /sse URL and headers such as Authorization=Bearer <token>.
Upstream binaries may not include this fork’s English changes. Download the appropriate ZIP from Releases. It contains artex, start.sh (start.bat on Windows), skills/, and config.example.json.
cp config.example.json config.json # Configure the database connection
./start.sh # Open http://localhost:8787Use start.sh or start.bat to run a prebuilt release. These supervisors restart the program after in-app updates; starting ./artex directly cannot restart it after replacement. For background operation: nohup ./start.sh >artex.log 2>&1 &.
# Export the static frontend
cd web && npm ci && npm run build:static && cd ..
# Copy into the embedded frontend directory
mkdir -p server/webui
cp -r web/out server/webui/dist
# The embedui tag embeds the frontend
CGO_ENABLED=0 go build -tags embedui -o artex ./cmd/artex
./start.shbuild.sh builds and embeds the frontend, strips debug information with the Go linker, and packages ZIP archives. Release mode defaults to Linux amd64/arm64, macOS amd64/arm64, and Windows amd64:
./build.sh --release
# Output: dist/artex-<version>-*.zipUPX is disabled by default because self-extracting binaries may be incompatible with some Linux kernels, virtualized environments, or security policies. Override the target list with ARTEX_TARGETS; use --upx only after confirming target compatibility:
ARTEX_TARGETS=linux/amd64,windows/amd64 ./build.sh --release
./build.sh --target linux/amd64 --upxUpgrades replace the program while preserving PostgreSQL's pgdata volume, ./data (including jwt.key and SQLite files), and ./skills. Database migrations run automatically: each startup reapplies the idempotent schema.sql, including ADD COLUMN and CREATE INDEX IF NOT EXISTS. Back up the database and ./data before upgrading.
Open System settings → Version and updates (/system/settings) to check for and install releases without signing into the server. The updater downloads the current-platform archive, verifies SHA256SUMS, smoke-tests the new binary with -h, stages artex.new, and exits. start.sh / start.bat restarts ARTEX and installs the replacement. The page waits for the new version and refreshes.
- Failed verification or smoke tests discard the staged binary and keep the current version. Three consecutive startup failures automatically roll back to
artex.old, preserving the failed binary asartex.failed. - Roll back to previous version restores
artex.old; database schema changes are not rolled back. - Updates restart the program and interrupt running tasks. Update during idle periods.
- Development builds (
devor suffixedgit describeversions) cannot update, preventing release binaries from overwriting local debug builds. - In-app updates use this fork’s fixed release source,
RikunjSindhwad/ARTEX; no upstream fallback is used if this fork has no published release. In Docker, in-app updates replace only the binary. Toolchains such as Playwright and nmap remain unchanged, and container recreation restores the image’s binary. Usedocker compose pull artex && docker compose up -d artexto update the image. - The Global proxy setting also applies to updates. Downloads use HTTPS and GitHub domains only.
cd ARTEX
./update.shOptionally pull current source, then choose Docker or local update:
- Docker: select an image tag, or keep
.env'sARTEX_TAG(defaultlatest). Pull and recreate containers; startup applies migrations. - Local: rebuild static frontend output and
./artex, then restart the process.
cd ARTEX
git pull # Optional: update compose files and scripts
# Set ARTEX_TAG=v0.2.0 in .env to pin a version; default is latest
docker compose pull artex
docker compose up -d artex # Restart applies schema migrations
docker image prune -f # Optional: remove old imagesUse this fork’s Releases when an English release is available. Upstream binaries do not include this fork’s English conversion. Download the new ZIP. Stop the old process and replace artex and skills/, preserving config.json and data/.
cp -r <extracted-directory>/skills ./ && cp <extracted-directory>/artex ./
./start.shgit pull
cd web && npm ci && npm run build:static && cd ..
mkdir -p server/webui
cp -r web/out server/webui/dist
CGO_ENABLED=0 go build -tags embedui -o artex ./cmd/artex
# Restart ./start.shDatabase: set config.json, or override it with ARTEX_PG_DSN.
{
"database": {
"host": "127.0.0.1", "port": 5432,
"user": "artex", "password": "yourpass",
"dbname": "artex", "sslmode": "disable"
}
}LLM: export ANTHROPIC_API_KEY=sk-... or OPENAI_API_KEY, or configure an LLM profile in the UI. Optional environment variables: ARTEX_LLM_PROVIDER, ARTEX_LLM_MODEL, ARTEX_LLM_BASE_URL, and ARTEX_LLM_PROXY.
Concurrency: set workers per task in System settings (default 3).
Listening addresses: ./start.sh -addr :8787 -proxy :8788. -addr serves the frontend/API; -proxy serves traffic recording. The supervisor forwards arguments unchanged.
Language: shipped interface text, reports, prompts, logs, scripts, and examples use English. Dates and numbers use English formatting. Existing user-authored content and captured evidence retain their original content.
The frontend, API, and SSE share the backend port (default :8787). Production activity streams use the same origin, so NEXT_PUBLIC_SSE_BASE is unnecessary. Expose HTTPS port 443 and keep 8787 private. Disable proxy buffering for SSE; otherwise the browser may connect but receive no events.
server {
listen 443 ssl;
server_name your.domain.com;
# Configure ssl_certificate and ssl_certificate_key.
location / {
proxy_pass http://127.0.0.1:8787;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
# SSE requires no buffering, a long timeout, and HTTP/1.1.
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}Set NEXT_PUBLIC_SSE_BASE at build time only when SSE must use a different origin, such as another subdomain. Next.js embeds it in the static bundle; setting it at container runtime has no effect.
The task’s Retest tab offers paginated finding selection, historical conclusions and evidence, and manual retest requests. Starting a retest preserves the current tab and shows a spinner with Retesting; a confirmed fix updates the finding’s remediation status.
Choose Retest on a finding row, or Start retest in finding details, and optionally provide a fixed version, test conditions, or constraints. ARTEX creates a separate retest-agent session without restarting the original scan. Flat, task-grouped, and asset views all support this action. Open the running session when needed; the action returns to Retest after completion. Conclusions are Still reproducible, Fixed, or Inconclusive, with evidence and a session link saved in finding details.
On first startup the backend seeds an editable retester agent. Configure its prompt, LLM, run budget, and tools in Agent management. It uses its assigned LLM or the globally active profile. Only a successfully completed Fixed retest automatically marks the finding fixed; running, failed, stopped, or other conclusions preserve its status. Original evidence and reports remain available. Status can also be changed manually. Concurrent requests reuse an existing retest session; stopped or failed sessions and service restarts allow a new retest.
History is currently available in finding details and sessions; it is not included in finding-report exports or task archives, and traffic packets are not linked automatically. Demo mode creates clearly labeled simulated records without contacting real targets.
./dev.sh # Backend :8787, recording proxy :8788, Next frontend at http://localhost:3000- Backend:
go run ./cmd/artex; omit-tags embeduito run without embedded frontend. - Frontend:
cd web && npm run dev;/apiproxies to the backend with hot reload. - Tests:
go test ./.... - Frontend type check:
cd web && npx tsc --noEmit. - English source audit, including documentation and skills:
python3 scripts/check_english.py. - Mock preview without backend:
cd web && NEXT_PUBLIC_MOCK=1 npm run dev.
ARTEX uses multiple LLM agents, a Go monolith with an embedded Next.js frontend, and PostgreSQL. The norma SDK provides agentcore, tool, permission, harness, memory, and transcript capabilities. Its core is a dual graph, with cross-worker trace sharing and persistent planner todos supporting autonomous execution.
flowchart TB
subgraph FE["Next.js frontend embedded with go:embed"]
UI["Dashboard · Tasks · Assets · Coverage · Traffic · Workspace · Settings"]
end
subgraph SRV["Go net/http server"]
API["REST /api/* · JWT · SSE"]
ENG["Engine scheduling loops"]
MGR["Manager: task, engine, and store lifecycle"]
end
subgraph AG["Agents: norma SDK"]
GO["Goals: decompose outcomes and extract scope"]
PL["Planner: generate intents"]
WK["Workers: execute intents"]
MA["Main agent: human interface"]
end
subgraph DB["PostgreSQL"]
AGRAPH["Asset graph: assets / companies / task_scope"]
EGRAPH["Exploration graph: exploration_nodes / anchors / activity"]
end
subgraph SUB["Supporting systems"]
PROXY["Recording proxy: MITM and CA"]
GUARD["Guard / interception approvals"]
ENR["Asynchronous DNS / HTTP enrichment"]
EXT["MCP · Skills · Memory · Reports"]
end
UI -->|HTTP| API
API --> MGR --> ENG
ENG --> PL
ENG --> WK
API --> MA
API --> GO
PL --> DB
WK --> DB
MA --> DB
GO --> DB
WK -->|Bash / HTTP recording| PROXY
WK --> GUARD
WK --> ENR
PL -.-> EXT
WK -.-> EXT
MA -.-> EXT
| Layer | Responsibility |
|---|---|
| Frontend | Static Next.js output embedded in one binary; visualize tasks, assets, exploration, coverage, and operator chat. |
| Server | HTTP routes, JWT authentication, SSE, and Manager-owned task/engine/store lifecycles. |
| Engine | One planner loop and N worker goroutines per task; intent claiming, deadlines, pause, and drain. |
| Agent | Goals/planner/worker/mainagent roles; ToolSet exposes the graphs as LLM tools. |
| Database | PostgreSQL/pgx persistence and embedded, idempotent startup schema. |
| Supporting systems | MITM recording, approvals, asynchronous enrichment, MCP, skills, memory, and reports. |
- Shared asset graph: global source of truth for
root_domain / subdomain / ip / service / app / endpoint, grouped by company. Code calculates hierarchy and deduplication keys; agents submit raw data. - Per-task exploration graph:
goal / intent / fact / finding / hintnodes connected throughspawns / derived_from / yields / proves, recording which evidence produced each direction and result. - Anchors:
exploration_anchors(node_id, asset_id)connects exploration nodes to assets. Query targets from an intent, or find tests/conclusions for an asset. These links power estimated coverage and tested-asset highlighting.
flowchart LR
subgraph EG["Per-task exploration graph"]
direction TB
G["Goal"] -->|spawns| I1["Intent A"]
I1 -->|yields| F1["Fact"]
F1 -->|derived_from| I2["Intent B"]
I2 -->|proves| FD["Finding"]
end
subgraph AG["Shared asset graph"]
direction TB
RD["root_domain"] --> SD["subdomain"] --> SV["service"] --> EP["endpoint"]
end
I1 -. anchor .-> SD
F1 -. anchor .-> SV
I2 -. anchor .-> EP
FD -. anchor .-> EP
The planner reads the situation, assesses goals, and dispatches only uncovered directions. Each worker executes one intent, writes assets/facts/findings, then stops.
Graph changes wake the planner through debounce. New intents enter the frontier; workers claim, execute, and record results. New evidence wakes the planner again until prove_goal establishes completion.
sequenceDiagram
autonumber
participant EV as Debounced graph changes
participant P as Planner
participant FR as Intent frontier
participant W as Worker
participant PX as Recording proxy
participant DB as Graphs and activity
EV-->>P: Wake
P->>DB: Read prefetched overview, scope, and coverage
P->>FR: Dispatch 0..N intents with asset_ids
Note over P,FR: Zero is normal when no direction is uncovered
W->>FR: Claim one intent
W->>DB: Read raw assets referenced by asset_ids
W->>PX: Execute tools: Kali / Bash / HTTP
PX-->>W: Recorded response with CA verification
W->>DB: Save facts, assets, findings, and step activity
DB-->>EV: Graph changed
EV-->>P: Wake again
Useful observations, including errors, response fragments, and hidden parameters, may exist in execution traces before becoming formal facts. Workers can reuse these observations without repeating work:
search_all_worker_traces(q)searches other workers in the same task, automatically excluding the caller and returningintent_id.list_worker_traceslocates previous work;get_worker_trace(intent_id, step_ids=[...])fetches specific full steps.
Workers keep their assigned-intent boundaries while sharing execution-level information.
flowchart LR
WA["Worker A: intent 12"] -->|Step activity| ACT[("Exploration activity")]
WB["Worker B: intent 34"] -->|Step activity| ACT
WC["Worker C: intent 56"] ==>|1. Search traces| ACT
ACT ==>|2. Matching A/B step IDs| WC
WC ==>|3. Fetch full steps| ACT
ACT ==>|4. Complete trace content| WC
Dependent chains, such as injection → credentials → lateral movement → privilege escalation, must run sequentially. Each planner wake-up uses a fresh session, while its task-level TodoWrite store persists. The planner records the chain once, dispatches only steps with real prerequisite facts, and marks completed steps as evidence arrives.
flowchart TB
subgraph TODO["Task-level persistent todos"]
direction LR
T1["1. Injection: completed"] -. prerequisites met .-> T2["2. Credentials: in progress"]
T2 -.-> T3["3. Lateral movement: waiting"] -.-> T4["4. Escalation: waiting"]
end
R1["Wake 1: dispatch intent 1"] --> T1
R2["Wake 2: fact from intent 1; dispatch intent 2"] --> T2
R3["Wake 3: fact from intent 2; dispatch intent 3"] --> T3
This preserves ordering and avoids duplicate work across event-driven, stateless sessions.
The upstream community is hosted through the SecSentry WeChat public account. Follow that account and send a private message to request access to the group.
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See LICENSE for the complete terms.
Anyone may use, modify, and distribute the project, but derivative works must also be released under AGPL-3.0. In particular, if you modify the project and provide it to users over a network, such as an online service, you must make the complete corresponding source code available to those users.
The open-source license itself does not restrict fields of use. The usage restrictions and disclaimer below are additional conditions and statements made by the original author.
ARTEX is intended only for personal learning, source-code research, and local technical validation. It must not be used to conduct actual tests against any online system or website.
- Read, study, and research the source code, and validate technical principles in a local, isolated environment.
- Personal learning, academic research, code review, and other non-offensive activities.
- Do not scan, probe, exploit, or attack websites, online services, or networked systems, regardless of authorization or ownership.
- Do not use this tool for actual penetration testing, attack-and-defense engagements, or production environments.
- Do not use it for unauthorized intrusion, data theft, extortion, denial of service, or other destructive or criminal activities.
- Do not use it in violation of applicable laws or regulations.
Users are responsible for complying with all applicable cybersecurity, data-protection, and computer-crime laws and regulations in their jurisdiction. In mainland China, these include the Cybersecurity Law, Data Security Law, Personal Information Protection Law, and related judicial interpretations. Users bear all legal responsibility and consequences arising from use of this tool.
The project is provided AS IS, without express or implied warranties. The authors and contributors accept no liability for direct or indirect losses, data loss, system damage, or legal disputes resulting from its use, whether proper or improper. Downloading, installing, or using this project means that you have read, understood, and agreed to all the terms above.