Securing Patient Data: PDP Law Compliance and SIMRS Technical Implementation
N
Back to Blog

Securing Patient Data: PDP Law Compliance and SIMRS Technical Implementation

Industri Kesehatan
Nugroho Setiawan · Konsultan IT & Full Stack Developer 30 Apr 2026 15 min baca 3,277 kata 481 views
This article discusses a comprehensive strategy for securing patient data in healthcare facilities in accordance with the Personal Data Protection Law (PDP Law). Learn about technical implementation steps, from data encryption to access management, as well as integration with standards such as FHIR

In today's digital era, healthcare facilities such as hospitals and clinics face a dual challenge: providing the best medical services while maintaining the confidentiality and security of patient data. Cyber threats are increasingly sophisticated, and data breaches can lead to significant fines, reputational damage, and loss of public trust. In Indonesia, Law Number 27 of 2022 on Personal Data Protection (PDP Law) has been enacted, requiring every data controller and processor to take concrete steps to protect sensitive information, particularly health data. As an Operations Manager and Full Stack Developer experienced in SIMRS development, BPJS/SatuSehat/FHIR integration, and various other enterprise systems, I fully understand the complexity and criticality of this security aspect. This article will guide you through the basic concepts of the PDP Law, the technical implementation details that must be present in a modern SIMRS, code examples you can apply, and best practices to ensure your patient data is secure and compliant with regulations.

Basic Concepts of Patient Data Security and the PDP Law

The Personal Data Protection Law (PDP Law) Number 27 of 2022 is the primary legal foundation for personal data governance in Indonesia. For healthcare facilities, an in-depth understanding of this law is vital because they manage specific, highly sensitive personal data. The PDP Law defines personal data as data about an individual who is identified or can be identified separately or in combination with other information. Specific personal data includes health information, biometric data, genetic data, criminal records, children's data, personal financial data, and sexual orientation data. Patient health data, therefore, falls into the most sensitive category and requires extra protection.

Healthcare facilities act as 'Personal Data Controllers' who determine the purposes and exercise control over data processing. Therefore, the responsibility for ensuring data security lies with them. The PDP Law underscores several principles of personal data processing, including: limited and specific data collection, lawful, transparent, and fair data processing, data accuracy, and adequate data protection. Violations of these principles can result in administrative sanctions in the form of written warnings, temporary suspension of data processing activities, administrative fines of up to 2% of annual revenue, and even revocation of business licenses.

In the context of data security, we always refer to three main pillars, known as the CIA Triad: Confidentiality, Integrity, and Availability. Confidentiality means data can only be accessed by authorized parties. Integrity ensures data is not unlawfully modified and remains accurate. Availability guarantees that data and systems can be accessed by authorized parties whenever needed. All technical and non-technical efforts in securing patient data must be based on these three pillars.

As a concrete example, imagine a hospital experiencing a data breach that exposes the medical records of thousands of patients, including diagnoses of chronic diseases and treatment histories. An incident like this not only violates data confidentiality but can also permanently damage the hospital's reputation and cause significant financial losses due to PDP Law fines and compensation claims from patients. The importance of implementing a strong security system, as will be discussed in the next section, is non-negotiable.

Technical Implementation of Data Security in SIMRS

Implementing PDP Law compliance in a Hospital Management Information System (SIMRS) requires a comprehensive technical approach. Here are several key areas that must be the focus:

Data Encryption

Encryption is the foundation of data security. Patient data must be encrypted both at rest (data-at-rest) and in transit (data-in-transit). For data-at-rest, you can use the Transparent Data Encryption (TDE) feature in databases such as PostgreSQL 16 (via the pghash extension or third-party solutions) or MySQL 8.x. Alternatively, filesystem-level encryption using LUKS (Linux Unified Key Setup) can protect the entire disk partition where data is stored. For data-in-transit, ensure all communication between SIMRS services, or between SIMRS and external systems such as BPJS Kesehatan or the SatuSehat platform, uses the Transport Layer Security (TLS) protocol version 1.2 or 1.3. Implement Nginx 1.24.x as a reverse proxy with SSL/TLS certificates from Let's Encrypt or another trusted CA to secure API endpoints.

Access Management (Authentication & Authorization)

