All features Security
Security

Security, access control & data management — technical details

Security in MindFlow is layered: authentication (who you are), authorisation (what you can do), and audit (what happened). Every sensitive action produces an audit record. Backups, scheduled tasks, and the plugin system are all visible and controllable to the clinic admin.

TOTP (RFC 6238) Argon2id DPDP Act 2023 OWASP Top 10

Authentication

2FA (TOTP)

pages/2fa_setup.php and pages/2fa_verify.php implement RFC 6238 Time-based One-Time Password (TOTP) 2FA for all staff accounts. Compatible with any TOTP app (Google Authenticator, Authy, Microsoft Authenticator). Recovery codes are generated at setup and stored hashed.

Password security

Passwords are hashed with Argon2id (PHP password_hash PASSWORD_ARGON2ID) with tuned memory/time cost. Minimum complexity is enforced. Password reset tokens are single-use, hashed in the database, and expire after 60 minutes.

Login rate limiting

login_attempts tracks failed logins per IP and per username. After 5 failures in 10 minutes, the account is soft-locked and an email alert is sent to the admin.

Google OAuth login

includes/google_login.php + api/google_jwt_callback.php: staff can sign in with a Google Workspace account if the clinic admin has configured a Google OAuth client ID/secret. This is in addition to (not a replacement for) the password-based login — 2FA still applies.

Roles & permissions (RBAC)

Role model

Users are assigned a role. roles defines the role name; role_permissions maps each role to a set of permission strings (e.g., patients.view, billing.edit, ipd.admit). includes/rbac.php provides checkPermission() used on every protected action.

Granularity

Permissions are defined at the action level (view, create, edit, delete) per module. A receptionist can be given patients.view but not prescriptions.create. The default roles (Admin, Doctor, Nurse, Receptionist, Pharmacist) are a starting point; admins can define custom roles.

Feature-level gating

Module-level access (e.g., accessing the Pharmacy portal) is controlled by includes/features.php featureEnabled() checks before RBAC — so a feature that is disabled at the plan level is inaccessible regardless of role.

Audit & incident logging

Audit logs

audit_logs records every significant action: patient record viewed, note saved, prescription signed, billing change, role change, login, logout. Columns: user_id, action, object_type, object_id, ip_address, user_agent, timestamp, payload_hash.

Security incidents

security_incidents (pages/security_incidents.php): a register for data breaches, unauthorised access events, and other security incidents. Separate from clinical incident reports. Each entry has severity, description, affected patients (count), containment actions, and resolution status.

Data rights register

data_rights_requests (pages/data_rights.php): tracks patient Subject Access Requests (SAR) and erasure requests under the DPDP Act. Status workflow: received → acknowledged → fulfilled / rejected, with a deadline tracker.

System logs

pages/system_logs.php: PHP error log viewer, cron run history, and a tail of the application log — filterable by level and date range. Accessible to clinic admins only.

Backups & data lifecycle

Automated backups

pages/backup.php + api/backup.php: database dumps are scheduled via the cron manager. Dumps are written to /backups/ (configurable path), compressed, and optionally encrypted. Backup history is visible in the UI with download links for the most recent N dumps.

Data reset

pages/data_reset.php allows a clinic admin to wipe all clinical data from a deployment (patients, appointments, notes, billing, etc.) while preserving settings and user accounts. Protected by a confirmation code. Primarily used for demo/trial resets.

DPDP erasure

A patient erasure request (from the portal or from the data rights register) triggers a hard-delete of PII fields in the patients table and soft-deletion of linked records. The audit_log retains the anonymised event (action + timestamp) but not the patient's identity.

API, plugins & scheduled tasks

External API

api/plan_control.php (used by the SaaS hoster) and general-purpose API endpoints are authenticated via API keys stored in app_settings. All API calls are logged in external_api_logs (endpoint, method, response code, latency). pages/api_usage.php visualises this log.

Plugin system

includes/plugin_loader.php discovers installed plugins (plugins/*/plugin.json), registers their hooks, and loads their settings. Plugins can add nav items, API handlers, and settings panels. includes/hooks.php provides the event system (do_action / add_action pattern). Plugins cannot override core code.

Cron manager

pages/cron_manager.php + includes/cron_jobs.php: all scheduled tasks (backup, reminder dispatch, appointment sync, expiry alerts, AI health audit) are defined here. Each task has a schedule (cron expression), last-run time, and a pass/fail log in cron_runs. The cron is triggered by a server cron job calling api/cron.php.

Update system

pages/updates.php + includes/updater.php: the admin can check for and apply application updates (database migrations + file updates) from within the admin UI, without server-level access.

Ready to see it in action?

The demo has real sample data — appointments, patients, prescriptions — so you can explore freely.

Try the demo ← All features