Lompat ke konten
dokumentasi.id
Commit 51864a8
v1
Star1,9 rb

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

2

Arsitektur Sistem

Guardian tersusun sebagai empat lapisan yang saling bergantung: lapisan CLI, lapisan engine workflow, lapisan agen, dan lapisan tool. Setiap lapisan hanya berbicara ke lapisan di bawahnya lewat satu antarmuka sempit, sehingga penggantian provider AI atau penambahan wrapper tool tidak menyentuh kode CLI.

Diagram lapisan

graph TD
    CLI["cli/main.py — Typer app"]:::config
    CMD["cli/commands/* — init | scan | recon | analyze | report | workflow"]:::config
    ENGINE["WorkflowEngine — core/workflow.py"]:::core
    SCHEMA["workflow_schema — compile_workflow / CompiledWorkflow"]:::derived
    MEMORY["PentestMemory — core/memory.py"]:::storage
    SCOPE["ScopeValidator — utils/scope_validator.py"]:::core
    AGENTS["BaseAgent — core/agent.py (Planner, ToolAgent, Analyst, Reporter)"]:::core
    CLIENT["AIClient — ai/ai_client.py (alias GeminiClient)"]:::abstract
    FACTORY["get_provider — ai/providers/__init__.py"]:::abstract
    PROVIDERS["Provider in-tree + entry point guardian.providers"]:::success
    TOOLBASE["BaseTool — tools/base_tool.py"]:::core
    TOOLS["Wrapper tool — tools/*.py via TOOL_REGISTRY"]:::success
    REPORTS[(reports/ session_<id>.json, report_<id>.md)]:::storage

    CLI --> CMD
    CMD --> ENGINE
    ENGINE --> SCHEMA
    ENGINE --> MEMORY
    ENGINE --> SCOPE
    ENGINE --> AGENTS
    AGENTS --> CLIENT
    CLIENT --> FACTORY
    FACTORY --> PROVIDERS
    AGENTS --> TOOLBASE
    TOOLBASE --> TOOLS
    ENGINE --> REPORTS
    MEMORY --> REPORTS

    style CLI fill:#f59e0b,color:#000
    style CMD fill:#f59e0b,color:#000
    style ENGINE fill:#8b5cf6,color:#fff
    style SCHEMA fill:#8b5cf6,color:#fff
    style MEMORY fill:#2d7d46,color:#fff
    style SCOPE fill:#8b5cf6,color:#fff
    style AGENTS fill:#8b5cf6,color:#fff
    style CLIENT fill:#f59e0b,color:#000
    style FACTORY fill:#f59e0b,color:#000
    style PROVIDERS fill:#2d7d46,color:#fff
    style TOOLBASE fill:#8b5cf6,color:#fff
    style TOOLS fill:#2d7d46,color:#fff
    style REPORTS fill:#336791,color:#fff
%% fig: Lapisan arsitektur Guardian
%% desc: CLI memanggil WorkflowEngine, yang mengoordinasi agen, provider AI, dan wrapper tool, lalu menyimpan checkpoint session ke reports/.
Fig. 1: Lapisan arsitektur GuardianCLI memanggil WorkflowEngine, yang mengoordinasi agen, provider AI, dan wrapper tool, lalu menyimpan checkpoint session ke reports/.

Lapisan CLI hanya mendaftarkan perintah. cli/main.py membuat satu typer.Typer dan menggabungkan setiap fungsi perintah dari cli/commands/ menjadi subcommand, ditambah dua sub-app kb dan telemetry (cli/main.py:64-83). Callback tingkat atas hanya mencetak banner, sehingga tidak ada logika domain di lapisan ini (cli/main.py:85-93).

Batas tanggung jawab per modul

ModulPeranTitik masuk
cli/main.pyRegistrasi perintah, versi, bannerapp, main
cli/commands/workflow.pyParsing opsi, override provider/model, pemanggilan engineworkflow_command, _run_workflow
core/workflow.pyOrkestrasi: validasi scope, compile DSL, eksekusi per generasi, checkpointWorkflowEngine.run_workflow, run_autonomous
core/workflow_schema.pySchema, validator, dan compiler DAGcompile_workflow, CompiledWorkflow
core/agent.pyKontrak agen dan penalaranBaseAgent, think, think_deeply
core/tool_agent.pyRegistry tool dan resolusi lazyTOOL_REGISTRY, _get_tool
ai/providers/__init__.pyRegistry dan factory providerPROVIDERS, get_provider
tools/base_tool.pyKontrak wrapper tool dan eksekusi subprocessBaseTool.execute
core/memory.pyState sesi dan ledger tokenPentestMemory, Finding, ToolExecution

