Teknis — OPA Data
Service sinkronisasi data policy RAGA yang dibangun di atas Bun + Express 5. Bertugas menarik data user-role dan role-grant dari user-service, menggabungkannya ke dalam shared JSON file, lalu mendorong data tersebut ke OPA (Open Policy Agent) melalui data API. Dipanggil oleh user-service setiap kali ada perubahan role atau policy.
Repository
| Key | Value |
|---|---|
| Git Remote | https://git.tlab.co.id/tarantula/tarantula-v2/opa-bun/opa-data.git |
| Branch Aktif | main |
git clone https://git.tlab.co.id/tarantula/tarantula-v2/opa-bun/opa-data.git
cd opa-dataTech Stack
| Layer | Teknologi |
|---|---|
| Runtime | Bun 1 |
| Framework | Express 5 (TypeScript) |
| HTTP Client | Axios |
| File I/O | Bun native (file, write) |
| Secret Management | Infisical SDK v5 |
| Logging | Morgan (HTTP request log) |
| Build | bun build --compile → binary tunggal |
Environment Variables
Tidak ada file .env — semua variabel diinjeksikan sebagai env var container.
Bootstrap (env var container)
| Variable | Default | Keterangan |
|---|---|---|
NODE_PORT | 3666 | Port server Express |
INFISICAL_SITE_URL | https://app.infisical.com | URL Infisical server |
INFISICAL_CLIENT_ID | — | Client ID Universal Auth |
INFISICAL_CLIENT_SECRET | — | Client Secret Universal Auth |
INFISICAL_ENVIRONMENT | — | Environment target (dev / staging / prod) |
INFISICAL_PROJECT_ID | — | ID project Infisical |
INFISICAL_PATH | — | Path secrets di Infisical |
Secrets via Infisical
| Variable | Keterangan |
|---|---|
URL_USER | Base URL user-service; digunakan untuk fetch /open-api/role-users dan /open-api/role-grants |
URL_OPA | Base URL OPA server; digunakan untuk PUT data ke {URL_OPA}/v1/data |
Endpoints
| Method | Path | Keterangan |
|---|---|---|
GET | /role-users | Sync mapping user → role dari user-service ke OPA |
GET | /role-grants | Sync mapping role → policy grants dari user-service ke OPA |
GET | /health | Health check → { status: "UP" } |
Jika response dari user-service bukan status 200, opa-data membalas 403 { info: "Conflict in timetable (blocked by OPA)" } (pesan bawaan dari kode, bukan konflik OPA sesungguhnya). Jika terjadi exception (mis. user-service atau OPA tidak dapat dihubungi), opa-data membalas 500 { info: "Internal Server Error" }.
Alur Sinkronisasi
Struktur Data di OPA
Data yang di-push ke OPA (PUT /v1/data) berbentuk JSON dengan struktur:
{
"user_roles": {
"john_doe": ["admin"],
"jane_smith": ["viewer"]
},
"role_grants": {
"admin": [
{ "id": 1, "name": "read", "label": "Read Workspace", "method": "GET", "path": "/workspace", "status": true },
{ "id": 2, "name": "write", "label": "Write Workspace", "method": "POST", "path": "/workspace", "status": true }
],
"viewer": [
{ "id": 1, "name": "read", "label": "Read Workspace", "method": "GET", "path": "/workspace", "status": true }
]
}
}Isi tiap grant di role_grants[role] bukan hasil transformasi opa-data — melainkan disalin apa adanya dari field policies pada response GET /open-api/role-grants milik user-service (id, name, label, method, path, status). Field method, path, dan status-lah yang benar-benar dipakai oleh policy Rego di OPA Config (grant.method, grant.path dengan wildcard *, grant.status == true); id, name, dan label ikut terbawa hanya sebagai metadata referensi. Request PUT /v1/data ke OPA dikirim dengan header Content-Type: application/json-patch+json.
Data ini digunakan oleh policy Rego di OPA Config untuk membuat keputusan otorisasi yang kemudian dikonsumsi oleh OPA Auth.
File /share/data.json
File ini berada di volume bersama antara container opa-data dan OPA. Setiap sync:
- File dibaca (jika tidak ada, dibuat baru dengan
{}) - Data baru di-merge (
Object.assign) ke existing data - File ditulis ulang
- Isi file yang sama di-PUT ke OPA data API
Posisi dalam Arsitektur
Build & Run
# Install dependencies
bun install
# Jalankan development
bun run index.ts
# Build binary tunggal (digunakan di Docker)
bun build --compile --minify --sourcemap --target=bun-linux-x64 ./index.ts --outfile opa-data
# Jalankan binary
./opa-dataDocker
docker build -t opa-data .
docker run -p 3666:3666 \
-v /host/share:/share \
-e INFISICAL_SITE_URL=http://... \
-e INFISICAL_CLIENT_ID=... \
-e INFISICAL_CLIENT_SECRET=... \
-e INFISICAL_ENVIRONMENT=dev \
-e INFISICAL_PROJECT_ID=... \
-e INFISICAL_PATH=... \
opa-dataVolume
-v /host/share:/sharediperlukan agar filedata.jsondapat dibaca oleh container OPA.