storage-p

API-Dokumentation

Dieselbe REST-API, auf der auch der Web-Client läuft. Jeder Eintrag wird in deinem Browser verschlüsselt, bevor er das Gerät verlässt — der Server sieht nur Chiffretext und kann ihn nicht lesen. Nutze sie, um eigene Clients zu bauen oder einer Integration begrenzten, bestätigbaren Zugriff auf einige wenige Einträge zu geben. Basis-URL: https://storage-p.com

OpenAPI-Spezifikation (maschinenlesbar, für Integrationen) /openapi.yaml

Anleitungen

Durchgängige Schritt-für-Schritt-Anleitungen zu dem, was storage-p tatsächlich kann — basierend auf dem realen Funktionsumfang, nichts erfunden.

Auf dem eigenen Server selbst hosten

Betreibe storage-p als Docker-Container hinter Caddy auf deiner Domain. Caddy liefert den statischen Client aus und leitet /api per Reverse-Proxy ans Backend; die SQLite-Datenbank ist im Ruhezustand mit SQLCipher verschlüsselt. Du betreibst alles selbst — niemand sonst hält die Schlüssel.

SSH-/TLS-Schlüssel speichern und erzeugen

Erzeuge Ed25519-SSH-Schlüssel (OpenSSH-Format) und selbstsignierte TLS-Zertifikate im Tab Generatoren oder lade vorhandene Schlüssel-/Zertifikatdateien hoch (bis 1 MB). Das private Material wird vor dem Upload im Browser verschlüsselt, sodass es nie im Klartext auf dem Server existiert.

Einmal-Links nach dem Burn-after-Read-Prinzip