Perintah workflow memvalidasi --provider terhadap daftar lima nama, lalu menyuntikkan nilainya ke config["ai"]["provider"] sebelum engine dibuat (cli/commands/workflow.py:125-151). Daftar itu lebih sempit daripada registry PROVIDERS yang memuat delapan entri in-tree, termasuk ollama, openai_compatible, dan litellm (ai/providers/init.py:19-29).

⚠️ Override lewat --provider pada guardian workflow menolak ollama, openai_compatible, dan litellm meskipun provider tersebut terdaftar di registry. Untuk memakainya, set ai.provider langsung di berkas konfigurasi.

Peran WorkflowEngine

WorkflowEngine adalah satu-satunya komponen yang memegang state eksekusi. Konstruktornya membuat PentestMemory, ScopeValidator, dan AIClient, lalu menginstansiasi empat agen dengan memori dan client yang sama (core/workflow.py:30-58). Nilai max_steps dibaca dari config["workflows"]["max_steps"] dengan default 20 (core/workflow.py:52-58).

run_workflow memvalidasi target, memuat YAML, mengompilasinya, lalu menjalankan langkah generasi demi generasi (core/workflow.py:64-132). Batas konkurensi diambil dari pentest.max_parallel_tools dengan default 3 dan diterapkan lewat asyncio.Semaphore (core/workflow.py:97-102). Setiap langkah menyimpan hasil ke step_results yang sekaligus menjadi konteks Jinja2 untuk langkah berikutnya, dan checkpoint ditulis setelah tiap langkah (core/workflow.py:108-132).

sequenceDiagram
    participant CLI as cli/commands/workflow.py
    participant E as WorkflowEngine
    participant S as workflow_schema
    participant T as ToolAgent
    participant B as BaseTool
    participant M as PentestMemory

    CLI->>E: WorkflowEngine(config, target)
    CLI->>E: run_workflow(name)
    E->>E: scope_validator.validate_target(target)
    E->>E: _load_workflow_doc(name)
    E->>S: compile_workflow(doc)
    S-->>E: CompiledWorkflow(levels)
    loop setiap generation
        E->>T: execute_tool(tool_name, target)
        T->>B: execute(target, stream_callback)
        B-->>T: parsed, raw_output, exit_code
        T-->>E: result dict
        E->>M: add_tool_execution(ToolExecution)
        E->>M: save_state(tmp) lalu os.replace
    end
    E-->>CLI: status, findings, session_id
%% fig: Siklus satu workflow run
%% desc: Perintah workflow membuat engine, memvalidasi scope, mengompilasi DAG, lalu menjalankan tool per generasi dan menulis checkpoint setelah setiap langkah.
Fig. 2: Siklus satu workflow runPerintah workflow membuat engine, memvalidasi scope, mengompilasi DAG, lalu menjalankan tool per generasi dan menulis checkpoint setelah setiap langkah.

Setiap langkah hasil kompilasi dieksekusi oleh _execute_compiled_step, yang mengevaluasi ekspresi when, merender parameters dengan Jinja2, lalu menjembatani ke _execute_step berbentuk v1 (core/workflow.py:675-743). Nilai yang dikembalikan berbentuk {id, success, command, exit_code, parsed, raw_output} sehingga {{ <id>.parsed.<key> }} pada langkah berikutnya tetap bekerja (core/workflow.py:736-743).

_save_session menulis session_<id>.json ke direktori output.save_path (default ./reports) melalui berkas sementara di direktori yang sama, lalu os.replace agar penggantian bersifat atomik (core/workflow.py:833-870). resume_session memuat kembali checkpoint itu dan mengembalikan False bila berkasnya tidak ada (core/workflow.py:872-892). Detail format DSL dan aturan kompilasi ada di Engine Workflow DSL v2.

Registry provider dan abstraksi client

AIClient membungkus satu provider dan mendelegasikan seluruh panggilan generasi ke objek itu; nama kelas provider dan model dicatat saat inisialisasi (ai/ai_client.py:20-31). Modul ai/gemini_client.py hanya me-rebind GeminiClient = AIClient demi kompatibilitas, sehingga seluruh agen dan engine tetap mengimpor nama lama (ai/gemini_client.py:6-11).

