Spaces:
Running
Running
File size: 4,553 Bytes
a6a5d8e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | # GDPR Article 17 — Right to Erasure Endpoint
**Flagship:** a11oy
**Endpoint:** `POST /api/a11oy/v2/erase`
**Doctrine v11 — 749 / 14 / 163 — replay hash c7c0ba17**
**Updated:** 2026-06-02
---
## Summary
Public flagships do not store end-user PII. All HF Spaces are unauthenticated and public.
This endpoint exists as the GDPR Article 17 minimum viable surface: it accepts an erasure
request, signs a receipt (whether or not any data exists to erase), and returns that signed
receipt to the caller.
---
## Request
```http
POST /api/a11oy/v2/erase
Content-Type: application/json
{
"caller_id": "<string — your identifier, used only to label the receipt>",
"confirmation": "DELETE-MY-DATA"
}
```
**Fields:**
| Field | Type | Required | Description |
|---|---|---|---|
| `caller_id` | string | yes | Caller-supplied identifier (not stored, used only in the receipt label) |
| `confirmation` | string | yes | Must be the literal string `DELETE-MY-DATA` |
---
## Response
```json
{
"status": "acknowledged",
"message": "Public flagships don't store user PII. Khipu chain receipts are auditable, not PII. Personal data deletion via rosie /api/rosie/v2/unay/erase (separate handler for operator session memory). Audit-trail receipt of this deletion request signed and returned.",
"receipt": {
"payload": {
"type": "gdpr_erase_request",
"flagship": "a11oy",
"caller_id_label": "<caller_id from request>",
"ts": "<ISO8601 timestamp>",
"doctrine": {
"declarations": 749,
"axioms": 14,
"sorries": 163,
"replay_hash": "c7c0ba17"
}
},
"signature": "<Wire D DSSE Ed25519 signature>",
"prev_hash": "<Khipu chain prev_hash>"
}
}
```
---
## What data is and is not held
| Data class | Held by a11oy? | Notes |
|---|---|---|
| PII from HF Space callers | **No** | HF Spaces are unauthenticated; no accounts, no cookies |
| Khipu chain receipts | Yes (audit trail) | Receipts are cryptographic audit records, not PII; deletion would break chain integrity |
| Operator session memory (rosie only) | rosie only | Route to `POST /api/rosie/v2/unay/erase` for operator session data |
| GitHub interaction data | GitHub (not us) | Contact GitHub directly for their data deletion |
---
## Implementation Reference
The endpoint handler (`serve.py`) must:
1. Validate `confirmation == "DELETE-MY-DATA"` — return 400 if not.
2. Build a receipt payload with `type: "gdpr_erase_request"`, `flagship`, `caller_id_label`, `ts`, and `doctrine` numbers.
3. Sign via `szl_dsse.sign(payload, WIRE_D_SIGNING_KEY)` — return 500 if signing fails.
4. Return 200 with `status: "acknowledged"` and the signed receipt.
5. **Do not log** `caller_id` beyond the signed receipt.
6. **Do not store** the request (the signed receipt itself is the audit trail).
```python
# Reference implementation (docs/reference; do not copy verbatim into serve.py without review)
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
import szl_dsse, datetime, os
router = APIRouter()
class EraseRequest(BaseModel):
caller_id: str
confirmation: str
@router.post("/api/a11oy/v2/erase")
async def gdpr_erase(body: EraseRequest):
if body.confirmation != "DELETE-MY-DATA":
raise HTTPException(400, "confirmation must be 'DELETE-MY-DATA'")
payload = {
"type": "gdpr_erase_request",
"flagship": "a11oy",
"caller_id_label": body.caller_id,
"ts": datetime.datetime.utcnow().isoformat() + "Z",
"doctrine": {"declarations": 749, "axioms": 14, "sorries": 163, "replay_hash": "c7c0ba17"},
}
key = os.environ.get("WIRE_D_SIGNING_KEY")
if not key:
raise HTTPException(500, "Signing key not configured")
receipt = szl_dsse.sign(payload, key)
return {
"status": "acknowledged",
"message": (
"Public flagships don't store user PII; Khipu chain receipts are auditable not PII. "
"Personal data deletion via rosie /api/rosie/v2/unay/erase (separate handler). "
"Audit-trail receipt of deletion request signed."
),
"receipt": receipt,
}
```
---
## Routing to rosie
For operator session memory (if applicable), route the request to rosie:
```http
POST https://SZLHOLDINGS-rosie.hf.space/api/rosie/v2/unay/erase
Content-Type: application/json
{
"caller_id": "<your identifier>",
"confirmation": "DELETE-MY-DATA"
}
```
---
*Co-Authored-By: Perplexity Computer Agent*
*Doctrine v11 — 749/14/163 — c7c0ba17*
|