Skip to content

Signing Platform Core API

By Romi Fadli, S.Kom. 9 min read Security & Secrets
On this page
A central core holding people, organisations, documents, and certificates, connected to eight surrounding services for storage, addresses, certificates, timestamps, the root, signing, thumbnails, and face challenges

Signing Platform Core API adalah jantung platform penandatanganan dokumen: aplikasi Laravel yang memegang orang, organisasi, sistem client, dan catatan, serta mengorkestrasi setiap service khusus di sekelilingnya. Kerjanya jauh lebih luas dari menandatangani. Ia mengelola akun user beserta identitasnya, organisasi beserta unitnya, sistem eksternal yang menandatangani lewat platform, dokumen beserta penanda tangan dan riwayatnya, stempel tanda tangan, dan sertifikat yang dipakai orang untuk menandatangani — lalu menyerahkan pekerjaan berat menandatangani, merender, menstempel waktu, dan menyimpan kepada service yang dibangun untuk itu.

Inilah satu-satunya module di platform yang milik satu project saja: ia memegang aturan dan data project itu, sementara service yang dipanggilnya bisa dipakai di mana pun. Saya tetap membangun dan menuliskannya sebagai module, supaya platform tetap satu kumpulan bagian yang konsisten dengan satu inti di tengahnya.

Sekilas

Bahasa & frameworkPHP, dengan Laravel, di atas PostgreSQL dan Redis
ArsitekturStateless Laravel Core
Versi2.15.1
StatusStabil, berjalan di production
BentukAPI HTTP dengan worker latar belakang, ditambah halaman depan publik yang dirender di server; antarmuka utamanya single-page application terpisah
Kode sumberPrivat
Apa module ini dan bagaimana keadaannya.

Yang dikerjakannya

A. Menjalankan penandatanganan dokumen

Dokumen di-upload, diberi satu atau lebih penanda tangan dalam tahap berurutan, lalu ditandatangani masing-masing secara bergiliran. Setiap tanda tangan adalah job di latar belakang: request langsung diterima, dokumen ditandai sedang ditandatangani, dan service signer mengerjakan bagian kriptografinya dengan sertifikat milik penanda tangan sendiri. Hash file yang sudah ditandatangani dicatat, sehingga dokumen bisa ditemukan lagi dari isinya, dan setiap versi bertanda tangan yang baru dirantai ke versi sebelumnya.

B. Mengelola orang dan identitasnya

Akun bisa dibuat langsung atau lewat identity provider eksternal, dilindungi autentikasi dua faktor, dan dikelola lintas perangkat. Sebelum seseorang boleh memegang sertifikat tanda tangan, identitasnya diverifikasi: data pribadi, dokumen identitas, dan tantangan wajah secara langsung, diperiksa oleh peninjau manusia.

C. Menerbitkan dan mengawasi sertifikat

Inti meminta sertifikat dari certificate authority penanda tangan atas nama seseorang, menjaga paling banyak satu sertifikat aktif per orang di tiap organisasi, dan memeriksa status pencabutan secara langsung ke authority itu, lalu memperbarui catatannya sendiri bila jawaban authority berbeda.

D. Mengatur siapa boleh melakukan apa

Organisasi berisi unit, unit berisi anggota, dan role diberi peringkat supaya tak ada yang bisa bertindak atas rekan setingkat atau orang di atasnya. Organisasi bisa menerima anggota secara otomatis dari allowlist alamat e-mail, dan administrator bisa menangguhkan akun tanpa menghapusnya.

E. Membiarkan sistem lain menandatangani lewatnya

Sistem client — pelanggan software-as-a-service platform ini — memanggil API client tersendiri dengan secret, origin yang diizinkan, dan izin per operasi miliknya sendiri. Client internal yang tepercaya boleh menautkan user secara langsung; client eksternal butuh persetujuan user. Hasilnya dikirim kembali ke tiap client lewat webhook, dikirim di latar belakang dan dicatat sampai berhasil.

F. Memperlihatkan platform kepada publik

Halaman beranda publik dirender oleh inti itu sendiri, dengan konten yang bisa diperbarui administrator, supaya mesin pencari bisa mengindeksnya; aplikasi tempat orang bekerja tinggal di repository-nya sendiri.

Antarmuka

