Teknis — OPA Config
Image yang menjalankan OPA (Open Policy Agent) server RAGA beserta policy Rego-nya. Bukan service HTTP kustom seperti opa-auth/opa-data — image ini hanya membungkus binary opa resmi, CLI Infisical, dan file policy, lalu menjalankan opa run --server yang diseklankan oleh subsistem OPA lainnya.
Repository
| Key | Value |
|---|---|
| Git Remote | https://git.tlab.co.id/tarantula/tarantula-v2/opa-bun/opa-config.git |
| Branch Aktif | main |
git clone https://git.tlab.co.id/tarantula/tarantula-v2/opa-bun/opa-config.git
cd opa-configTech Stack
| Layer | Teknologi |
|---|---|
| Base Image | Alpine 3.20 |
| Policy Engine | OPA binary v1.5.1 (diunduh langsung dari rilis GitHub saat build image) |
| Bahasa Policy | Rego |
| Secret Management | Infisical CLI (bukan SDK) — dijalankan lewat infisical run --watch |
Environment Variables
Tidak ada file .env runtime — running.sh membaca variabel bootstrap dari environment container, lalu Infisical CLI menyuntikkan sisanya sebagai environment variable ke proses opa run.
| Variable | Keterangan |
|---|---|
INFISICAL_CLIENT_ID | Client ID Universal Auth (wajib, dicek di awal running.sh) |
INFISICAL_CLIENT_SECRET | Client Secret Universal Auth (wajib) |
INFISICAL_PATH | Path secrets di Infisical |
INFISICAL_PROJECT_ID | ID project Infisical |
INFISICAL_ENVIRONMENT | Environment target (dev / staging / prod) |
JWT_SECRET | Dideklarasikan di .env.example ("samakan dengan yang ada di user-service") untuk dipakai policy Rego memverifikasi signature JWT lewat opa.runtime()["env"]["JWT_SECRET"] |
Struktur File
opa-config/
├── Dockerfile # Alpine + binary opa + Infisical CLI
├── running.sh # Entrypoint: login Infisical → jalankan `opa run --server`
├── config.yml # Konfigurasi OPA server (decision log, dll — saat ini nonaktif)
├── policy.rego # Policy Rego aktif (dimuat oleh running.sh)
├── policy.old.rego # Varian policy sebelumnya (tidak dimuat)
├── policy.new.v0.rego # Draft varian policy berikutnya (tidak dimuat)
└── .env.exampleHanya
policy.regoyang dimuat olehrunning.sh(lihat perintah di bawah).policy.old.regodanpolicy.new.v0.regoada di repo sebagai riwayat/draft, tidak aktif di runtime.
Startup (running.sh)
# 1. Login ke Infisical pakai Universal Auth
export INFISICAL_TOKEN=$(infisical login \
--method=universal-auth \
--client-id="$INFISICAL_CLIENT_ID" \
--client-secret="$INFISICAL_CLIENT_SECRET" \
--silent --plain)
# 2. Jalankan OPA server dengan secret ter-inject sebagai env var,
# memuat config, data, dan policy dari volume /share
exec infisical run --watch --path="$INFISICAL_PATH" --projectId="$INFISICAL_PROJECT_ID" --env="$INFISICAL_ENVIRONMENT" -- \
opa run --log-level=debug --server --addr 0.0.0.0:8181 -c /share/config.yml /share/data.json /share/policy.rego--watch membuat Infisical CLI memantau perubahan secret dan me-restart proses opa run bila ada update — sehingga rotasi secret di Infisical tidak butuh redeploy manual, kecuali untuk secret yang dihardcode langsung di file policy (lihat catatan di bawah).
Konfigurasi OPA Server (config.yml)
Saat ini seluruh isi config.yml dalam keadaan commented out — OPA server berjalan dengan pengaturan default (tanpa decision log ke service eksternal). Jika diaktifkan, konfigurasi ini akan mengirim setiap keputusan otorisasi ke service logger (opa-logger-v2) untuk audit trail:
# services:
# logger:
# url: http://opa-logger-v2:3000
# decision_logs:
# console: true
# service: logger
# reporting:
# min_delay_seconds: 0
# max_delay_seconds: 1Alur Keputusan Policy (policy.rego)
Policy verify_access menerima input: { method, token, path } dari opa-auth dan mengevaluasi lewat rule berikut:
| Rule | Fungsi |
|---|---|
token | Memverifikasi signature JWT (HS256) lalu mendekode payload-nya. Gagal verifikasi → is_token_valid: false. |
is_token_not_exp | True jika token.payload.exp belum lewat waktu sekarang. |
user_roles | Diambil dari data.user_roles[token.payload.username] — data yang disuplai OPA Data. |
user_is_granted | Menggabungkan seluruh grant dari data.role_grants[role] untuk semua role milik user. |
path_matches | Mencocokkan grant.path dengan input.path per segmen, mendukung wildcard * pada satu segmen. |
user_cases | Grant yang method-nya cocok, status == true, dan path-nya match. |
allow | true jika: method OPTIONS, atau path adalah /auth/login / /auth/refresh-token (whitelist tanpa token), atau (token belum expired dan ada minimal satu user_cases yang cocok). |
Catatan teknis:
policy.regoyang aktif saat ini memverifikasi signature JWT dengan secret yang di-hardcode langsung di file policy, bukan dibaca dari environment variableJWT_SECRETseperti padapolicy.old.rego/policy.new.v0.rego. Akibatnya, rotasiJWT_SECRETdi Infisical/user-service tidak akan otomatis diikuti oleh policy yang sedang aktif — perlu penyelarasan agar mekanismenya konsisten dengan dua varian file lain.
Build & Run
docker build -t opa-config .
docker run -p 8181:8181 \
-v /host/share:/share \
-e INFISICAL_CLIENT_ID=... \
-e INFISICAL_CLIENT_SECRET=... \
-e INFISICAL_PATH=... \
-e INFISICAL_PROJECT_ID=... \
-e INFISICAL_ENVIRONMENT=dev \
opa-configVolume
-v /host/share:/sharewajib ada dan sama dengan volume yang dipakai OPA Data —config.yml,data.json, danpolicy.regosemuanya dibaca dari path/share.