Security Hardening

Security Hardening & Cryptographic Infrastructure

1. Application-Layer Field-Level Encryption (CLE)

To ensure strict compliance with the Kenya Data Protection Act (2019), Personally Identifiable Information (PII) must never be stored in cleartext inside database blocks or logs. The HMIS enforces Application-Layer Cryptographic Field-Level Encryption using AES-256-GCM.

Rendering Chart

1.1 Python Cryptographic Mixin Implementation

The Django persistence layer uses an abstract model field mixin to automate encryption and decryption during database read/write cycles:

import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from django.db import models
from django.conf import settings

class EncryptedStorageField(models.BinaryField):
    """
    Custom Django model field that encrypts cleartext strings into 
    authenticated AES-256-GCM ciphertext binaries before database write.
    """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.key = bytes.fromhex(settings.FIELD_ENCRYPTION_MASTER_KEY)

    def get_prep_value(self, value):
        if not value:
            return None
        if isinstance(value, bytes):
            return value
            
        # Generate a secure random 12-byte initialization vector (IV)
        aesgcm = AESGCM(self.key)
        nonce = os.urandom(12)
        ciphertext = aesgcm.encrypt(nonce, value.encode('utf-8'), None)
        
        # Prepend the nonce to the ciphertext to allow accurate decryption
        return nonce + ciphertext

    def from_db_value(self, value, expression, connection):
        if not value:
            return None
            
        nonce = value[:12]
        ciphertext = value[12:]
        aesgcm = AESGCM(self.key)
        
        try:
            decrypted_bytes = aesgcm.decrypt(nonce, ciphertext, None)
            return decrypted_bytes.decode('utf-8')
        except Exception:
            return "[DECRYPTION_ERROR: Tampering Detected]"

2. Multi-Tenant Role-Based Access Control (RBAC)

System privileges are strictly coupled to functional roles within the clinical hierarchy. Access control is enforced using a declarative permissions model down to the individual API route level.

2.1 Role-Based Privilege Grid

System RoleScope BoundariesAllowed OperationsData Access Restrictions
HRIO / ClerkMaster Patient IndexCreate Patient, Search Record, Print IDBlocked from reading clinical notes/vitals.
Triage NurseOPD Triage, Ward CareRead Patient, Write Vitals, Enqueue PatientCannot prescribe drugs or modify bills.
Medical OfficerGlobal Clinical ScopeRead Patient, Write History, Order Labs, PrescribeCannot modify financial transaction status.
PharmacistPharmacy ModuleRead Prescriptions, Dispense Items, Track InventoryBlocked from viewing psychiatric consultation blocks.
Billing OfficerFinancial LedgerCollect Cash, Trigger M-Pesa, Split BillsBlocked from writing clinical diagnostic rows.

2.2 API Authorization Decorator Pattern

The backend uses functional Python decorators to intercept and validate user clearance tokens before route execution:

from functools import wraps
from ninja.errors import HttpError
from django.http import HttpRequest

def enforce_system_clearance(allowed_roles: list):
    """
    Django Ninja API gateway decorator to enforce strict token-level 
    RBAC enforcement on active incoming HTTP requests.
    """
    def decorator(view_func):
        @wraps(view_func)
        def wrapper(request: HttpRequest, *args, **kwargs):
            if not request.auth or not hasattr(request.auth, 'system_role'):
                raise HttpError(401, "Authentication Credentials Missing")
                
            if request.auth.system_role not in allowed_roles:
                raise HttpError(403, "Access Revoked: Insufficient Hierarchy Privileges")
                
            return view_func(request, *args, **kwargs)
        return wrapper
    return decorator

3. API & Web Session Security Hardening

To secure the user session pipeline across browser instances and analyzer gateways, the backend enforces specific token management and browser protection headers.

3.1 Token and Session Security Settings

  • State Management Isolation: Authentication tokens use cryptographically signed JWT payloads with short lifetimes (15-minute access token lifespan, 8-hour sliding refresh window token).
  • Defensive HTTP Response Headers: The reverse proxy layer injects strict security policy parameters into every outbound transmission sequence:
# Caddy Secure Header Injection Definitions
header {
    Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    X-Frame-Options "DENY"
    X-Content-Type-Options "nosniff"
    X-XSS-Protection "1; mode=block"
    Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; object-src 'none';"
    Referrer-Policy "strict-origin-when-cross-origin"
}
  1. On-Premise Physical Server Infrastructure Hardening Since deployment occurs locally on server hardware within the physical boundaries of a Level 4 hospital, software configurations must defend against physical intrusions and local network exploits.
Rendering Chart

4.1 Linux Operating System Hardening Policy

  • SSH Port Obfuscation: The standard SSH port is remapped from 22 to 2222. Password-based authentication is explicitly disabled in /etc/ssh/sshd_config, requiring cryptographically signed SSH keys for all administrative connections.
  • UFW Firewall Rule Enforcement: The host system blocks all network ports by default, opening only essential access paths:
# Production host firewall rules configuration
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 80/tcp comment 'HTTP automated dynamic ACME upgrade path'
sudo ufw allow 443/tcp comment 'HTTPS incoming clients connectivity portal'
sudo ufw allow 2222/tcp comment 'Obfuscated Admin management gateway interface'
sudo ufw enable
  • Database Access Isolation: PostgreSQL is configured to reject external TCP network requests by enforcing listen_addresses = 'localhost' within postgresql.conf. External network routing inside the monolith relies entirely on isolated, virtual Docker-managed networks.

Document Verification Block

Author: Ian Wataka - Backend DeveloperTarget Scope: Level 4 Hospital Production Infrastructure