Tool AI untuk coding makin sering dipakai lewat CLI karena cepat dan mudah diotomasi. Masalahnya, banyak implementasi default mengirim context terlalu besar, menyatukan banyak proyek dalam satu session, atau ikut membawa file dan log yang tidak seharusnya dikirim. Akibatnya ada dua dampak langsung: token overhead membengkak dan secret lebih mudah bocor.
Jika tujuan Anda adalah membuat CLI AI yang hemat token dan aman, pendekatannya bukan sekadar menambahkan redaction di akhir. Anda perlu merancang alur session, pemilihan context, validasi file, dan pencatatan aktivitas sejak awal. Ini sejalan dengan diskusi yang muncul pada tren overhead token di AI coding tools, misalnya pada perbandingan konteks seperti yang dibahas di Systima. Fokus artikel ini adalah langkah teknis yang bisa langsung diterapkan.
Tujuan praktis: hanya kirim data yang benar-benar diperlukan ke model, pisahkan session per proyek atau task, dan pastikan secret tidak ikut keluar melalui prompt, attachment, cache, atau log.
Mengapa CLI AI sering boros token dan rawan bocor
Penyebab paling umum bukan modelnya, melainkan cara integrasi dilakukan:
- Context terlalu lebar: seluruh repository, log build panjang, atau banyak file yang sebenarnya tidak relevan ikut dimasukkan ke prompt.
- Session tidak dipisah: history dari proyek A terbawa ke proyek B, sehingga token bertambah dan risiko kebocoran silang meningkat.
- Attachment tanpa validasi: path file diterima mentah dari input user atau automation script, lalu dikirim apa adanya.
- Prompt tidak disanitasi: secret dalam environment, URL internal, token API, atau isi file konfigurasi bisa ikut masuk.
- Logging berlebihan: request/response model disimpan utuh untuk debugging, termasuk isi prompt dan secret.
- Retry otomatis tanpa kontrol: permintaan gagal diulang berkali-kali dengan payload yang sama besar, sehingga boros token dan memperbesar jejak data sensitif.
Prinsip dasarnya sederhana: kurangi scope data, batasi umur session, dan treat prompt sebagai jalur data sensitif.
Desain session yang aman untuk membatasi token dan secret pada CLI AI
1. Pisahkan session per proyek
Jangan gunakan satu history global untuk semua repository. Session idealnya diikat minimal oleh:
- identitas proyek atau root directory,
- branch atau workspace jika relevan,
- tujuan task, misalnya bugfix, review, atau refactor.
Mengapa ini efektif? Karena history yang disimpan tetap relevan dengan pekerjaan saat ini. Model tidak perlu menerima ulang konteks lintas proyek yang tidak berguna, dan prompt dari proyek lain tidak ikut terbawa.
Praktik yang baik:
- Buat session store per direktori proyek.
- Tambahkan TTL atau batas ukuran history.
- Sediakan perintah eksplisit untuk reset session.
- Jangan memulihkan session lama secara otomatis jika root proyek berubah.
sessions/
project-a/
session.json
project-b/
session.jsonIsi session tidak perlu menyimpan seluruh prompt lengkap. Simpan metadata seperlunya, misalnya daftar file yang sudah dibahas, ringkasan singkat hasil sebelumnya, dan ID request internal. Ini lebih hemat dibanding menyimpan transcript mentah yang panjang.
2. Gunakan ringkasan, bukan transcript penuh
Banyak CLI AI mengandalkan seluruh riwayat percakapan untuk menjaga konteks. Ini nyaman, tetapi mahal. Alternatif yang lebih baik adalah melakukan rolling summary: setelah beberapa interaksi, rangkum poin penting lalu buang detail yang tidak lagi dibutuhkan.
Contoh data yang layak dipertahankan:
- modul yang sedang diubah,
- kontrak API yang relevan,
- keputusan implementasi yang sudah disetujui,
- error terakhir yang sedang diinvestigasi.
Data yang sering tidak perlu dipertahankan penuh:
- seluruh output build,
- isi file yang sudah tidak dibahas,
- beberapa percobaan prompt yang gagal.
Minimalkan context yang dikirim ke model
1. Kirim potongan file, bukan seluruh repository
Anti-pattern yang sering terjadi adalah menjalankan attachment otomatis untuk semua file yang berubah atau bahkan semua file di direktori kerja. Lebih aman dan efisien jika Anda:
- mengambil hanya file yang relevan dengan task,
- mengirim cuplikan baris tertentu, bukan satu file penuh jika tidak perlu,
- memprioritaskan file entry-point, stack trace terkait, atau modul dependensi terdekat.
Misalnya, jika task hanya memperbaiki error pada handler API, kirim:
- stack trace yang sudah diringkas,
- fungsi handler terkait,
- kontrak request/response yang relevan,
- satu atau dua file dependency yang benar-benar dipakai.
Jangan ikut mengirim file lock, artefak build, log runtime besar, atau direktori vendor kecuali memang dibutuhkan.
2. Terapkan budget token di level CLI
Jangan menunggu provider menolak request karena terlalu besar. Tetapkan budget sebelum request dibuat:
- batas ukuran total karakter atau byte untuk context,
- batas jumlah file yang boleh dilampirkan,
- batas ukuran per file atau per snippet,
- strategi fallback saat melewati budget, misalnya meringkas log atau meminta user memilih file.
MAX_ATTACHMENTS=5
MAX_FILE_BYTES=65536
MAX_PROMPT_BYTES=180000
MAX_LOG_LINES=200Nilai persisnya bergantung pada model dan workflow Anda, jadi lebih aman gunakan desain berbasis batas internal daripada asumsi kapasitas tertentu dari provider.
3. Hindari pengiriman file sensitif secara default
Secara default, file berikut sebaiknya tidak pernah diikutkan otomatis:
.envdan varian sejenis,- credential cloud, SSH key, token CI, sertifikat, private key,
- file backup database, dump SQL, dan export data pengguna,
- direktori seperti
.git,.aws,.ssh,secrets, atau file konfigurasi internal sensitif, - log yang bisa berisi Authorization header, cookie, atau payload PII.
Gunakan denylist minimum untuk pola berbahaya, tetapi jangan berhenti di sana. Untuk attachment yang diizinkan, lebih aman menggunakan allowlist.
Validasi path dan allowlist untuk upload atau attachment
1. Normalisasi path sebelum dibaca
Jangan percaya path mentah dari argumen CLI, output tool lain, atau input user. Normalisasi terlebih dahulu lalu pastikan file tetap berada di dalam root proyek yang diizinkan. Ini mencegah path traversal dan pembacaan file di luar workspace.
import path from 'node:path';
import fs from 'node:fs';
function resolveAllowedPath(projectRoot, inputPath) {
const fullPath = path.resolve(projectRoot, inputPath);
const normalizedRoot = path.resolve(projectRoot) + path.sep;
if (!fullPath.startsWith(normalizedRoot)) {
throw new Error('Path di luar root proyek ditolak');
}
const stat = fs.statSync(fullPath);
if (!stat.isFile()) {
throw new Error('Hanya file reguler yang boleh dilampirkan');
}
return fullPath;
}Kenapa perlu normalisasi? Karena string path seperti ../../.env bisa lolos jika Anda hanya memeriksa substring atau prefix secara naif.
2. Gunakan allowlist ekstensi dan direktori
Setelah path lolos validasi root, batasi lagi berdasarkan jenis file dan lokasi:
- izinkan hanya ekstensi yang relevan, misalnya
.js,.ts,.py,.go,.md,.jsontertentu, - izinkan hanya direktori sumber seperti
src/,app/,pkg/,tests/, - tolak direktori sensitif, artefak build, dan hidden directory tertentu.
const ALLOWED_DIRS = ['src/', 'app/', 'tests/'];
const ALLOWED_EXT = new Set(['.js', '.ts', '.py', '.go', '.md', '.json']);
function isAllowedForUpload(projectRoot, fullPath) {
const relative = path.relative(projectRoot, fullPath).replaceAll('\\', '/');
const ext = path.extname(fullPath).toLowerCase();
const dirAllowed = ALLOWED_DIRS.some(dir => relative.startsWith(dir));
const extAllowed = ALLOWED_EXT.has(ext);
return dirAllowed && extAllowed;
}Trade-off: allowlist bisa terasa ketat dan kadang perlu penyesuaian. Namun untuk tool yang berinteraksi dengan model eksternal, default ketat jauh lebih aman daripada default permisif.
Sanitasi prompt dan masking secret di log
1. Perlakukan prompt sebagai data keluar
Begitu prompt dikirim ke provider, data tersebut keluar dari boundary lokal Anda. Karena itu, sanitasi harus dilakukan sebelum payload dibentuk, bukan hanya saat logging.
Minimal lakukan pemeriksaan untuk:
- token API yang mengikuti pola umum,
- private key, certificate block, dan secret multiline,
- header Authorization, cookie, session ID,
- URL internal, hostname sensitif, atau identifier tenant jika perlu,
- alamat email, nomor telepon, atau PII lain sesuai kebutuhan organisasi.
Penting untuk dipahami: regex saja tidak cukup sempurna. Kombinasikan beberapa lapisan:
- denylist file sensitif,
- scanner pola secret ringan sebelum kirim,
- review eksplisit jika ada temuan,
- opsi fail closed untuk workflow sensitif.
function redactSecrets(text) {
return text
.replace(/-----BEGIN[\s\S]+?PRIVATE KEY-----[\s\S]+?-----END[\s\S]+?PRIVATE KEY-----/g, '[REDACTED_PRIVATE_KEY]')
.replace(/Authorization:\s*Bearer\s+[A-Za-z0-9._-]+/gi, 'Authorization: Bearer [REDACTED]')
.replace(/(api[_-]?key|token|secret)\s*[:=]\s*['"]?[^'"\s]+['"]?/gi, '$1=[REDACTED]');
}Contoh di atas berguna sebagai baseline, tetapi jangan menganggapnya sebagai perlindungan lengkap. Format secret sangat beragam.
2. Masking secret di log dan telemetry
Banyak kebocoran justru terjadi bukan ke model, melainkan ke sistem observability internal. Hindari menyimpan:
- prompt mentah penuh,
- response model mentah yang memantulkan secret,
- daftar file attachment lengkap tanpa filter,
- environment variables saat mode debug.
Yang lebih aman untuk dicatat:
- ID request internal,
- nama session atau proyek,
- jumlah file yang dikirim,
- ukuran prompt setelah sanitasi,
- hasil validasi dan alasan penolakan,
- status provider dan durasi request.
{
"request_id": "req_01...",
"project": "billing-service",
"session_id": "sess_01...",
"attachments_count": 3,
"prompt_bytes": 18420,
"redaction_applied": true,
"provider_status": "ok"
}Jika Anda tetap perlu menyimpan payload untuk debugging, simpan hanya pada mode yang sangat terbatas, terenkripsi, berumur pendek, dan tidak aktif secara default.
Rate limit dan audit trail untuk abuse prevention
1. Rate limit permintaan otomatis
CLI AI sering dijalankan oleh script, hook, atau agent lain. Tanpa rate limit, satu loop bug bisa mengirim ratusan request mahal dalam waktu singkat. Terapkan pembatas minimal per:
- user lokal atau identity yang menjalankan CLI,
- session,
- proyek,
- interval waktu tertentu.
Selain mengontrol biaya, ini juga membantu mendeteksi penyalahgunaan dan mengurangi spam retry ke provider.
Praktik yang disarankan:
- debounce untuk event file watcher,
- exponential backoff saat retry,
- batas retry maksimum,
- circuit breaker sederhana jika provider berulang kali gagal,
- tolak request baru jika queue lokal sudah terlalu panjang.
MAX_REQUESTS_PER_MINUTE=20
MAX_RETRIES=2
RETRY_BACKOFF_MS=10002. Audit trail yang cukup untuk investigasi
Audit trail bukan berarti menyimpan semua isi prompt. Tujuannya adalah menyediakan jejak yang cukup untuk menjawab pertanyaan seperti:
- siapa yang menjalankan request,
- dari proyek dan session mana request berasal,
- file apa yang diminta untuk diikutkan,
- validator mana yang menolak atau mengizinkan request,
- berapa besar payload yang keluar,
- kapan request dijalankan dan ke provider mana.
Untuk mencegah abuse, audit trail harus sulit dimanipulasi dan tidak bercampur dengan log debug biasa. Pada lingkungan tim, kirim metadata ini ke sistem logging terpusat dengan kontrol akses yang jelas.
Contoh alur aman untuk CLI AI
- User menjalankan CLI di root proyek tertentu.
- CLI membuat atau memuat session per proyek, bukan session global.
- Task dianalisis, lalu file kandidat dikumpulkan dari input user atau hasil pencarian lokal.
- Setiap path dinormalisasi dan diverifikasi tetap berada di dalam root proyek.
- File difilter menggunakan allowlist direktori dan ekstensi.
- Ukuran file, jumlah file, dan total context diperiksa terhadap budget token internal.
- Isi file, log, dan prompt digabung lalu melewati proses sanitasi secret.
- Jika scanner menemukan pola sensitif berisiko tinggi, request dibatalkan atau perlu konfirmasi eksplisit.
- Request dikirim dengan rate limit dan retry yang terkontrol.
- Audit trail hanya menyimpan metadata penting, bukan payload mentah penuh.
- Setelah beberapa interaksi, transcript diringkas agar session tetap kecil.
User Input
-> Session Resolver (per-project)
-> File Collector
-> Path Validator
-> Allowlist / Denylist Filter
-> Token Budget Check
-> Prompt Sanitizer
-> Rate Limit / Retry Guard
-> Model Provider
-> Metadata Audit LogChecklist implementasi
- Session dipisah per proyek, bukan global.
- Ada TTL atau mekanisme reset session yang jelas.
- History lama diringkas, tidak selalu dikirim penuh.
- Attachment default dibatasi ke file relevan saja.
.env, credential, key, dump data, dan hidden directory sensitif diblokir default.- Semua path dinormalisasi dan diverifikasi tetap di bawah root proyek.
- Allowlist direktori dan ekstensi diterapkan sebelum upload/attachment.
- Ada batas jumlah file, ukuran file, dan ukuran total context.
- Prompt dan attachment melewati sanitasi secret sebelum request dibuat.
- Log hanya menyimpan metadata aman, bukan payload mentah penuh.
- Retry otomatis dibatasi dan memakai backoff.
- Rate limit diterapkan untuk mencegah loop mahal dan abuse.
- Ada audit trail untuk siapa, kapan, dari proyek mana, dan berapa besar data keluar.
- Tersedia mode review atau konfirmasi manual untuk request berisiko tinggi.
Anti-pattern umum yang perlu dihindari
1. Satu session untuk semua repository
Ini menyebabkan token menumpuk tanpa manfaat dan meningkatkan peluang kebocoran silang antarproyek.
2. Mengirim seluruh output command
Output seperti npm install, build log panjang, atau hasil test lengkap sering tidak perlu. Ambil bagian error yang relevan saja.
3. Denylist saja tanpa allowlist
Denylist penting, tetapi biasanya selalu ada pola file baru yang lolos. Allowlist memberi kontrol lebih kuat untuk default aman.
4. Logging payload mentah demi debugging
Ini salah satu sumber insiden paling umum. Jika perlu sekali, aktifkan hanya sementara, terenkripsi, dan hapus cepat.
5. Mengandalkan regex secret sebagai satu-satunya kontrol
Secret bisa punya format tak terduga. Gunakan beberapa lapisan kontrol, bukan hanya satu scanner teks.
6. Retry tak terbatas pada automation
Saat provider error, script yang terus mengulang request akan membakar token dan memperbesar jejak data yang keluar.
Tips debugging jika implementasi terlalu ketat
Hardening yang baik memang bisa membuat CLI terasa lebih ketat. Jika user mengeluh konteks kurang atau file terlalu sering ditolak, lakukan debugging pada metadata, bukan dengan membuka payload mentah.
- Catat file mana yang ditolak dan aturan mana yang memblokirnya.
- Catat ukuran context sebelum dan sesudah trimming.
- Tambahkan mode explain yang menampilkan alasan file tidak ikut terkirim.
- Sediakan perintah untuk meminta satu file tambahan secara eksplisit, tetap lewat validasi yang sama.
- Ukur berapa sering ringkasan session dipakai agar Anda tahu apakah context terlalu cepat dipotong.
Dengan cara ini, Anda bisa menyesuaikan aturan tanpa mengorbankan keamanan dasar.
Penutup
Membatasi token dan secret pada CLI AI bukan tugas terpisah. Keduanya saling terkait: semakin kecil dan terarah context yang Anda kirim, semakin rendah biaya dan semakin kecil permukaan kebocoran. Fondasi utamanya adalah session per proyek, pemilihan context yang minimal, sanitasi sebelum kirim, allowlist attachment, masking log, serta rate limit dan audit trail.
Jika Anda sedang mengeraskan integrasi CLI AI di tim, mulai dari hal yang paling berdampak: pisahkan session, blok file sensitif secara default, validasi semua path, dan hentikan logging payload mentah. Empat langkah itu biasanya sudah menurunkan token overhead sekaligus risiko kebocoran secara signifikan.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!