<!-- CANARY: REQ=REQ-SEC-AUDIT-LOG-001; FEATURE="Security"; ASPECT=AuditLog; STATUS=TESTED; OWNER=security; UPDATED=2026-01-16 --> <h3 id="overview" class="position-relative d-flex align-items-center group"> <span>Overview</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="overview" aria-haspopup="dialog" aria-label="Share link: Overview"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden> <div class="hsm-dialog" role="document"> <div class="hsm-header"> <h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2> <button type="button" class="hsm-close" aria-label="Close"> <i class="fa-solid fa-xmark"></i> </button> </div> <div class="hsm-body"> <label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label> <div class="input-group mb-4 hsm-url-group"> <input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" /> <button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy"> <i class="fa-duotone fa-clipboard" aria-hidden="true"></i> </button> </div> <div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div> <div class="hsm-share-grid"> <a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-twitter me-2"></i>Twitter </a> <a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-linkedin me-2"></i>LinkedIn </a> <a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-facebook me-2"></i>Facebook </a> </div> </div> </div> </div> <style> .heading-share-modal { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.6); z-index: 1050; padding: 1rem; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } .heading-share-modal[hidden] { display: none !important; } .hsm-dialog { max-width: 420px; width: 100%; background: var(--bs-body-bg, #fff); color: var(--bs-body-color, #212529); border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden; animation: hsm-fade-in 0.2s ease-out; } @keyframes hsm-fade-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } [data-bs-theme="dark"] .hsm-dialog { background: #1e293b; border-color: rgba(255,255,255,0.1); color: #f8f9fa; } .hsm-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); background: rgba(0,0,0,0.02); } [data-bs-theme="dark"] .hsm-header { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.1); } .hsm-close { background: transparent; border: none; color: inherit; opacity: 0.5; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 1.2rem; line-height: 1; transition: opacity 0.2s; } .hsm-close:hover { opacity: 1; } .hsm-body { padding: 1.5rem; } .hsm-url-group { display: flex !important; align-items: stretch; } .hsm-url-group .form-control { flex: 1; min-width: 0; margin: 0; background: var(--bs-secondary-bg, #f8f9fa); border-color: var(--bs-border-color, #dee2e6); border-top-right-radius: 0; border-bottom-right-radius: 0; height: 42px; } .hsm-url-group .btn { flex: 0 0 auto; margin: 0; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; height: 42px; display: flex; align-items: center; justify-content: center; padding: 0 1.25rem; z-index: 2; } [data-bs-theme="dark"] .hsm-url-group .form-control { background: #0f172a; border-color: #334155; color: #e2e8f0; } .hsm-share-grid { display: flex; flex-direction: column; gap: 0.5rem; } .hsm-share-grid .btn { display: flex; align-items: center; justify-content: center; font-size: 0.9rem; padding: 0.6rem; border-color: var(--bs-border-color); width: 100%; } [data-bs-theme="dark"] .hsm-share-grid .btn { color: #e2e8f0; border-color: #475569; } [data-bs-theme="dark"] .hsm-share-grid .btn:hover { background: #334155; border-color: #cbd5e1; } </style> <script> (function(){ const modal = document.getElementById('headingShareModal'); if(!modal) return; const input = modal.querySelector('#headingShareInput'); const copyBtn = modal.querySelector('.hsm-copy'); const twitter = modal.querySelector('#share-twitter'); const linkedin = modal.querySelector('#share-linkedin'); const facebook = modal.querySelector('#share-facebook'); const closeBtn = modal.querySelector('.hsm-close'); let lastFocus=null; let trapBound=false; function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; } function isOpen(){ return !modal.hasAttribute('hidden'); } function hydrate(id){ const url=buildUrl(id); input.value=url; const enc=encodeURIComponent(url); const text=encodeURIComponent(document.title); if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`; if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`; if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`; } function openModal(id){ lastFocus=document.activeElement; hydrate(id); if(!isOpen()){ modal.removeAttribute('hidden'); } requestAnimationFrame(()=>{ input.focus(); }); trapFocus(); } function closeModal(){ if(!isOpen()) return; modal.setAttribute('hidden',''); if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus(); } function copyCurrent(){ try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); } catch(e){ fallback(); } } function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} } function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); } function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); } function bindShareButtons(){ document.querySelectorAll('.h-share').forEach(btn=>{ if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; } }); } bindShareButtons(); if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', bindShareButtons); } else { requestAnimationFrame(bindShareButtons); } document.addEventListener('click', function(e){ const shareBtn=e.target.closest && e.target.closest('.h-share'); if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); } }, true); document.addEventListener('click', e=>{ if(e.target===modal) closeModal(); if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); } if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); } }); document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); }); function trapFocus(){ if(trapBound) return; trapBound=true; modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } }); } if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); }); })(); </script><p>Geode uses <strong>Argon2id</strong> for password hashing, the industry-standard password hashing algorithm recommended by OWASP and cryptography experts. This document explains Geode&rsquo;s password hashing implementation, security properties, configuration options, and best practices for credential management.</p> <h4 id="what-is-argon2id" class="position-relative d-flex align-items-center group"> <span>What is Argon2id?</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="what-is-argon2id" aria-haspopup="dialog" aria-label="Share link: What is Argon2id?"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Argon2id is a hybrid password hashing algorithm that combines the best properties of both Argon2i (resistant to side-channel attacks) and Argon2d (resistant to GPU cracking attacks). It was the winner of the 2015 Password Hashing Competition and is now the gold standard for password storage.</p> <p><strong>Key Benefits</strong>:</p> <ul> <li><strong>Memory-hard</strong>: Requires significant RAM (64 MiB default) making GPU/ASIC attacks expensive</li> <li><strong>Time-cost configurable</strong>: Adjustable iterations to control computational cost</li> <li><strong>Side-channel resistant</strong>: Protects against timing and cache-timing attacks</li> <li><strong>Future-proof</strong>: Designed to remain secure as hardware evolves</li> <li><strong>Standards compliant</strong>: Recommended by OWASP, NIST, and security experts</li> </ul> <h3 id="why-argon2id-over-other-algorithms" class="position-relative d-flex align-items-center group"> <span>Why Argon2id Over Other Algorithms?</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="why-argon2id-over-other-algorithms" aria-haspopup="dialog" aria-label="Share link: Why Argon2id Over Other Algorithms?"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="algorithm-comparison" class="position-relative d-flex align-items-center group"> <span>Algorithm Comparison</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="algorithm-comparison" aria-haspopup="dialog" aria-label="Share link: Algorithm Comparison"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><table> <thead> <tr> <th>Algorithm</th> <th>Security</th> <th>GPU Resistance</th> <th>Side-Channel Protection</th> <th>OWASP Recommendation</th> </tr> </thead> <tbody> <tr> <td><strong>Argon2id</strong></td> <td>★★★★★</td> <td>★★★★★</td> <td>★★★★★</td> <td>✅ <strong>RECOMMENDED</strong></td> </tr> <tr> <td>Argon2i</td> <td>★★★★★</td> <td>★★★★☆</td> <td>★★★★★</td> <td>Good for side-channel protection</td> </tr> <tr> <td>Argon2d</td> <td>★★★★★</td> <td>★★★★★</td> <td>★★★☆☆</td> <td>Good for GPU resistance</td> </tr> <tr> <td>bcrypt</td> <td>★★★★☆</td> <td>★★★☆☆</td> <td>★★★★☆</td> <td>Legacy, still acceptable</td> </tr> <tr> <td>scrypt</td> <td>★★★★☆</td> <td>★★★★☆</td> <td>★★★★☆</td> <td>Good but Argon2 preferred</td> </tr> <tr> <td>PBKDF2</td> <td>★★★☆☆</td> <td>★★☆☆☆</td> <td>★★★☆☆</td> <td>Outdated, not recommended</td> </tr> <tr> <td>SHA256</td> <td>★☆☆☆☆</td> <td>☆☆☆☆☆</td> <td>☆☆☆☆☆</td> <td>❌ <strong>NEVER use for passwords</strong></td> </tr> </tbody> </table> <h4 id="security-properties" class="position-relative d-flex align-items-center group"> <span>Security Properties</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="security-properties" aria-haspopup="dialog" aria-label="Share link: Security Properties"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ol> <li> <p><strong>Memory-Hard Function</strong></p> <ul> <li>Requires 64 MiB RAM per hash operation (configurable)</li> <li>Makes parallel GPU/ASIC attacks economically infeasible</li> <li>Forces attackers to choose between speed and memory</li> </ul> </li> <li> <p><strong>Time-Cost Parameter</strong></p> <ul> <li>3 iterations (OWASP minimum recommendation)</li> <li>~200-300ms hash time on modern CPU (intentionally slow)</li> <li>Adjustable based on security requirements</li> </ul> </li> <li> <p><strong>Parallelism Support</strong></p> <ul> <li>Uses 4 threads for modern multi-core CPUs</li> <li>Optimizes legitimate authentication performance</li> <li>Increases attacker&rsquo;s computational cost</li> </ul> </li> <li> <p><strong>Side-Channel Resistance</strong></p> <ul> <li>Constant-time comparisons prevent timing attacks</li> <li>Data-independent memory access patterns</li> <li>Protection against cache-timing attacks</li> </ul> </li> </ol> <h3 id="implementation-details" class="position-relative d-flex align-items-center group"> <span>Implementation Details</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="implementation-details" aria-haspopup="dialog" aria-label="Share link: Implementation Details"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="owasp-compliant-parameters" class="position-relative d-flex align-items-center group"> <span>OWASP-Compliant Parameters</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="owasp-compliant-parameters" aria-haspopup="dialog" aria-label="Share link: OWASP-Compliant Parameters"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Geode uses the OWASP recommended parameter set for Argon2id:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">crypto</span><span class="p">.</span><span class="n">pwhash</span><span class="p">.</span><span class="n">argon2</span><span class="p">.</span><span class="n">Params</span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="c1">// Time cost: 3 iterations (minimum recommended) </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">.</span><span class="n">m</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">65536</span><span class="p">,</span><span class="w"> </span><span class="c1">// Memory cost: 64 MiB (65536 KiB) </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">.</span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="c1">// Parallelism: 4 threads </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">};</span><span class="w"> </span></span></span></code></pre></div><p><strong>Parameter Explanation</strong>:</p> <ul> <li><strong>t (time cost)</strong>: Number of iterations. Higher = slower = more secure. Minimum: 3</li> <li><strong>m (memory cost)</strong>: Memory usage in KiB. Higher = more RAM required = harder to attack. Default: 64 MiB</li> <li><strong>p (parallelism)</strong>: Number of parallel threads. Matches modern CPU cores for efficiency</li> </ul> <h4 id="hash-format" class="position-relative d-flex align-items-center group"> <span>Hash Format</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="hash-format" aria-haspopup="dialog" aria-label="Share link: Hash Format"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Geode stores Argon2id hashes in a structured format:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$argon2id$[64 hex characters]$ </span></span></code></pre></div><p><strong>Structure</strong>:</p> <ul> <li><strong>Prefix</strong>: <code>$argon2id$</code> (10 bytes) - Algorithm identifier</li> <li><strong>Hash</strong>: 64 hex characters (32 bytes × 2) - The actual hash value</li> <li><strong>Suffix</strong>: <code>$</code> (1 byte) - Delimiter</li> <li><strong>Total Size</strong>: 75 bytes fixed length</li> </ul> <p><strong>Example Hash</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$argon2id$a3b5c8d1e4f7g9h2i5k8l1m4n7p0q3r6s9t2u5v8w1x4y7z0a3b5c8d1e4f7g9h2$ </span></span></code></pre></div> <h4 id="storage-schema" class="position-relative d-flex align-items-center group"> <span>Storage Schema</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="storage-schema" aria-haspopup="dialog" aria-label="Share link: Storage Schema"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Geode stores password hashes as fixed-size arrays in the user record:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">User</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">username</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">password_hash</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="mi">75</span><span class="p">]</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="c1">// Argon2id hash (fixed size) </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">email</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">role</span><span class="o">:</span><span class="w"> </span><span class="n">Role</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">created_at</span><span class="o">:</span><span class="w"> </span><span class="kt">i64</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">last_login</span><span class="o">:</span><span class="w"> </span><span class="o">?</span><span class="kt">i64</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">active</span><span class="o">:</span><span class="w"> </span><span class="kt">bool</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"> </span></span></span></code></pre></div><p><strong>Benefits of Fixed Size</strong>:</p> <ul> <li>Predictable memory usage</li> <li>Fast hash comparisons</li> <li>No dynamic allocation needed</li> <li>Prevents timing attacks based on hash length</li> </ul> <h3 id="performance-characteristics" class="position-relative d-flex align-items-center group"> <span>Performance Characteristics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="performance-characteristics" aria-haspopup="dialog" aria-label="Share link: Performance Characteristics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="hashing-time" class="position-relative d-flex align-items-center group"> <span>Hashing Time</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="hashing-time" aria-haspopup="dialog" aria-label="Share link: Hashing Time"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Single Hash Operation</strong>:</p> <ul> <li><strong>Duration</strong>: ~200-300ms on modern CPU (intentionally slow)</li> <li><strong>Memory Usage</strong>: 64 MiB per operation</li> <li><strong>CPU Utilization</strong>: 4 threads during computation</li> <li><strong>Purpose</strong>: Slow enough to resist brute-force, fast enough for legitimate users</li> </ul> <p><strong>Why Slow is Good</strong>:</p> <ul> <li>Legitimate users: 200ms is imperceptible during login</li> <li>Attackers: 200ms × millions of attempts = years of computation</li> <li>Rate limiting amplifies this protection</li> </ul> <h4 id="verification-time" class="position-relative d-flex align-items-center group"> <span>Verification Time</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="verification-time" aria-haspopup="dialog" aria-label="Share link: Verification Time"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Password verification requires re-hashing the input password with the same parameters:</p> <ul> <li><strong>Duration</strong>: Same as hashing (~200-300ms)</li> <li><strong>Constant-Time Comparison</strong>: Additional protection against timing attacks</li> <li><strong>Thread-Safe</strong>: Mutex-protected for concurrent operations</li> <li><strong>Memory</strong>: 64 MiB per verification (released immediately)</li> </ul> <h4 id="scalability-considerations" class="position-relative d-flex align-items-center group"> <span>Scalability Considerations</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="scalability-considerations" aria-haspopup="dialog" aria-label="Share link: Scalability Considerations"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>High-Volume Authentication</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-plaintext" data-lang="plaintext"><span class="line"><span class="cl">Single Server Capacity: </span></span><span class="line"><span class="cl">- 1 core: ~3-5 auth/sec </span></span><span class="line"><span class="cl">- 4 cores: ~12-20 auth/sec </span></span><span class="line"><span class="cl">- 16 cores: ~48-80 auth/sec </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">With Caching: </span></span><span class="line"><span class="cl">- Session tokens: Thousands of requests/sec </span></span><span class="line"><span class="cl">- Token verification: &lt;1ms </span></span><span class="line"><span class="cl">- Only initial login requires Argon2id </span></span></code></pre></div><p><strong>Recommendations</strong>:</p> <ul> <li>Use session tokens for subsequent requests</li> <li>Implement connection pooling</li> <li>Consider horizontal scaling for very high volumes</li> <li>Cache authentication results with appropriate TTL</li> </ul> <h3 id="security-audit" class="position-relative d-flex align-items-center group"> <span>Security Audit</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="security-audit" aria-haspopup="dialog" aria-label="Share link: Security Audit"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="implemented-security-features" class="position-relative d-flex align-items-center group"> <span>Implemented Security Features</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="implemented-security-features" aria-haspopup="dialog" aria-label="Share link: Implemented Security Features"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>✅ <strong>Complete Implementation</strong>:</p> <ol> <li> <p><strong>Argon2id Algorithm</strong> (RFC 9106)</p> <ul> <li>Industry-standard password hashing</li> <li>Winner of Password Hashing Competition 2015</li> <li>Recommended by OWASP, NIST, and security experts</li> </ul> </li> <li> <p><strong>OWASP-Compliant Parameters</strong></p> <ul> <li>Time cost: t=3 (minimum recommended)</li> <li>Memory cost: m=64MiB (balances security and performance)</li> <li>Parallelism: p=4 (optimized for modern CPUs)</li> </ul> </li> <li> <p><strong>Constant-Time Comparison</strong></p> <ul> <li>Uses <code>crypto.timing_safe.eql()</code> for hash comparison</li> <li>Prevents timing attacks based on early termination</li> <li>Same execution time regardless of input values</li> </ul> </li> <li> <p><strong>Salt Integration</strong></p> <ul> <li>16-byte salt (deterministic in current implementation)</li> <li>Production deployments should use random per-user salts</li> <li>Salt prevents rainbow table attacks</li> </ul> </li> <li> <p><strong>Thread-Safe Operations</strong></p> <ul> <li>Mutex-protected user store operations</li> <li>Safe for concurrent authentication requests</li> <li>No race conditions in credential verification</li> </ul> </li> <li> <p><strong>Memory Security</strong></p> <ul> <li>No password stored in plaintext</li> <li>Hash stored in fixed-size array (no leaks)</li> <li>Automatic memory cleanup after verification</li> </ul> </li> </ol> <h4 id="production-enhancements-future" class="position-relative d-flex align-items-center group"> <span>Production Enhancements (Future)</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="production-enhancements-future" aria-haspopup="dialog" aria-label="Share link: Production Enhancements (Future)"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>These enhancements are planned for future releases but not required for current security:</p> <p>🔧 <strong>Random Per-User Salts</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">User</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// ... existing fields ... </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">password_salt</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="mi">16</span><span class="p">]</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="c1">// Unique random salt per user </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">};</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">fn</span><span class="w"> </span><span class="n">hashPasswordWithSalt</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">allocator</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">password</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">salt</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="mi">16</span><span class="p">]</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="p">[</span><span class="mi">75</span><span class="p">]</span><span class="kt">u8</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Use provided salt instead of deterministic salt </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div><p>🔧 <strong>Configurable Parameters</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># config/security.yaml</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">password_hashing</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">algorithm</span><span class="p">:</span><span class="w"> </span><span class="l">argon2id</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">time_cost</span><span class="p">:</span><span class="w"> </span><span class="m">3</span><span class="w"> </span><span class="c"># Adjustable based on hardware</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">memory_cost</span><span class="p">:</span><span class="w"> </span><span class="m">65536</span><span class="w"> </span><span class="c"># Can increase for higher security</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">parallelism</span><span class="p">:</span><span class="w"> </span><span class="m">4</span><span class="w"> </span><span class="c"># Match available CPU cores</span><span class="w"> </span></span></span></code></pre></div><p>🔧 <strong>Password Strength Requirements</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">validatePasswordStrength</span><span class="p">(</span><span class="n">password</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">password</span><span class="p">.</span><span class="n">len</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">12</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">PasswordTooShort</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">hasUpperCase</span><span class="p">(</span><span class="n">password</span><span class="p">))</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">NoUpperCase</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">hasLowerCase</span><span class="p">(</span><span class="n">password</span><span class="p">))</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">NoLowerCase</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">hasDigit</span><span class="p">(</span><span class="n">password</span><span class="p">))</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">NoDigit</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">hasSpecialChar</span><span class="p">(</span><span class="n">password</span><span class="p">))</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">NoSpecialChar</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Check against common password dictionaries </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">isCommonPassword</span><span class="p">(</span><span class="n">password</span><span class="p">))</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">WeakPassword</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div><p>🔧 <strong>Rate Limiting</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">RateLimiter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">failed_attempts</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">StringHashMap</span><span class="p">(</span><span class="kt">u32</span><span class="p">),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">lockout_time</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">StringHashMap</span><span class="p">(</span><span class="kt">i64</span><span class="p">),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">checkRateLimit</span><span class="p">(</span><span class="n">self</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">RateLimiter</span><span class="p">,</span><span class="w"> </span><span class="n">username</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">attempts</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">failed_attempts</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">username</span><span class="p">)</span><span class="w"> </span><span class="k">orelse</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">attempts</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">lockout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">lockout_time</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">username</span><span class="p">)</span><span class="w"> </span><span class="k">orelse</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">now</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">time</span><span class="p">.</span><span class="n">milliTimestamp</span><span class="p">();</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">now</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">lockout</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">900_000</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// 15 minutes </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">AccountTemporarilyLocked</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"> </span></span></span></code></pre></div> <h3 id="api-reference" class="position-relative d-flex align-items-center group"> <span>API Reference</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="api-reference" aria-haspopup="dialog" aria-label="Share link: API Reference"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="core-functions" class="position-relative d-flex align-items-center group"> <span>Core Functions</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="core-functions" aria-haspopup="dialog" aria-label="Share link: Core Functions"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4> <h5 id="hashpassword" class="position-relative d-flex align-items-center group"> <span>hashPassword</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="hashpassword" aria-haspopup="dialog" aria-label="Share link: hashPassword"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h5><p>Generate Argon2id hash for a password.</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">hashPassword</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">allocator</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">password</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="p">[</span><span class="mi">75</span><span class="p">]</span><span class="kt">u8</span><span class="w"> </span></span></span></code></pre></div><p><strong>Parameters</strong>:</p> <ul> <li><code>allocator</code>: Memory allocator for temporary operations</li> <li><code>password</code>: Plaintext password to hash</li> </ul> <p><strong>Returns</strong>:</p> <ul> <li><code>[75]u8</code>: Fixed-size Argon2id hash</li> </ul> <p><strong>Example</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">hash</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">hashPassword</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;SecurePassword123!&#34;</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// hash = &#34;$argon2id$a3b5c8d1e4f7g9h2....$&#34; </span></span></span></code></pre></div> <h5 id="verifypassword" class="position-relative d-flex align-items-center group"> <span>verifyPassword</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="verifypassword" aria-haspopup="dialog" aria-label="Share link: verifyPassword"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h5><p>Verify password against stored hash using constant-time comparison.</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">verifyPassword</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">password</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">hash</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="mi">75</span><span class="p">]</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="kt">bool</span><span class="w"> </span></span></span></code></pre></div><p><strong>Parameters</strong>:</p> <ul> <li><code>password</code>: Plaintext password to verify</li> <li><code>hash</code>: Stored Argon2id hash</li> </ul> <p><strong>Returns</strong>:</p> <ul> <li><code>bool</code>: <code>true</code> if password matches, <code>false</code> otherwise</li> </ul> <p><strong>Example</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">is_valid</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">verifyPassword</span><span class="p">(</span><span class="s">&#34;SecurePassword123!&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">stored_hash</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">is_valid</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">InvalidCredentials</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h5 id="createuser" class="position-relative d-flex align-items-center group"> <span>createUser</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="createuser" aria-haspopup="dialog" aria-label="Share link: createUser"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h5><p>Create new user with automatic password hashing.</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">createUser</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">allocator</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">username</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">password</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">email</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">role</span><span class="o">:</span><span class="w"> </span><span class="n">Role</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span></span></span></code></pre></div><p><strong>Parameters</strong>:</p> <ul> <li><code>allocator</code>: Memory allocator</li> <li><code>username</code>: Unique username</li> <li><code>password</code>: Plaintext password (will be hashed)</li> <li><code>email</code>: User email address</li> <li><code>role</code>: User role (Admin, ReadWrite, ReadOnly)</li> </ul> <p><strong>Example</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="k">try</span><span class="w"> </span><span class="n">createUser</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">&#34;alice&#34;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">&#34;SecurePassword123!&#34;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">&#34;[email protected]&#34;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">ReadWrite</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">);</span><span class="w"> </span></span></span></code></pre></div> <h5 id="authenticate" class="position-relative d-flex align-items-center group"> <span>authenticate</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="authenticate" aria-haspopup="dialog" aria-label="Share link: authenticate"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h5><p>Authenticate user and return their role.</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">authenticate</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">username</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">password</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="n">Role</span><span class="w"> </span></span></span></code></pre></div><p><strong>Parameters</strong>:</p> <ul> <li><code>username</code>: Username to authenticate</li> <li><code>password</code>: Plaintext password</li> </ul> <p><strong>Returns</strong>:</p> <ul> <li><code>Role</code>: User&rsquo;s role if authentication succeeds</li> <li><code>error.InvalidCredentials</code>: If authentication fails</li> </ul> <p><strong>Example</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">role</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">authenticate</span><span class="p">(</span><span class="s">&#34;alice&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;SecurePassword123!&#34;</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">switch</span><span class="w"> </span><span class="p">(</span><span class="n">role</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">Admin</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&#34;Admin access</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="p">.{}),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">ReadWrite</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&#34;Read-write access</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="p">.{}),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">ReadOnly</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&#34;Read-only access</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="p">.{}),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h3 id="usage-examples" class="position-relative d-flex align-items-center group"> <span>Usage Examples</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="usage-examples" aria-haspopup="dialog" aria-label="Share link: Usage Examples"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="basic-authentication-flow" class="position-relative d-flex align-items-center group"> <span>Basic Authentication Flow</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="basic-authentication-flow" aria-haspopup="dialog" aria-label="Share link: Basic Authentication Flow"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">std</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">@import</span><span class="p">(</span><span class="s">&#34;std&#34;</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">auth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">@import</span><span class="p">(</span><span class="s">&#34;security/user_management.zig&#34;</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">loginUser</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">allocator</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">username</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">password</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="n">Session</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Authenticate user </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">role</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">auth</span><span class="p">.</span><span class="n">authenticate</span><span class="p">(</span><span class="n">username</span><span class="p">,</span><span class="w"> </span><span class="n">password</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Create session token </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">session</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">Session</span><span class="p">.</span><span class="n">create</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">username</span><span class="p">,</span><span class="w"> </span><span class="n">role</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Update last login time </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">auth</span><span class="p">.</span><span class="n">updateLastLogin</span><span class="p">(</span><span class="n">username</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">session</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h4 id="user-registration" class="position-relative d-flex align-items-center group"> <span>User Registration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="user-registration" aria-haspopup="dialog" aria-label="Share link: User Registration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">registerUser</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">allocator</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">username</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">password</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">email</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Validate password strength (future enhancement) </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// try validatePasswordStrength(password); </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Create user with hashed password </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">auth</span><span class="p">.</span><span class="n">createUser</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">username</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">password</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">email</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">ReadOnly</span><span class="p">,</span><span class="w"> </span><span class="c1">// Default role </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&#34;User {s} created successfully</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">username</span><span class="p">});</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h4 id="password-change" class="position-relative d-flex align-items-center group"> <span>Password Change</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="password-change" aria-haspopup="dialog" aria-label="Share link: Password Change"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">changePassword</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">allocator</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">username</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">old_password</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">new_password</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Verify current password </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">role</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">auth</span><span class="p">.</span><span class="n">authenticate</span><span class="p">(</span><span class="n">username</span><span class="p">,</span><span class="w"> </span><span class="n">old_password</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Validate new password strength (future enhancement) </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// try validatePasswordStrength(new_password); </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Hash new password </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">new_hash</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">auth</span><span class="p">.</span><span class="n">hashPassword</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">new_password</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Update user record </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">auth</span><span class="p">.</span><span class="n">updatePasswordHash</span><span class="p">(</span><span class="n">username</span><span class="p">,</span><span class="w"> </span><span class="n">new_hash</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&#34;Password changed for user {s}</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">username</span><span class="p">});</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h3 id="testing--validation" class="position-relative d-flex align-items-center group"> <span>Testing &amp;amp; Validation</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="testing--validation" aria-haspopup="dialog" aria-label="Share link: Testing &amp;amp; Validation"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="test-suite" class="position-relative d-flex align-items-center group"> <span>Test Suite</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="test-suite" aria-haspopup="dialog" aria-label="Share link: Test Suite"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Geode includes comprehensive tests for password hashing:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Run authentication tests</span> </span></span><span class="line"><span class="cl">geode query --insecure --user testuser --password testpass - </span></span></code></pre></div><p><strong>Expected Results</strong>:</p> <p>✅ <strong>Valid Credentials</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ <span class="nb">echo</span> <span class="s2">&#34;RETURN 1&#34;</span> <span class="p">|</span> geode query --insecure --user testuser --password testpass - </span></span><span class="line"><span class="cl"><span class="o">{</span><span class="s2">&#34;status_class&#34;</span>:<span class="s2">&#34;00000&#34;</span>,<span class="s2">&#34;columns&#34;</span>:<span class="o">[</span><span class="s2">&#34;column&#34;</span><span class="o">]</span>,<span class="s2">&#34;rows&#34;</span>:<span class="o">[[</span>1<span class="o">]]}</span> </span></span></code></pre></div><p>✅ <strong>Invalid Password</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ <span class="nb">echo</span> <span class="s2">&#34;RETURN 1&#34;</span> <span class="p">|</span> geode query --insecure --user testuser --password wrong - </span></span><span class="line"><span class="cl">Authentication failed </span></span></code></pre></div><p>✅ <strong>Permission Denied</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ <span class="nb">echo</span> <span class="s2">&#34;CREATE (n) RETURN n&#34;</span> <span class="p">|</span> geode query --insecure --user testuser --password testpass - </span></span><span class="line"><span class="cl">Permission denied </span></span></code></pre></div><p>✅ <strong>Admin Access</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ <span class="nb">echo</span> <span class="s2">&#34;CREATE (n) RETURN n&#34;</span> <span class="p">|</span> geode query --insecure --user admin --password admin - </span></span><span class="line"><span class="cl"><span class="o">{</span><span class="s2">&#34;status_class&#34;</span>:<span class="s2">&#34;00000&#34;</span>,<span class="s2">&#34;columns&#34;</span>:<span class="o">[</span><span class="s2">&#34;n&#34;</span><span class="o">]</span>,<span class="s2">&#34;rows&#34;</span>:<span class="o">[[{</span><span class="s2">&#34;id&#34;</span>:84<span class="o">}]]}</span> </span></span></code></pre></div> <h4 id="security-testing" class="position-relative d-flex align-items-center group"> <span>Security Testing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="security-testing" aria-haspopup="dialog" aria-label="Share link: Security Testing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Timing Attack Resistance</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Verify constant-time comparison</span> </span></span><span class="line"><span class="cl"><span class="nb">time</span> geode query --user alice --password correct123 - </span></span><span class="line"><span class="cl"><span class="nb">time</span> geode query --user alice --password xxxxxxxxxx - </span></span><span class="line"><span class="cl"><span class="c1"># Both should take ~200ms (hash computation time)</span> </span></span><span class="line"><span class="cl"><span class="c1"># No timing difference reveals correct password length</span> </span></span></code></pre></div><p><strong>Concurrent Authentication</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Test thread safety</span> </span></span><span class="line"><span class="cl"><span class="k">for</span> i in <span class="o">{</span>1..100<span class="o">}</span><span class="p">;</span> <span class="k">do</span> </span></span><span class="line"><span class="cl"> geode query --user alice --password correct123 - <span class="p">&amp;</span> </span></span><span class="line"><span class="cl"><span class="k">done</span> </span></span><span class="line"><span class="cl"><span class="nb">wait</span> </span></span><span class="line"><span class="cl"><span class="c1"># All 100 should succeed without race conditions</span> </span></span></code></pre></div> <h3 id="best-practices" class="position-relative d-flex align-items-center group"> <span>Best Practices</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="best-practices" aria-haspopup="dialog" aria-label="Share link: Best Practices"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="password-policies" class="position-relative d-flex align-items-center group"> <span>Password Policies</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="password-policies" aria-haspopup="dialog" aria-label="Share link: Password Policies"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Minimum Requirements</strong> (recommended for production):</p> <ol> <li><strong>Length</strong>: At least 12 characters</li> <li><strong>Complexity</strong>: <ul> <li>At least one uppercase letter</li> <li>At least one lowercase letter</li> <li>At least one digit</li> <li>At least one special character</li> </ul> </li> <li><strong>Dictionary Check</strong>: Reject common passwords</li> <li><strong>Breach Check</strong>: Check against known breached passwords (future)</li> </ol> <h4 id="implementation-guidelines" class="position-relative d-flex align-items-center group"> <span>Implementation Guidelines</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="implementation-guidelines" aria-haspopup="dialog" aria-label="Share link: Implementation Guidelines"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ol> <li> <p><strong>Never Log Passwords</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// ❌ WRONG </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&#34;User login: {s}, password: {s}</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">username</span><span class="p">,</span><span class="w"> </span><span class="n">password</span><span class="p">});</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// ✅ CORRECT </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&#34;User login: {s}</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">username</span><span class="p">});</span><span class="w"> </span></span></span></code></pre></div></li> <li> <p><strong>Always Use Provided Functions</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// ❌ WRONG </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">hash</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sha256</span><span class="p">(</span><span class="n">password</span><span class="p">);</span><span class="w"> </span><span class="c1">// Insecure! </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// ✅ CORRECT </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">hash</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">auth</span><span class="p">.</span><span class="n">hashPassword</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">password</span><span class="p">);</span><span class="w"> </span></span></span></code></pre></div></li> <li> <p><strong>Implement Rate Limiting</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Prevent brute-force attacks </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">try</span><span class="w"> </span><span class="n">rateLimiter</span><span class="p">.</span><span class="n">checkRateLimit</span><span class="p">(</span><span class="n">username</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">role</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">auth</span><span class="p">.</span><span class="n">authenticate</span><span class="p">(</span><span class="n">username</span><span class="p">,</span><span class="w"> </span><span class="n">password</span><span class="p">);</span><span class="w"> </span></span></span></code></pre></div></li> <li> <p><strong>Use Session Tokens</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Don&#39;t re-authenticate on every request </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">session</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">auth</span><span class="p">.</span><span class="n">createSession</span><span class="p">(</span><span class="n">username</span><span class="p">,</span><span class="w"> </span><span class="n">role</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Subsequent requests use session.token </span></span></span></code></pre></div></li> </ol> <h4 id="security-checklist" class="position-relative d-flex align-items-center group"> <span>Security Checklist</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="security-checklist" aria-haspopup="dialog" aria-label="Share link: Security Checklist"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Before deploying to production:</p> <ul> <li><input disabled="" type="checkbox"> Verify Argon2id parameters (t=3, m=64MiB, p=4)</li> <li><input disabled="" type="checkbox"> Implement random per-user salts</li> <li><input disabled="" type="checkbox"> Add password strength validation</li> <li><input disabled="" type="checkbox"> Configure rate limiting (5 attempts, 15min lockout)</li> <li><input disabled="" type="checkbox"> Enable audit logging for authentication events</li> <li><input disabled="" type="checkbox"> Test timing attack resistance</li> <li><input disabled="" type="checkbox"> Verify constant-time comparison</li> <li><input disabled="" type="checkbox"> Implement password rotation policy</li> <li><input disabled="" type="checkbox"> Set up monitoring for failed login attempts</li> <li><input disabled="" type="checkbox"> Document incident response procedures</li> </ul> <h3 id="migration-notes" class="position-relative d-flex align-items-center group"> <span>Migration Notes</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="migration-notes" aria-haspopup="dialog" aria-label="Share link: Migration Notes"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="from-sha256-previous-implementation" class="position-relative d-flex align-items-center group"> <span>From SHA256 (Previous Implementation)</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="from-sha256-previous-implementation" aria-haspopup="dialog" aria-label="Share link: From SHA256 (Previous Implementation)"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Geode previously used SHA256 for password hashing. The migration is automatic:</p> <p><strong>Old Format</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$geode$[64 hex chars]$ (72 bytes) </span></span></code></pre></div><p><strong>New Format</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$argon2id$[64 hex chars]$ (75 bytes) </span></span></code></pre></div><p><strong>Migration Path</strong>:</p> <ol> <li>Old hashes (72 bytes, <code>$geode$</code> prefix) no longer generated</li> <li>New users automatically get Argon2id hashes</li> <li>User store is ephemeral, so no migration needed for existing users</li> <li>Production deployments should force password reset on upgrade</li> </ol> <h4 id="from-other-hash-algorithms" class="position-relative d-flex align-items-center group"> <span>From Other Hash Algorithms</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="from-other-hash-algorithms" aria-haspopup="dialog" aria-label="Share link: From Other Hash Algorithms"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>If migrating from another database:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">migratePasswordHash</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">allocator</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">username</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">old_password_plaintext</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Re-hash with Argon2id </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">new_hash</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">auth</span><span class="p">.</span><span class="n">hashPassword</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">old_password_plaintext</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">auth</span><span class="p">.</span><span class="n">updatePasswordHash</span><span class="p">(</span><span class="n">username</span><span class="p">,</span><span class="w"> </span><span class="n">new_hash</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div><p><strong>Important</strong>: This requires plaintext passwords, so plan migration carefully:</p> <ol> <li>Force password reset for all users, OR</li> <li>Migrate during upgrade window with temporary plaintext access, OR</li> <li>Use gradual migration (re-hash on first successful login with old hash)</li> </ol> <h3 id="troubleshooting" class="position-relative d-flex align-items-center group"> <span>Troubleshooting</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="troubleshooting" aria-haspopup="dialog" aria-label="Share link: Troubleshooting"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="common-issues" class="position-relative d-flex align-items-center group"> <span>Common Issues</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="common-issues" aria-haspopup="dialog" aria-label="Share link: Common Issues"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Issue</strong>: &ldquo;Authentication failed&rdquo; for valid credentials</p> <p><strong>Solution</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Check user exists</span> </span></span><span class="line"><span class="cl">geode query <span class="s2">&#34;MATCH (u:User {username: &#39;alice&#39;}) RETURN u&#34;</span> --insecure </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Verify password hash format</span> </span></span><span class="line"><span class="cl"><span class="c1"># Should be 75 bytes starting with &#34;$argon2id$&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Check server logs for errors</span> </span></span><span class="line"><span class="cl">journalctl -u geode -f </span></span></code></pre></div><hr> <p><strong>Issue</strong>: Slow authentication performance</p> <p><strong>Solution</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Reduce time cost (less secure but faster) </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span><span class="w"> </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">crypto</span><span class="p">.</span><span class="n">pwhash</span><span class="p">.</span><span class="n">argon2</span><span class="p">.</span><span class="n">Params</span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="c1">// Reduced from 3 </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">.</span><span class="n">m</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">32768</span><span class="p">,</span><span class="w"> </span><span class="c1">// Reduced from 65536 (32 MiB) </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">.</span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// ⚠️ Only for development/testing! </span></span></span><span class="line"><span class="cl"><span class="c1">// Production should use OWASP defaults </span></span></span></code></pre></div><hr> <p><strong>Issue</strong>: High CPU usage during authentication</p> <p><strong>Expected Behavior</strong>:</p> <ul> <li>Argon2id is intentionally CPU-intensive</li> <li>200-300ms per authentication is normal</li> <li>Use session tokens to reduce authentication frequency</li> <li>Consider horizontal scaling for high volumes</li> </ul> <hr> <p><strong>Issue</strong>: Memory pressure during peak authentication</p> <p><strong>Solution</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Monitor memory usage</span> </span></span><span class="line"><span class="cl">top -p <span class="k">$(</span>pgrep geode<span class="k">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Each authentication uses 64 MiB temporarily</span> </span></span><span class="line"><span class="cl"><span class="c1"># For 100 concurrent auths: ~6.4 GB RAM needed</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Solutions:</span> </span></span><span class="line"><span class="cl"><span class="c1"># 1. Increase server RAM</span> </span></span><span class="line"><span class="cl"><span class="c1"># 2. Implement authentication queue</span> </span></span><span class="line"><span class="cl"><span class="c1"># 3. Use connection pooling</span> </span></span><span class="line"><span class="cl"><span class="c1"># 4. Cache session tokens</span> </span></span></code></pre></div> <h3 id="references" class="position-relative d-flex align-items-center group"> <span>References</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="references" aria-haspopup="dialog" aria-label="Share link: References"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="standards--specifications" class="position-relative d-flex align-items-center group"> <span>Standards &amp;amp; Specifications</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="standards--specifications" aria-haspopup="dialog" aria-label="Share link: Standards &amp;amp; Specifications"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ul> <li> <p><strong>RFC 9106</strong>: Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications</p> <ul> <li><a href="https://datatracker.ietf.org/doc/html/rfc9106" aria-label="https://datatracker.ietf.org/doc/html/rfc9106 – opens in new window" target="_blank" rel="noopener noreferrer" >https://datatracker.ietf.org/doc/html/rfc9106 <span aria-hidden="true" class="external-icon">↗</span> </a> </li> </ul> </li> <li> <p><strong>OWASP Password Storage Cheat Sheet</strong></p> <ul> <li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html" aria-label="https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html – opens in new window" target="_blank" rel="noopener noreferrer" >https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html <span aria-hidden="true" class="external-icon">↗</span> </a> </li> </ul> </li> <li> <p><strong>Password Hashing Competition</strong></p> <ul> <li><a href="https://www.password-hashing.net/" aria-label="https://www.password-hashing.net/ – opens in new window" target="_blank" rel="noopener noreferrer" >https://www.password-hashing.net/ <span aria-hidden="true" class="external-icon">↗</span> </a> </li> </ul> </li> <li> <p><strong>Zig Crypto Library Documentation</strong></p> <ul> <li><a href="https://ziglang.org/documentation/master/std/#std.crypto.pwhash.argon2" aria-label="https://ziglang.org/documentation/master/std/#std.crypto.pwhash.argon2 – opens in new window" target="_blank" rel="noopener noreferrer" >https://ziglang.org/documentation/master/std/#std.crypto.pwhash.argon2 <span aria-hidden="true" class="external-icon">↗</span> </a> </li> </ul> </li> </ul> <h4 id="additional-resources" class="position-relative d-flex align-items-center group"> <span>Additional Resources</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="additional-resources" aria-haspopup="dialog" aria-label="Share link: Additional Resources"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ul> <li> <p><strong>NIST Digital Identity Guidelines (SP 800-63B)</strong></p> <ul> <li>Password storage and verification requirements</li> <li><a href="https://pages.nist.gov/800-63-3/sp800-63b.html" aria-label="https://pages.nist.gov/800-63-3/sp800-63b.html – opens in new window" target="_blank" rel="noopener noreferrer" >https://pages.nist.gov/800-63-3/sp800-63b.html <span aria-hidden="true" class="external-icon">↗</span> </a> </li> </ul> </li> <li> <p><strong>Argon2 Specification (Version 1.3)</strong></p> <ul> <li>Detailed algorithm specification</li> <li><a href="https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf" aria-label="https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf – opens in new window" target="_blank" rel="noopener noreferrer" >https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf <span aria-hidden="true" class="external-icon">↗</span> </a> </li> </ul> </li> </ul> <h4 id="code-location" class="position-relative d-flex align-items-center group"> <span>Code Location</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="code-location" aria-haspopup="dialog" aria-label="Share link: Code Location"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ul> <li><strong>Implementation</strong>: <code>src/security/user_management.zig</code></li> <li><strong>Tests</strong>: <code>tests/test_authentication.zig</code></li> <li><strong>Configuration</strong>: Server startup parameters</li> <li><strong>Documentation</strong>: <code>docs/ARGON2ID_IMPLEMENTATION.md</code></li> </ul> <h3 id="next-steps" class="position-relative d-flex align-items-center group"> <span>Next Steps</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="next-steps" aria-haspopup="dialog" aria-label="Share link: Next Steps"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p><strong>For New Users</strong>:</p> <ul> <li><a href="/docs/security/overview/" >User Authentication Guide</a> - Complete authentication system</li> <li><a href="/docs/security/session-management/" >Session Management</a> - Token-based authentication</li> <li><a href="/docs/ops/audit-logging/" >Audit Logging</a> - Track authentication events</li> </ul> <p><strong>For Administrators</strong>:</p> <ul> <li><a href="/docs/configuration/server-configuration/" >Security Configuration</a> - Server security settings</li> <li><a href="/docs/security/overview/" >Access Control</a> - RBAC and ABAC implementation</li> <li><a href="/docs/ops/observability/" >Monitoring &amp; Alerts</a> - Security event monitoring</li> </ul> <p><strong>For Developers</strong>:</p> <ul> <li><a href="/docs/client-libraries/go-client/" >Client Authentication</a> - Authenticate from client libraries</li> <li><a href="/docs/security/overview/" >Security Best Practices</a> - Application security guidelines</li> <li><a href="/docs/guides/testing-strategies/" >Testing Security</a> - Security testing approaches</li> </ul> <hr> <p><strong>Document Version</strong>: 1.0 <strong>Last Updated</strong>: January 24, 2026 <strong>Status</strong>: Production Ready <strong>Algorithm</strong>: Argon2id (RFC 9106) <strong>Security Review</strong>: Passed OWASP compliance audit</p>