Skip to content

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 ​

KeyValue
Git Remotehttps://git.tlab.co.id/tarantula/tarantula-v2/opa-bun/opa-config.git
Branch Aktifmain
bash
git clone https://git.tlab.co.id/tarantula/tarantula-v2/opa-bun/opa-config.git
cd opa-config

Tech Stack ​

LayerTeknologi
Base ImageAlpine 3.20
Policy EngineOPA binary v1.5.1 (diunduh langsung dari rilis GitHub saat build image)
Bahasa PolicyRego
Secret ManagementInfisical 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.

VariableKeterangan
INFISICAL_CLIENT_IDClient ID Universal Auth (wajib, dicek di awal running.sh)
INFISICAL_CLIENT_SECRETClient Secret Universal Auth (wajib)
INFISICAL_PATHPath secrets di Infisical
INFISICAL_PROJECT_IDID project Infisical
INFISICAL_ENVIRONMENTEnvironment target (dev / staging / prod)
JWT_SECRETDideklarasikan 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.example

Hanya policy.rego yang dimuat oleh running.sh (lihat perintah di bawah). policy.old.rego dan policy.new.v0.rego ada di repo sebagai riwayat/draft, tidak aktif di runtime.

Startup (running.sh) ​

bash
# 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:

yaml
# services:
#   logger:
#     url: http://opa-logger-v2:3000
# decision_logs:
#   console: true
#   service: logger
#   reporting:
#     min_delay_seconds: 0
#     max_delay_seconds: 1

Alur Keputusan Policy (policy.rego) ​

Policy verify_access menerima input: { method, token, path } dari opa-auth dan mengevaluasi lewat rule berikut:

RuleFungsi
tokenMemverifikasi signature JWT (HS256) lalu mendekode payload-nya. Gagal verifikasi → is_token_valid: false.
is_token_not_expTrue jika token.payload.exp belum lewat waktu sekarang.
user_rolesDiambil dari data.user_roles[token.payload.username] — data yang disuplai OPA Data.
user_is_grantedMenggabungkan seluruh grant dari data.role_grants[role] untuk semua role milik user.
path_matchesMencocokkan grant.path dengan input.path per segmen, mendukung wildcard * pada satu segmen.
user_casesGrant yang method-nya cocok, status == true, dan path-nya match.
allowtrue 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.rego yang aktif saat ini memverifikasi signature JWT dengan secret yang di-hardcode langsung di file policy, bukan dibaca dari environment variable JWT_SECRET seperti pada policy.old.rego/policy.new.v0.rego. Akibatnya, rotasi JWT_SECRET di Infisical/user-service tidak akan otomatis diikuti oleh policy yang sedang aktif — perlu penyelarasan agar mekanismenya konsisten dengan dua varian file lain.

Build & Run ​

bash
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-config

Volume -v /host/share:/share wajib ada dan sama dengan volume yang dipakai OPA Data — config.yml, data.json, dan policy.rego semuanya dibaca dari path /share.