Consent Management
On this page
- Core Principle
- GDPR Articles Covered
- Architecture
- Purposes (GDPR Article 6)
- Consent Scopes
- Usage Examples
- Grant Consent
- Check Consent
- Withdraw Consent
- Validate Query Before Execution
- Purpose Limitation
- Automatic Validation
- Data Minimization
- Consent Expiry
- Audit Trail
- Integration with Server
- API Layer
- Consent Management API
- Formal Verification
- TLA+ Specification
- Kani Proofs
- Best Practices
- 1. Always Specify Purpose
- 2. Request Minimal Scope
- 3. Set Expiry for Time-Limited Processing
- 4. Provide Withdrawal UI
- Kernel Integration
- Consent Withdrawal and Erasure
- Related Documentation
Kimberlite provides GDPR-compliant consent tracking for personal data processing.
Core Principle
Processing personal data requires lawful basis under GDPR Article 6. Consent is one of the valid bases, requiring:
- Freely given - Subject has genuine choice
- Specific - Consent for particular purpose
- Informed - Subject understands what they’re consenting to
- Unambiguous - Clear affirmative action
- Withdrawable - As easy to withdraw as to give
Result: Consent isn’t a checkbox—it’s a legally binding contract with the data subject.
GDPR Articles Covered
| Article | Requirement | Kimberlite Support |
|---|---|---|
| Article 6 | Lawful basis for processing | Purpose validation |
| Article 7 | Conditions for consent | Consent tracking |
| Article 5(1)(b) | Purpose limitation | Purpose enforcement |
| Article 5(1)(c) | Data minimization | Scope validation |
Architecture
ConsentRecord =
Purposes (GDPR Article 6)
Kimberlite supports 8 purposes with automatic validation:
| Purpose | Lawful Basis | Requires Consent | Valid for PHI | Valid for PCI |
|---|---|---|---|---|
| Marketing | Article 6(1)(a) | Yes | No | No |
| Analytics | Article 6(1)(f) | No | No | No |
| Contractual | Article 6(1)(b) | No | Yes | Yes |
| LegalObligation | Article 6(1)(c) | No | Yes | Yes |
| VitalInterests | Article 6(1)(d) | No | Yes | Yes |
| PublicTask | Article 6(1)(e) | No | Yes | No |
| Research | Article 9(2)(j) | Yes | Yes | No |
| Security | Article 6(1)(f) | No | Yes | Yes |
Consent Scopes
Control what data is covered by consent:
Usage Examples
Grant Consent
use ConsentTracker;
use Purpose;
let mut tracker = new;
// Grant consent for marketing
let consent_id = tracker.grant_consent.unwrap;
// Grant consent with specific scope
let consent_id = tracker.grant_consent_with_scope.unwrap;
Check Consent
// Check if subject has valid consent
if tracker.check_consent else
Withdraw Consent
// Withdraw consent (GDPR Article 7(3))
tracker.withdraw_consent.unwrap;
// Consent is now invalid
assert!;
Validate Query Before Execution
use ConsentValidator;
use DataClass;
let mut validator = new;
validator.grant_consent.unwrap;
// Validate before query execution
let result = validator.validate_query;
match result
Purpose Limitation
GDPR Article 5(1)(b) requires data be collected for “specified, explicit and legitimate purposes.”
Automatic Validation
use ;
use DataClass;
// Valid: Marketing with consent for PII
assert!;
// Invalid: Marketing not allowed for PHI (HIPAA violation)
assert!;
// Invalid: Analytics not allowed for PCI (PCI DSS violation)
assert!;
// Valid: Contractual processing for any data class
assert!;
Data Minimization
GDPR Article 5(1)(c) requires data be “adequate, relevant and limited to what is necessary.”
// Check if purpose satisfies data minimization
assert!;
assert!;
Consent Expiry
Set expiry dates for time-limited consent:
use ;
let consent_id = tracker.grant_consent.unwrap;
// Get mutable record and set expiry
let record = tracker.consents.get_mut.unwrap;
record.expires_at = Some; // 1 year
// After expiry, consent automatically becomes invalid
Audit Trail
All consent operations are logged:
- Consent granted → Timestamp recorded
- Consent withdrawn → Timestamp recorded
- Query rejected → Audit log entry
-- Query consent audit trail
SELECT subject_id, purpose, granted_at, withdrawn_at
FROM __consent_audit
WHERE subject_id = 'user@example.com'
ORDER BY granted_at DESC;
Integration with Server
API Layer
// In kimberlite-server request handler
Consent Management API
// POST /consent/grant
// POST /consent/withdraw
// GET /consent/list
Formal Verification
TLA+ Specification
specs/tla/compliance/GDPR.tla proves consent properties:
Article 6 (Lawful Basis):
GDPR_Article_6_LawfulBasis ==
\A ds \in DataSubject :
\A op \in Operation :
op.purpose \in {"Contractual", "LegalObligation"}
\/ HasValidConsent(ds, op.purpose)
Article 7 (Consent Conditions):
GDPR_Article_7_ConsentConditions ==
\A ds \in DataSubject :
\A consent \in consentRecords[ds] :
/\ consent.granted_at # NULL
/\ consent.withdrawn_at # NULL => consent.valid = FALSE
Kani Proofs
5 bounded model checking proofs (#41-45):
Proof #41: Consent grant/withdraw correctness
- Withdrawn consent is never valid
is_withdrawn()returns true after withdrawal
Proof #42: Purpose validation for data classes
- Marketing not allowed for PHI/PCI
- Contractual allowed for all classes
Proof #43: Consent validator enforcement
- Queries without required consent are rejected
- Withdrawn consent is treated as no consent
Proof #44: Consent expiry handling
- Expired consent is treated as invalid
is_expired()returns true past expiry
Proof #45: Multiple consents per subject
- Subject can have multiple valid consents
- Withdrawing one doesn’t affect others
Run proofs:
Best Practices
1. Always Specify Purpose
// ✓ Good: Explicit purpose
validator.validate_query?;
// ✗ Bad: Implicit purpose (none)
// No way to validate consent
2. Request Minimal Scope
// ✓ Good: Request only contact info for email campaign
tracker.grant_consent_with_scope?;
// ✗ Avoid: Requesting AllData when ContactInfo suffices
tracker.grant_consent_with_scope?;
3. Set Expiry for Time-Limited Processing
// ✓ Good: Campaign-specific consent with expiry
let consent_id = tracker.grant_consent?;
let record = tracker.consents.get_mut.unwrap;
record.expires_at = Some; // Campaign duration
4. Provide Withdrawal UI
Make withdrawal as easy as granting consent (GDPR Article 7(3)):
// UI: "Manage Consents" page
Kernel Integration
Consent is enforced at the kernel level — queries and writes for PII/PHI/Sensitive data are rejected unless valid consent exists:
// Validate consent via TenantHandle
tenant.validate_consent?;
// Returns Ok(()) if valid consent exists
// Returns Err(ComplianceError) if no consent
// Grant consent (returns consent_id for withdrawal)
let consent_id = tenant.grant_consent?;
// Withdraw consent
tenant.withdraw_consent?;
Automatic behavior:
- Queries for PII, PHI, Sensitive data require valid consent for the stated purpose
- Queries for Public, Deidentified data do not require consent
- Purposes that don’t require consent (e.g.,
LegalObligation,VitalInterests) bypass consent checking
Consent Withdrawal and Erasure
When consent is withdrawn and no remaining valid consents exist for the subject, an erasure request can be automatically triggered per GDPR Article 17:
// Withdraw consent
tenant.withdraw_consent?;
// If no remaining consents → trigger erasure
let mut engine = new;
let request = engine.request_erasure?;
// request.deadline = now + 30 days
See: Right to Erasure for the complete erasure workflow.
Related Documentation
- Right to Erasure - GDPR Article 17 (triggered by consent withdrawal)
- Data Portability - GDPR Article 20 data export
- Data Classification - 8-level classification system
- RBAC - Role-based access control
- Field-Level Masking - Data minimization for masked fields
- Compliance Overview - Multi-framework compliance
Key Takeaway: Consent management isn’t a feature you bolt on—it’s a legal requirement. Kimberlite makes it impossible to process personal data without valid consent.