BidangYang dibukanya
Autentikasilogin, refresh token yang berotasi, dua faktor, identity provider eksternal, signing key publik dari token-tokennya
Userakun, perangkat, role, template stempel
Organisasiorganisasi, unit, anggota, allowlist e-mail
Identitasverifikasi identitas, tantangan wajah, antrean peninjau
Sertifikatpermintaan, persetujuan, pencabutan, status langsung
Dokumen dan fileupload lewat link berumur pendek, penanda tangan, penandatanganan, versi bertanda tangan
Sistem clientpengelolaan client, dan API client tersendiri dengan autentikasinya sendiri
Administrasidashboard, job yang gagal, konten halaman publik
Readinesssatu endpoint yang memeriksa database, cache, storage, dan setiap service yang dibutuhkan inti
Bidang-bidang API, masing-masing di file route-nya sendiri.

Standar

StandarYang dijaminnya di sini
JSON Web Token dengan RS256, dan JWKS yang diterbitkansatu format token untuk setiap login, bisa diverifikasi service mana pun tanpa memanggil inti
OAuth 2.0 dan OpenID Connect, dengan PKCElogin lewat provider eksternal, ditukar menjadi token milik inti sendiri
TOTP (RFC 6238)autentikasi dua faktor dengan aplikasi authenticator apa pun
OCSP (RFC 6960)status pencabutan langsung untuk setiap sertifikat yang dipakai platform
Presigned URL, AWS Signature Version 4file berpindah antara browser dan storage tanpa melewati inti
W3C Trace Context dan OpenTelemetrysatu trace dari request user melewati setiap service dan job latar belakang
UUIDv7identitas publik dan request id yang terurut waktu dan tak membuka urutan internal
Standar yang dipatuhi inti, dan yang dijamin masing-masing.

Di dalamnya

Inti ini mengikuti Stateless Laravel Core: node tak memegang apa pun, pekerjaan lambat berjalan sebagai job di antrean, file tak pernah menyentuh server, setiap login berakhir dengan token milik inti sendiri, dan setiap request, job, serta panggilan keluar di-trace. Tiap service khusus dijangkau lewat satu class miliknya sendiri, dengan konfigurasi, timeout, dan keluarga error-nya sendiri.

Keputusan rancangan

Inti memutuskan; service khusus yang bekerja. Menandatangani, menstempel waktu, menerbitkan sertifikat, merender thumbnail, menantang wajah, menyimpan file, dan mencari data wilayah masing-masing menjadi milik service yang dibangun untuk tugas itu, dan inti mengorkestrasinya. Bila satu service tak punya yang dibutuhkan inti, saya memintanya di service itu, tak mengakalinya di sini — endpoint batch yang kini ditawarkan service storage ada karena inti membutuhkannya. Data wilayah dulu tinggal di tabel milik inti; kini ia pindah ke service alamat, dan organisasi menyimpan snapshot wilayahnya, bukan foreign key, sehingga perubahan kode wilayah resmi tak pernah diam-diam merusak record yang sudah ada.

Penandatanganan tak pernah membuat siapa pun menunggu. Request penandatanganan diperiksa sebelum masuk antrean — passphrase penanda tangan diverifikasi, jadi job tak pernah berangkat dari passphrase yang salah — lalu langsung diterima, dengan dokumen ditandai sedang ditandatangani, bukan sudah ditandatangani. Passphrase itu berjalan terenkripsi melewati antrean. Webhook ke client yang gagal tak pernah membatalkan tanda tangan; pengirimannya diulang dan dicatat terpisah.

Data pribadi dilindungi sebagai data, bukan hanya saat dikirim. Nomor telepon, data kelahiran, nomor identitas, dan secret dua faktor dienkripsi di database, dan nomor identitas bisa dicari tanpa mendekripsi apa pun. Nomor identitas polos tak pernah muncul di respons login, karena di sana ia akan mengendap di storage browser dan log. Satu registry menjadi satu-satunya tempat yang memutuskan apakah nomor identitas sudah terpakai, sehingga tak ada dua jalur kode yang bisa berbeda pendapat. Foto identitas yang ditampilkan ke peninjau membawa watermark yang menandai penayangnya, sehingga gambar yang bocor bisa ditelusuri, dan foto wajah dihapus dari storage begitu verifikasi disetujui.