The system must be equipped with strong authentication and authorization mechanisms. Implement strict Role-Based Access Control (RBAC), where each user (doctor, nurse, admin, medical records staff) only has access rights appropriate to their role and job requirements (the principle of least privilege). For example, a nurse can only view the medical record data of patients in their ward, while an IT admin may not have direct access to patient data but only to system logs. Multi-Factor Authentication (MFA) must be implemented for all access to SIMRS, whether via TOTP (such as Google Authenticator) or hardware devices such as YubiKey. For integration with external applications or patient portals, Single Sign-On (SSO) based on OpenID Connect/OAuth 2.0 must be used to minimize credential exposure.

Audit Trail and Monitoring

Every activity that occurs in the SIMRS must be recorded in detail in an audit trail. This includes who accessed what data, when, from where, and what changes were made. These logs are crucial for digital forensics in the event of a security incident and to prove compliance. Use a centralized log aggregation system such as the ELK Stack (Elasticsearch, Logstash, Kibana) to collect, analyze, and monitor logs in real-time. Accreditation standards such as JCI or KARS often require log retention of at least 5 years, so ensure your logging system can meet this requirement.

Secure Integration with Health Standards

Integration with national platforms such as SatuSehat or BPJS Kesehatan must be carried out with the highest security standards. SatuSehat, which is based on FHIR R4, requires the use of OAuth 2.0 for authentication and authorization of API access. Ensure your SIMRS uses a leading FHIR library (for example, HAPI FHIR 6.8 as a FHIR server or client) that is securely configured. For application development, use modern frameworks such as Laravel 11.x (with PHP 8.2+) or Node.js 20 LTS, which provide strong built-in security features and an active community for security updates. Always validate and sanitize incoming and outgoing data to prevent injection attacks or data manipulation.

Example Security Implementation Code

To provide a concrete illustration, here are some examples of data security implementation using frameworks and technologies commonly used in modern SIMRS development.

1. Encrypting Sensitive Data Using Laravel Crypt Facade

Laravel provides an easy-to-use encryption facility through the Crypt facade. This is ideal for securing specific personal data such as NIK, BPJS numbers, or certain medical information before storing it in the database. The encryption key is taken from the APP_KEY environment variable, which must be kept confidential and rotated periodically.

use Illuminate\Support\Facades\Crypt;use Illuminate\Support\Facades\Log;// Example of sensitive data$nikPasien = '3273010101800001'; // Fictitious NIK$noBpjs = '0001234567890'; // Fictitious BPJS number// Encrypt data before storing to database$encryptedNik = Crypt::encryptString($nikPasien);$encryptedNoBpjs = Crypt::encryptString($noBpjs);Log::info('Encrypted NIK: ' . $encryptedNik);Log::info('Encrypted BPJS No: ' . $encryptedNoBpjs);// Save $encryptedNik and $encryptedNoBpjs to database// ...// When data is needed, perform decryption$decryptedNik = Crypt::decryptString($encryptedNik);$decryptedNoBpjs = Crypt::decryptString($encryptedNoBpjs);Log::info('Decrypted NIK: ' . $decryptedNik); // Output: 3273010101800001Log::info('Decrypted BPJS No: ' . $decryptedNoBpjs); // Output: 0001234567890

The code above shows how sensitive data such as NIK and BPJS numbers can be encrypted before being stored in the database and decrypted when needed. It is important to ensure that your APP_KEY is a strong random string and never hardcoded. Rotating encryption keys periodically is also a good security practice to reduce risk if the key is compromised.

2. Middleware for Role-Based Access Control (RBAC) in Laravel

RBAC is an important pillar in access management. With RBAC, you can define roles (for example, 'admin', 'doctor', 'nurse', 'medical_record') and grant access permissions to certain resources only to relevant roles. Laravel allows efficient RBAC implementation using middleware.

