initial commit

This commit is contained in:
2026-07-13 01:45:37 +02:00
commit ecbb8bba9b
14 changed files with 1685 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
# File Drop Integration Contract
Version: `filedrop.v1`
The File Drop service is backend/API-first. UI code is only an integration example. Host systems discover an active dropbox, encrypt locally to the advertised recipient key, then commit ciphertext and the E2EE envelope to the intake endpoint.
## Discovery
`GET /api/dropbox/current`
Response:
```json
{
"contractVersion": "filedrop.v1",
"dropboxId": "default",
"fingerprint": "recipient-key-fingerprint",
"key": {
"fingerprint": "recipient-key-fingerprint",
"publicKey": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." },
"source": "configured",
"status": "active"
},
"label": "Interling secure intake",
"publicKey": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." },
"source": "configured",
"status": "active",
"recipientKeys": [
{
"fingerprint": "recipient-key-fingerprint",
"publicKey": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." },
"source": "configured",
"status": "active"
},
{
"fingerprint": "master-recovery-fingerprint",
"publicKey": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." },
"source": "configured",
"status": "active"
}
]
}
```
Integrations must show or otherwise pin the recipient `fingerprint` where key authenticity matters.
The `key.status` value is one of `active`, `rotating`, or `revoked`. Upload UIs must not accept new files for revoked keys.
## Upload Commit
`POST /api/uploads/intake`
Content type: `multipart/form-data`
Fields:
- `ciphertext`: encrypted file bytes.
- `envelope`: JSON E2EE envelope from `@addideas/sefidrop/e2ee`.
- `contactName`: sender name.
- `contactEmail`: sender email.
- `dropboxId`: discovery response id.
- `routingLabel`: operational routing label.
- `serviceType`: optional operational service type.
- `languagePair`: optional operational language pair.
- `requestedDeadline`: optional operational date.
- `projectPublicId`: optional existing order id for project-specific drop links.
The original filename, note, MIME type, and other sensitive sender metadata stay in the encrypted E2EE metadata envelope.
New integrations should encrypt to every active `recipientKeys[]` entry and submit an envelope with `recipients[]`. The legacy `recipient` field remains required and mirrors the first recipient wrap for older consumers.
Response:
```json
{
"id": "upload-id",
"orderId": "INTAKE-20260710-XXXXXXXX",
"storageKey": "upload-id.enc",
"status": "ciphertext_received"
}
```
## Event
Each accepted upload emits a `filedrop.upload.received` event. Interling records that event in `project_events`, links the ciphertext row to an order, and exposes it in the portal timeline.
The event payload is intentionally host-neutral:
```json
{
"contractVersion": "filedrop.v1",
"eventType": "filedrop.upload.received",
"occurredAt": "2026-07-10T17:32:07.000Z",
"sender": { "contactEmail": "client@example.com" },
"routing": {
"dropboxId": "default",
"serviceType": "translation",
"languagePair": "DE -> EN"
},
"storage": {
"driver": "local",
"key": "upload-id.enc",
"manifestKey": "upload-id.json"
},
"upload": {
"id": "upload-id",
"ciphertextByteLength": 12345,
"ciphertextSha256": "base64url-sha256",
"recipientKeyFingerprint": "recipient-key-fingerprint",
"recipientKeyFingerprints": ["recipient-key-fingerprint", "master-recovery-fingerprint"]
}
}
```
## Webhook Signature
Future standalone deployments can deliver the same event via webhook instead of direct DB integration.
Signed webhook deliveries use these headers:
- `x-filedrop-webhook-id`: stable id for idempotency.
- `x-filedrop-timestamp`: Unix timestamp in seconds.
- `x-filedrop-signature`: HMAC-SHA256 signature, formatted as `v1=<hex>`.
The signature input is:
```txt
<timestamp>.<raw request body>
```
Receivers should reject old timestamps and verify the signature with a shared webhook secret.
## Storage Boundary
The package exposes a `FileDropStorage` interface. The current Interling host uses the local filesystem adapter; a standalone service can provide S3-compatible storage without changing the upload commit contract.

View File

@@ -0,0 +1,59 @@
# Return File Key Model
File drops and returned deliverables use the same browser-only cryptographic boundary, but they need different recipient discovery.
## Principle
The server stores ciphertext, public keys, key fingerprints, wrapped content keys, routing metadata, and audit events. It must not receive private keys or plaintext file bytes.
Each encrypted file should have one content key and one or more recipient key wraps:
- office intake key for incoming client material;
- assigned contractor key for source files that need contractor access;
- client account key for deliverables returned through the portal;
- master recovery key for operational recovery.
The existing single-recipient envelope remains valid for simple file drops. New envelopes include `recipients[]` while keeping the legacy `recipient` field readable.
## Client Delivery
Client accounts need a recipient key pair before they can receive encrypted deliverables.
Recommended flow:
1. The browser creates or imports a P-256 recipient key pair.
2. The private key stays browser-side and can be downloaded as a JSON key file or pasted/imported later.
3. The public key and fingerprint are registered with the host system.
4. Deliverables are encrypted in the browser to the client public key and the master recovery public key.
5. The client decrypts in the browser by presenting the private key file or pasted private key.
For non-technical clients, the private-key file is the least ambiguous first UX. Passphrase-protected key files can be added later.
## Contractor Access
Contractors should have their own registered public key. When a source file needs contractor access, an authorized office browser decrypts or unwraps the content key and re-encrypts/rewraps it to the contractor key. The server only receives the updated recipient wrap.
Contractor deliverables are uploaded as encrypted ciphertext and recorded as a source-deliverable pair:
- source file id;
- deliverable file id;
- contractor user id;
- delivery status and review timestamps.
## Master Recovery Key
The master recovery key is a public key configured in the host system. Its private key should be kept offline or in a controlled operator keystore, never in the application database.
Every real encrypted file should include a master recipient wrap. Recovery is then possible by importing the master private key in a browser-only operator tool and re-encrypting the content key to a new client or contractor key.
## Host API Shape
A host system should provide:
- recipient key registration for account keys;
- active public-key discovery for client, contractor, office, and master recipients;
- encrypted file upload for source and deliverable purposes;
- recipient wrap update for assignment/recovery workflows;
- encrypted file download with access checks only.
The host remains responsible for orders, users, payment state, permissions, and audit trails. Sefidrop remains responsible for the ciphertext and envelope contract.