<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Data Privacy on Ghost in the data</title><link>https://ghostinthedata.info/tags/data-privacy/</link><description>Ghost in the data</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>Ghost in the data</copyright><lastBuildDate>Fri, 21 Nov 2025 09:00:00 +1100</lastBuildDate><atom:link href="https://ghostinthedata.info/tags/data-privacy/index.xml" rel="self" type="application/rss+xml"/><item><title>Balancing Data Accessibility and Privacy in Financial Services</title><link>https://ghostinthedata.info/posts/2025/2025-11-21-data-accessibility-and-privacy/</link><pubDate>Fri, 21 Nov 2025 09:00:00 +1100</pubDate><guid>https://ghostinthedata.info/posts/2025/2025-11-21-data-accessibility-and-privacy/</guid><author>Chris Hillman</author><description>Explore the complex interplay between data accessibility and privacy in banking, with practical strategies for implementing effective anonymisation policies, retention protocols, and data minimisation techniques that maintain regulatory compliance without sacrificing analytical value.</description><content:encoded>&lt;h2 id="the-data-tightrope-where-accessibility-meets-privacy">The Data Tightrope: Where Accessibility Meets Privacy&lt;/h2>
&lt;p>Let&amp;rsquo;s face it—in today&amp;rsquo;s data landscape, data is simultaneously your most valuable asset and your biggest potential liability.&lt;/p>
&lt;p>Finding that sweet spot where data remains accessible enough to drive business decisions while being locked down enough to satisfy privacy regulations. It&amp;rsquo;s not just about ticking compliance boxes—it&amp;rsquo;s about maintaining customer trust while still extracting every bit of analytical value from your data assets.&lt;/p>
&lt;/br>
&lt;/br>
&lt;h2 id="the-four-tier-data-storage-reality">The Four-Tier Data Storage Reality&lt;/h2>
&lt;hr>
&lt;p>Most financial institutions operate with multiple data storage options, each with its own tradeoffs. Here&amp;rsquo;s how I&amp;rsquo;ve seen it play out in practice:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Glacier/Cold Storage&lt;/strong>: Dirt cheap but painfully slow—we&amp;rsquo;re talking potentially days to retrieve data. Perfect for those regulatory archival requirements where immediacy isn&amp;rsquo;t essential.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Iceberg Relational Databases&lt;/strong>: Your traditional SQL databases offering a balance of speed and cost. This is where most of your operational data lives.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>In-memory Caching Solutions&lt;/strong> (Redis, Memcached): Lightning-fast but expensive. Reserve these for those mission-critical nanosecond accesses.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Hybrid Solutions&lt;/strong> (like Druid): Offering column-store capabilities with better performance than traditional databases but lower cost than pure in-memory solutions.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Each tier has its place in your architecture, but—and this is crucial—each needs its own privacy controls. I&amp;rsquo;ve seen too many organisations focus all their privacy efforts on relational databases while neglecting controls on their cold storage or caching layers. Remember Facebook&amp;rsquo;s Cambridge Analytica debacle? That wasn&amp;rsquo;t a failure of their primary database privacy controls; it was a failure in their broader data ecosystem.&lt;/p>
&lt;/br>
&lt;/br>
&lt;h2 id="anonymisation-vs-pseudonymization-more-than-just-semantics">Anonymisation vs. Pseudonymization: More Than Just Semantics&lt;/h2>
&lt;hr>
&lt;p>Here&amp;rsquo;s where things get interesting—and where I&amp;rsquo;ve seen many companies stumble. The distinction between anonymisation and pseudonymization isn&amp;rsquo;t just academic; it fundamentally affects how you can use your data and what regulatory requirements apply.&lt;/p>
&lt;h3 id="anonymisation-the-one-way-trip">Anonymisation: The One-Way Trip&lt;/h3>
&lt;p>Truly anonymised data is aggregated to the point where it cannot be traced back to an individual. Take our retail banking metrics dashboard showing &amp;ldquo;170 million active accounts in Australia&amp;rdquo;—valuable for trend analysis but impossible to connect to any specific customer.&lt;/p>
&lt;p>But anonymisation has limitations. I learned this the hard way when we created what we thought was an anonymised dashboard. By slicing the data across too many dimensions (location, account type, account age, balance tier), we inadvertently created a situation where some data points could be traced back to specific high-net-worth individuals. The fix? Adding minimum thresholds for each dimensional cut to prevent de-anonymisation.&lt;/p>
&lt;h3 id="pseudonymization-maintaining-the-bridge">Pseudonymization: Maintaining the Bridge&lt;/h3>
&lt;p>Pseudonymization differs fundamentally in that it maintains a separate mapping table linking the scrubbed identifiers to the original data. Replace customer IDs with randomly generated tokens while maintaining a secured mapping table accessible only to authorised personnel.&lt;/p>
&lt;p>This approach gives you more analytical flexibility but requires rigorous governance of that mapping table. The moment that mapping table becomes compromised, all pseudonymized data effectively becomes identified again.&lt;/p>
&lt;/br>
&lt;/br>
&lt;h2 id="practical-implementation">Practical Implementation&lt;/h2>
&lt;hr>
&lt;p>Let me walk you through a example. We created an anonymised version of sport player data as a proxy for customer financial data. Here&amp;rsquo;s how we structured it:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Player Name&lt;/strong> (representing our customer identifier)&lt;/li>
&lt;li>&lt;strong>Anonymised ID&lt;/strong> (a bigint with no connection to the original ID)&lt;/li>
&lt;li>&lt;strong>Last Active Season&lt;/strong> (similar to &amp;ldquo;last transaction date&amp;rdquo;)&lt;/li>
&lt;li>&lt;strong>Current Season&lt;/strong> (representing the present time benchmark)&lt;/li>
&lt;/ul>
&lt;p>The anonymisation policy stated that players inactive for five years or more would be completely anonymised. This mirrors our policy where customer data achieves a different privacy status after extended inactivity.&lt;/p>
&lt;p>Here&amp;rsquo;s what the implementation looked like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">-- Create the anonymized table
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">CREATE&lt;/span> &lt;span style="color:#66d9ef">TABLE&lt;/span> anonymized_players (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> anonymized_player_ID INT,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> start_position VARCHAR,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> points DOUBLE,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> season INT,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> game_ID INT,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">PRIMARY&lt;/span> &lt;span style="color:#66d9ef">KEY&lt;/span> (anonymized_player_ID)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">-- Partition for performance
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">ALTER&lt;/span> &lt;span style="color:#66d9ef">TABLE&lt;/span> anonymized_players
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PARTITION &lt;span style="color:#66d9ef">BY&lt;/span> RANGE (season);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">-- Identify players for anonymization
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">WITH&lt;/span> combined &lt;span style="color:#66d9ef">AS&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">-- Join original and anonymized tables
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#66d9ef">SELECT&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> p.player_name,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> a.anonymized_id,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> p.last_active_season,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">EXTRACT&lt;/span>(&lt;span style="color:#66d9ef">YEAR&lt;/span> &lt;span style="color:#66d9ef">FROM&lt;/span> &lt;span style="color:#66d9ef">CURRENT_DATE&lt;/span>) &lt;span style="color:#66d9ef">as&lt;/span> current_season
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">FROM&lt;/span> players p
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">LEFT&lt;/span> &lt;span style="color:#66d9ef">JOIN&lt;/span> anonymized_players a &lt;span style="color:#66d9ef">ON&lt;/span> p.player_id &lt;span style="color:#f92672">=&lt;/span> a.original_id
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">-- Apply the anonymization policy
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">INSERT&lt;/span> &lt;span style="color:#66d9ef">INTO&lt;/span> anonymized_players (player_name, anonymized_id)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SELECT&lt;/span> player_name, anonymized_id
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">FROM&lt;/span> combined
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">WHERE&lt;/span> last_active_season &lt;span style="color:#f92672">&amp;lt;&lt;/span> current_season &lt;span style="color:#f92672">-&lt;/span> &lt;span style="color:#ae81ff">5&lt;/span>;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The real magic happens with those time-based policies. We have to carefully track player (customer) returns and maintain consistent anonymised IDs. Think about Michael Jordan&amp;rsquo;s comeback—if he retired in 1998 and returned in 2001, he&amp;rsquo;d maintain the same anonymised ID because he didn&amp;rsquo;t exceed our five-year threshold. If he&amp;rsquo;d stayed retired for six years, he&amp;rsquo;d receive a completely new anonymised ID upon return.&lt;/p>
&lt;/br>
&lt;/br>
&lt;h2 id="the-sliding-window-challenge">The Sliding Window Challenge&lt;/h2>
&lt;hr>
&lt;p>This sliding window concept creates fascinating technical challenges. We need to:&lt;/p>
&lt;ol>
&lt;li>Maintain rolling retention policies that automatically anonymise data after the specified period&lt;/li>
&lt;li>Handle returns gracefully without compromising privacy&lt;/li>
&lt;li>Ensure consistency across all data tiers&lt;/li>
&lt;/ol>
&lt;p>One approach we&amp;rsquo;ve found effective is using Iceberg tables with time travel capabilities. This allows us to maintain a view of our table history while only serving the current state to clients.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">-- The simplified approach to identifying last partition update
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">SELECT&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> partition_key,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">MAX&lt;/span>(committed_at) &lt;span style="color:#66d9ef">as&lt;/span> last_update
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">FROM&lt;/span> iceberg_partitions
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">WHERE&lt;/span> partition_key &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#39;season=2003&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">GROUP&lt;/span> &lt;span style="color:#66d9ef">BY&lt;/span> partition_key;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/br>
&lt;/br>
&lt;h2 id="retention-policies-logical-vs-creation-date">Retention Policies: Logical vs. Creation Date&lt;/h2>
&lt;hr>
&lt;p>The retention policy headache doesn&amp;rsquo;t end with anonymisation. You also need to decide whether to base your retention on:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Logical Date&lt;/strong>: Tied to when the event actually occurred&lt;/li>
&lt;li>&lt;strong>Creation Date&lt;/strong>: When the data was loaded into your warehouse&lt;/li>
&lt;/ol>
&lt;p>This seemingly minor distinction creates massive downstream implications. Let me illustrate:&lt;/p>
&lt;p>Imagine you have a 50-year-old partition (data from 1975). With a logical date retention policy, that partition might be deleted tomorrow because it exceeds your retention window. With a creation date policy, if you just loaded that data last week, it would be retained regardless of how old the actual data is.&lt;/p>
&lt;p>My recommendation? Use logical date retention for operational data and creation date for historical archives. This gives you the best of both worlds—efficient purging of operational data while maintaining valuable historical information.&lt;/p>
&lt;/br>
&lt;/br>
&lt;h2 id="implementing-data-minimisation-in-practice">Implementing Data Minimisation in Practice&lt;/h2>
&lt;hr>
&lt;p>Data minimisation isn&amp;rsquo;t just theoretical—here&amp;rsquo;s how we&amp;rsquo;ve implemented it:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Identify Low-Value Data&lt;/strong>: We analyse query patterns to identify rarely accessed data that can be archived or removed.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Regular Audits&lt;/strong>: Schedule quarterly reviews of storage and retention policies.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Efficient Data Modelling&lt;/strong>: Design schemas to minimise redundancy while maximising query performance.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Compression Strategies&lt;/strong>: Apply appropriate compression techniques based on access patterns.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Some organisations, like Facebook, have sophisticated tools like &amp;ldquo;Cockpit&amp;rdquo; to analyse data usage patterns. While most of us don&amp;rsquo;t have such advanced tooling, we can implement similar practices at a smaller scale:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">-- Simple query to identify rarely used tables
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">SELECT&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">table_name&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> last_query_date,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> DATEDIFF(&lt;span style="color:#66d9ef">day&lt;/span>, last_query_date, &lt;span style="color:#66d9ef">CURRENT_DATE&lt;/span>) &lt;span style="color:#66d9ef">as&lt;/span> days_since_last_access
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">FROM&lt;/span> table_access_logs
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ORDER&lt;/span> &lt;span style="color:#66d9ef">BY&lt;/span> days_since_last_access &lt;span style="color:#66d9ef">DESC&lt;/span>;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The beauty of this approach is that it helps us maintain compliance with data minimisation principles in privacy regulations while also improving our operational efficiency.&lt;/p>
&lt;h2 id="the-special-case-of-active-investigations">The Special Case of Active Investigations&lt;/h2>
&lt;hr>
&lt;p>Data privacy isn&amp;rsquo;t always straightforward. What happens when a customer requests deletion, but their data is needed for an active fraud investigation? These edge cases require careful consideration and clear policies.&lt;/p>
&lt;p>We&amp;rsquo;ve implemented a special retention flag in our system that can override standard deletion processes when legal requirements necessitate it. This ensures we maintain compliance with both privacy regulations and legal obligations.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">-- Simplified example of deletion logic with legal hold exceptions
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">DELETE&lt;/span> &lt;span style="color:#66d9ef">FROM&lt;/span> customer_data
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">WHERE&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> customer_id &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#f92672">?&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">AND&lt;/span> &lt;span style="color:#66d9ef">NOT&lt;/span> &lt;span style="color:#66d9ef">EXISTS&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">SELECT&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">FROM&lt;/span> legal_holds
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">WHERE&lt;/span> customer_id &lt;span style="color:#f92672">=&lt;/span> customer_data.customer_id
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">AND&lt;/span> is_active &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">true&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> );
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/br>
&lt;/br>
&lt;h2 id="wrapping-up-the-human-element">Wrapping Up: The Human Element&lt;/h2>
&lt;hr>
&lt;p>At the end of the day, data management isn&amp;rsquo;t just a technical challenge—it&amp;rsquo;s a human one. The electricity consumed by our data operations, the privacy of our customers, and the insights we generate all have real-world impacts on people&amp;rsquo;s lives.&lt;/p>
&lt;p>As data professionals in the financial sector, we have a responsibility to make conscious choices about how we manage data. By prioritising data efficiency, respecting privacy, and fostering a culture of awareness within our organisations, we can contribute to a more sustainable and ethical data ecosystem.&lt;/p>
&lt;p>I&amp;rsquo;d love to hear about your experiences balancing data accessibility and privacy in your organisation. What challenges have you faced, and what solutions have you implemented? Let&amp;rsquo;s continue this conversation in the comments below.&lt;/p>
&lt;p>Remember, every bit of data we manage represents a real person with real privacy concerns. Let&amp;rsquo;s never lose sight of that as we navigate the complex world of data engineering in financial services.&lt;/p></content:encoded><category>Data Engineering</category><category>Data Quality &amp; Governance</category><category>Data Privacy</category><category>Anonymisation</category><category>Retention Policies</category><category>Banking</category><category>Data Minimisation</category><category>GDPR</category><category>Data Governance</category></item></channel></rss>