// app/Http/Middleware/CheckRole.phpnamespace App\Http\Middleware;use Closure;use Illuminate\Http\Request;use Symfony\Component\HttpFoundation\Response;class CheckRole{    /**     * Handle an incoming request.     *     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next     */    public function handle(Request $request, Closure $next, ...$roles): Response    {        if (! $request->user()) {            abort(401, 'Unauthenticated.');        }        // Assume User model has 'role' column or hasRole() method        if (! $request->user()->hasAnyRole($roles)) {            abort(403, 'Access denied. You do not have the required permissions.');        }        return $next($request);    }}// In User.php model (example implementation of hasAnyRole method)class User extends Authenticatable{    // ...    public function hasAnyRole(array $roles): bool    {        return in_array($this->role, $roles); // Assume 'role' column in users table    }}// Usage in route (routes/api.php or routes/web.php)Route::middleware(['auth:sanctum', 'role:admin'])->group(function () {    Route::get('/data-pasien/semua', [PasienController::class, 'getAllPatients']);});Route::middleware(['auth:sanctum', 'role:dokter,perawat'])->group(function () {    Route::get('/data-pasien/saya', [PasienController::class, 'getMyPatients']);});

This CheckRole middleware will check whether the authenticated user has one of the roles allowed to access a particular route. If not, access will be denied with status code 403 (Forbidden). This ensures that only authorized staff can view or manipulate patient data according to their duties and responsibilities, in accordance with the principle of least privilege and UU PDP compliance.

Data and Error Handling in Integration

In the SIMRS ecosystem, integration with external systems such as SatuSehat or BPJS is commonplace. However, this integration process is also a potential point of vulnerability if not handled properly. It is important to understand secure data structures and how to handle errors that may occur during communication between systems.

Example Secure Payload: FHIR Patient Resource

FHIR (Fast Healthcare Interoperability Resources) is a healthcare data interoperability standard adopted by SatuSehat. Sending patient data via FHIR must follow the established structure and ensure that sensitive data is handled appropriately. The following is an example of a realistic FHIR Patient Resource R4, highlighting how patient identification and demographic data are managed:

{  "resourceType": "Patient",  "id": "example-patient-id",  "meta": {    "profile": [      "http://hl7.org/fhir/R4/StructureDefinition/Patient"    ]  },  "text": {    "status": "generated",    "div": "

Patient: Budi Santoso

" }, "identifier": [ { "use": "usual", "type": { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/v2-0203", "code": "NI", "display": "National unique individual identifier" } ], "text": "Nomor Induk Kependudukan" }, "system": "https://example.org/fhir/sid/nik", "value": "1234567890123456", "assigner": { "display": "Dinas Kependudukan dan Pencatatan Sipil" } }, { "use": "official", "type": { "coding": [ { "system": "http://terminology.hl7.org/CodeSystem/v2-0203", "code": "MC", "display": "Medical record number" } ], "text": "Nomor Rekam Medis" }, "system": "https://example.com/fhir/sid/mrn", "value": "MRN-000123" } ], "active": true, "name": [ { "use": "official", "family": "Santoso", "given": [ "Budi" ], "prefix": [ "Tn." ] } ], "gender": "male", "birthDate": "1980-01-01", "address": [ { "use": "home", "line": [ "Jl. Mawar No. 10" ], "city": "Jakarta", "postalCode": "12345", "country": "ID" } ], "telecom": [ { "system": "phone", "value": "+6281234567890", "use": "mobile" } ]}

The payload above shows how the NIK and Medical Record Number (MRN) are uniquely identified using systems and values. It is important to ensure that this unique identification is not misused and that other sensitive data (for example, diagnosis details) is included only when truly necessary and with appropriate consent. Pseudonymization or tokenization can be an additional strategy to protect patient identity when interacting with external systems that do not require full identity.

Example Error Message and Handling

Authentication or authorization errors are common in API integration. Proper handling is crucial to maintaining system availability and data security. One common scenario is an expired or invalid access token.

