Skip to content

Latest commit

 

History

History
226 lines (176 loc) · 6.79 KB

File metadata and controls

226 lines (176 loc) · 6.79 KB

TFEP Legal & Regulatory Notices

Send non-repudiable notices with cryptographic proof of delivery — suitable for regulatory compliance, legal service of process, and audit notifications.


The Problem with Email Notices

Email has no mechanism for:

  • Proving who sent the notice (SMTP From is trivially spoofed)
  • Proving the recipient received it (read receipts are unreliable and optional)
  • Preventing the sender from later denying they sent it (repudiation)

TFEP solves all three:

  • Who sent it: Ed25519 signature verifiable against the sender's DID document
  • Delivery proof: Mandatory receipt automatically sent by the recipient's gateway
  • Non-repudiation: Signed timestamp + message ID cannot be altered retroactively

Sending a Legal Notice

curl -X POST http://localhost:8080/api/v1/notices/send \
  -H "Authorization: Bearer $TFEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient_did": "did:web:respondent.example",
    "subject": "Notice of Compliance Requirement — Case 2026-001",
    "body": "Pursuant to Section 12(b) of the Data Act, you are hereby required...",
    "metadata": {
      "case_number": "CASE-2026-001",
      "issuer": "Acme Regulatory Authority",
      "issue_date": "2026-05-31",
      "deadline": "2026-08-01",
      "notice_type": "compliance",
      "response_url": "https://portal.acme-authority.gov/respond/CASE-2026-001"
    }
  }'

What happens:

  1. The gateway wraps the notice in a legal_notice TFEP envelope
  2. Sets request_receipt: true — the recipient is asked to send a receipt
  3. Issues a permit so the recipient's gateway can send the receipt back
  4. Signs the envelope with the gateway's Ed25519 key
  5. Delivers via SMTP to the recipient's gateway (MX lookup)
  6. Stores locally as direction: outbound

Delivery Receipt

When the recipient's TFEP gateway receives the notice, it automatically sends a receipt message back to the sender. The receipt contains:

  • bounced_message_id — the ID of the original notice
  • timestamp — when the receipt was generated (at the recipient's gateway)
  • sender_did of the recipient — proving who acknowledged it

The sender's gateway stores the receipt and links it to the original notice via receipt_message_id.


Checking Notice Status

# Get the notice and its receipt (if received)
curl -H "Authorization: Bearer $TFEP_API_KEY" \
  "http://localhost:8080/api/v1/notices/{notice-id}"

Before receipt:

{
  "notice": {
    "id": "550e8400-...",
    "subject": "Notice of Compliance...",
    "direction": "outbound",
    "receipt_message_id": ""
  }
}

After receipt:

{
  "notice": {
    "id": "550e8400-...",
    "subject": "Notice of Compliance...",
    "receipt_message_id": "7c9e6679-..."
  },
  "receipt": {
    "id": "7c9e6679-...",
    "message_type": "receipt",
    "sender_did": "did:web:respondent.example",
    "received_at": "2026-05-31T14:23:11Z"
  }
}

List all sent notices:

curl -H "Authorization: Bearer $TFEP_API_KEY" \
  "http://localhost:8080/api/v1/notices?direction=outbound"

Proof of Delivery

A complete delivery proof consists of:

  1. Original notice (stored locally):

    • TFEP envelope: message_id, sender_did, timestamp, body_hash
    • Ed25519 signature over the canonical envelope hash
    • Your private key signs → your public key (in your DID document) verifies
  2. Delivery receipt (stored locally, sent by recipient):

    • TFEP envelope: bounced_message_id = original message_id, sender_did of recipient
    • Ed25519 signature by the recipient's key

Together, these two signed records prove:

  • You sent notice X at time T to did:web:respondent.example
  • The respondent's gateway received and processed it at time T2
  • Neither party can alter the message_id, timestamp, or content without breaking the signature

Metadata Fields

Recommended metadata schema for legal notices:

{
  "case_number":    "CASE-2026-001",
  "issuer":         "Acme Regulatory Authority",
  "issue_date":     "2026-05-31",
  "deadline":       "2026-08-01",
  "notice_type":    "compliance",
  "response_url":   "https://portal.example.gov/respond/CASE-2026-001",
  "statute":        "Data Act §12(b)",
  "jurisdiction":   "EU",
  "confidential":   false
}

Notice types: compliance, subpoena, audit, regulatory, cease-and-desist, data-breach, gdpr-sar


Querying Notices

# All outbound notices (sent by you)
curl -H "Authorization: Bearer $TFEP_API_KEY" \
  "http://localhost:8080/api/v1/notices?direction=outbound"

# All inbound notices (received by you)
curl -H "Authorization: Bearer $TFEP_API_KEY" \
  "http://localhost:8080/api/v1/notices?direction=inbound"

# Specific notice + receipt
curl -H "Authorization: Bearer $TFEP_API_KEY" \
  "http://localhost:8080/api/v1/notices/{id}"

Sender Setup for Regulatory Bodies

A regulatory agency deploying TFEP for official notices:

1. Generate identity:

./tfep-gateway keygen --domain authority.gov

2. Publish DID document: Deploy the output JSON to https://authority.gov/.well-known/did.json. This is the public record of your signing key.

3. Add DNS record:

_tfep.authority.gov TXT "v=TFEP1; did=did:web:authority.gov; policy=bridge; caps=v1"

4. Configure:

# config.yaml
identity:
  did: did:web:authority.gov
  priv_key_file: ed25519.pem
trust:
  send_receipts: true
  auto_approve_permits: false  # require explicit permits for inbound from regulated entities

5. Send notices: Use the REST API or the CLI send command. Every notice is automatically signed with did:web:authority.gov.


Full Working Example

# Send notice and poll for receipt
go run ./examples/legal-notice \
  --gateway http://localhost:8080 \
  --api-key $TFEP_API_KEY \
  --to did:web:respondent.example \
  --subject "Notice of Audit — Case 2026-001" \
  --body "You are required to provide documentation within 30 days." \
  --case-number CASE-2026-001 \
  --deadline 2026-08-01 \
  --issuer "Acme Regulatory Authority" \
  --timeout 10m

The program sends the notice and polls every 10 seconds until the delivery receipt arrives or the timeout expires.


Security Considerations

  • Key storage: Use --passphrase with keygen and set TFEP_KEY_PASSPHRASE. The key is AES-256-GCM encrypted at rest.
  • Key compromise: If your signing key is compromised, immediately rotate with ./tfep-gateway rotate-key --domain authority.gov and publish the new DID document. The old key can be marked revoked: true.
  • Receipt forgery: Receipts are signed by the recipient's key. A forged receipt would require compromising the recipient's private key.
  • Timestamp tampering: Timestamps are inside the signed envelope — any alteration breaks the signature.