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)
fetchSpecimenFromMiniopulled the officer's 400 KB specimen PDF from Artesca and cached it (SpecimenFilerow, sourceMINIO).- 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). - Auto path: the detector found the document's signature at (482,1240)–(875,1490) and compared it against the real specimen.
- Manual-draw path:
POST /signature-regionwith a drawn box cropped exactly that region and re-compared — box persisted withmanual: true. - 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.