// Example Error Response from external API (e.g., SatuSehat){  "error": "Unauthorized access",  "message": "Invalid or expired access token.",  "code": 401}// Example error handling in PHP code (using Guzzle HTTP Client)use GuzzleHttp\Client;use GuzzleHttp\Exception\ClientException;use Illuminate\Support\Facades\Log;class SatuSehatService{    protected $httpClient;    protected $accessToken;    public function __construct()    {        $this->httpClient = new Client([            'base_uri' => 'https://api.satusehat.kemkes.go.id/fhir-r4/v1/',            'timeout'  => 10.0,        ]);        $this->accessToken = $this->getSatuSehatAccessToken(); // Get token from cache or DB    }    protected function getSatuSehatAccessToken(): string    {        // Implementation to retrieve or refresh SatuSehat access token        // For example, from database or cache        return 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'; // Actual token        // If token expired, call refresh token endpoint and store the new one    }    protected function refreshSatuSehatToken(): string    {        // Logic to call SatuSehat refresh token endpoint        // and store new token to cache/database        Log::info('Refreshing SatuSehat access token...');        // ... (implementation of API call to refresh token endpoint)        $newAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.NEW_TOKEN...';        $this->accessToken = $newAccessToken;        return $newAccessToken;    }    public function sendPatientData(array $patientData): array    {        try {            $response = $this->httpClient->post('Patient', [                'headers' => [                    'Authorization' => 'Bearer ' . $this->accessToken,                    'Content-Type' => 'application/json'                ],                'json' => $patientData            ]);            return json_decode($response->getBody()->getContents(), true);        } catch (ClientException $e) {            $statusCode = $e->getResponse()->getStatusCode();            $errorMessage = $e->getResponse()->getBody()->getContents();            Log::error('SatuSehat API Error: ' . $statusCode . ' - ' . $errorMessage);            if ($statusCode === 401 && str_contains($errorMessage, 'expired access token')) {                Log::warning('SatuSehat Access Token expired. Attempting to refresh...');                try {                    $newAccessToken = $this->refreshSatuSehatToken();                    // Retry request with new token                    $response = $this->httpClient->post('Patient', [                        'headers' => [                            'Authorization' => 'Bearer ' . $newAccessToken,                            'Content-Type' => 'application/json'                        ],                        'json' => $patientData                    ]);                    return json_decode($response->getBody()->getContents(), true);                } catch (ClientException $retryE) {                    Log::critical('Failed to refresh token and retry SatuSehat API: ' . $retryE->getMessage());                    throw new \Exception('Failed to completely send patient data to SatuSehat after token refresh.');                }            } else {                throw new \Exception('Failed to send patient data to SatuSehat: ' . $errorMessage);            }        }    }}

The code above shows how you can handle a 401 (Unauthorized) error caused by an expired access token. After detecting such an error, the system should automatically attempt to refresh the token and retry the request. If the refresh and retry attempts also fail, the error should be logged critically, and the admin should be notified. Detailed logging and automatic notifications are essential to ensure service availability and compliance with security standards.

Best Practices for Patient Data Security

  1. Conduct Periodic Risk Assessment: Proactively identify vulnerabilities, threats, and potential impacts on patient data. Use industry-standard frameworks such as NIST SP 800-30 to conduct a comprehensive risk assessment, at least annually or after significant changes to the system.
  2. Implement End-to-End Encryption: Ensure data is encrypted at every stage: at rest (data-at-rest) using the AES-256 algorithm for databases and filesystems, and in transit (data-in-transit) using the TLS 1.3 protocol for all network communications, including APIs and VPN connections.
  3. Implement Strict Role-Based Access Control (RBAC): Grant access rights only as needed for the job (the principle of least privilege). Review and update user access rights periodically, at least every six months, to ensure there is no unnecessary accumulation of access rights.
  4. Require Multi-Factor Authentication (MFA) for All Access: Implement MFA for all users and access to the SIMRS system, servers, networks, and cloud services. This can be a combination of a password with TOTP (Time-based One-Time Password) via an application such as Google Authenticator or a hardware device such as YubiKey.
  5. Conduct Audit Trails and Monitor System Activity: Record every access, modification, and deletion of patient data in detail. Use a SIEM (Security Information and Event Management) system such as the ELK Stack to analyze logs in real time, detect anomalies, and provide early warnings of potential security incidents.
  6. Regularly Perform Patching and System Updates: Ensure that all operating systems, databases (for example, PostgreSQL 16, MySQL 8.x), application frameworks (Laravel 11.x, Node.js 20 LTS), and third-party libraries are always updated with the latest security patches. Automate the patching process where possible to reduce security gaps.
  7. Provide Data Security Training for Staff: Educate all employees of healthcare facilities about the importance of personal data protection, internal security policies, how to identify phishing attacks, and other basic cybersecurity practices. Staff awareness is a crucial first line of defense.
  8. Design a Disaster Recovery Plan (DRP): Prepare a detailed plan to restore data and system operations in the event of a security incident, system failure, or natural disaster. Perform regular data backups and periodically test the restore process to ensure the effectiveness of your DRP.
  9. Conduct Penetration Testing (Pentest) and Vulnerability Assessment (VA) Periodically: Involve certified independent third parties to conduct pentests and VAs on your SIMRS system at least once a year. This will help identify security gaps that may be missed by internal testing and provide an objective external perspective.

