think
16px
820px

AHU MinIO (Artesca S3) Spesimen Fetch — Done Report (2026-07-13)

Status: LIVE on staging (ahu-ai-ocr:799a9380) — the spesimen registry's reference PDFs now auto-fetch from AHU's real object store, and the full signature-comparison chain was proven end-to-end against a real officer's real specimen.


What the creds unlocked

Fact Finding
Endpoint https://s3.artesca.ahu.go.id — the S3 API answers on 443 (the noted :9000 is firewall-filtered from our hosts); path-style URLs
Bucket apostille-prod (not apostille as the registry docs implied)
TLS serves an internal Artesca-CA cert with an incomplete chain — verification fails against public roots
Proof a real 400 KB specimen PDF (spesimen-file/202604/291120419-drsasep-dadang-mulyana-sh-mh.pdf) fetched with the creds, HTTP 200

Implementation: Bun.S3Client has no per-client CA/insecure option, so the specimen client now signs its own GETs (lib/s3-signed-fetch.ts, minimal SigV4, GET-only, unit-pinned vectors) and applies the TLS exception per-request only (SPECIMEN_MINIO_INSECURE_TLS=on — never process-wide; drop it once AHU serves a full chain). Staging env carries the five SPECIMEN_MINIO_* vars.

End-to-end proof (all through deployed code, real data)

  1. fetchSpecimenFromMinio pulled the officer's 400 KB specimen PDF from Artesca and cached it (SpecimenFile row, source MINIO).
  2. The demo submission's signer was matched to the real officer Drs. Asep Dadang Mulyana, S.H., M.H. — Hakim Pengadilan Agama Sumber (spesimen id 291120419).
  3. Auto path: the detector found the document's signature at (482,1240)–(875,1490) and compared it against the real specimen.
  4. Manual-draw path: POST /signature-region with a drawn box cropped exactly that region and re-compared — box persisted with manual: true.
  5. UI shows the whole story: green "cocok di registri" card → "Lihat spesimen tanda tangan" (streams the Artesca PDF) → side-by-side crops with "0% — kemungkinan berbeda" — which is the correct verdict: the document is signed by DARSANI while the matched specimen belongs to Mulyana, and the AI honestly flags them as different hands.

⚠️ One remaining blocker for the organic flow on staging

The spesimen registry MySQL (192.168.72.33, user bht-abi) refuses connections from the staging host — the grant is IP-scoped and doesn't cover 192.168.83.20 (it works from valserver). Consequence on staging: signer search/auto-matching silently returns nothing, so every signer comes out UNMATCHED unless seeded. MinIO fetching itself is unaffected once a match exists.

Fix needed from AHU's DBA: allow bht-abi (or a read-only equivalent) from 192.168.83.20 on the v1_appapos database — one GRANT statement. Until then I can bridge via a proxy on valserver if you want it sooner.

Do you need a new permohonan to test signature bbox + manual draw?

No. The existing demo (cee52830…/review) is now fully set up:
- the signer is matched with the real specimen attached — the comparison block is live;
- "Lihat lokasi ttd di dokumen" highlights the auto-detected box on the scan;
- "Tandai ulang" opens the draw-a-rectangle modal — drag a box around the actual signature and "Simpan & bandingkan" re-runs the comparison with your crop (the score updates and your box shows as (manual)).

For a fully organic run (upload → classify → match via the "Perbaiki" search → auto specimen → compare), the registry grant above is the only missing piece — the search finds no officers from staging until it lands.