get_provider membaca config["ai"]["provider"] dengan default gemini, mencari nama itu di registry, lalu mengimpor kelasnya lewat importlib.import_module dan getattr (ai/providers/init.py:90-109). Nama yang tidak dikenal memunculkan ValueError berisi daftar provider yang tersedia, sedangkan kegagalan impor dibungkus menjadi RuntimeError (ai/providers/init.py:97-119).

graph LR
    CFG["config[ai][provider]"]:::config
    LOOKUP["get_provider"]:::abstract
    MERGE["_discover_plugin_providers"]:::derived
    INTREE["PROVIDERS in-tree (8 entri)"]:::success
    EP["entry point guardian.providers"]:::derived
    IMPORT["importlib.import_module"]:::core
    ERR["ValueError: Unknown provider"]:::failure

    CFG --> LOOKUP
    LOOKUP --> MERGE
    INTREE --> MERGE
    EP --> MERGE
    MERGE -->|nama ditemukan| IMPORT
    LOOKUP -->|nama tidak ada| ERR

    style CFG fill:#f59e0b,color:#000
    style LOOKUP fill:#f59e0b,color:#000
    style MERGE fill:#8b5cf6,color:#fff
    style INTREE fill:#2d7d46,color:#fff
    style EP fill:#8b5cf6,color:#fff
    style IMPORT fill:#8b5cf6,color:#fff
    style ERR fill:#dc2626,color:#fff
%% fig: Resolusi provider pada factory
%% desc: Factory menggabungkan registry in-tree dengan entry point plugin, lalu mengimpor kelas provider; nama tak dikenal berakhir sebagai ValueError.
Fig. 3: Resolusi provider pada factoryFactory menggabungkan registry in-tree dengan entry point plugin, lalu mengimpor kelas provider; nama tak dikenal berakhir sebagai ValueError.

Penggabungan entry point dilakukan sekali per proses dan di-cache di _discovered_cache. Nama yang sudah ada di PROVIDERS tidak boleh ditimpa plugin: upaya itu dicatat sebagai warning lalu dilewati (ai/providers/init.py:35-73). Kontrak plugin dan daftar provider lengkap dibahas di Provider AI dan Kontrak Plugin.

Lapisan agen

BaseAgent adalah kelas abstrak dengan satu metode wajib execute (core/agent.py:16-36). Semua penalaran melewati think, yang memanggil generate_with_usage dan mencatat ThinkingStep serta TokenUsage ke memori (core/agent.py:40-60). think_deeply menambahkan loop kritik diri dan opsi judge_model, yang dibaca dari argumen atau config["ai"]["judge_model"] (core/agent.py:62-99).

Setiap agen konkret menerima config, gemini_client, dan memory yang sama. PlannerAgent.decide_next_action membangun prompt dari memory.get_context_for_ai(), membungkus temuan dengan wrap_untrusted, lalu mem-parse keputusan (core/planner.py:19-69). Pembagian peran antar agen, termasuk DebateTriage dan VisualTriage yang dipanggil dari _execute_step, dijelaskan di Sistem Multi-Agen.

Lapisan tool

TOOL_REGISTRY memetakan nama tool ke string module:Class, dan resolusi baru terjadi saat tool pertama kali dipakai sehingga startup tidak mengimpor seluruh wrapper (core/tool_agent.py:15-79). _discover_plugin_tools menggabungkan registry in-tree dengan entry point guardian.tools dan memberi kelas risiko default active bagi tool plugin (core/tool_agent.py:169-205). _get_tool mengimpor kelas, menginstansiasinya, dan menyimpannya di cache _instances (core/tool_agent.py:219-230).

BaseTool memeriksa ketersediaan tool sekali di konstruktor dan menyimpan hasilnya di is_available; bila tidak tersedia, execute mengembalikan hasil skipped alih-alih melempar exception (tools/base_tool.py:24-69). Eksekusi memakai asyncio.create_subprocess_exec dengan tool_timeout dari pentest.tool_timeout (default 300 detik) dan meneruskan setiap baris keluaran ke stream_callback (tools/base_tool.py:80-119). Karena execute tidak pernah melempar exception, WorkflowEngine dapat memutuskan lanjut atau lewati langkah. Klasifikasi risiko dan gate konfirmasi diuraikan di Integrasi Tool dan Pemilihan Tool serta Keamanan, Scope, dan Sanitasi.

Perintah sederhana seperti scan melewati engine sepenuhnya: ia memuat konfigurasi, menginstansiasi NmapTool, dan memanggil execute langsung (cli/commands/scan.py:65-79). Ini batas penting — jalur tool tunggal tidak menulis checkpoint, sehingga --resume hanya berlaku untuk perintah workflow.