Privacy-by-Design Architecture and Built-in Compliance for GDPR, HIPAA, CCPA
Joe Scanlin
November 2025
This section addresses enterprise requirements for privacy, security, and regulatory compliance. Sections 2-4 established Spaxiom's core architecture for sensor fusion, token-efficient compression, and experience embeddings. Before exploring specific applications, we must address a critical requirement for enterprise deployment: privacy, security, and regulatory compliance.
Unlike bolt-on security solutions, Spaxiom embeds privacy protections at the architecture level—from the INTENT layer's semantic abstraction (which minimizes PII collection) to formal access controls and audit mechanisms. This section describes privacy-by-design principles, encryption strategies, anonymization techniques, compliance with major regulations (GDPR, HIPAA, CCPA), and advanced privacy-preserving methods like federated learning.
Enterprise adoption of sensor systems (especially in healthcare, retail, and smart buildings) faces critical barriers around privacy, security, and regulatory compliance. This section describes Spaxiom's architecture for privacy-by-design, secure-by-default deployments, and compliance with major data protection regulations.
Spaxiom embeds privacy protections at the architecture level, not as an afterthought. Key principles:
The INTENT layer inherently reduces data collection to semantically meaningful events rather than raw sensor streams:
# Raw camera stream (privacy-invasive):
# - 1920x1080 @ 30fps = 62 MB/s per camera
# - Contains identifiable faces, clothing, activities
# Spaxiom event stream (privacy-preserving):
{
"type": "OccupancyChanged",
"zone": "conference_room_a",
"count": 5, # Aggregate count, no identities
"timestamp": "2025-01-06T14:23:00Z"
}
# Data rate: ~500 bytes/event, ~10 events/min = 5 KB/min (99.999% reduction)
Privacy benefit: No personally identifiable information (PII) is stored. Event schema excludes faces, names, biometrics by design.
from spaxiom.governance import RetentionPolicy
# GDPR-compliant: delete events after 30 days
policy = RetentionPolicy(
max_age_days=30,
auto_purge=True,
exceptions=["SafetyIncident", "AuditEvent"] # Retain for compliance
)
runtime.set_retention_policy(policy)
# Automatic deletion
# - Events older than 30 days are purged nightly
# - Safety incidents retained for 7 years (regulatory requirement)
# - Audit logs immutable, retained indefinitely
Users can opt-out of tracking on a per-zone basis:
from spaxiom.governance import ConsentManager
consent = ConsentManager()
# User opts out of tracking in "employee_lounge"
consent.opt_out(user_id="employee_42", zones=["employee_lounge", "restroom_a"])
# Runtime respects opt-out
@runtime.on_event("OccupancyChanged")
def handle_occupancy(event):
if consent.is_opted_out(zone=event["zone"]):
return # Skip processing for opted-out zones
# Process normally for consented zones
process_event(event)
When publishing aggregate metrics (e.g., "average occupancy per floor"), add calibrated noise to prevent re-identification:
from spaxiom.privacy import DifferentialPrivacy
dp = DifferentialPrivacy(epsilon=1.0, delta=1e-5) # (ε, δ)-DP guarantee
# Query: average occupancy in zone over past week
true_avg = store.query_avg(zone="floor_5", metric="occupancy", window="7d")
# Add Laplace noise for privacy
noisy_avg = dp.add_noise(true_avg, sensitivity=1.0)
# Publish noisy statistic (safe for release)
report["floor_5_avg_occupancy"] = noisy_avg
Guarantee: ε=1.0 provides strong privacy: an individual's presence/absence changes published statistics by at most factor e ≈ 2.71.
from spaxiom.security import RBAC, Role
rbac = RBAC()
# Define roles
rbac.add_role(Role(
name="facility_manager",
permissions=["read:occupancy", "read:energy", "write:hvac_settings"]
))
rbac.add_role(Role(
name="security_officer",
permissions=["read:*", "read:security_events", "write:alert_acknowledgment"]
))
rbac.add_role(Role(
name="data_analyst",
permissions=["read:aggregate_stats"] # No raw events
))
# Assign user to role
rbac.assign_user("user_123", role="facility_manager")
# Enforce at query time
@runtime.query_events
def query(user, event_type, zone):
if not rbac.can(user, f"read:{event_type}"):
raise PermissionDenied(f"User {user} cannot read {event_type}")
return store.query(event_type=event_type, zone=zone)
Fine-grained policies based on attributes (zone, time, sensitivity):
from spaxiom.security import ABAC, Policy
abac = ABAC()
# Policy: facility managers can read occupancy in public zones during work hours
abac.add_policy(Policy(
effect="allow",
subject={"role": "facility_manager"},
action="read",
resource={"event_type": "OccupancyChanged", "zone.type": "public"},
condition=lambda ctx: 9 <= ctx.hour <= 17 # 9am-5pm
))
# Policy: security officers can read all events in restricted zones anytime
abac.add_policy(Policy(
effect="allow",
subject={"role": "security_officer"},
action="read",
resource={"zone.type": "restricted"},
condition=lambda ctx: True
))
# Enforce
if not abac.is_allowed(user=user, action="read", resource=event):
raise PermissionDenied()
from spaxiom.security import EncryptedEventStore
# SQLite/Postgres with AES-256 encryption
store = EncryptedEventStore(
backend="postgres",
connection_string="postgresql://localhost/spaxiom",
encryption_key=load_key_from_kms("aws:kms:key-id-123"),
algorithm="AES-256-GCM"
)
# Events encrypted before write, decrypted on read
store.write(event) # Encrypted in database
event = store.read(event_id) # Decrypted transparently
from spaxiom.connectors import MQTTBridge
# Edge → Cloud: mutual TLS authentication
bridge = MQTTBridge(
broker="cloud.example.com",
port=8883,
tls_version="TLSv1.3",
client_cert="/path/to/client-cert.pem",
client_key="/path/to/client-key.pem",
ca_cert="/path/to/ca-cert.pem",
verify_hostname=True
)
# All event transmissions encrypted end-to-end
# Intel SGX / AWS Nitro Enclaves for processing PII
from spaxiom.security import SecureEnclave
enclave = SecureEnclave(provider="aws_nitro")
# Process sensitive events inside enclave (memory encrypted, isolated)
@enclave.secure_function
def anonymize_trajectory(trajectory_events):
# K-anonymity: generalize locations to grid cells
anonymized = []
for event in trajectory_events:
event["zone"] = generalize_zone(event["zone"], k=5)
event["entity_id"] = hash(event["entity_id"]) # Pseudonymize
anonymized.append(event)
return anonymized
# Call from untrusted host (data never visible outside enclave)
anon_traj = enclave.call(anonymize_trajectory, sensitive_trajectory)
Generalize spatiotemporal data so each trajectory is indistinguishable from at least k-1 others:
from spaxiom.privacy import KAnonymizer
anonymizer = KAnonymizer(k=5)
# Trajectory: sequence of (zone, timestamp) tuples
trajectory = [
{"zone": "loading_dock", "time": "2025-01-06T10:00:00Z"},
{"zone": "warehouse_aisle_3", "time": "2025-01-06T10:05:00Z"},
{"zone": "office_break_room", "time": "2025-01-06T10:15:00Z"},
]
# Generalize zones to higher-level regions
anon_trajectory = anonymizer.anonymize(trajectory)
# Result:
# [
# {"zone": "loading_area", "time": "2025-01-06T10:00:00Z"}, # Generalized
# {"zone": "warehouse_zone", "time": "2025-01-06T10:05:00Z"},
# {"zone": "common_area", "time": "2025-01-06T10:15:00Z"},
# ]
from spaxiom.privacy import SpatialCloaking
cloaking = SpatialCloaking(grid_size=5.0) # 5m grid cells
# Exact location
event = {"type": "FallEvent", "x": 12.34, "y": 8.76}
# Cloak to grid cell center
cloaked = cloaking.cloak(event)
# Result: {"type": "FallEvent", "x": 12.5, "y": 8.75} # Snapped to grid
# Reduce timestamp precision to prevent re-identification
from datetime import datetime
exact_time = datetime(2025, 1, 6, 14, 23, 47, 123456)
# Bin to 5-minute intervals
binned_time = exact_time.replace(minute=(exact_time.minute // 5) * 5,
second=0, microsecond=0)
# Result: 2025-01-06 14:20:00 (precision reduced)
Spaxiom provides built-in support for GDPR Articles 5, 25, 32:
| GDPR Requirement | Spaxiom Implementation |
|---|---|
| Art. 5: Data Minimization | INTENT layer emits only semantic events, no raw sensor data or PII |
| Art. 17: Right to Erasure | Automatic event purging after retention period; on-demand deletion API |
| Art. 20: Data Portability | Export events as JSON/CSV for user-requested data transfers |
| Art. 25: Privacy by Design | Event schemas exclude PII; zone-based consent; differential privacy |
| Art. 32: Security Measures | Encryption at rest/transit, RBAC/ABAC, audit logging, anomaly detection |
# GDPR-compliant data subject access request (DSAR)
from spaxiom.governance import GDPR
gdpr = GDPR(runtime)
# User requests their data (Art. 15)
user_data = gdpr.export_user_data(user_id="user_42", format="json")
# Returns: all events where user_42 was identified, in machine-readable format
# User requests deletion (Art. 17: "Right to be Forgotten")
gdpr.delete_user_data(user_id="user_42")
# Deletes all events, pseudonymized IDs, and derivative data for user_42
Healthcare deployments require HIPAA compliance for Protected Health Information (PHI):
from spaxiom.governance import HIPAA
hipaa = HIPAA(runtime)
# Validate event schema is PHI-free
event = {"type": "GaitInstability", "zone": "ward_b", "stability_score": 0.23}
assert hipaa.is_phi_free(event) # True: no identifiers
# Audit log
hipaa.log_access(user="nurse_42", action="read", resource="GaitInstability",
zone="ward_b", timestamp="2025-01-06T14:23:00Z")
from spaxiom.governance import CCPA
ccpa = CCPA(runtime)
# Consumer requests disclosure of collected data
data = ccpa.disclose_data(consumer_id="consumer_123")
# Consumer opts out of "sale" (sharing with third parties)
ccpa.opt_out_of_sale(consumer_id="consumer_123")
# Consumer requests deletion
ccpa.delete_consumer_data(consumer_id="consumer_123")
from spaxiom.security import AuditLogger
# Write-only, tamper-evident audit log
audit = AuditLogger(backend="append_only_db") # e.g., WORM storage
# Log every data access
@runtime.on_query
def log_query(user, query):
audit.log({
"timestamp": now(),
"user": user,
"action": "query",
"query": query.to_dict(),
"result_count": len(query.results),
"ip_address": request.remote_addr
})
# Audit logs are cryptographically signed (tamper detection)
signature = audit.sign(log_entry, private_key)
audit.verify(log_entry, signature, public_key) # Detect modifications
from spaxiom.security import AnomalyDetector
detector = AnomalyDetector()
# Train on normal access patterns
detector.train(audit_logs_30_days)
# Real-time anomaly detection
@audit.on_log_entry
def check_anomaly(log_entry):
anomaly_score = detector.score(log_entry)
if anomaly_score > 0.95: # Highly anomalous
alert_security_team(
message=f"Suspicious access by {log_entry['user']}",
details=log_entry
)
# Example anomalies:
# - User accessing 1000s of events in 1 minute (data exfiltration?)
# - Access from unusual IP address/location
# - Access to zones user has never queried before
When training ML models on data from multiple sites (hospitals, retail chains), federated learning avoids centralizing raw data:
from spaxiom.federated import FederatedTrainer
# Each site trains locally, shares only model updates (not data)
trainer = FederatedTrainer(
model=fall_risk_classifier,
sites=["hospital_a", "hospital_b", "hospital_c"],
aggregation="federated_averaging" # FedAvg algorithm
)
# Training loop
for round in range(100):
# Each site trains on local data
local_updates = []
for site in sites:
local_model = train_on_site(site, epochs=1)
local_updates.append(local_model.get_weights())
# Central server aggregates weight updates (no raw data shared)
global_weights = federated_average(local_updates)
trainer.set_weights(global_weights)
# Distribute updated model back to sites
for site in sites:
site.update_model(global_weights)
# Privacy guarantee: raw events never leave site, only model gradients
For highly sensitive analytics (e.g., cross-hospital benchmarking), use secure multi-party computation (MPC):
from spaxiom.security import SecureMPC
# Three hospitals want to compute average fall rate without revealing individual rates
mpc = SecureMPC(parties=["hospital_a", "hospital_b", "hospital_c"])
# Each hospital provides secret-shared input
hospital_a.share_input(fall_rate=0.012) # 1.2% fall rate
hospital_b.share_input(fall_rate=0.018)
hospital_c.share_input(fall_rate=0.015)
# Compute average using MPC protocol (no party sees others' inputs)
avg_fall_rate = mpc.compute_average() # → 0.015 (1.5%)
# Result revealed, but individual inputs remain secret
Spaxiom includes controls mapped to ISO 27001 Annex A:
# Generate SOC 2 compliance report
from spaxiom.compliance import SOC2Report
report = SOC2Report(runtime)
# Trust Service Criteria
report.add_evidence(
criterion="CC6.1", # Logical access controls
evidence="RBAC policy enforcing least privilege",
artifacts=[rbac_config, access_logs_6_months]
)
report.add_evidence(
criterion="CC6.7", # Encryption
evidence="AES-256-GCM for data at rest, TLS 1.3 for data in transit",
artifacts=[encryption_config, tls_certificates]
)
# Export for auditor review
report.export("soc2_report_2025.pdf")
A European retail chain deployed Spaxiom for customer journey analytics while maintaining GDPR compliance:
# Privacy-preserving retail analytics
from spaxiom import Zone, Condition
from spaxiom.intent import CustomerJourney
from spaxiom.privacy import DifferentialPrivacy
# Zones: entrance, electronics, clothing, checkout
zones = [Zone.named(z) for z in ["entrance", "electronics", "clothing", "checkout"]]
# Track aggregate flows (no individual identification)
journey = CustomerJourney(zones=zones, anonymize=True)
# Differential privacy for published metrics
dp = DifferentialPrivacy(epsilon=1.0)
# Query: average dwell time in electronics section
true_dwell = journey.avg_dwell_time(zone="electronics", window="7d")
noisy_dwell = dp.add_noise(true_dwell, sensitivity=60.0) # seconds
print(f"Avg dwell time: {noisy_dwell:.1f}s") # Safe to publish
# GDPR compliance:
# ✓ No personal data collected (faces, names, biometrics)
# ✓ Data minimization (only zone transitions)
# ✓ Purpose limitation (analytics only, not marketing)
# ✓ Storage limitation (30-day retention)
# ✓ Differential privacy (published statistics are private)
# Result: Chain improved store layout based on flow analysis,
# reduced checkout wait times by 18%, no GDPR violations
| Attack Vector | Mitigation |
|---|---|
| Sensor spoofing (inject fake events) | Cryptographic authentication of sensor messages (HMAC, digital signatures) |
| Network eavesdropping | TLS 1.3 encryption for all network traffic |
| Database breach | Encryption at rest, key rotation, access logging |
| Insider data exfiltration | Rate limiting, anomaly detection, audit logging |
| Replay attacks | Timestamp validation, nonce-based authentication |
| DoS (flood runtime with events) | Rate limiting, backpressure, circuit breakers |
Adding privacy protections (noise, generalization) reduces data utility. Spaxiom provides tools to quantify this tradeoff:
from spaxiom.privacy import PrivacyUtilityAnalysis
analysis = PrivacyUtilityAnalysis()
# Baseline: no privacy (ε=∞)
baseline_utility = analysis.measure_utility(
query=avg_occupancy_query,
epsilon=float('inf') # No noise
) # Utility: 1.0 (perfect accuracy)
# With differential privacy
for epsilon in [10.0, 1.0, 0.1]:
utility = analysis.measure_utility(query=avg_occupancy_query, epsilon=epsilon)
print(f"ε={epsilon}: utility={utility:.3f}")
# Output:
# ε=10.0: utility=0.95 (minimal accuracy loss)
# ε=1.0: utility=0.82 (moderate accuracy loss)
# ε=0.1: utility=0.45 (strong privacy, significant accuracy loss)
# Choose ε based on risk tolerance and use case
Spaxiom's privacy and security architecture provides defense-in-depth:
By embedding privacy and security into the architecture (not bolting them on afterward), Spaxiom enables enterprise deployments in regulated industries (healthcare, finance, government) while maintaining the semantic richness needed for intelligent applications.