| Metric | What It Measures | How It's Calculated |
|---|---|---|
| Score (0-10) | Movement quality | min() of 3s and 5s window scores. Each window: slide through data, find best q-diff range, map to 0–10 via knot curve. Capped at 7 unless 7s data exists (see 7s Bonus below). |
| Q-Diff | Raw quaternion rotation range | The q_diff_range from each window (max−min of q-diff values in best window). Explorer shows QD 3s, QD 5s, and QD 7s columns. |
| Risk | Clinical risk level | From worst score across all 4 test types: Critical <4, High 4–6, Moderate 6–8, Low ≥8 |
| Stability % | How still overall | % of all data samples where q-diff < 0.005 threshold. Uses the entire test, not just a window. |
| Max Duration | Longest stable stretch | Longest continuous run of samples below threshold (in seconds). |
Why Score and Stability Can Differ
Score and stability measure different things:
- Score = best window's q-diff range (peak-to-valley), mapped through a curve. It asks: "In your best stretch, how much did you move?"
- Stability % = fraction of all samples below threshold. It asks: "Across the whole test, how often were you still?"
A patient can be stable 95% of the time (high stability) but have one brief spike in their best window (lower score). Or they can have a very calm 7s window (high score) but be shaky for the rest of the test (low stability).
Note: The base score uses min() of 3s and 5s window scores. The 7s window is used separately for the bonus cap (see below).
Test Types
lbeo | Left Balance Eyes Open |
rbeo | Right Balance Eyes Open |
lbec | Left Balance Eyes Closed |
rbec | Right Balance Eyes Closed |
Balance/Difference
Absolute difference between average left scores and average right scores. Highlights asymmetry between sides.
Color: <1 green, 1–3 yellow, >3 red
Duration Penalty
Short tests are penalized:
- Only 3s window exists (no 5s) → subtract 3 points
7-Second Bonus
Maximum score is capped at 7 unless the test has 7-second q-diff data. If 7s data exists, the cap is raised based on the q-diff range:
| 7s Q-Diff Range | Max Score |
|---|---|
| ≤ 0.0015 | 10 |
| 0.0015 – 0.002 | 9 |
| 0.002 – 0.003 | 8 |
| > 0.003 or no 7s data | 7 |
Fatigue Patterns
| fatigues | Good short-term (≥7) but drops >3 by 7s |
| consistent | Good short-term (≥7) and stays within 3 |
| unstable | Poor short-term (<7) with small drop |
| declining | Poor short-term (<7) and drops >2 |
Kinometric uses practice-level PHI isolation. Each practice (clinic/organization) is a separate data boundary with its own patients, test results, and questionnaire data.
Data Model
| Table | Purpose |
|---|---|
practices | Practice/clinic records. Each can have its own athenaOne API credentials. |
user_practices | Many-to-many: users belong to 1+ practices with a role (admin, clinician, readonly). |
patients.practice_id | Every patient belongs to exactly one practice. |
test_results.practice_id | Every test result scoped to one practice. |
questions.practice_id | Every questionnaire scoped to one practice. |
Roles
| admin | Full access: manage users, providers, patients, view all data within practice |
| clinician | Standard access: manage patients, run tests, view results |
| readonly | View-only: can see patients and results but cannot modify |
| superadmin | Cross-practice access (is_admin=true). Bypasses all filters. |
| super tester | Rapid-fire testing: auto-bypasses duplicate test check, batch test storage (is_super_tester=true) |
Patient Types
| Athena Patient | Linked to athenaOne EMR via athena_patient_id. PDF upload to EMR available. |
| Non-Athena Patient | Standalone in Kinometric. Same test/score/PDF workflow. No EMR upload. Used for test/demo or practices without EMR. |
How Isolation Works
- Every API request resolves an active practice: explicit
active_practice_idparam → session → user's default → first membership addPracticeFilter()appendsAND practice_id = :idto all PHI queries- New patients, tests, and questions are stamped with the active
practice_id - 31 PHP endpoints enforce practice scoping via
practice_filter.php - Superadmins bypass all filters for administrative oversight
| ID | First Name | Last Name | DOB | Patient ID | Sex |
|---|
Loading rankings...
| Name ▲ | DOB ▲ | Last Test ▲ | Best ▲ | Worst ▲ | Bal/Diff ▲ | Max Dur ▲ | Q-Diff ▲ | Risk ▲ | AI |
|---|
Loading data...
| Name ▲ | DOB ▲ | Last Test ▲ | Best ▲ | Worst ▲ | Bal/Diff ▲ | Max Dur ▲ | QD 3s ▲ | QD 5s ▲ | QD 7s ▲ | Stability ▲ | Risk ▲ | AI |
|---|
This tool lets you experiment with how balance scores are calculated without affecting production data. Adjust parameters, re-analyze all ~800 CSV files, and see how score distributions change.
The scoring curve maps q-diff range (sensor movement variability) to a raw score (0-10). Lower q-diff = more stable = higher score.
- Drag points on the chart to adjust the curve visually
- Edit exact values in the knot table below the chart
- Add/remove points to change curve complexity
- Between points, scores are linearly interpolated
- Values outside the curve range are clamped to the nearest endpoint
Production uses 6 knot points. Fewer points = smoother curve, more points = finer control.
After the curve produces a raw score, the rescale function maps it to the final 0-10 range. This controls score distribution shape.
- Linear (default) — even spread between low and high bounds
- Power — power >1 compresses high scores, <1 compresses low scores
- Sigmoid — S-curve that clusters scores near the midpoint
- Exponential — emphasizes differences at the high end
- None — use raw score directly (no rescaling)
Low/High Bounds define the raw score range that maps to 0-10. Scores outside bounds are clamped.
- Start Row — skip initial sensor samples (warmup period). Default 200 (~2 seconds at 100Hz)
- Stable Threshold — q-diff below this is considered perfectly stable. Lower = stricter
- Outlier Percentile — use this percentile of q-diff to ignore spikes. 98 = ignore top 2%
- Aggregation — how to combine multiple time windows into one score: Min (worst window, strictest), Max (best window, most lenient), Mean, or Median
- Target Windows — time windows in seconds to analyze. Each window is scored independently, then aggregated
Production defaults: start=200, threshold=0.02, percentile=98, aggregation=min, windows=3,5,7
- Save/Load presets to keep parameter configurations you want to compare
- Import/Export as JSON files to share configurations
- Run Analysis processes all ~800 cached CSV files (~40 seconds)
- Score Calculator lets you test a single q-diff value against current settings instantly
- Rebuild Cache re-extracts data from CSV files (only needed if new test files are added)
Typical workflow: load production preset, adjust one parameter, run analysis, compare distributions. Nothing writes to the database.
Scoring Curve (drag points to adjust)
| Point | Q-diff Range (X) | Raw Score (Y) | Final Score | Tests in Range | Target |
|---|
Score Calculator
Scoring Mode
Score from longest stable stretch. Map seconds to 0-10 score.
Duration Penalty
Penalty subtracted from score when test recording is too short for all analysis windows. Set to 0 to disable.
Rescale Function
Analysis Parameters
| Patient | Overall | Left Q-diff | Right Q-diff | LBEO | RBEO | LBEC | RBEC |
|---|
| File ▲ | Patient ▲ | Type ▲ | Date ▲ | Score ▼ | Risk ▲ | 3s ▲ | 5s ▲ | 7s ▲ | Worst Q-diff ▲ | Worst Bal ▲ | Stable% ▲ | Penalty ▲ |
|---|
Running analysis...
Patients in Range
0| Name | Type | Date | Score | Risk | Worst Q-diff | 3s | 5s | 7s | Stable% | Penalty |
|---|
athenaOne Hierarchy
Practice — The top-level entity (our sandbox is practice 195900). A practice is a medical business (e.g., "Kinometric Physical Therapy"). Everything lives under a practice.
Departments — Physical locations or logical divisions within a practice. Think "Main Office", "Downtown Clinic", "Satellite Office". Our sandbox has 32 departments. Each has its own address, phone, and scheduling.
Providers — Doctors, PTs, clinicians who see patients. A provider can work at multiple departments (e.g., Dr. Smith sees patients at both Main Office and Downtown). Providers have IDs and schedules tied to departments.
Patients — People receiving care. A patient belongs to the practice (not a single department), which is why a patient ID works across all departments. However, athenaOne tracks a primarydepartmentid and many API calls require a departmentid for billing/scheduling context.
Practice (195900)
├── Department 1 (Main Office)
│ ├── Provider 71 (sees patients here)
│ └── Provider 22 (sees patients here)
├── Department 21 (Satellite)
│ └── Provider 71 (also works here)
└── Patients (practice-wide, not dept-locked)
└── Patient 2201 — primary dept 1, provider 71
Kinometric Database Mapping
| athenaOne | Kinometric DB | Status |
|---|---|---|
| Practice | practices table |
Mapped — multi-practice system with per-practice Athena config, patient/test/question isolation |
| Department | departments table |
Partial — 4 departments exist (PASS-TEST, PASS-MD, PASS-FL, PASS-PA) but no link to practices table; no athena department ID mapping |
| Provider | providers table |
Partial — 9 providers linked to departments; used for patient isolation via provider_id. No athena provider ID mapping |
| Patient | patients table |
Mapped — realpatientid stores athena patient ID; practice_id + provider_id for isolation |
| Location | locations table |
Internal — 5 physical locations under departments; no athena equivalent |
Gaps
- No department ↔ practice link:
departmentshas nopractice_idFK. In athenaOne, departments are per-practice. - No athena ID on providers/departments: We can't match our Dr. Rao to athena provider 71, or our PASS-MD to athena department 1.
- Provider belongs to one department: Our
providers.department_idis a single FK. In athenaOne, providers work across multiple departments. - Patient → provider is optional: Only 4 of 389 patients have a
provider_id. The practice_id system handles isolation instead.
Not loaded
| ID | Name | DOB | Sex | Status |
|---|
No log loaded yet.
| Name | DOB | Real ID |
|---|
| ID | Note | Date | Status | |
|---|---|---|---|---|
| Verify a patient to see documents | ||||
| ID | Name | Address | Phone | State |
|---|---|---|---|---|
| Loading... | ||||
| ID | Username | Display Name | Admin | Practices | Actions | |
|---|---|---|---|---|---|---|
| Loading... | ||||||
| ID | First Name | Last Name | DOB | Patient ID | Sex | Actions |
|---|---|---|---|---|---|---|
| Loading... | ||||||
Security & HIPAA Compliance
Server-side security controls protecting credentials, config files, and infrastructure.
Loading audit...
Authentication mechanisms and access control for API and web interfaces.
athenaOne integration security — OAuth, data flow, input validation, and access controls.
HIPAA Security Rule compliance checklist with specific CFR references. Last audited: February 2026.
| Requirement | CFR | Implementation | Status | Evidence |
|---|---|---|---|---|
| Risk Analysis | §308(a)(1)(ii)(A) | Annual risk assessment covering all PHI, threats, and safeguards | Done | |
| Risk Management | §308(a)(1)(ii)(B) | Controls implemented per risk assessment findings; gap remediation tracked | Done | |
| Sanction Policy | §308(a)(1)(ii)(C) | Confidentiality agreement includes consequences for violation (termination, penalties) | Done | |
| Information System Activity Review | §308(a)(1)(ii)(D) | HIPAA audit log reviewed; automated security audit scripts run monthly | Done | |
| Security Officer | §308(a)(2) | Formal designation pending — development team manages security | Pending | |
| Workforce Security | §308(a)(3) | Multi-practice isolation via practice_filter.php. Roles: admin, clinician, readonly per practice. Superadmin bypasses for oversight. 31 endpoints enforced. | Done | |
| Access Management | §308(a)(4) | 3 active users, unique accounts, no shared credentials, admin-managed | Done | |
| Security Awareness Training | §308(a)(5) | Staff confidentiality agreement signed before access; formal program pending | Partial | |
| Security Incident Procedures | §308(a)(6) | Breach response plan with 5-step procedure, 5 scenarios, notification timelines | Done | |
| Contingency Plan | §308(a)(7) | Automated nightly encrypted backups to off-site server; restore tested | Done | |
| Evaluation | §308(a)(8) | Annual risk assessment; automated security audits; 225 automated API tests + 75 Python unit tests | Done | |
| Business Associate Agreements | §308(b) | Linode BAA: in progress. Anthropic, Microsoft: pending. | In Progress |
| Requirement | CFR | Implementation | Status | Evidence |
|---|---|---|---|---|
| Facility Access Controls | §310(a)(1) | Hosted in Linode/Akamai data center (SOC 2 certified, physical access controls) | Done | |
| Workstation Use | §310(b) | SSH key authentication only; no shared accounts; UFW firewall | Done | |
| Workstation Security | §310(c) | Server: SSH/HTTP/HTTPS only (UFW). No physical access except via Linode. | Done | |
| Device & Media Controls | §310(d) | No PHI cached on mobile devices (in-memory only); CSV files server-side; patient delete cascades to files | Done |
| Requirement | CFR | Implementation | Status | Evidence |
|---|---|---|---|---|
| Unique User Identification | §312(a)(2)(i) | Each user has unique username + user_id; no shared accounts | Done | |
| Emergency Access | §312(a)(2)(ii) | Superadmin account + direct database access available | Done | |
| Automatic Logoff | §312(a)(2)(iii) | 15-minute idle timeout: PHP server-side + JS client-side | Done | |
| Encryption at Rest | §312(a)(2)(iv) | Backups: AES-256 GPG. Emailed PDFs: AES-256. Server disk: Linode encryption pending. | Partial | |
| Audit Controls | §312(b) | HIPAA audit log (JSON, who/what/when/IP); auth logs; error logs; auto-pruned | Done | |
| Integrity Controls | §312(c)(1) | Parameterized SQL, input validation, base64 validation, path traversal prevention | Done | |
| Authentication | §312(d) | bcrypt password hashing; 64-char random session tokens; per-request verification | Done | |
| Transmission Security | §312(e)(1) | TLS 1.2/1.3 on all connections; HTTPS enforced; OAuth2 for athenaOne | Done |
| Requirement | CFR | Implementation | Status | Evidence |
|---|---|---|---|---|
| Risk Assessment Document | §308(a)(1) | PHI inventory, 14 threats rated, safeguard checklist, gap analysis | Done | |
| Breach Response Plan | §308(a)(6) | 5-step procedure, 5 scenarios, notification timelines, documentation requirements | Done | |
| Staff Confidentiality Agreement | §308(a)(3) | PHI handling, device security, reporting obligations, consequences; signed before access | Done | |
| Password Policy | §312(d) | 8+ chars, uppercase + lowercase + number, cannot match username; enforced on all entry points | Done | |
| Backup & Recovery | §308(a)(7) | Nightly: pg_dump + CSV + configs + code → GPG AES-256 → rsync to off-site server. 30-day retention. Restore tested. | Done | |
| Data Disposal | §310(d)(2) | Patient delete cascades to test_results, questions (FK), and CSV files on disk | Done | |
| Email PHI Protection | §312(e)(1) | No patient names in email subject or filename; PDF encrypted with AES-256 password | Done | |
| API Key Management | §312(a)(1) | Keys in /etc/ with 640 permissions; excluded from git; rotated Feb 2026 | Done |
| Item | Description | Status | Target |
|---|---|---|---|
| BAA — Linode/Akamai | BAA requested, business info submitted. Awaiting agreement from Linode. | In Progress | Q1 2026 |
| BAA — Anthropic | Required for AI analysis feature (sends scores + questionnaire, no names) | Pending | Q1 2026 |
| BAA — Microsoft | Required for Graph API email (sends encrypted PDF reports) | Pending | Q1 2026 |
| Server Disk Encryption | Enable Linode local disk encryption (AES-256). Requires instance migration. | Pending | Q1 2026 |
| 2FA for Admin Accounts | Infrastructure exists (is_2fa_on column); not yet enabled for active users | Pending | Q2 2026 |
| Security Officer Designation | Formal written designation of HIPAA Security Officer | Pending | Q1 2026 |
| Formal Training Program | Security awareness training beyond confidentiality agreement | Pending | Q2 2026 |
| Run tmp_secure.sh | Server hardening script (8 sections): requires sudo bash tmp_secure.sh | Pending | Q1 2026 |
| # | Document | Description | Date | Path |
|---|---|---|---|---|
| HIPAA Policy Documents | ||||
| 1 | Risk Assessment | PHI inventory, 14 threats analyzed, safeguard checklist, gap analysis with remediation targets | Feb 2026 | |
| 2 | Breach Response Plan | 5-step incident response (Contain→Investigate→Assess→Notify→Remediate), 5 scenarios, HHS notification timelines | Feb 2026 | |
| 3 | Staff Confidentiality Agreement | Workforce agreement: PHI rules, device security, reporting obligations, consequences. Sign before access. | Feb 2026 | |
| athenaOne Integration | ||||
| 4 | API Technical Specification | Full athenahealth submission document: security questions, 5 use cases, workflow, API summary, compliance | Feb 2026 | |
| 5 | Validation Plan | 5-phase go-live plan: sandbox testing (11 cases), tech spec submission, production credentials, validation, go-live | Feb 2026 | |
| 6 | Workflow Graphic Prompt | Mermaid diagram + ChatGPT prompt for generating polished architecture diagram for tech spec | Feb 2026 | |
| 7 | App Upload Button Spec | Implementation spec for Flutter Athena upload: endpoint, request/response, guard rails, error handling | Feb 2026 | |
| 8 | App Upload Field Mapping | Field-by-field mapping: FFAppState → JSON request body, pattern to follow (same as Email PDF) | Feb 2026 | |
| Infrastructure | ||||
| 9 | Backup Scripts | 3 scripts: nightly encrypted backup (DB+CSV+configs+code), setup wizard, restore tool. AES-256 GPG → off-site. | Feb 2026 | backup/*.sh |
| 10 | Password Policy | Shared PHP validation: 8+ chars, upper+lower+number, no username match. Enforced on all 3 entry points. | Feb 2026 | password_policy.php |
| 11 | Session Timeout | 15-min idle timeout (PHP server-side + JS client-side). Shared include for 12 legacy pages + SPA. | Feb 2026 | session_timeout.php |
| 12 | Patient Data Cleanup | Cascade delete: FK on questions, CSV file deletion on patient remove. All 3 delete handlers updated. | Feb 2026 | patient_cleanup.php |
| 13 | Server Hardening Script | 8-section hardening: tmp permissions, log rotation, file permissions, firewall verification. Requires sudo. | Feb 2026 | tmp_secure.sh |
| Multi-Practice System | ||||
| 14 | Practice Filter Module | Core multi-practice PHI isolation: getUserPractices, getActivePracticeId, addPracticeFilter, canAccessPatient, canAccessTest, isSuperAdmin. 31 endpoints enforced. | Feb 2026 | practice_filter.php |
| 15 | Migration Script | Creates practices + user_practices tables, adds practice_id to patients/test_results/questions, migrates all data, enforces NOT NULL. | Feb 2026 | |
| 16 | athenaOne Tech Spec (Updated) | Updated with multi-practice data model, per-practice Athena credentials, non-Athena patient support. | Feb 2026 | |
/var/www/kinometric/docs/.
Automated tests: 225/225 API + 75/75 Python passing. Multi-practice isolation: 31 endpoints enforced. Last audit: February 19, 2026.
Document
Android/iOS app security — HIPAA-compliant data handling, authentication, and device protection.
Encryption in Transit
| Protocol | Details | Status |
|---|---|---|
| TLS Version | TLS 1.2 and TLS 1.3 supported | Active |
| Cipher Suites | AES-256-GCM, ChaCha20-Poly1305 | Active |
| Key Exchange | ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) | Active |
| Certificate | 2048-bit RSA with SHA-256 signature | Active |
Encryption at Rest (Device)
| Storage Type | Encryption Method | Status |
|---|---|---|
| Login Credentials | AES-256 via iOS Keychain / Android EncryptedSharedPreferences | Active |
| Session Tokens | Hardware-backed secure storage (Secure Enclave / Keystore) | Active |
| Test Data Files | Device-level encryption (FileVault / Android FBE) | Active |
| Cached Data | Encrypted application sandbox | Active |
Data Minimization
| Data Type | What We Collect | What We DON'T Collect |
|---|---|---|
| Patient Identity | Internal ID number only | Full SSN, insurance numbers |
| Test Results | Balance measurements, timestamps | GPS location, device identifiers |
| File Names | Anonymized ID {id}-{type}-{d}-{m}-{y}.csv | Patient name, DOB in filename |
| Error Logs | Technical errors only | Patient data, test results |
Password Authentication
| Feature | Implementation | Status |
|---|---|---|
| Transmission | Passwords sent over TLS, never in plain text | Active |
| Server Storage | bcrypt hashed with unique salt per user | Active |
| Password Policy | Minimum 8 characters, requires uppercase + lowercase + number, cannot match username | Active |
| Session Tokens | 64-char hex key regenerated on each login, invalidates previous | Active |
| Practice Isolation | practice_filter.php multi-practice PHI isolation (31 endpoints). Roles: admin, clinician, readonly per practice. | Active |
Biometric Authentication
| Platform | Technology | Security Level | Status |
|---|---|---|---|
| iOS | Touch ID / Face ID | Hardware-secured, Secure Enclave | Planned |
| Android | Fingerprint / Face Unlock | TEE (Trusted Execution Environment) | Planned |
Session Security
| Feature | Setting | Purpose | Status |
|---|---|---|---|
| Inactivity Timeout | 15 minutes | Locks session after no user activity | Planned |
| Activity Detection | Touch, scroll, navigation | Resets timeout on any interaction | Planned |
| Session Lock | Requires re-authentication | Biometric or password to resume | Planned |
| Token Expiration | Server-enforced | New key on each login invalidates previous | Active |
Role-Based Access (Multi-Practice)
| Role | Scope | Capabilities |
|---|---|---|
| readonly | Single practice | View patients and results within practice (no modifications) |
| clinician | Single practice | Manage patients, run tests, view results within practice |
| admin | Practice management | User management, audit logs, all patients in practice |
| superadmin | Cross-practice | All patients across all practices. Security dashboard, infrastructure. |
Tamper Protection
| Check | What It Detects | Action Taken | Status |
|---|---|---|---|
| Debug Mode Detection | App running in development mode | Warning logged, restricted in production | Planned |
| Jailbreak/Root Detection | Compromised device OS | User warned, may restrict PHI access | Planned |
| App Signature Verification | Modified/repackaged APK | Blocks execution if signature invalid | Planned |
| Debugger Detection | Attached debugging tools | Prevents runtime inspection | Planned |
| No Hardcoded Credentials | Secrets in source code | Dev backdoor removed, REST API replaces SFTP | Active |
Code Protection
| Technique | Tool | Purpose | Status |
|---|---|---|---|
| Code Shrinking | R8/ProGuard | Removes unused code, reduces attack surface | Planned |
| Obfuscation | R8/ProGuard | Renames classes/methods to meaningless names | Planned |
| Dart Obfuscation | Flutter --obfuscate | Obfuscates Dart/Flutter code | Planned |
| Debug Symbol Removal | --split-debug-info | Separates debug symbols from release | Planned |
OWASP Mobile Top 10 Coverage
| Risk | Mitigation |
|---|---|
| M1: Improper Platform Usage | Proper use of iOS Keychain, Android Keystore |
| M2: Insecure Data Storage | Encrypted storage, no sensitive data in logs |
| M3: Insecure Communication | TLS 1.2+, certificate validation |
| M4: Insecure Authentication | Biometrics, session timeout, strong passwords |
| M5: Insufficient Cryptography | AES-256, industry-standard algorithms |
| M6: Insecure Authorization | Server-side access control, role-based access |
| M7: Client Code Quality | Code review, static analysis, testing |
| M8: Code Tampering | Integrity checks, obfuscation, signature verification |
| M9: Reverse Engineering | Obfuscation, no hardcoded secrets |
| M10: Extraneous Functionality | No debug endpoints in production |
Anonymization
| Data Element | Privacy Approach |
|---|---|
| File Names | Internal ID instead of patient name (e.g., 437-lb-eo-16-2-2026.csv) |
| Internal IDs | System-generated numbers, not SSN or MRN |
| Test Results | Associated with internal ID only, no PII in data files |
| Error Logs | Scrubbed of all patient identifiers before collection |
| Crash Reports | Technical data only, no PHI included |
Data Retention
| Data Type | Retention Period | Deletion Method |
|---|---|---|
| Test Results | Per practice policy (typically 7 years) | Secure overwrite |
| Audit Logs | 6 years minimum (HIPAA requirement) | Archived, then destroyed |
| Session Data | Until logout or timeout | Memory cleared |
| Local Test Files | Deleted after successful upload | Secure file deletion |
Third-Party Data Sharing
| Vendor | Data Shared | BAA Required |
|---|---|---|
| Anthropic (AI Analysis) | Scores + questionnaire only (no names) | Yes |
| athenaOne (EHR) | PDF reports via authenticated API | Yes |
| Microsoft Graph (Email) | PDF reports via email | Yes |
| Hosting Provider | Server infrastructure | Yes |
Mobile Application Security Features
| Feature | iOS | Android |
|---|---|---|
| Biometric Auth | Touch ID / Face ID via LocalAuthentication | BiometricPrompt API |
| Secure Storage | Keychain Services (kSecAttrAccessibleWhenUnlocked) | EncryptedSharedPreferences (AES-256-GCM) |
| Session Timeout | 15-min NSTimer with activity tracking | 15-min Handler with touch event monitoring |
| Code Obfuscation | Dart obfuscation (--obfuscate) | ProGuard/R8 + Dart obfuscation |
| Certificate Validation | NSURLSession server trust evaluation | OkHttp with certificate transparency |
| Integrity Check | Jailbreak detection (Cydia, sandbox escape) | Root detection (su, Magisk), signature verification |
| Network Security | App Transport Security (ATS) enforced | Network Security Config (cleartext blocked) |
| Data at Rest | FileProtection Complete Until First Auth | File-Based Encryption (FBE) |
Cryptographic Standards
| Purpose | Algorithm | Key Size | Standard |
|---|---|---|---|
| Data Encryption | AES-GCM | 256-bit | NIST SP 800-38D |
| Password Hashing | bcrypt | Cost factor 12 | OWASP recommendation |
| TLS | TLS 1.2/1.3 | ECDHE-256 | RFC 8446 |
| Random Generation | SecureRandom | N/A | Platform CSPRNG |
Compliance Standards
| Standard | Coverage | Notes |
|---|---|---|
| HIPAA Security Rule | Full | 45 CFR Part 164, all safeguards |
| HIPAA Privacy Rule | Full | 45 CFR Part 160 and 164 |
| HITECH Act | Full | Breach notification, penalties |
| NIST CSF | Aligned | Identify, Protect, Detect, Respond, Recover |
| OWASP MASVS | Level 2 | Mobile Application Security Verification |
| OWASP ASVS | Level 2 | Application Security Verification (API) |
Overall Security Status
| Security Feature | Technology | Compliance | Status |
|---|---|---|---|
| Encryption in transit | TLS 1.2/1.3 (HTTPS) | 164.312(e)(1) | Active |
| Encryption at rest (device) | Keystore / Keychain | 164.312(a)(2)(iv) | Active |
| Encryption at rest (server) | Disk encryption (LUKS) | 164.312(a)(2)(iv) | Not Yet |
| Authentication | bcrypt + 64-char tokens | 164.312(d) | Active |
| Access control | practice_filter.php (15 endpoints) | 164.312(a)(1) | Active |
| Audit logging | JSON Lines (who/what/when/IP) | 164.312(b) | Active |
| Secure upload | REST API (back_upload_csv.php) | 164.312(e)(1) | Active |
| Input validation | Parameterized SQL, ID checks | OWASP Top 10 | Active |
| Biometric auth | Fingerprint / Face ID | 164.312(d) | Planned |
| Session timeout | 15-min idle timeout (PHP + JS) | 164.312(a)(2)(iii) | Active |
| Tamper detection | Integrity + root/jailbreak | 164.312(c)(1) | Planned |
| Code obfuscation | R8 + Flutter --obfuscate | Best Practice | Planned |
| Firewall | ufw (22/80/443 only) | 164.312(e)(1) | Ready |
| DB localhost binding | PostgreSQL localhost only | 164.312(e)(1) | Ready |
Last updated: February 2026
HIPAA-required access audit log — every patient data access is recorded.
HIPAA Incident Response Plan — 45 CFR 164.308(a)(6) & 164.408
Incident Log
No incidents reported. Use the button above to report a security incident.
Incident Response Process
HIPAA requires covered entities to identify, respond to, and mitigate security incidents. 45 CFR 164.308(a)(6)(ii)
- Identify the incident — unauthorized access, data breach, system compromise, credential leak
- Document immediately — what, when, who discovered, what systems/data affected
- Report — notify the Security Officer (Charlie Rogers) and management (Anant Johnson)
- Preserve evidence — do NOT delete logs, do NOT reboot servers. Screenshot/export the HIPAA audit log
- Check audit log — review
athena_hipaa_audit.logfor unauthorized patient access patterns
- Isolate affected systems — disable compromised user accounts, revoke encryption keys
- Rotate credentials — Athena OAuth keys, DB password, API keys, user passwords
- Block access — update firewall, change SSH keys, disable unnecessary accounts
- Preserve the HIPAA audit log — copy
test/logs/athena_hipaa_audit.logto secure backup - Check Athena — review what patient data was accessed via the audit log
- Determine scope — which patients' data was accessed? How many records?
- Run audit scripts:
php monthlyAuditScripts/security_audit.php
php monthlyAuditScripts/athena_access_audit.php - Review server logs — Apache access logs, auth logs, syslog
- Determine root cause — how did the breach occur?
- Assess if PHI was actually viewed/exfiltrated — breach vs. security incident
HIPAA Breach Notification Rule — 45 CFR 164.400-414
- Determine if breach notification is required — was unsecured PHI accessed by unauthorized person?
- Notify affected individuals within 60 days of discovery (164.404)
- Notify HHS — if <500 individuals: annual report. If 500+: within 60 days (164.408)
- Notify media — if 500+ individuals in a single state (164.406)
- Notify Athena Health — as business associate, per BAA terms
- Fix the vulnerability that caused the incident
- Run full security audit to check for related issues
- Update security controls (firewall rules, access policies)
- Re-run credential rotation check
- Implement additional monitoring if needed
- Incident report (date, description, scope)
- Investigation findings and root cause
- List of affected individuals
- Notifications sent (copies)
- Remediation actions taken
- HIPAA audit log exports for the incident period
Charlie Rogers
charlie.rogers@flightsystems.net
Anant Johnson
anant@johnsonconsultingllc.com
Jake Millhausen
jake@johnsonconsultingllc.com
Laura Cossick
lcossick@painandspinespecialists.com
HHS Breach Portal: https://ocrportal.hhs.gov/ocr/breach/wizard_breach.jsf
Security awareness training program for all workforce members handling PHI. Required by 45 CFR 164.308(a)(5).
Reference: docs/hipaa_staff_confidentiality.md —
The following training modules address HIPAA Security Rule requirements. Each module should be completed by all workforce members upon hire and annually thereafter. Completion must be documented and retained for 6 years per 45 CFR 164.530(j).
| # | Module | Topics Covered | Duration | Frequency | CFR Reference |
|---|---|---|---|---|---|
| 1 | HIPAA Fundamentals |
|
30 min | Annual | §164.530(b) |
| 2 | Password & Authentication Security |
|
20 min | Annual | §164.308(a)(5)(ii)(D) |
| 3 | PHI Handling & Data Security |
|
20 min | Annual | §164.312(a)(1) |
| 4 | Mobile Device & App Security |
|
15 min | Annual | §164.310(d)(1) |
| 5 | Incident Reporting & Breach Response |
|
15 min | Annual | §164.308(a)(6) |
| 6 | Practice Isolation & Access Controls |
|
15 min | Annual | §164.312(a)(1) |
| Total Training Time | ~2 hours | ||||
| Phase | Target | Actions | Status |
|---|---|---|---|
| Phase 1: Foundation | Completed | Staff confidentiality agreement created and signed by all current users before access | Done |
| Phase 2: Program Design | Q2 2026 | Develop training materials for all 6 modules; create knowledge assessment questions; set up completion tracking | In Progress |
| Phase 3: Initial Rollout | Q2 2026 | All current workforce members complete training; document completion dates; address any knowledge gaps | Planned |
| Phase 4: Ongoing | Annual | Annual refresher training; update materials for new threats; train new hires within 30 days of access | Planned |
| Name | Role | Confidentiality Agreement | Training Completed | Next Due | Status |
|---|---|---|---|---|---|
| steve | Admin | Signed | — | Q2 2026 | Agreement Only |
| Dan | User | Signed | — | Q2 2026 | Agreement Only |
| efsi | Superadmin | Signed | — | Q2 2026 | Agreement Only |
Policy: New workforce members must complete all 6 modules within 30 days of being granted PHI access. Annual refresher training is due on the anniversary of initial completion. Records retained for 6 years per 45 CFR 164.530(j).
Per HIPAA, the following must be documented and retained for each training event:
- Date of training and modules completed
- Names of attendees and their roles
- Training materials used (version and content summary)
- Assessment results (if knowledge check is administered)
- Signature or electronic acknowledgment of completion
- Trainer name and qualifications
Generate a comprehensive HIPAA compliance report for auditors. Includes every safeguard requirement, implementation details, status, and evidence.
HIPAA Compliance Report
This report compiles all compliance details from the HIPAA checklist into a single downloadable document. It covers Administrative, Physical, and Technical Safeguards plus Organizational Policies — 32 line items total with specific implementation evidence for each.
- Cover Page — Title, date, prepared for/by, organization
- Executive Summary — Overall compliance posture, counts by status
- System Description — Architecture, PHI inventory, data flow
- Administrative Safeguards (45 CFR 164.308) — 12 requirements
- Physical Safeguards (45 CFR 164.310) — 4 requirements
- Technical Safeguards (45 CFR 164.312) — 8 requirements
- Organizational & Policy Requirements — 8 requirements
- Gap Analysis & Remediation Plan — Open items with target dates
- Document Inventory — All policy documents with descriptions
Scoring files...
No CSV files found for this date.
| Patient ▲ | Type ▲ | Score ▲ | Risk ▲ | Max Dur ▲ | QD 3s ▲ | QD 5s ▲ | QD 7s ▲ | Stability ▲ | Fatigue ▲ | Penalty ▲ | 7s Bonus ▲ |
|---|