FAQ

  1. Q: What is the difference between sensitive personal data and general personal data according to the PDP Law?
    A: Sensitive personal data, such as health, biometric, and genetic data, requires stricter protection because the potential risks are greater if a breach occurs. General personal data, such as names and addresses, still needs to be protected but at a level that may differ slightly in terms of access control and encryption. The PDP Law classifies this data to ensure a level of security proportional to its sensitivity and potential impact on data subjects.
  2. Q: Is data encryption enough to comply with the PDP Law?
    A: Encryption is a crucial component, but it is not enough on its own. PDP Law compliance requires a holistic approach that includes strict access management, comprehensive audit trails, clear internal policies, ongoing staff training, and a solid disaster recovery plan. Encryption protects confidentiality, but data integrity and availability must also be ensured through other layered security controls.
  3. Q: How can I ensure my SIMRS system is compatible with SatuSehat standards while remaining secure?
    A: Ensure that the SatuSehat integration implementation follows the security specifications set by the Ministry of Health, especially regarding OAuth 2.0 authentication and the use of JSON Web Token (JWT). Use tested libraries or SDKs for FHIR and ensure your FHIR server (for example, HAPI FHIR 6.8) is securely configured. Perform strict validation of incoming and outgoing data and implement adequate logging for every transaction with SatuSehat.
  4. Q: What is the maximum fine if there is a violation of the PDP Law?
    A: Administrative fines for legal entities that violate the PDP Law can reach 2% of annual revenue or turnover, in addition to potential criminal sanctions and the obligation to compensate data subjects. These heavy sanctions show the government's seriousness in protecting personal data and encourage healthcare facilities to invest seriously in data security. Serious violations can also result in revocation of business licenses.
  5. Q: What is the role of the Operations Manager or Clinic Owner in data security?
    A: The Operations Manager or Clinic Owner holds a central role in establishing and enforcing data security policies at their facility. They are responsible for ensuring adequate resource allocation for the implementation of security technology, establishing strict standard operating procedures, and monitoring compliance on an ongoing basis. Strong leadership from top management is essential to building an effective and responsive data security culture.
  6. Q: How often should security audits and penetration testing be conducted?
    A: Internal security audits should be conducted at least every 6 months, or whenever there is a significant change to the system architecture or new features are implemented. Penetration testing by an independent third party should ideally be conducted at least once a year to obtain an objective assessment of external vulnerabilities. This frequency helps identify new security gaps and ensures security controls remain effective as cyber threats evolve.

Securing patient data is not only a legal obligation under the PDP Law, but also a form of ethical and professional commitment by healthcare facilities to their patients. By adopting a proactive security strategy, investing in the right technology, and consistently training staff, you not only comply with regulations but also build a strong foundation of trust with the community. A layered approach, from end-to-end encryption, role-based access management, to comprehensive audit trails and secure integration with standards such as FHIR/SatuSehat, is the key to success. If you need assistance in auditing an existing SIMRS system, designing a compliant security architecture, or implementing secure integration with SatuSehat/BPJS using the latest technology (PHP 8.2+, Laravel 11.x, PostgreSQL 16, HAPI FHIR 6.8, Node.js 20 LTS), our team at Nugroho Setiawan is ready to be your partner. We have deep experience in SIMRS, Bridging, and the development of secure and efficient systems. Don't delay any longer, contact us for a free consultation and realize a secure and compliant healthcare system.

This article is part of the knowledge base of Nugroho Setiawan, an IT consultant in Jogja (Yogyakarta). Related solutions: SIMRS (Hospital Information System) BPJS & SatuSehat Integration. Need a free consultation?

Terakhir diperbarui 18 Oct 2026

Komentar

Komentar ditinjau sebelum tampil.

Belum ada komentar. Jadilah yang pertama!

Butuh bantuan implementasi?

Saya membantu konsultasi IT & pengembangan aplikasi untuk rumah sakit, klinik, dan bisnis di Yogyakarta (DIY), Magelang, dan sekitarnya.

Produk & Solusi SIMRS ERP Portfolio Konsultasi Gratis