> For the complete documentation index, see [llms.txt](https://docs.haikaldev.my.id/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.haikaldev.my.id/referensi/keamanan.md).

# Keamanan

AI-Haikaru **menjalankan kode yang ditulis AI atas permintaan orang di grup** — di server yang juga memegang sesi WhatsApp-nya sendiri, API key, dan riwayat chat orang-orang.

Halaman ini menjelaskan apa yang dijaga, bagaimana, dan — sama pentingnya — **apa yang sengaja tidak dibuat** karena tidak bisa dibuat aman.

## Apa yang dipertaruhkan

Dari folder workspace, tiga tingkat `cd ..` sampai ke akar repo. Di sana ada:

| Aset                            | Kalau bocor                                                               |
| ------------------------------- | ------------------------------------------------------------------------- |
| `.env`                          | API key AI (kuota ratusan juta token) — dipakai orang lain atas tagihanmu |
| `data/baileys_auth/`            | **Sesi WhatsApp bot — menyalinnya = mengambil alih akunnya**              |
| `data/history/`, `data/memory/` | Percakapan asli & memori puluhan orang                                    |

{% hint style="info" %}
Semua desain di bawah ini adalah tentang membuat **jarak tiga-`cd` itu tidak bisa ditempuh**.
{% endhint %}

## Lapisan 1 — eksekusi kode terkurung

### Tanpa shell — dan kenapa bash sengaja tidak ada

Kode dijalankan lewat `execFile`/`spawn` dengan **argumen berupa array** — tidak ada shell yang menafsirkan. `; rm -rf ~` di nama berkas cuma jadi nama berkas aneh, bukan perintah kedua.

{% hint style="danger" %}
**Konsekuensi jujurnya: runtime `bash` tidak ada dan tidak akan ada** di kontainer ini.

Pterodactyl tidak memberi root, jadi tiga mitigasi standar mati semua:

* tidak bisa bikin user terpisah (`useradd` butuh root)
* tidak bisa `chroot`
* tidak ada Docker-in-Docker

Shell penuh = akses penuh ke tiga aset di atas. Ada **mutation test** yang menjaga keputusan ini: kalau suatu hari `bash` dimasukkan ke enum runtime, tesnya **gagal**.
{% endhint %}

### Env dibangun dari nol

Env proses anak **bukan** `{...process.env}` — disusun dari nol (PATH, HOME→workspace, TMPDIR, LANG, plus beberapa var Windows untuk dev).

Kalau env bot diwariskan, satu baris `console.log(process.env)` yang tampak tak berdosa mencetak API key ke chat.

### Permission model Node

Kode node dijalankan dengan `--experimental-permission --allow-fs-read/-write=<workspace>` — pengurungan yang **ditegakkan runtime Node**, bukan kesopanan. Baca `.env`, tulis ke luar folder, spawn `child_process` — semuanya mati dengan `ERR_ACCESS_DENIED`.

Nama flag-nya berbeda antar versi Node (20–22 vs 23+), jadi dideteksi saat runtime.

{% hint style="warning" %}
**Python tidak punya padanan mekanisme ini.** Yang menjaganya env bersih + cwd + timeout. Ini diterima secara sadar dan ditulis terbuka di sini — bukan disembunyikan.
{% endhint %}

### Timeout yang membunuh sampai tuntas

`SIGTERM` → 2 detik → `SIGKILL`, ke **seluruh process group** (POSIX `kill(-pid)`; Windows `taskkill /T`). Server yang mem-fork pekerja tidak meninggalkan yatim pemegang port.

Plus jaring terakhir untuk kasus cucu yang memegang pipa stdout — **sudah terbukti terjadi**, bukan teori.

### Batas sumber daya

| Batas                                        | Kenapa                                                                                         |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Maks **2 proses bersamaan** (global)         | Kontainer ini juga menjalankan bot — 10 grup serempak `npm install` membuat WhatsApp-nya putus |
| Keluaran dipotong **256 KB sambil mengalir** | Loop `console.log` tak berujung tidak sempat memakan RAM                                       |
| Kuota disk dicek **sebelum** eksekusi        | Bukan setelah disk penuh                                                                       |

## Lapisan 2 — pagar path (satu pintu)

Semua baca/tulis/hapus/pindah/saji melewati `workspacePath.js`. Tekniknya, dan kenapa masing-masing ada:

{% hint style="success" %}
Rute web (`/site/`) memakai fungsi baca **yang sama** — trik yang ditangkal di jalur chat otomatis tertangkal dari internet. `%2e%2e/%2e%2e/.env` lewat HTTP sungguhan ada di suite pengujian.
{% endhint %}

## Lapisan 3 — izin di jalur eksekusi

{% hint style="danger" %}
**Prinsip terpenting di seluruh bot:** deskripsi tool hanya *mengarahkan* model; yang **menghentikan** adalah kode.

Orang yang berhasil membujuk AI (*"aku pemiliknya kok"*, *"aku admin"*) tidak mendapat apa-apa, karena pemeriksaan izinnya ada di pelaksana — bukan di prompt.
{% endhint %}

* Workspace **pribadi**: hanya pemilik — membaca pun tidak boleh, admin grup pun ditolak
* Workspace **grup**: admin + yang di-`share`. Admin yang turun jabatan langsung kehilangan akses (status admin dicek langsung, tidak disalin ke daftar)
* Gerbangnya diperiksa **sekali di pintu masuk, sebelum percabangan per-action** — satu `case` yang lupa memanggil pemeriksaan adalah satu jalur lolos, dan penempatan ini menghilangkan kemungkinan itu
* `/ws` dan tool AI memakai pelaksana yang sama — **tidak ada jalur kedua yang bisa lebih longgar**
* Identitas berasal dari `senderJid` yang **sudah diautentikasi WhatsApp** — tidak ada OTP, karena OTP hanya membuktikan ulang yang sudah terbukti

## Lapisan 4 — situs yang tayang

| Penjagaan                         | Alasannya                                                                                                                                                                                                                              |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Opt-in**                        | Sebelum `publish`, `/site/<id>/` menjawab 404 yang **identik** dengan workspace yang tidak ada — keberadaan proyek pun tidak bocor. Satu bentuk 404 untuk semua kegagalan, supaya perbedaan jawaban tidak bisa dipakai meraba struktur |
| **CSP `sandbox`** di tiap respons | JS situs user berjalan dengan origin buram: tidak bisa `fetch('/api/status')` (yang berisi QR login saat bot re-login), tidak bisa menyentuh `/config`                                                                                 |
| **`nosniff`**                     | Browser tidak menebak-nebak octet-stream jadi sesuatu yang bisa dieksekusi                                                                                                                                                             |
| **Port terpisah** (`SITE_PORT`)   | Domain situs yang dibagikan publik dilayani app yang *hanya tahu situs* — `/config` dan QR login tidak pernah ikut ke domain itu                                                                                                       |

{% hint style="info" %}
Konsekuensi `sandbox`: `localStorage` mati di situs workspace. Itu **disebut jujur di dokumentasi**, dan persona bot dilarang menulis kode yang memakainya — supaya tidak ada situs yang tampak jadi lalu diam-diam kehilangan state.
{% endhint %}

## Data & kredensial

* `.env`, `data/`, `scratch/`, `bin/` semuanya di `.gitignore` — **riwayat chat orang tidak pernah boleh masuk repo publik**
* Kredensial di dashboard `/config` ditampilkan sebagai mask; nilai asli **tidak pernah dikirim ke browser**. Portal mati total tanpa `CONFIG_TOKEN` (*fail closed*), dan token dibandingkan dengan `timingSafeEqual`
* **Nomor telepon anggota grup tidak dikirim ke gateway AI** pada tiap pesan — penyertaan nomor bersifat opt-in dan tercatat di log
* Media masuk dibersihkan setelah 30 hari; file hasil generate 7 hari; workspace tak tersentuh 30 hari

## Melaporkan celah

{% hint style="success" %}
Nemu sesuatu? Buka issue di [github.com/AnakTentara/AI-Haikaru/issues](https://github.com/AnakTentara/AI-Haikaru/issues) — atau kalau sensitif, hubungi Haikal langsung (kontak di profil GitHub).
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.haikaldev.my.id/referensi/keamanan.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