Tak ada yang membocorkan apa yang ada. Identitas publik berupa UUID acak, tak pernah urutan internal, sehingga record tak bisa dihitung satu per satu. Endpoint yang bisa membocorkan apakah satu akun ada — reset password, e-mail verifikasi — menjawab dengan cara yang sama dalam kedua keadaan. Tindakan yang berdampak panjang mewajibkan password dimasukkan lagi, dan administrator tak bisa bertindak atas rekan setingkat atau role di atasnya.

Setiap versi bertanda tangan tetap tersambung. Hash tiap file yang ditandatangani disimpan, sehingga dokumen bisa dikenali dari file-nya saja. Ketika dokumen bertanda tangan di-upload lagi untuk tanda tangan berikutnya, versi barunya dirantai ke hash sebelumnya, dan karena byte file tak pernah melewati inti, hash itu dibaca kembali dari storage, tak dihitung dari upload yang tak pernah dilihat inti.

Dua jenis client, dua tingkat kepercayaan. Client internal — sistem yang dijalankan organisasi yang sama — dipercaya menautkan user-nya secara langsung dan menerima izin bawaan. Client eksternal harus mendapat persetujuan tiap user lewat token sekali pakai dan dibatasi pada operasi yang diizinkan baginya, diperiksa pada setiap panggilan. Secret client disimpan dalam bentuk hash, dan user yang dirujuk client dikenali lewat rujukan yang diturunkan platform sendiri, bukan identitas karangan client.

Sertifikat diperiksa di tempat asalnya. Status pencabutan ditanyakan langsung ke certificate authority, dan bila jawabannya berbeda dari catatan inti, catatan itulah yang mengikuti authority, dengan alasan pencabutan yang sebenarnya ikut disimpan. Sertifikat milik authority itu sendiri diambil sekali dan di-cache, tak disimpan sebagai file di server.

Storage selalu terhitung. Setiap object key yang dirujuk database dikenal satu indeks, tak ada yang dihapus dari storage tanpa bertanya kepadanya lebih dulu, dan audit read-only membandingkan storage dengan database sebelum apa pun disapu.

Spesifikasi

MasukanRequest dari aplikasi web, dari sistem client, dan dari administrator
HasilRespons JSON, dokumen bertanda tangan di storage, sertifikat atas nama user, webhook ke sistem client, e-mail
Bergantung padaPostgreSQL, Redis, dan service platform untuk storage, alamat, sertifikat, stempel waktu, penandatanganan, thumbnail, dan tantangan wajah
Kerja latar belakangJob di antrean untuk penandatanganan, thumbnail, webhook, e-mail, dan pemrosesan allowlist
KeamananToken RS256 dengan refresh token yang berotasi, autentikasi dua faktor, rate limit di Redis, data pribadi terenkripsi, role berperingkat
ObservabilityTrace, log, metrics, dan event audit OpenTelemetry, berlanjut melintasi setiap service dan job
Berjalan sebagaiContainer berisi web server dan worker antrean di bawah satu supervisor, ditambah kapasitasnya dengan menambah salinan
Yang diterima, dikembalikan, dan dibutuhkan inti.

Terkait

Service storage tempat setiap file, stempel, dan dokumen bertanda tangan berpindah.

Service alamat yang memasok data wilayah untuk organisasi.

Certificate authority yang menerbitkan sertifikat tiap penanda tangan dan menjawab pemeriksaan pencabutan.

Timestamp authority di balik tanggal setiap tanda tangan.

Root publisher di puncak rantai kepercayaan platform.

Signer yang mengubah setiap request di antrean menjadi tanda tangan PDF jangka panjang.

Renderer yang memberi setiap dokumen thumbnail halaman pertamanya.

Tantangan wajah yang membuktikan seseorang hadir selama verifikasi identitas.

Ke mana trace satu request yang melewati semua service ini berakhir.

Istilah

Orkestrasi
Mengoordinasikan beberapa service supaya bersama-sama menuntaskan satu pekerjaan, tanpa mengerjakan pekerjaan itu sendiri.
Enumerasi
Menemukan record atau akun mana yang ada dengan mencoba identitas satu per satu lalu membandingkan jawabannya.
Webhook
Request yang dikirim satu sistem ke alamat sistem lain untuk memberitahukan bahwa sesuatu telah terjadi.
Software as a service
Software yang dipakai pelanggan lewat server penyedianya, di sini dengan menyambungkan sistem milik mereka ke platform.

