mirror of
https://git.mills.io/saltyim/saltyim.git
synced 2024-06-30 18:51:03 +00:00
![James Mills](/assets/img/avatar_default.png)
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>
140 lines
4.3 KiB
Markdown
140 lines
4.3 KiB
Markdown
---
|
|
title: Salty.im Blob Storage v1
|
|
description: A proposal for a secure blob store for the reference broker and client for Salty.im
|
|
tags: 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
|
|
|
|
```go
|
|
// 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 |
|
|
| ------------ | ------------- | ------------- | -------- |
|
|
| operators[^1]| blob[^2] | everything[^3]| P1 |
|
|
| other users | blob[^2] | everything[^3]| P1 |
|
|
|
|
[^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.
|
|
|
|
#### 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:
|
|
|
|
- https://salty.yourdomain.tld/shared/:owner/:key
|
|
|
|
Where:
|
|
|
|
- `:owner` is the owner's public key.
|
|
- `:key` is the blob's identifying key (_content-addressing_).
|
|
|
|
### Access Controls
|
|
|
|
> [name=James Mills] TBD |