<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 -->
<p>Documentation tagged with <strong>Field-Level Encryption (FLE)</strong> in the Geode graph database. FLE provides application-level encryption for specific sensitive fields, ensuring that confidential data like credit cards, SSNs, and health records remain encrypted even from database administrators.</p>
<h3 id="introduction-to-field-level-encryption" class="position-relative d-flex align-items-center group">
<span>Introduction to Field-Level Encryption</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="introduction-to-field-level-encryption"
aria-haspopup="dialog"
aria-label="Share link: Introduction to Field-Level Encryption">
<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>Field-Level Encryption (FLE) is a selective encryption technique that protects specific sensitive properties while leaving other data unencrypted for querying and indexing. Unlike Transparent Data Encryption (TDE) which encrypts all data at rest, FLE provides granular control—you choose exactly which fields to encrypt based on sensitivity and compliance requirements.</p>
<p>FLE addresses the zero-trust security model: even if an attacker gains database access (through compromised credentials, SQL injection, or insider threats), encrypted fields remain protected. Only applications with the correct encryption keys can decrypt the data.</p>
<p>Key differences from TDE:</p>
<ul>
<li><strong>TDE</strong>: Encrypts all data on disk, transparent to queries, protects against physical theft</li>
<li><strong>FLE</strong>: Encrypts specific fields, requires application awareness, protects against database compromise</li>
</ul>
<p>FLE is essential for:</p>
<ul>
<li><strong>PCI-DSS compliance</strong>: Credit card data must be encrypted</li>
<li><strong>HIPAA compliance</strong>: Protected Health Information (PHI) requires encryption</li>
<li><strong>GDPR compliance</strong>: Personal data should be encrypted when possible</li>
<li><strong>Zero-trust architecture</strong>: Minimize trust in database layer</li>
<li><strong>Multi-tenant isolation</strong>: Ensure tenants can’t access each other’s sensitive data</li>
</ul>
<p>Geode’s FLE implementation provides:</p>
<ul>
<li>Client-side encryption (data encrypted before reaching database)</li>
<li>Deterministic and randomized encryption modes</li>
<li>Queryable encryption for deterministic fields</li>
<li>Automatic key rotation</li>
<li>Integration with Key Management Systems (KMS)</li>
</ul>
<h3 id="core-fle-concepts" class="position-relative d-flex align-items-center group">
<span>Core FLE Concepts</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-fle-concepts"
aria-haspopup="dialog"
aria-label="Share link: Core FLE Concepts">
<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="encryption-modes" class="position-relative d-flex align-items-center group">
<span>Encryption Modes</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="encryption-modes"
aria-haspopup="dialog"
aria-label="Share link: Encryption Modes">
<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>FLE supports two encryption modes with different trade-offs:</p>
<p><strong>Deterministic Encryption</strong>:</p>
<ul>
<li>Same plaintext always produces same ciphertext</li>
<li>Enables equality queries (WHERE ssn = $encrypted_value)</li>
<li>Reveals when two records have the same value</li>
<li>Use for: Fields requiring exact-match queries (SSN, email, account numbers)</li>
</ul>
<p><strong>Randomized Encryption</strong>:</p>
<ul>
<li>Same plaintext produces different ciphertext each time</li>
<li>Prevents all queries on encrypted field</li>
<li>Maximum security (no pattern leakage)</li>
<li>Use for: Highly sensitive fields without query requirements (credit card CVV, passwords)</li>
</ul>
<p>Example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Plaintext SSN: "123-45-6789"
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Deterministic encryption:
</span></span><span class="line"><span class="cl">- First record: "AES256(123-45-6789, key)" → "Xy7$mP2qR..."
</span></span><span class="line"><span class="cl">- Second record: "AES256(123-45-6789, key)" → "Xy7$mP2qR..." (same ciphertext)
</span></span><span class="line"><span class="cl">- Can query: WHERE ssn = "Xy7$mP2qR..."
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Randomized encryption:
</span></span><span class="line"><span class="cl">- First record: "AES256(123-45-6789, key, random_iv)" → "Xy7$mP2qR..."
</span></span><span class="line"><span class="cl">- Second record: "AES256(123-45-6789, key, random_iv)" → "9fK#nQ8tZ..." (different!)
</span></span><span class="line"><span class="cl">- Cannot query deterministically
</span></span></code></pre></div>
<h4 id="data-encryption-keys-dek" class="position-relative d-flex align-items-center group">
<span>Data Encryption Keys (DEK)</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="data-encryption-keys-dek"
aria-haspopup="dialog"
aria-label="Share link: Data Encryption Keys (DEK)">
<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>Each encrypted field uses a Data Encryption Key (DEK):</p>
<ul>
<li><strong>Field-specific DEKs</strong>: Different key for SSN vs. credit card</li>
<li><strong>Key rotation</strong>: Periodically rotate DEKs without re-encrypting all data</li>
<li><strong>Key derivation</strong>: Derive field keys from master key</li>
</ul>
<p>Key hierarchy:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Customer Master Key (CMK) [AWS KMS]
</span></span><span class="line"><span class="cl"> |
</span></span><span class="line"><span class="cl"> +-- Application Master Key (AMK)
</span></span><span class="line"><span class="cl"> |
</span></span><span class="line"><span class="cl"> +-- Field DEK (ssn)
</span></span><span class="line"><span class="cl"> +-- Field DEK (credit_card)
</span></span><span class="line"><span class="cl"> +-- Field DEK (health_records)
</span></span></code></pre></div>
<h4 id="encrypted-property-metadata" class="position-relative d-flex align-items-center group">
<span>Encrypted Property Metadata</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="encrypted-property-metadata"
aria-haspopup="dialog"
aria-label="Share link: Encrypted Property Metadata">
<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 encrypted properties with metadata:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"ssn"</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">"value"</span><span class="p">:</span> <span class="s2">"Xy7$mP2qR..."</span><span class="p">,</span> <span class="c1">// Encrypted ciphertext
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">"algorithm"</span><span class="p">:</span> <span class="s2">"AES-256-GCM"</span><span class="p">,</span> <span class="c1">// Encryption algorithm
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">"key_id"</span><span class="p">:</span> <span class="s2">"dek-ssn-v2"</span><span class="p">,</span> <span class="c1">// Which DEK was used
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">"mode"</span><span class="p">:</span> <span class="s2">"deterministic"</span><span class="p">,</span> <span class="c1">// Encryption mode
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">"iv"</span><span class="p">:</span> <span class="s2">"base64-iv"</span><span class="p">,</span> <span class="c1">// Initialization vector (randomized mode)
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nt">"tag"</span><span class="p">:</span> <span class="s2">"base64-auth-tag"</span> <span class="c1">// Authentication tag
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This metadata enables:</p>
<ul>
<li>Key rotation (identify which key encrypted each value)</li>
<li>Algorithm agility (migrate to new algorithms)</li>
<li>Authenticated encryption (detect tampering)</li>
</ul>
<h3 id="how-fle-works-in-geode" class="position-relative d-flex align-items-center group">
<span>How FLE Works in Geode</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="how-fle-works-in-geode"
aria-haspopup="dialog"
aria-label="Share link: How FLE Works in Geode">
<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="client-side-encryption" class="position-relative d-flex align-items-center group">
<span>Client-Side Encryption</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="client-side-encryption"
aria-haspopup="dialog"
aria-label="Share link: Client-Side Encryption">
<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>FLE encryption happens in the client library before data reaches the database:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client</span> <span class="kn">import</span> <span class="n">Client</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client.encryption</span> <span class="kn">import</span> <span class="n">EncryptionConfig</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Configure encryption</span>
</span></span><span class="line"><span class="cl"><span class="n">encryption_config</span> <span class="o">=</span> <span class="n">EncryptionConfig</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">kms_provider</span><span class="o">=</span><span class="s1">'aws-kms'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">master_key_arn</span><span class="o">=</span><span class="s1">'arn:aws:kms:us-east-1:123:key/abc-123'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">field_configs</span><span class="o">=</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Person.ssn'</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'algorithm'</span><span class="p">:</span> <span class="s1">'AES-256-GCM'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'deterministic'</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Person.medical_notes'</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'algorithm'</span><span class="p">:</span> <span class="s1">'AES-256-GCM'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'randomized'</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'CreditCard.number'</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'algorithm'</span><span class="p">:</span> <span class="s1">'AES-256-GCM'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'deterministic'</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Initialize client with encryption</span>
</span></span><span class="line"><span class="cl"><span class="n">client</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="s1">'localhost:3141'</span><span class="p">,</span> <span class="n">encryption</span><span class="o">=</span><span class="n">encryption_config</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Insert with automatic encryption</span>
</span></span><span class="line"><span class="cl"><span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> INSERT (:Person {
</span></span></span><span class="line"><span class="cl"><span class="s2"> name: 'Alice',
</span></span></span><span class="line"><span class="cl"><span class="s2"> ssn: '123-45-6789', // Encrypted deterministically
</span></span></span><span class="line"><span class="cl"><span class="s2"> medical_notes: 'Patient has...' // Encrypted randomly
</span></span></span><span class="line"><span class="cl"><span class="s2"> })
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Query encrypted field (deterministic only)</span>
</span></span><span class="line"><span class="cl"><span class="n">result</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (p:Person {ssn: '123-45-6789'}) // Client encrypts parameter
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN p.name, p.ssn
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># p.ssn is automatically decrypted in result</span>
</span></span></code></pre></div><p>The database never sees plaintext sensitive data.</p>
<h4 id="queryable-encryption-deterministic" class="position-relative d-flex align-items-center group">
<span>Queryable Encryption (Deterministic)</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="queryable-encryption-deterministic"
aria-haspopup="dialog"
aria-label="Share link: Queryable Encryption (Deterministic)">
<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>Deterministic encryption enables equality queries:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Client</span><span class="w"> </span><span class="py">automatically</span><span class="w"> </span><span class="py">encrypts</span><span class="w"> </span><span class="py">the</span><span class="w"> </span><span class="py">SSN</span><span class="w"> </span><span class="py">parameter</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">ssn</span><span class="p">:</span><span class="w"> </span><span class="nv">$ssn</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">email</span><span class="err">;</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="err">--</span><span class="w"> </span><span class="py">Supported</span><span class="w"> </span><span class="py">operations</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">deterministic</span><span class="w"> </span><span class="py">fields</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">ssn</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nv">$ssn</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">Equality</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">OR</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">ssn</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="p">[</span><span class="nv">$ssn1</span><span class="p">,</span><span class="w"> </span><span class="nv">$ssn2</span><span class="p">,</span><span class="w"> </span><span class="nv">$ssn3</span><span class="p">]</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">clause</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">;</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="err">--</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">supported</span><span class="w"> </span><span class="p">(</span><span class="py">requires</span><span class="w"> </span><span class="py">plaintext</span><span class="w"> </span><span class="py">comparison</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">ssn</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="err">'</span><span class="py">000</span><span class="err">-</span><span class="py">00</span><span class="err">-</span><span class="py">0000</span><span class="err">'</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">Range</span><span class="w"> </span><span class="kd">query</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="nc">NOT</span><span class="w"> </span><span class="py">SUPPORTED</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">OR</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">ssn</span><span class="w"> </span><span class="py">STARTS</span><span class="w"> </span><span class="py">WITH</span><span class="w"> </span><span class="err">'</span><span class="py">123</span><span class="err">'</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">Pattern</span><span class="w"> </span><span class="py">matching</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">SUPPORTED</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="key-rotation" class="position-relative d-flex align-items-center group">
<span>Key Rotation</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="key-rotation"
aria-haspopup="dialog"
aria-label="Share link: Key Rotation">
<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>Rotate encryption keys without re-encrypting all data:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Rotate DEK for SSN field</span>
</span></span><span class="line"><span class="cl"><span class="n">client</span><span class="o">.</span><span class="n">rotate_field_key</span><span class="p">(</span><span class="s1">'Person.ssn'</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Old data remains encrypted with old key (metadata stores key version)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># New inserts use new key</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Background job can re-encrypt old data gradually</span>
</span></span></code></pre></div><p>Geode tracks which key version encrypted each value, enabling:</p>
<ul>
<li>Zero-downtime rotation</li>
<li>Gradual re-encryption</li>
<li>Key compromise recovery</li>
</ul>
<h4 id="schema-declaration" class="position-relative d-flex align-items-center group">
<span>Schema Declaration</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="schema-declaration"
aria-haspopup="dialog"
aria-label="Share link: Schema Declaration">
<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>Declare encrypted fields in schema:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Define</span><span class="w"> </span><span class="py">encrypted</span><span class="w"> </span><span class="py">properties</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">CONSTRAINT</span><span class="w"> </span><span class="py">person_ssn_encrypted</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">REQUIRE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">ssn</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">ENCRYPTED</span><span class="w"> </span><span class="py">DETERMINISTIC</span><span class="err">;</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="py">CREATE</span><span class="w"> </span><span class="py">CONSTRAINT</span><span class="w"> </span><span class="py">person_medical_encrypted</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">FOR</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">REQUIRE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">medical_notes</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">ENCRYPTED</span><span class="w"> </span><span class="py">RANDOMIZED</span><span class="err">;</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="err">--</span><span class="w"> </span><span class="py">Geode</span><span class="w"> </span><span class="py">enforces</span><span class="w"> </span><span class="py">encryption</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">INSERT</span><span class="w"> </span><span class="p">(:</span><span class="nc">Person</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="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">Bob</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">ssn</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">plaintext</span><span class="err">-</span><span class="py">ssn</span><span class="err">'</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">ERROR</span><span class="p">:</span><span class="w"> </span><span class="nc">ssn</span><span class="w"> </span><span class="py">must</span><span class="w"> </span><span class="py">be</span><span class="w"> </span><span class="py">encrypted</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">})</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div><p>This prevents accidental plaintext storage.</p>
<h3 id="use-cases" class="position-relative d-flex align-items-center group">
<span>Use Cases</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="use-cases"
aria-haspopup="dialog"
aria-label="Share link: Use Cases">
<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="pci-dss-compliance" class="position-relative d-flex align-items-center group">
<span>PCI-DSS Compliance</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="pci-dss-compliance"
aria-haspopup="dialog"
aria-label="Share link: PCI-DSS Compliance">
<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>Protect credit card data:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Configure FLE for payment data</span>
</span></span><span class="line"><span class="cl"><span class="n">encryption_config</span> <span class="o">=</span> <span class="n">EncryptionConfig</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">field_configs</span><span class="o">=</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Payment.card_number'</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'deterministic'</span><span class="p">,</span> <span class="c1"># Enable lookups by card number</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'algorithm'</span><span class="p">:</span> <span class="s1">'AES-256-GCM'</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Payment.cvv'</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'randomized'</span><span class="p">,</span> <span class="c1"># Maximum security for CVV</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'algorithm'</span><span class="p">:</span> <span class="s1">'AES-256-GCM'</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Payment.expiry'</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'deterministic'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'algorithm'</span><span class="p">:</span> <span class="s1">'AES-256-GCM'</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Store payment</span>
</span></span><span class="line"><span class="cl"><span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> INSERT (:Payment {
</span></span></span><span class="line"><span class="cl"><span class="s2"> card_number: '4532-1234-5678-9010', // Encrypted
</span></span></span><span class="line"><span class="cl"><span class="s2"> cvv: '123', // Encrypted
</span></span></span><span class="line"><span class="cl"><span class="s2"> expiry: '12/25', // Encrypted
</span></span></span><span class="line"><span class="cl"><span class="s2"> amount: 99.99, // Plaintext (not sensitive)
</span></span></span><span class="line"><span class="cl"><span class="s2"> merchant: 'Acme Corp' // Plaintext
</span></span></span><span class="line"><span class="cl"><span class="s2"> })
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Query by card number (deterministic encryption)</span>
</span></span><span class="line"><span class="cl"><span class="n">payments</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (p:Payment {card_number: $card_number})
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN p.amount, p.merchant, p.expiry
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">,</span> <span class="n">card_number</span><span class="o">=</span><span class="s1">'4532-1234-5678-9010'</span><span class="p">)</span>
</span></span></code></pre></div>
<h4 id="hipaa-compliance" class="position-relative d-flex align-items-center group">
<span>HIPAA Compliance</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="hipaa-compliance"
aria-haspopup="dialog"
aria-label="Share link: HIPAA Compliance">
<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>Protect Protected Health Information (PHI):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">encryption_config</span> <span class="o">=</span> <span class="n">EncryptionConfig</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">field_configs</span><span class="o">=</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Patient.ssn'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'deterministic'</span><span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Patient.medical_record_number'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'deterministic'</span><span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Patient.diagnosis'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'randomized'</span><span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Patient.treatment_notes'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'randomized'</span><span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Patient.prescription'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'randomized'</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Insert patient data</span>
</span></span><span class="line"><span class="cl"><span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> INSERT (:Patient {
</span></span></span><span class="line"><span class="cl"><span class="s2"> name: 'John Doe', // Plaintext (public identifier)
</span></span></span><span class="line"><span class="cl"><span class="s2"> ssn: '987-65-4321', // Encrypted deterministically
</span></span></span><span class="line"><span class="cl"><span class="s2"> mrn: 'MRN-123456', // Encrypted deterministically
</span></span></span><span class="line"><span class="cl"><span class="s2"> diagnosis: 'Type 2 Diabetes', // Encrypted randomly
</span></span></span><span class="line"><span class="cl"><span class="s2"> treatment_notes: '...', // Encrypted randomly
</span></span></span><span class="line"><span class="cl"><span class="s2"> age: 45 // Plaintext (not PHI in this context)
</span></span></span><span class="line"><span class="cl"><span class="s2"> })
</span></span></span><span class="line"><span class="cl"><span class="s2">"""</span><span class="p">)</span>
</span></span></code></pre></div>
<h4 id="multi-tenant-saas" class="position-relative d-flex align-items-center group">
<span>Multi-Tenant SaaS</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="multi-tenant-saas"
aria-haspopup="dialog"
aria-label="Share link: Multi-Tenant SaaS">
<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>Isolate tenant data cryptographically:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Each tenant gets unique encryption keys</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">TenantEncryptionConfig</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tenant_id</span><span class="p">,</span> <span class="n">master_key_arn</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">config</span> <span class="o">=</span> <span class="n">EncryptionConfig</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">kms_provider</span><span class="o">=</span><span class="s1">'aws-kms'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">master_key_arn</span><span class="o">=</span><span class="n">master_key_arn</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">key_namespace</span><span class="o">=</span><span class="sa">f</span><span class="s1">'tenant-</span><span class="si">{</span><span class="n">tenant_id</span><span class="si">}</span><span class="s1">'</span><span class="p">,</span> <span class="o">//</span> <span class="n">Tenant</span><span class="o">-</span><span class="n">specific</span> <span class="n">keys</span>
</span></span><span class="line"><span class="cl"> <span class="n">field_configs</span><span class="o">=</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Document.content'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'randomized'</span><span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Document.metadata'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'deterministic'</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Tenant A's client</span>
</span></span><span class="line"><span class="cl"><span class="n">tenant_a_client</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="s1">'localhost:3141'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">encryption</span><span class="o">=</span><span class="n">TenantEncryptionConfig</span><span class="p">(</span><span class="s1">'tenant-a'</span><span class="p">,</span> <span class="n">kms_key_a</span><span class="p">)</span><span class="o">.</span><span class="n">config</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Tenant B's client (different keys)</span>
</span></span><span class="line"><span class="cl"><span class="n">tenant_b_client</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="s1">'localhost:3141'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">encryption</span><span class="o">=</span><span class="n">TenantEncryptionConfig</span><span class="p">(</span><span class="s1">'tenant-b'</span><span class="p">,</span> <span class="n">kms_key_b</span><span class="p">)</span><span class="o">.</span><span class="n">config</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Even if Tenant A compromises database, can't decrypt Tenant B's data</span>
</span></span></code></pre></div>
<h4 id="personally-identifiable-information-pii" class="position-relative d-flex align-items-center group">
<span>Personally Identifiable Information (PII)</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="personally-identifiable-information-pii"
aria-haspopup="dialog"
aria-label="Share link: Personally Identifiable Information (PII)">
<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>Protect PII for GDPR compliance:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">encryption_config</span> <span class="o">=</span> <span class="n">EncryptionConfig</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">field_configs</span><span class="o">=</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'User.email'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'deterministic'</span><span class="p">},</span> <span class="c1"># Queryable for login</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'User.phone'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'deterministic'</span><span class="p">},</span> <span class="c1"># Queryable for contact</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'User.address'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'randomized'</span><span class="p">},</span> <span class="c1"># No query needed</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'User.date_of_birth'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'randomized'</span><span class="p">},</span> <span class="c1"># No query needed</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'User.ip_address'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'mode'</span><span class="p">:</span> <span class="s1">'deterministic'</span><span class="p">},</span> <span class="c1"># Queryable for audit</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">)</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="choosing-encryption-mode" class="position-relative d-flex align-items-center group">
<span>Choosing Encryption Mode</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="choosing-encryption-mode"
aria-haspopup="dialog"
aria-label="Share link: Choosing Encryption Mode">
<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>Use Deterministic Encryption When</strong>:</p>
<ul>
<li>Need to query by exact value (login, lookup)</li>
<li>Field has high cardinality (many unique values)</li>
<li>Pattern leakage is acceptable</li>
</ul>
<p><strong>Use Randomized Encryption When</strong>:</p>
<ul>
<li>Maximum security required</li>
<li>No query requirements</li>
<li>Field has low cardinality (reveals patterns)</li>
<li>Compliance demands strongest encryption</li>
</ul>
<h4 id="minimize-encrypted-fields" class="position-relative d-flex align-items-center group">
<span>Minimize Encrypted Fields</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="minimize-encrypted-fields"
aria-haspopup="dialog"
aria-label="Share link: Minimize Encrypted Fields">
<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>Only encrypt what’s truly sensitive:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Good: Selective encryption</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'name'</span><span class="p">:</span> <span class="s1">'Alice'</span><span class="p">,</span> <span class="o">//</span> <span class="n">Plaintext</span> <span class="p">(</span><span class="ow">not</span> <span class="n">sensitive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'email'</span><span class="p">:</span> <span class="s1">'...'</span><span class="p">,</span> <span class="o">//</span> <span class="n">Deterministic</span> <span class="p">(</span><span class="n">need</span> <span class="n">to</span> <span class="n">query</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'ssn'</span><span class="p">:</span> <span class="s1">'...'</span><span class="p">,</span> <span class="o">//</span> <span class="n">Deterministic</span> <span class="p">(</span><span class="n">need</span> <span class="n">to</span> <span class="n">verify</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'medical_notes'</span><span class="p">:</span> <span class="s1">'...'</span> <span class="o">//</span> <span class="n">Randomized</span> <span class="p">(</span><span class="n">very</span> <span class="n">sensitive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Bad: Over-encryption</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'name'</span><span class="p">:</span> <span class="s1">'...'</span><span class="p">,</span> <span class="o">//</span> <span class="n">Encrypted</span> <span class="p">(</span><span class="n">why</span><span class="err">?</span> <span class="n">need</span> <span class="n">to</span> <span class="n">display</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'created_at'</span><span class="p">:</span> <span class="s1">'...'</span><span class="p">,</span> <span class="o">//</span> <span class="n">Encrypted</span> <span class="p">(</span><span class="n">why</span><span class="err">?</span> <span class="n">need</span> <span class="n">to</span> <span class="n">sort</span><span class="o">/</span><span class="nb">filter</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'public_bio'</span><span class="p">:</span> <span class="s1">'...'</span> <span class="o">//</span> <span class="n">Encrypted</span> <span class="p">(</span><span class="n">why</span><span class="err">?</span> <span class="n">it</span><span class="s1">'s public!)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Over-encryption hurts performance and usability without security benefit.</p>
<h4 id="key-management" class="position-relative d-flex align-items-center group">
<span>Key Management</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="key-management"
aria-haspopup="dialog"
aria-label="Share link: Key Management">
<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>Use KMS</strong>: Never hardcode encryption keys</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Good</span>
</span></span><span class="line"><span class="cl"><span class="n">config</span> <span class="o">=</span> <span class="n">EncryptionConfig</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">kms_provider</span><span class="o">=</span><span class="s1">'aws-kms'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">master_key_arn</span><span class="o">=</span><span class="s1">'arn:aws:kms:...'</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Bad</span>
</span></span><span class="line"><span class="cl"><span class="n">config</span> <span class="o">=</span> <span class="n">EncryptionConfig</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">master_key</span><span class="o">=</span><span class="s1">'hardcoded-key-here'</span> <span class="o">//</span> <span class="n">NEVER</span> <span class="n">DO</span> <span class="n">THIS</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></div></li>
<li>
<p><strong>Rotate keys regularly</strong>: Quarterly or annually</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Schedule automated key rotation</span>
</span></span><span class="line"><span class="cl"><span class="n">client</span><span class="o">.</span><span class="n">schedule_key_rotation</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">field</span><span class="o">=</span><span class="s1">'Person.ssn'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">interval_days</span><span class="o">=</span><span class="mi">90</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></div></li>
<li>
<p><strong>Separate keys by sensitivity</strong>: SSN vs. email</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">config</span> <span class="o">=</span> <span class="n">EncryptionConfig</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">field_configs</span><span class="o">=</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Person.ssn'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'key_id'</span><span class="p">:</span> <span class="s1">'high-security-dek'</span><span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'Person.email'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'key_id'</span><span class="p">:</span> <span class="s1">'medium-security-dek'</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></div></li>
</ol>
<h4 id="application-design" class="position-relative d-flex align-items-center group">
<span>Application Design</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="application-design"
aria-haspopup="dialog"
aria-label="Share link: Application Design">
<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><strong>Encrypt at client</strong>: Never send plaintext to database</li>
<li><strong>Validate before encrypt</strong>: Reject invalid SSNs before encrypting</li>
<li><strong>Cache decrypted values</strong>: Avoid repeated decryption</li>
<li><strong>Handle encryption errors</strong>: Key unavailable, KMS timeout, etc.</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">create_user</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">ssn</span><span class="p">,</span> <span class="n">email</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Validate BEFORE encrypting</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="ow">not</span> <span class="n">is_valid_ssn</span><span class="p">(</span><span class="n">ssn</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Invalid SSN format"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> INSERT (:User {name: $name, ssn: $ssn, email: $email})
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> <span class="n">ssn</span><span class="o">=</span><span class="n">ssn</span><span class="p">,</span> <span class="n">email</span><span class="o">=</span><span class="n">email</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">EncryptionError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Encryption failed: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Handle gracefully (retry, alert, etc.)</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span>
</span></span></code></pre></div>
<h3 id="performance-considerations" class="position-relative d-flex align-items-center group">
<span>Performance 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="performance-considerations"
aria-haspopup="dialog"
aria-label="Share link: Performance 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>
</h3>
<h4 id="encryption-overhead" class="position-relative d-flex align-items-center group">
<span>Encryption Overhead</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="encryption-overhead"
aria-haspopup="dialog"
aria-label="Share link: Encryption Overhead">
<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>Typical performance impact:</p>
<ul>
<li><strong>Encryption latency</strong>: +0.5-2ms per encrypted field</li>
<li><strong>Decryption latency</strong>: +0.5-2ms per encrypted field</li>
<li><strong>Query performance</strong>: Deterministic fields support indexes, minimal impact</li>
<li><strong>Insert throughput</strong>: 10-20% reduction for heavily encrypted records</li>
</ul>
<h4 id="optimization-tips" class="position-relative d-flex align-items-center group">
<span>Optimization Tips</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="optimization-tips"
aria-haspopup="dialog"
aria-label="Share link: Optimization Tips">
<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>Batch operations</strong>: Amortize KMS overhead</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Encrypt batch before inserting</span>
</span></span><span class="line"><span class="cl"><span class="n">encrypted_users</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">encrypt_batch</span><span class="p">(</span><span class="n">users</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">query</span><span class="p">,</span> <span class="n">params</span> <span class="ow">in</span> <span class="n">insert_queries</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">rollback</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span>
</span></span></code></pre></div></li>
<li>
<p><strong>Cache DEKs</strong>: Avoid repeated KMS calls</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">config</span> <span class="o">=</span> <span class="n">EncryptionConfig</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">kms_provider</span><span class="o">=</span><span class="s1">'aws-kms'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">dek_cache_size</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span> <span class="c1"># Cache up to 1000 DEKs</span>
</span></span><span class="line"><span class="cl"> <span class="n">dek_cache_ttl</span><span class="o">=</span><span class="mi">3600</span> <span class="c1"># Cache for 1 hour</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></div></li>
<li>
<p><strong>Use connection pooling</strong>: Reuse encrypted connections</p>
</li>
<li>
<p><strong>Minimize encrypted fields</strong>: Only encrypt what’s necessary</p>
</li>
</ol>
<h3 id="related-topics" class="position-relative d-flex align-items-center group">
<span>Related Topics</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="related-topics"
aria-haspopup="dialog"
aria-label="Share link: Related Topics">
<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><ul>
<li><a
href="/tags/tde/"
>Transparent Data Encryption (TDE)</a>
- Full database encryption</li>
<li><a
href="/tags/security/"
>Security</a>
- Overall security features</li>
<li><a
href="/tags/encryption/"
>Encryption</a>
- Encryption capabilities</li>
<li><a
href="/tags/compliance/"
>Compliance</a>
- Regulatory compliance</li>
<li><a
href="/tags/authentication/"
>Authentication</a>
- Access control</li>
</ul>
<h3 id="further-reading" class="position-relative d-flex align-items-center group">
<span>Further Reading</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="further-reading"
aria-haspopup="dialog"
aria-label="Share link: Further Reading">
<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><ul>
<li><a
href="/docs/security/field-level-encryption/"
>Field-Level Encryption Guide</a>
- Complete FLE documentation</li>
<li><a
href="/docs/security/kms-integration/"
>KMS Integration</a>
- KMS integration guide</li>
<li><a
href="/docs/client-libraries/"
>Client Libraries</a>
- Language-specific FLE usage</li>
</ul>
<p>Geode’s Field-Level Encryption provides granular protection for sensitive data with queryable encryption support, enabling compliance with PCI-DSS, HIPAA, and GDPR while maintaining application functionality.</p>
Tag
1 article
Tag: Field-Level Encryption (FLE)
Explore Geode documentation tagged with fle. Learn about fle features, best practices, and implementation details.