Technologies covered

  • PHP
  • Laravel
  • PostgreSQL
  • Redis
  • OpenTelemetry
  • OAuth 2.0

About the author

Photo of Romi Fadli

Romi Fadli, S.Kom.

Solution Architect · Backend Engineer · Embedded Systems

In my day job I work as a solution architect. I design the system, lead the team that builds it — quality assurance, backend developers, a UI developer, DevOps and DevSecOps — and write the most critical modules myself, such as a certificate authority, a long-term PDF signer, and the core API of a personnel system.

I work across the whole stack that a running system actually needs. On the hardware side that means PCB design, microcontrollers, and embedded firmware — including RISC-V boards running FreeRTOS and Embassy, speaking MQTT over mutually authenticated TLS on a microcontroller with 64 KB of SRAM.

Most of my day-to-day work is software: Rust backends and API modules built on Clean Architecture, an OAuth2/OpenID Connect authorization server written from scratch, PAdES document signing, and certificate authorities — root CAs, timestamping authorities, and OCSP responders. I also build the frontends that sit on top of them.

Running all of that means infrastructure: Docker Compose stacks, networking, Mikrotik and RADIUS, observability with OpenTelemetry, and a steady habit of writing command-line tools and utilities for Linux when the existing ones do not fit.

Share

Enjoyed this?

Get an email when a new article is published.

Referenced by

The core API at the centre, fed by storage, address, face and preview services, with documents sent across a boundary to an external signing platform

Inti Laravel sistem kepegawaian aparatur sipil negara: record pegawai dan riwayat karier, usulan swalayan yang diperiksa, keputusan kenaikan gaji berkala, kenaikan pangkat, dan pensiun, aturan dari peraturan, bagan organisasi berversi, dan akses berlingkup sampai satu unit.

11 min read Read more →
A memory chip holding a key, circled by refresh arrows, beside a browser window where a signature stamp is being dragged into place on a PDF page

Aplikasi browser Vue dari platform penandatanganan dokumen: sesi disimpan di memori dan diperbarui oleh satu refresh berantrean, login PKCE, stempel ditaruh presisi di halaman PDF, verifikasi identitas dengan tantangan wajah, persetujuan client, dan administrasi berbasis role.

10 min read Read more →
A purple root circle linked to a blue and an orange intermediate circle, which lead to a signed document with a green seal and to a clock.

Aurograf

DevOps

Platform tanda tangan digital Pemerintah Kota Tangerang Selatan: penanda tangan membuktikan identitasnya, menandatangani PDF hingga PAdES B-LTA dengan sertifikat dari otoritas milik platform sendiri, dan siapa pun bisa memverifikasinya — versi 2, yang saya rancang, bangun, dan operasikan.

10 min read Read more →

Related Articles

A memory chip holding a key, circled by refresh arrows, beside a browser window where a signature stamp is being dragged into place on a PDF page

Aplikasi browser Vue dari platform penandatanganan dokumen: sesi disimpan di memori dan diperbarui oleh satu refresh berantrean, login PKCE, stempel ditaruh presisi di halaman PDF, verifikasi identitas dengan tantangan wajah, persetujuan client, dan administrasi berbasis role.

10 min read Read more →
A signed PDF with a QR stamp, wrapped in four nested frames for the signature, its timestamp, the embedded validation data, and the archive timestamp

Service Python yang menandatangani PDF sampai PAdES B-LTA dengan stempel yang terlihat — menanamkan stempel waktu, sertifikat, dan bukti pencabutan, lalu stempel waktu arsip — supaya tanda tangan tetap bisa diverifikasi lama setelah sertifikatnya kedaluwarsa, dan memverifikasi PDF bertanda tangan.

10 min read Read more →
A document's fingerprint passing through a clock, signed by a certificate below it, and returning as a time seal stamped on the same document

Timestamp authority berbahasa Rust yang menstempel hash dokumen dengan waktu bertanda tangan berbasis NTP sesuai RFC 3161, supaya tanda tangan PDF tetap bisa diverifikasi setelah sertifikatnya kedaluwarsa — menerbitkan sendiri sertifikat penanda tangannya, dengan OCSP dan CRL publik.

9 min read Read more →