hub / content /engineering /security.html
amirmh's picture
Deploy Travi Company Hub β€” rebuilt from monolithic hub.html (79 docs, lazy-loaded partials, static space)
5a79992 verified
Raw
History Blame Contribute Delete
26 kB
<article class="doc" id="doc-engineering-security" aria-hidden="true">
<div class="strip">
<span class="tag">Engineering</span>
<span class="sep">&middot;</span>
<span>Security Architecture</span>
</div>
<h1>Security Architecture</h1>
<p style="font-size:15px;color:var(--slate);margin-bottom:28px;max-width:700px;line-height:1.6;">
A technical overview of Travi's security posture β€” covering network topology, data protection, threat model, access controls, and compliance certifications. Designed to support hospital IT security reviews and investor due diligence.
</p>
<!-- ── SECURITY ARCHITECTURE SVG ─────────────────────────────────────────── -->
<div style="width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;">
<svg viewBox="0 0 960 640" xmlns="http://www.w3.org/2000/svg"
style="width:100%;min-width:640px;max-width:960px;display:block;margin:0 auto;font-family:'Inter',sans-serif;">
<defs>
<marker id="sec-arr" markerWidth="8" markerHeight="8" refX="7" refY="3.5" orient="auto">
<path d="M0,0 L0,7 L8,3.5 Z" fill="#0ea5e9"/>
</marker>
<marker id="sec-arr-red" markerWidth="8" markerHeight="8" refX="7" refY="3.5" orient="auto">
<path d="M0,0 L0,7 L8,3.5 Z" fill="#f87171"/>
</marker>
<marker id="sec-arr-green" markerWidth="8" markerHeight="8" refX="7" refY="3.5" orient="auto">
<path d="M0,0 L0,7 L8,3.5 Z" fill="#10b981"/>
</marker>
<filter id="sec-shadow">
<feDropShadow dx="0" dy="2" stdDeviation="3" flood-color="rgba(0,0,0,0.3)"/>
</filter>
<linearGradient id="sec-bg" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#0b1628"/><stop offset="100%" stop-color="#0d2340"/>
</linearGradient>
</defs>
<rect width="960" height="640" rx="16" fill="url(#sec-bg)"/>
<!-- Title -->
<text x="480" y="34" text-anchor="middle" font-size="11" font-weight="700" letter-spacing="0.14em" fill="#22d3ee">TRAVI AI AGENT Β· SECURITY</text>
<text x="480" y="56" text-anchor="middle" font-size="17" font-weight="800" fill="#f0f6ff">Network &amp; Security Architecture</text>
<!-- ── INTERNET ZONE ── -->
<rect x="20" y="76" width="130" height="200" rx="10" fill="rgba(239,68,68,0.06)" stroke="rgba(239,68,68,0.3)" stroke-width="1.5" stroke-dasharray="5,4"/>
<text x="85" y="96" text-anchor="middle" font-size="9.5" font-weight="700" letter-spacing="0.1em" fill="#f87171">INTERNET</text>
<rect x="32" y="106" width="106" height="40" rx="7" fill="rgba(15,23,42,0.8)" stroke="#334155" stroke-width="1"/>
<text x="85" y="121" text-anchor="middle" font-size="18"></text>
<text x="85" y="139" text-anchor="middle" font-size="10" fill="#94a3b8">Hospital EHR</text>
<rect x="32" y="156" width="106" height="40" rx="7" fill="rgba(15,23,42,0.8)" stroke="#334155" stroke-width="1"/>
<text x="85" y="171" text-anchor="middle" font-size="18"></text>
<text x="85" y="189" text-anchor="middle" font-size="10" fill="#94a3b8">Patient SMS</text>
<rect x="32" y="206" width="106" height="40" rx="7" fill="rgba(15,23,42,0.8)" stroke="#334155" stroke-width="1"/>
<text x="85" y="221" text-anchor="middle" font-size="18">πŸ–₯️</text>
<text x="85" y="239" text-anchor="middle" font-size="10" fill="#94a3b8">Clinician UI</text>
<!-- ── WAF + CDN ── -->
<rect x="175" y="100" width="110" height="152" rx="10" fill="rgba(239,68,68,0.08)" stroke="#ef4444" stroke-width="1.5" filter="url(#sec-shadow)"/>
<text x="230" y="120" text-anchor="middle" font-size="9.5" font-weight="700" letter-spacing="0.08em" fill="#f87171">PERIMETER</text>
<text x="230" y="148" text-anchor="middle" font-size="22">πŸ›‘οΈ</text>
<text x="230" y="168" text-anchor="middle" font-size="11" font-weight="700" fill="#f0f6ff">WAF</text>
<text x="230" y="182" text-anchor="middle" font-size="9.5" fill="#64748b">AWS Shield + CloudFront</text>
<line x1="230" y1="190" x2="230" y2="200" stroke="rgba(255,255,255,0.1)" stroke-width="1"/>
<text x="230" y="218" text-anchor="middle" font-size="18"></text>
<text x="230" y="236" text-anchor="middle" font-size="10" fill="#94a3b8">CDN / DDoS</text>
<text x="230" y="248" text-anchor="middle" font-size="9.5" fill="#64748b">TLS 1.3 enforced</text>
<!-- Arrows: Internet β†’ WAF -->
<line x1="150" y1="126" x2="170" y2="150" stroke="#ef4444" stroke-width="1.5" marker-end="url(#sec-arr-red)"/>
<line x1="150" y1="176" x2="170" y2="170" stroke="#ef4444" stroke-width="1.5" marker-end="url(#sec-arr-red)"/>
<line x1="150" y1="226" x2="170" y2="190" stroke="#ef4444" stroke-width="1.5" marker-end="url(#sec-arr-red)"/>
<!-- ── AWS VPC ── -->
<rect x="310" y="76" width="630" height="480" rx="12" fill="rgba(14,165,233,0.04)" stroke="rgba(14,165,233,0.2)" stroke-width="1.5" stroke-dasharray="6,4"/>
<text x="625" y="96" text-anchor="middle" font-size="10" font-weight="700" letter-spacing="0.1em" fill="#38bdf8">AWS VPC β€” us-east-1</text>
<!-- Public Subnet -->
<rect x="322" y="106" width="180" height="180" rx="10" fill="rgba(14,165,233,0.06)" stroke="rgba(14,165,233,0.2)" stroke-width="1" stroke-dasharray="4,3"/>
<text x="412" y="124" text-anchor="middle" font-size="9" font-weight="700" letter-spacing="0.1em" fill="rgba(56,189,248,0.7)">PUBLIC SUBNET</text>
<!-- API Gateway -->
<rect x="334" y="132" width="156" height="50" rx="8" fill="rgba(15,23,42,0.9)" stroke="#0ea5e9" stroke-width="1.5" filter="url(#sec-shadow)"/>
<text x="412" y="152" text-anchor="middle" font-size="18">πŸšͺ</text>
<text x="412" y="170" text-anchor="middle" font-size="11" font-weight="700" fill="#f0f6ff">API Gateway</text>
<text x="412" y="182" text-anchor="middle" font-size="9.5" fill="#64748b">Rate limit Β· JWT auth</text>
<!-- Load Balancer -->
<rect x="334" y="196" width="156" height="50" rx="8" fill="rgba(15,23,42,0.9)" stroke="#0ea5e9" stroke-width="1" filter="url(#sec-shadow)"/>
<text x="412" y="216" text-anchor="middle" font-size="18">βš–οΈ</text>
<text x="412" y="234" text-anchor="middle" font-size="11" font-weight="700" fill="#f0f6ff">ALB</text>
<text x="412" y="246" text-anchor="middle" font-size="9.5" fill="#64748b">Application Load Balancer</text>
<!-- Private Subnet -->
<rect x="522" y="106" width="400" height="180" rx="10" fill="rgba(16,185,129,0.04)" stroke="rgba(16,185,129,0.2)" stroke-width="1" stroke-dasharray="4,3"/>
<text x="722" y="124" text-anchor="middle" font-size="9" font-weight="700" letter-spacing="0.1em" fill="rgba(52,211,153,0.7)">PRIVATE SUBNET β€” no public IPs</text>
<!-- App Servers -->
<rect x="534" y="132" width="120" height="50" rx="8" fill="rgba(15,23,42,0.9)" stroke="#14b8a6" stroke-width="1.5" filter="url(#sec-shadow)"/>
<text x="594" y="152" text-anchor="middle" font-size="18"></text>
<text x="594" y="170" text-anchor="middle" font-size="11" font-weight="700" fill="#f0f6ff">App Servers</text>
<text x="594" y="182" text-anchor="middle" font-size="9.5" fill="#64748b">ECS Fargate</text>
<!-- AI Workers -->
<rect x="670" y="132" width="120" height="50" rx="8" fill="rgba(15,23,42,0.9)" stroke="#14b8a6" stroke-width="1.5" filter="url(#sec-shadow)"/>
<text x="730" y="152" text-anchor="middle" font-size="18">🧠</text>
<text x="730" y="170" text-anchor="middle" font-size="11" font-weight="700" fill="#f0f6ff">AI Workers</text>
<text x="730" y="182" text-anchor="middle" font-size="9.5" fill="#64748b">Lambda Β· async</text>
<!-- Audit Service -->
<rect x="806" y="132" width="106" height="50" rx="8" fill="rgba(15,23,42,0.9)" stroke="#14b8a6" stroke-width="1" filter="url(#sec-shadow)"/>
<text x="859" y="152" text-anchor="middle" font-size="18">πŸ“œ</text>
<text x="859" y="170" text-anchor="middle" font-size="11" font-weight="700" fill="#f0f6ff">Audit Svc</text>
<text x="859" y="182" text-anchor="middle" font-size="9.5" fill="#64748b">CloudTrail</text>
<!-- Data Subnet -->
<rect x="322" y="306" width="600" height="230" rx="10" fill="rgba(139,92,246,0.04)" stroke="rgba(139,92,246,0.2)" stroke-width="1" stroke-dasharray="4,3"/>
<text x="622" y="324" text-anchor="middle" font-size="9" font-weight="700" letter-spacing="0.1em" fill="rgba(167,139,250,0.7)">DATA SUBNET β€” encrypted at rest (AES-256)</text>
<!-- PHI Vault -->
<rect x="334" y="334" width="130" height="60" rx="8" fill="rgba(15,23,42,0.9)" stroke="#ef4444" stroke-width="1.5" filter="url(#sec-shadow)"/>
<text x="399" y="355" text-anchor="middle" font-size="18"></text>
<text x="399" y="374" text-anchor="middle" font-size="11" font-weight="700" fill="#f0f6ff">PHI Vault</text>
<text x="399" y="386" text-anchor="middle" font-size="9.5" fill="#64748b">RDS Β· field-level enc.</text>
<!-- Outcome DB -->
<rect x="480" y="334" width="130" height="60" rx="8" fill="rgba(15,23,42,0.9)" stroke="#a78bfa" stroke-width="1.5" filter="url(#sec-shadow)"/>
<text x="545" y="355" text-anchor="middle" font-size="18">πŸ—„οΈ</text>
<text x="545" y="374" text-anchor="middle" font-size="11" font-weight="700" fill="#f0f6ff">Outcome DB</text>
<text x="545" y="386" text-anchor="middle" font-size="9.5" fill="#64748b">PostgreSQL Β· de-id</text>
<!-- Secrets Manager -->
<rect x="626" y="334" width="130" height="60" rx="8" fill="rgba(15,23,42,0.9)" stroke="#a78bfa" stroke-width="1" filter="url(#sec-shadow)"/>
<text x="691" y="355" text-anchor="middle" font-size="18">πŸ—οΈ</text>
<text x="691" y="374" text-anchor="middle" font-size="11" font-weight="700" fill="#f0f6ff">Secrets Mgr</text>
<text x="691" y="386" text-anchor="middle" font-size="9.5" fill="#64748b">AWS KMS Β· rotation</text>
<!-- S3 Audit Logs -->
<rect x="772" y="334" width="130" height="60" rx="8" fill="rgba(15,23,42,0.9)" stroke="#a78bfa" stroke-width="1" filter="url(#sec-shadow)"/>
<text x="837" y="355" text-anchor="middle" font-size="18">πŸͺ£</text>
<text x="837" y="374" text-anchor="middle" font-size="11" font-weight="700" fill="#f0f6ff">S3 Audit Logs</text>
<text x="837" y="386" text-anchor="middle" font-size="9.5" fill="#64748b">Immutable Β· Glacier</text>
<!-- Backup -->
<rect x="334" y="410" width="568" height="50" rx="8" fill="rgba(15,23,42,0.7)" stroke="rgba(255,255,255,0.08)" stroke-width="1"/>
<text x="618" y="430" text-anchor="middle" font-size="10" fill="#64748b"> Automated daily backups Β· Cross-region replication (us-west-2) Β· RTO &lt; 4h Β· RPO &lt; 1h</text>
<text x="618" y="450" text-anchor="middle" font-size="10" fill="#64748b"> All data encrypted in transit (TLS 1.3) and at rest (AES-256) Β· KMS key rotation every 90 days</text>
<!-- Arrows inside VPC -->
<line x1="490" y1="182" x2="490" y2="196" stroke="#0ea5e9" stroke-width="1.5" marker-end="url(#sec-arr)"/>
<line x1="490" y1="246" x2="594" y2="246" stroke="#0ea5e9" stroke-width="1" stroke-dasharray="3,3"/>
<line x1="594" y1="246" x2="594" y2="132" stroke="#0ea5e9" stroke-width="1" stroke-dasharray="3,3" marker-end="url(#sec-arr)"/>
<line x1="594" y1="182" x2="670" y2="182" stroke="#14b8a6" stroke-width="1" stroke-dasharray="3,3" marker-end="url(#sec-arr)"/>
<line x1="594" y1="182" x2="594" y2="334" stroke="#a78bfa" stroke-width="1" stroke-dasharray="3,3" marker-end="url(#sec-arr)"/>
<line x1="730" y1="182" x2="730" y2="334" stroke="#a78bfa" stroke-width="1" stroke-dasharray="3,3" marker-end="url(#sec-arr)"/>
<!-- WAF β†’ API Gateway -->
<line x1="285" y1="157" x2="330" y2="157" stroke="#0ea5e9" stroke-width="2" marker-end="url(#sec-arr)"/>
<!-- Compliance badges row -->
<rect x="322" y="472" width="600" height="72" rx="10" fill="rgba(255,255,255,0.02)" stroke="rgba(255,255,255,0.06)" stroke-width="1"/>
<text x="622" y="490" text-anchor="middle" font-size="9.5" font-weight="700" letter-spacing="0.1em" fill="rgba(148,163,184,0.6)">COMPLIANCE &amp; CERTIFICATIONS</text>
<!-- Badges -->
<rect x="334" y="498" width="88" height="36" rx="6" fill="rgba(239,68,68,0.1)" stroke="#ef4444" stroke-width="0.5"/>
<text x="378" y="514" text-anchor="middle" font-size="10" font-weight="700" fill="#f87171">HIPAA</text>
<text x="378" y="528" text-anchor="middle" font-size="9" fill="#94a3b8">BAA signed</text>
<rect x="432" y="498" width="88" height="36" rx="6" fill="rgba(14,165,233,0.1)" stroke="#0ea5e9" stroke-width="0.5"/>
<text x="476" y="514" text-anchor="middle" font-size="10" font-weight="700" fill="#38bdf8">SOC 2 T2</text>
<text x="476" y="528" text-anchor="middle" font-size="9" fill="#94a3b8">In progress Q3 '26</text>
<rect x="530" y="498" width="88" height="36" rx="6" fill="rgba(16,185,129,0.1)" stroke="#10b981" stroke-width="0.5"/>
<text x="574" y="514" text-anchor="middle" font-size="10" font-weight="700" fill="#34d399">FHIR R4</text>
<text x="574" y="528" text-anchor="middle" font-size="9" fill="#94a3b8">Certified</text>
<rect x="628" y="498" width="88" height="36" rx="6" fill="rgba(139,92,246,0.1)" stroke="#a78bfa" stroke-width="0.5"/>
<text x="672" y="514" text-anchor="middle" font-size="10" font-weight="700" fill="#c4b5fd">SMART</text>
<text x="672" y="528" text-anchor="middle" font-size="9" fill="#94a3b8">on FHIR</text>
<rect x="726" y="498" width="88" height="36" rx="6" fill="rgba(245,158,11,0.1)" stroke="#f59e0b" stroke-width="0.5"/>
<text x="770" y="514" text-anchor="middle" font-size="10" font-weight="700" fill="#fbbf24">Pen Test</text>
<text x="770" y="528" text-anchor="middle" font-size="9" fill="#94a3b8">Annual Β· Q2 '26</text>
<rect x="824" y="498" width="88" height="36" rx="6" fill="rgba(255,255,255,0.04)" stroke="rgba(255,255,255,0.1)" stroke-width="0.5"/>
<text x="868" y="514" text-anchor="middle" font-size="10" font-weight="700" fill="#94a3b8">GDPR</text>
<text x="868" y="528" text-anchor="middle" font-size="9" fill="#64748b">Ready (EU expansion)</text>
<!-- Legend -->
<rect x="20" y="580" width="920" height="46" rx="8" fill="rgba(255,255,255,0.02)" stroke="rgba(255,255,255,0.05)" stroke-width="1"/>
<rect x="36" y="596" width="12" height="12" rx="2" fill="rgba(239,68,68,0.3)" stroke="#ef4444" stroke-width="0.5"/>
<text x="54" y="607" font-size="9.5" fill="#94a3b8">Untrusted / internet zone</text>
<rect x="180" y="596" width="12" height="12" rx="2" fill="rgba(14,165,233,0.2)" stroke="#0ea5e9" stroke-width="0.5"/>
<text x="198" y="607" font-size="9.5" fill="#94a3b8">Public subnet</text>
<rect x="300" y="596" width="12" height="12" rx="2" fill="rgba(16,185,129,0.2)" stroke="#10b981" stroke-width="0.5"/>
<text x="318" y="607" font-size="9.5" fill="#94a3b8">Private subnet (no public IP)</text>
<rect x="490" y="596" width="12" height="12" rx="2" fill="rgba(139,92,246,0.2)" stroke="#a78bfa" stroke-width="0.5"/>
<text x="508" y="607" font-size="9.5" fill="#94a3b8">Data subnet (encrypted at rest)</text>
<line x1="700" y1="602" x2="724" y2="602" stroke="#ef4444" stroke-width="1.5" marker-end="url(#sec-arr-red)"/>
<text x="730" y="607" font-size="9.5" fill="#94a3b8">Untrusted traffic</text>
<line x1="820" y1="602" x2="844" y2="602" stroke="#0ea5e9" stroke-width="1.5" marker-end="url(#sec-arr)"/>
<text x="850" y="607" font-size="9.5" fill="#94a3b8">Internal traffic</text>
</svg>
</div>
<!-- ── THREAT MODEL ─────────────────────────────────────────────────────────── -->
<h2 id="threat-model" style="margin-top:36px;">Threat Model &amp; Controls</h2>
<div style="overflow-x:auto;-webkit-overflow-scrolling:touch;margin:16px 0 28px;">
<table style="width:100%;border-collapse:collapse;min-width:600px;">
<thead>
<tr style="background:var(--surface);border-bottom:2px solid var(--border);">
<th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Threat</th>
<th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Likelihood</th>
<th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Control</th>
<th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Status</th>
</tr>
</thead>
<tbody>
<tr style="border-bottom:1px solid var(--border);">
<td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);">PHI data breach</td>
<td style="padding:10px 14px;"><span style="background:rgba(239,68,68,0.12);color:#f87171;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">HIGH</span></td>
<td style="padding:10px 14px;font-size:13px;color:var(--slate);">AES-256 field-level encryption, PHI vault isolation, no PHI in logs, BAA with all vendors</td>
<td style="padding:10px 14px;"><span style="background:rgba(16,185,129,0.12);color:#34d399;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">MITIGATED</span></td>
</tr>
<tr style="border-bottom:1px solid var(--border);background:rgba(255,255,255,0.015);">
<td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);">API injection / SSRF</td>
<td style="padding:10px 14px;"><span style="background:rgba(245,158,11,0.12);color:#fbbf24;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">MEDIUM</span></td>
<td style="padding:10px 14px;font-size:13px;color:var(--slate);">WAF with OWASP ruleset, input validation at API Gateway, parameterized queries, SSRF blocklist</td>
<td style="padding:10px 14px;"><span style="background:rgba(16,185,129,0.12);color:#34d399;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">MITIGATED</span></td>
</tr>
<tr style="border-bottom:1px solid var(--border);">
<td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);">LLM prompt injection</td>
<td style="padding:10px 14px;"><span style="background:rgba(245,158,11,0.12);color:#fbbf24;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">MEDIUM</span></td>
<td style="padding:10px 14px;font-size:13px;color:var(--slate);">Structured output schema enforcement, 7-gate post-processing validation, human review flag for anomalous outputs</td>
<td style="padding:10px 14px;"><span style="background:rgba(16,185,129,0.12);color:#34d399;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">MITIGATED</span></td>
</tr>
<tr style="border-bottom:1px solid var(--border);background:rgba(255,255,255,0.015);">
<td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);">Credential compromise</td>
<td style="padding:10px 14px;"><span style="background:rgba(245,158,11,0.12);color:#fbbf24;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">MEDIUM</span></td>
<td style="padding:10px 14px;font-size:13px;color:var(--slate);">AWS Secrets Manager with auto-rotation, no hardcoded secrets, MFA enforced for all admin access, least-privilege IAM</td>
<td style="padding:10px 14px;"><span style="background:rgba(16,185,129,0.12);color:#34d399;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">MITIGATED</span></td>
</tr>
<tr style="border-bottom:1px solid var(--border);">
<td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);">DDoS / availability</td>
<td style="padding:10px 14px;"><span style="background:rgba(14,165,233,0.12);color:#38bdf8;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">LOW</span></td>
<td style="padding:10px 14px;font-size:13px;color:var(--slate);">AWS Shield Standard + Advanced, CloudFront CDN, auto-scaling ECS Fargate, rate limiting at API Gateway</td>
<td style="padding:10px 14px;"><span style="background:rgba(16,185,129,0.12);color:#34d399;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">MITIGATED</span></td>
</tr>
<tr style="border-bottom:1px solid var(--border);background:rgba(255,255,255,0.015);">
<td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);">Insider threat</td>
<td style="padding:10px 14px;"><span style="background:rgba(14,165,233,0.12);color:#38bdf8;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">LOW</span></td>
<td style="padding:10px 14px;font-size:13px;color:var(--slate);">Role-based access control, immutable audit log, no single person can access PHI vault + audit logs simultaneously, background checks</td>
<td style="padding:10px 14px;"><span style="background:rgba(16,185,129,0.12);color:#34d399;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">MITIGATED</span></td>
</tr>
<tr>
<td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);">Third-party vendor breach</td>
<td style="padding:10px 14px;"><span style="background:rgba(245,158,11,0.12);color:#fbbf24;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">MEDIUM</span></td>
<td style="padding:10px 14px;font-size:13px;color:var(--slate);">BAA with all PHI-touching vendors (Twilio, OpenAI, AWS), annual vendor security review, data minimization β€” vendors receive de-identified data only</td>
<td style="padding:10px 14px;"><span style="background:rgba(245,158,11,0.12);color:#fbbf24;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">MONITORED</span></td>
</tr>
</tbody>
</table>
</div>
<!-- ── ACCESS CONTROL ──────────────────────────────────────────────────────── -->
<h2 id="access-control" style="margin-top:8px;">Access Control Model</h2>
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px;margin:16px 0 28px;">
<div style="background:var(--surface);border:1px solid var(--border);border-left:3px solid #0ea5e9;border-radius:8px;padding:12px 14px;">
<div style="font-size:10px;font-weight:700;color:#38bdf8;letter-spacing:.08em;text-transform:uppercase;margin-bottom:6px;">Patient</div>
<p style="font-size:12.5px;color:var(--slate);line-height:1.5;margin:0;">SMS only. No login, no account. Patient token is pseudonymous β€” no PII in the messaging layer. Consent captured via SMS reply.</p>
</div>
<div style="background:var(--surface);border:1px solid var(--border);border-left:3px solid #14b8a6;border-radius:8px;padding:12px 14px;">
<div style="font-size:10px;font-weight:700;color:#2dd4bf;letter-spacing:.08em;text-transform:uppercase;margin-bottom:6px;">Care Coordinator</div>
<p style="font-size:12.5px;color:var(--slate);line-height:1.5;margin:0;">SSO via hospital IdP (SAML 2.0). Read access to assigned patient cohort only. Cannot access PHI vault directly. MFA required.</p>
</div>
<div style="background:var(--surface);border:1px solid var(--border);border-left:3px solid #f59e0b;border-radius:8px;padding:12px 14px;">
<div style="font-size:10px;font-weight:700;color:#fbbf24;letter-spacing:.08em;text-transform:uppercase;margin-bottom:6px;">Physician</div>
<p style="font-size:12.5px;color:var(--slate);line-height:1.5;margin:0;">Receives alerts in EHR in-basket only. No Travi login required. All interactions logged via FHIR Communication resource write-back.</p>
</div>
<div style="background:var(--surface);border:1px solid var(--border);border-left:3px solid #a78bfa;border-radius:8px;padding:12px 14px;">
<div style="font-size:10px;font-weight:700;color:#c4b5fd;letter-spacing:.08em;text-transform:uppercase;margin-bottom:6px;">Hospital Admin</div>
<p style="font-size:12.5px;color:var(--slate);line-height:1.5;margin:0;">Read-only analytics API access. Can query aggregate outcomes and HRRP metrics. No access to individual patient records. Scoped JWT tokens.</p>
</div>
<div style="background:var(--surface);border:1px solid var(--border);border-left:3px solid #ef4444;border-radius:8px;padding:12px 14px;">
<div style="font-size:10px;font-weight:700;color:#f87171;letter-spacing:.08em;text-transform:uppercase;margin-bottom:6px;">Travi Engineering</div>
<p style="font-size:12.5px;color:var(--slate);line-height:1.5;margin:0;">Zero standing access to production PHI. Break-glass access requires dual approval + is logged immutably. Prod access reviewed quarterly.</p>
</div>
<div style="background:var(--surface);border:1px solid var(--border);border-left:3px solid #10b981;border-radius:8px;padding:12px 14px;">
<div style="font-size:10px;font-weight:700;color:#34d399;letter-spacing:.08em;text-transform:uppercase;margin-bottom:6px;">Compliance Officer</div>
<p style="font-size:12.5px;color:var(--slate);line-height:1.5;margin:0;">Read-only access to audit logs and access reports. Can trigger access reviews. Cannot modify data. Separate audit-only IAM role.</p>
</div>
</div>
<div style="background:color-mix(in srgb,#10b981 8%,var(--surface));border:1px solid color-mix(in srgb,#10b981 30%,var(--border));border-radius:10px;padding:16px 20px;">
<div style="font-size:11px;font-weight:700;color:#34d399;letter-spacing:.08em;text-transform:uppercase;margin-bottom:8px;">Penetration Testing &amp; Vulnerability Management</div>
<p style="font-size:13px;color:var(--slate);line-height:1.6;margin:0;">Annual third-party penetration test conducted by a CREST-certified firm. Most recent test: Q2 2026 β€” zero critical findings, two medium findings (both remediated within 14 days). Continuous vulnerability scanning via AWS Inspector and Snyk on all container images and dependencies. CVE patching SLA: critical within 24h, high within 7 days.</p>
</div>
<p style="margin-top:20px;font-size:13px;color:var(--slate);">
<strong>See also:</strong>
<a href="#doc-engineering-dataflow" style="color:var(--accent);text-decoration:none;" onclick="showDoc('doc-engineering-dataflow')">FHIR R4 Data Flow</a> β€” for how PHI moves through the pipeline, and
<a href="#doc-product-cycle" style="color:var(--accent);text-decoration:none;" onclick="showDoc('doc-product-cycle')">Product Cycle Diagram</a> β€” for the end-to-end episode execution flow.
</p>
</article>