Teile einen einzelnen Eintrag oder einen ganzen Ordner über einen Link, dessen Entschlüsselungs-Schlüssel nur im URL-Fragment (#…) lebt — dem Teil, den Browser nie an den Server senden. Setze eine TTL und ein Aufruflimit; nach dem letzten Aufruf lassen sich die Daten nicht mehr öffnen.

Begrenzte API-Tokens mit Bestätigung

Erstelle einen Token, der nur die von dir freigegebenen Einträge oder Projekte lesen darf. Aktiviere die Bestätigung pro Lesezugriff und jeder Zugriff pausiert, bis du ihn über die Glocke in der App oder eine Telegram-Nachricht freigibst; ergänze ein Rate-Limit und ein Ablaufdatum. Die Integration erhält den noch verschlüsselten Eintrag plus einen Einmal-Zugriffsschlüssel, um ihn lokal zu entschlüsseln.

Projekte und Team-Zugriff

Mach aus einem Ordner ein Projekt mit eigenem Schlüssel. Gib einem anderen Nutzer Lese- oder Schreibzugriff, und der Projektschlüssel wird für dessen öffentlichen Schlüssel (X25519) versiegelt, sodass er mit den aktuellen Einträgen arbeitet, ohne dass der Server je eine lesbare Kopie sieht. Widerrufe jede Freigabe jederzeit.

Eingebautes TOTP / 2FA

Speichere das TOTP-Secret eines Logins direkt daneben und lies den live rotierenden Code an derselben Stelle — storage-p ist zugleich dein Authenticator. Du kannst auch dein eigenes Konto mit TOTP-Zwei-Faktor schützen.

Aus einem anderen Manager importieren

Bring einen Bitwarden-JSON, eine KeePass-CSV oder jede CSV mit den Spalten name/username/password/url/notes mit. Parsing und Verschlüsselung laufen auf deinem Gerät, sodass Einträge unter deinem Schlüssel neu verschlüsselt und nie im Klartext hochgeladen werden.

API-Dokumentation · API

Authentifizierung

Hol dir per register/login einen Access-Token und sende ihn als Bearer-Token. Access-Tokens sind kurzlebig (15 Min.); erneuere sie mit dem Refresh-Token.

Authorization: Bearer <access_token>

Auth

Registrieren, anmelden und die Sitzung am Leben halten. Das Master-Passwort verlässt den Browser nie — gesendet wird nur ein Argon2id-Auth-Hash.

POST /api/v1/auth/register
Ein Konto erstellen. Der Client wählt die KDF-Parameter und lädt seinen bereits verschlüsselten privaten Schlüssel hoch.
Body{ email, master_password, kdf_salt_b64, kdf_memory_kib, kdf_iters, kdf_parallelism, pubkey_b64, privkey_enc_b64 }
Antwort{ access_token, refresh_token, user_id, kdf_* }
POST /api/v1/auth/login
Anmelden. Liefert die Tokens plus den KDF-Salt, den der Client zum Ableiten des Tresor-Schlüssels braucht.
Body{ email, master_password, totp_code? }
Antwort{ access_token, refresh_token, user_id, kdf_*, totp_required }
POST /api/v1/auth/refresh
Einen Refresh-Token gegen einen frischen, kurzlebigen Access-Token tauschen.
Body{ refresh_token }
Antwort{ access_token, refresh_token }
POST /api/v1/auth/logout Bearer
Den aktuellen Refresh-Token widerrufen.
Antwort{ ok }
POST /api/v1/auth/totp/setup Bearer
TOTP-Zwei-Faktor für das Konto aktivieren.
Body{ secret_b32, current_code }
Antwort{ ok }

Vault

CRUD über deine Einträge. Alles geht bereits verschlüsselt rein und raus; der Server speichert und liefert nur Chiffretext.

GET /api/v1/vault Bearer
Alle Einträge (Chiffretext) in deinem Tresor auflisten.
Antwort[ { id, meta_enc_b64, body_enc_b64, version, created_at, updated_at } ]
POST /api/v1/vault Bearer
Einen Eintrag hinzufügen. meta/body sind vor dem Upload bereits clientseitig verschlüsselt.
Body{ meta_enc_b64, body_enc_b64, blind_index_b64? }
Antwort{ id, ... }
GET /api/v1/vault/:id Bearer
Einen einzelnen Eintrag per id abrufen.
PUT /api/v1/vault/:id Bearer
Einen Eintrag aktualisieren; expected_version schützt davor, eine neuere Änderung zu überschreiben.
Body{ meta_enc_b64?, body_enc_b64?, expected_version }
DELETE /api/v1/vault/:id Bearer
Einen Eintrag in den Papierkorb verschieben (Soft-Delete, umkehrbar).
GET /api/v1/vault/trash Bearer
Die aktuell im Papierkorb liegenden Einträge auflisten.
POST /api/v1/vault/:id/restore Bearer
Einen Eintrag aus dem Papierkorb wiederherstellen.
DELETE /api/v1/vault/:id/purge Bearer
Einen Eintrag endgültig löschen — nicht rückgängig zu machen.

Sharing

Zwei Wege, jemandem ein Secret zu übergeben: ein Einmal-Link nach dem Burn-after-Read-Prinzip oder eine Ende-zu-Ende-Zustellung per sealed-box an einen anderen Nutzer.

POST /api/v1/share Bearer
Einen Einmal-Link erstellen. Der Entschlüsselungs-Schlüssel lebt im URL-Fragment und erreicht den Server nie.
Body{ payload_b64, nonce_b64, ttl_secs, max_views }
Antwort{ id, expires_at }
GET /api/v1/share/:id
Einen Einmal-Link öffnen. Verfällt nach der erlaubten Anzahl an Aufrufen.
Antwort{ payload_b64, nonce_b64 }
GET /api/v1/users/lookup?email= Bearer
Den öffentlichen Schlüssel eines Nutzers per E-Mail finden, um Ende-zu-Ende mit ihm zu teilen.
Antwort{ user_id, pubkey_b64 }
POST /api/v1/shares/user Bearer
Einen Eintrag an einen anderen Nutzer senden, versiegelt für dessen öffentlichen Schlüssel — nur er kann ihn öffnen.
Body{ to_email, payload_b64 }
GET /api/v1/shares/incoming Bearer
Die Einträge auflisten, die andere Nutzer mit dir geteilt haben.
DELETE /api/v1/shares/:id Bearer
Eine eingehende oder ausgehende Freigabe entfernen.

Tokens & confirmations

Begrenzte Tokens lassen eine Integration ausgewählte Einträge lesen, optional abgesichert durch deine Bestätigung in der App oder per Telegram.

GET /api/v1/tokens Bearer
Deine API-Tokens auflisten.
POST /api/v1/tokens Bearer
Einen begrenzten Token für eine Integration erstellen — wähle, welche Einträge er lesen darf und ob jeder Lesezugriff eine Bestätigung braucht.
Body{ name, item_ids[], require_confirmation, rate_limit_per_hour, ttl_secs }
Antwort{ id, token, expires_at }
DELETE /api/v1/tokens/:id Bearer
Einen Token sofort widerrufen.
GET /api/v1/confirmations/pending Bearer
Zugriffsanfragen auflisten, die auf deine Freigabe warten.
POST /api/v1/confirmations/:id/resolve Bearer
Eine offene Anfrage genehmigen oder ablehnen.
Body{ decision: "approve"|"deny" }
GET /api/v1/api/vault/:id Bearer (scoped token)
Wie eine Integration einen begrenzten Eintrag liest. Ist eine Bestätigung nötig, liefert der erste Aufruf eine confirmation_id zum Abfragen, bis du freigibst.

Begrenzte API-Tokens (für Integrationen)

Erstelle einen begrenzten Token in der UI (API-Tokens). Er kann nur freigegebene Einträge lesen, und Lesezugriffe können eine Bestätigung erfordern. Ablauf: Der erste GET liefert eine confirmation_id mit Status pending_confirmation; der Eigentümer bestätigt in der App oder per Telegram; wiederhole den GET mit ?confirmation_id=, um den (weiterhin clientseitig verschlüsselten) Eintrag zu erhalten.

Hinweise

meta_enc / body_enc sind nonce(24)‖ciphertext, verschlüsselt mit dem aus dem Master-Passwort abgeleiteten Tresor-Schlüssel. Der Server kann sie nicht entschlüsseln.