6
1
mirror of https://git.mills.io/saltyim/saltyim.git synced 2024-06-28 09:41:02 +00:00
prologic-saltyim/docs/BlogStorage.md
James Mills ddd16c202f Add blob service and support for signing and verifying HTTP requests (#178)
Alternative to #177

The way this works is:

Client:

- Client creates a normal `net/http.Request{}` object using the `Request()` function in `utils.go`. The `http.Request{}` object is then signed using the Client's Ed25519 private key.
- The HTTP Method and Path (_note this is important_) are hashed, as well as the request body (if any) using the FNV128a hashing algorithm.
- This hash is then signed by the Client's's Ed25519 private key.
- The resulting signature is then encoded to Base64 (_standard encoding_) and added to the HTTP headers as a `Signature:` header.
- In addition the Client's Ed25519 public key is added to the HTTP headers as `Signer:`

Server:

- The server calculates the same FNV128a hash of the HTTP Request Method and Path and the body (if any)
- The server decodes the HTTP header `Signature:`
- The server then uses the Client's Ed25519 public key in the HTTP header `Signer:` to verify the signature of the `Signature:` HTTP header which gives us back the original FNV128a hash the Client calculated for the request.
- The server then compares the Client's hash with the expected hash to see if they compare equally.

Co-authored-by: James Mills <1290234+prologic@users.noreply.github.com>
Co-authored-by: Jon Lundy <jon@xuu.cc>
Reviewed-on: https://git.mills.io/saltyim/saltyim/pulls/178
Reviewed-by: xuu <xuu@noreply@mills.io>
2023-01-25 23:05:29 +00:00

4.3 KiB

title description tags
Salty.im Blob Storage v1 A proposal for a secure blob store for the reference broker and client for Salty.im blob, store, saltyim

Salty.im Blob Storage v1

Design proposal for a blob storage v1 design for the reference broker and client https://git.mills.io/saltyim/saltyim

[toc]

API

Types

// Blob defines the type, filename and whether or not a blob is publicly accessible or not.
// A Blob also holds zero r more properties as a map of key/value pairs of string interpreted
// by the client.
type Blob struct {
	Type       string
	Public     bool
	Filename   string
	Properties map[string]string
}

// BlobRequest is the request used by clients to update blob metadata for blobs stored on a broker.
type BlobRequest struct {
	Blob
}

Endpoints

  • PUT /api/v1/blob/:key
    • Stores or updates a blob's contents.
  • POST /api/v1/blob/:key
    • Updates metadata of a blob
  • DELETE /api/v1/blob/:key
    • Deletes a blob
  • HEAD /api/v1/blob/:key
    • Returns metadata of a blob
  • GET /api/v1/blob/:key
    • Returns metadata and the blob's contents

General flow of requests and responses:

  1. All requests are signed by the client using it's private key.
  2. Updates to metadata are performed using a POST requests and a body marshaled to JSON using the NewBlobRequest() object, all other requests either use their raw request body (PUT), headers (HEAD, and GET) or an empty body (DELETE).
  3. Verification of all signed requests are performed to ensure only the owner of the blob(s) can make modifications, delete or otherwise update a blob's metadata or its contents.
  4. All responses are standard HTTP response codes as appropriate to the success or failure of a given request:
    • 200 Ok
    • 201 Created
    • 400 Bad Request
    • 401 Unauthorized
    • 403 Forbidden
    • 404 Not Found
    • 500 Internal Server Error

Storage

Blobs are stored on-disk in a path structure:

/path/to/data/blobs/<owner>/<key>

Where:

  • <owner> is owner's public key.
  • <key> is the key for the blob (computed or specified by the client) and is the content address of the stored blob.

Security

It is up to the client to decide whether or not the stored blob and its contents are encrypted. before submitting it to the blob store service on the broker for storage.

Threat Model

[name=James Mills] Still working on this...

The following list of items are threat we simply do not care about or are considered "out of scope":

  • public key -- This is public knowledge by design, it can be looked up via a user's Salty Address using for example salty-chat lookup <address>.
  • law enforcement / state actor -- We will consider state actors and law enforcement to be out of scope simply because given the resources of powerful actors, if they really wanted to access the contents of a blob, they probably will. However we will make it as hard as we can.
Threat Actor Affected Data Vulnerability Priority
operators1 blob2 everything3 P1
other users blob2 everything3 P1

Threat Actors

  1. another user
  2. broker operator
  3. server operator
  4. network operator
  5. casual eavesdropper
  6. law enforcement
  7. state actor

Affected Data

  1. public key
  2. blob location
  3. blob contents
  4. blob metadata

Vulnerabilities

  1. learn the data
  2. spoof the data
  3. delete the data
  4. prevent owner from reading the data
  5. prevent owner from modifying/deleting the data

Properties

A blob can be accompanied by one or more "Properties" that are stored alongside the blob:

Stored on-disk as a simple .json file along-side the blob as <key>.json

Sharing

If a blob's .Public flag is set to true then the blob is publicly accessible via a shared URL of the form:

Where:

  • :owner is the owner's public key.
  • :key is the blob's identifying key (content-addressing).

Access Controls

[name=James Mills] TBD


  1. all operators, including broker, server and network operators ↩︎

  2. all data about a blob, including its location, its contents and metadata ↩︎

  3. all or most of the data is vulnerable, including spoofing, modifying, deleting and preventing the other from access, modifying or deleting. ↩︎