sangamdas/privacy-finality-reference
0
1from pathlib import Path2import sys3import json4import gradio as gr5 6# Make the local src/ package importable inside the Hugging Face Space.7ROOT = Path(__file__).resolve().parent8sys.path.insert(0, str(ROOT / "src"))9 10from privacy_finality.authority import PermitAuthority, WorkloadKey11from privacy_finality.models import CandidateAct12from privacy_finality.ped import ProtectedEnforcementDomain, ValidationDenied13from privacy_finality.replay_store import SQLiteFinalityStore14from privacy_finality.sink import FinalitySink, FinalityDenied15from privacy_finality.vaults import SMEVaultSet16 17 18def run_demo(test_case):19 vaults = SMEVaultSet.demo()20 ped = ProtectedEnforcementDomain(vaults)21 22 authority = PermitAuthority()23 workload = WorkloadKey.generate("sme-ai-support-v1")24 25 store = SQLiteFinalityStore()26 27 sink = FinalitySink(28 sink_id="support-output-gateway-1",29 authority_public_key_b64=authority.public_key_b64,30 crypto_policy=vaults.crypto_policy,31 store=store,32 )33 34 if test_case == "Permitted customer-support act":35 act = CandidateAct(36 actor="ai-support-agent-3",37 workload_id="sme-ai-support-v1",38 subject_id="customer-2184",39 operation="GET_DELIVERY_STATUS",40 resource_id="order-81472",41 requested_attributes=(42 "delivery_status",43 "expected_delivery_date",44 ),45 purpose="CUSTOMER_SUPPORT",46 recipient="customer-2184",47 destination="support-session:932",48 jurisdiction_context="EU",49 policy_epoch=472,50 nonce="demo-allow-001",51 finality_sink="support-output-gateway-1",52 )53 54 elif test_case == "Purpose substitution":55 act = CandidateAct(56 actor="ai-support-agent-3",57 workload_id="sme-ai-support-v1",58 subject_id="customer-2184",59 operation="GET_DELIVERY_STATUS",60 resource_id="order-81472",61 requested_attributes=("delivery_status",),62 purpose="TARGETED_MARKETING",63 recipient="customer-2184",64 destination="support-session:932",65 jurisdiction_context="EU",66 policy_epoch=472,67 nonce="demo-purpose-001",68 finality_sink="support-output-gateway-1",69 )70 71 elif test_case == "Excessive data request":72 act = CandidateAct(73 actor="ai-support-agent-3",74 workload_id="sme-ai-support-v1",75 subject_id="customer-2184",76 operation="GET_DELIVERY_STATUS",77 resource_id="order-81472",78 requested_attributes=(79 "delivery_status",80 "expected_delivery_date",81 "payment_reference",82 "marketing_profile",83 ),84 purpose="CUSTOMER_SUPPORT",85 recipient="customer-2184",86 destination="support-session:932",87 jurisdiction_context="EU",88 policy_epoch=472,89 nonce="demo-data-001",90 finality_sink="support-output-gateway-1",91 )92 93 elif test_case == "Wrong destination":94 act = CandidateAct(95 actor="ai-support-agent-3",96 workload_id="sme-ai-support-v1",97 subject_id="customer-2184",98 operation="GET_DELIVERY_STATUS",99 resource_id="order-81472",100 requested_attributes=("delivery_status",),101 purpose="CUSTOMER_SUPPORT",102 recipient="customer-2184",103 destination="external-platform:attacker",104 jurisdiction_context="EU",105 policy_epoch=472,106 nonce="demo-destination-001",107 finality_sink="support-output-gateway-1",108 )109 110 else:111 return "ERROR", "Unknown test case", "{}"112 113 candidate_json = json.dumps(114 act.to_dict(),115 indent=2,116 sort_keys=True,117 )118 119 try:120 grant = ped.validate(act)121 122 permit = authority.issue(123 grant,124 workload,125 ttl_seconds=60,126 )127 128 proof = workload.proof(permit)129 130 released = sink.release(131 act,132 permit,133 proof,134 dict(grant.selected_values),135 )136 137 details = {138 "decision": "ALLOW",139 "candidate_act_digest": act.digest(),140 "purpose": grant.purpose,141 "permitted_attributes": list(grant.permitted_attributes),142 "recipient": grant.recipient,143 "destination": grant.destination,144 "policy_epoch": grant.policy_epoch,145 "finality_sink": grant.finality_sink,146 "released_effect": released,147 "effects_recorded": store.count_effects(),148 }149 150 return (151 "ALLOW — Finality Sink released the protected effect.",152 json.dumps(details, indent=2, sort_keys=True),153 candidate_json,154 )155 156 except ValidationDenied as exc:157 details = {158 "decision": "DENY",159 "stage": "Protected Enforcement Domain",160 "reasons": exc.reasons,161 "effects_recorded": store.count_effects(),162 }163 164 return (165 "DENY — Candidate Act remained non-effective.",166 json.dumps(details, indent=2, sort_keys=True),167 candidate_json,168 )169 170 except FinalityDenied as exc:171 details = {172 "decision": "DENY",173 "stage": "Finality Sink",174 "reason": exc.reason,175 "effects_recorded": store.count_effects(),176 }177 178 return (179 "DENY — Finality Sink withheld effectuation.",180 json.dumps(details, indent=2, sort_keys=True),181 candidate_json,182 )183 184 185with gr.Blocks(title="Privacy Finality Reference") as demo:186 187 gr.Markdown(188 """189# Execution-Finality Reference Demonstration190 191### Candidate-Act-Based Enforcement for AI, Privacy and Data Governance192 193This runnable demonstration shows the common execution-finality substrate described by the194**Privacy Finality Reference v0.1.0**.195 196It demonstrates:197 198**Candidate Act → Protected Validation → Act-Bound Authority → Finality Sink → External Effect**199 200The current implementation uses a synthetic SME privacy scenario to demonstrate201purpose limitation, minimum-data scope, recipient and destination binding,202non-bearer proof-of-possession, policy-epoch checks, replay protection and203fail-closed effectuation.204 205The architecture is intended for technical research concerning **GDPR and broader206global privacy/data-protection requirements, AI governance including the EU AI Act,207and related national governance frameworks** where applicable constraints have208already been translated into machine-readable rules.209 210**This demo does not determine legal compliance.**211It enforces supplied technical constraints.212"""213 )214 215 test_case = gr.Dropdown(216 choices=[217 "Permitted customer-support act",218 "Purpose substitution",219 "Excessive data request",220 "Wrong destination",221 ],222 value="Permitted customer-support act",223 label="Select execution scenario",224 )225 226 run_button = gr.Button("Run Candidate Act")227 228 decision = gr.Textbox(229 label="Finality Decision",230 interactive=False,231 )232 233 details = gr.Code(234 label="Validation / Finality Result",235 language="json",236 )237 238 candidate = gr.Code(239 label="Candidate Act",240 language="json",241 )242 243 gr.Markdown(244 """245---246 247### Core invariant248 249> **AI may compute the act, but computation alone is not authority for the act to become externally effective.**250 251Repository:252https://github.com/sangmdas/privacy-finality-reference253 254Versioned release:255https://github.com/sangmdas/privacy-finality-reference/releases/tag/v0.1.0256"""257 )258 259 run_button.click(260 fn=run_demo,261 inputs=test_case,262 outputs=[decision, details, candidate],263 )264 265 266if __name__ == "__main__":267 demo.launch()268 