Skip to content

Update docs for http api #188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
612 changes: 258 additions & 354 deletions docs/http/database.md

Large diffs are not rendered by default.

35 changes: 0 additions & 35 deletions docs/http/energy.md

This file was deleted.

72 changes: 22 additions & 50 deletions docs/http/identity.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,23 @@
# `/identity` HTTP API
# `/v1/identity` HTTP API

The HTTP endpoints in `/identity` allow clients to generate and manage Spacetime public identities and private tokens.
The HTTP endpoints in `/v1/identity` allow clients to generate and manage Spacetime public identities and private tokens.

## At a glance

| Route | Description |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------ |
| [`/identity GET`](#identity-get) | Look up an identity by email. |
| [`/identity POST`](#identity-post) | Generate a new identity and token. |
| [`/identity/websocket_token POST`](#identitywebsocket_token-post) | Generate a short-lived access token for use in untrusted contexts. |
| [`/identity/:identity/set-email POST`](#identityidentityset-email-post) | Set the email for an identity. |
| [`/identity/:identity/databases GET`](#identityidentitydatabases-get) | List databases owned by an identity. |
| [`/identity/:identity/verify GET`](#identityidentityverify-get) | Verify an identity and token. |
| Route | Description |
| -------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| [`POST /v1/identity`](#post-v1identity) | Generate a new identity and token. |
| [`POST /v1/identity/websocket-token`](#post-v1identitywebsocket-token) | Generate a short-lived access token for use in untrusted contexts. |
| [`GET /v1/identity/public-key`](#get-v1identitypublic-key) | Get the public key used for verifying tokens. |
| [`GET /v1/identity/:identity/databases`](#get-v1identityidentitydatabases) | List databases owned by an identity. |
| [`GET /v1/identity/:identity/verify`](#get-v1identityidentityverify) | Verify an identity and token. |

## `/identity GET`

Look up Spacetime identities associated with an email.

Accessible through the CLI as `spacetime identity find <email>`.

#### Query Parameters

| Name | Value |
| ------- | ------------------------------- |
| `email` | An email address to search for. |

#### Returns

Returns JSON in the form:

```typescript
{
"identities": [
{
"identity": string,
"email": string
}
]
}
```

The `identities` value is an array of zero or more objects, each of which has an `identity` and an `email`. Each `email` will be the same as the email passed as a query parameter.

## `/identity POST`
## `POST /v1/identity`

Create a new identity.

Accessible through the CLI as `spacetime identity new`.

#### Query Parameters

| Name | Value |
| ------- | ----------------------------------------------------------------------------------------------------------------------- |
| `email` | An email address to associate with the new identity. If unsupplied, the new identity will not have an associated email. |

#### Returns

Returns JSON in the form:
Expand All @@ -65,7 +29,7 @@ Returns JSON in the form:
}
```

## `/identity/websocket_token POST`
## `POST /v1/identity/websocket-token`

Generate a short-lived access token which can be used in untrusted contexts, e.g. embedded in URLs.

Expand All @@ -87,7 +51,15 @@ Returns JSON in the form:

The `token` value is a short-lived [JSON Web Token](https://datatracker.ietf.org/doc/html/rfc7519).

## `/identity/:identity/set-email POST`
## `GET /v1/identity/public-key`

Fetches the public key used by the database to verify tokens.

#### Returns

Returns a response of content-type `application/pem-certificate-chain`.

## `POST /v1/identity/:identity/set-email`

Associate an email with a Spacetime identity.

Expand All @@ -111,7 +83,7 @@ Accessible through the CLI as `spacetime identity set-email <identity> <email>`.
| --------------- | --------------------------------------------------------------- |
| `Authorization` | A Spacetime token [encoded as Basic authorization](/docs/http). |

## `/identity/:identity/databases GET`
## `GET /v1/identity/:identity/databases`

List all databases owned by an identity.

Expand All @@ -133,7 +105,7 @@ Returns JSON in the form:

The `addresses` value is an array of zero or more strings, each of which is the address of a database owned by the identity passed as a parameter.

## `/identity/:identity/verify GET`
## `GET /v1/identity/:identity/verify`

Verify the validity of an identity/token pair.

Expand Down
37 changes: 11 additions & 26 deletions docs/http/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,22 @@ Rather than a password, each Spacetime identity is associated with a private tok

### Generating identities and tokens

Clients can request a new identity and token via [the `/identity POST` HTTP endpoint](/docs/http/identity#identity-post).
SpacetimeDB can derive an identity from the `sub` and `iss` claims of any [OpenID Connect](https://openid.net/developers/how-connect-works/) compliant [JSON Web Token](https://jwt.io/).

Alternately, a new identity and token will be generated during an anonymous connection via the WebSocket API, and passed to the client as an `IdentityToken` message.

### Encoding `Authorization` headers
Clients can request a new identity and token signed by the SpacetimeDB host via [the `POST /v1/identity` HTTP endpoint](/docs/http/identity#post-v1identity). Such a token will not be portable to other SpacetimeDB clusters.

Many SpacetimeDB HTTP endpoints either require or optionally accept a token in the `Authorization` header. SpacetimeDB authorization headers use `Basic` authorization with the username `token` and the token as the password. Because Spacetime tokens are not passwords, and SpacetimeDB Cloud uses TLS, usual security concerns about HTTP `Basic` authorization do not apply.
Alternately, a new identity and token will be generated during an anonymous connection via the WebSocket API, and passed to the client as an `IdentityToken` message.

To construct an appropriate `Authorization` header value for a `token`:
### `Authorization` headers

1. Prepend the string `token:`.
2. Base64-encode.
3. Prepend the string `Basic `.
Many SpacetimeDB HTTP endpoints either require or optionally accept a token in the `Authorization` header. SpacetimeDB authorization headers are of the form `Authorization: Bearer ${token}`, where `token` is an [OpenID Connect](https://openid.net/developers/how-connect-works/) compliant [JSON Web Token](https://jwt.io/), such as the one returned from [the `POST /v1/identity` HTTP endpoint](/docs/http/identity#post-v1identity).

#### Rust
# Top level routes

```rust
fn auth_header_value(token: &str) -> String {
let username_and_password = format!("token:{}", token);
let base64_encoded = base64::prelude::BASE64_STANDARD.encode(username_and_password);
format!("Basic {}", encoded)
}
```
| Route | Description |
| ----------------------------- | ------------------------------------------------------ |
| [`GET /v1/ping`](#get-v1ping) | No-op. Used to determine whether a client can connect. |

#### C#
## `GET /v1/ping`

```csharp
public string AuthHeaderValue(string token)
{
var username_and_password = Encoding.UTF8.GetBytes($"token:{auth}");
var base64_encoded = Convert.ToBase64String(username_and_password);
return "Basic " + base64_encoded;
}
```
Does nothing and returns no data. Clients can send requests to this endpoint to determine whether they are able to connect to SpacetimeDB.
1 change: 0 additions & 1 deletion docs/nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ const nav = {
page('HTTP', 'http', 'http/index.md'),
page('`/identity`', 'http/identity', 'http/identity.md'),
page('`/database`', 'http/database', 'http/database.md'),
page('`/energy`', 'http/energy', 'http/energy.md'),
section('Data Format'),
page('SATS-JSON', 'sats-json', 'sats-json.md'),
page('BSATN', 'bsatn', 'bsatn.md'),
Expand Down
2 changes: 1 addition & 1 deletion docs/sats-json.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,4 @@ SATS array and map types are homogeneous, meaning that each array has a single e

### `AlgebraicTypeRef`

`AlgebraicTypeRef`s are JSON-encoded as non-negative integers. These are indices into a typespace, like the one returned by the [`/database/schema/:name_or_address GET` HTTP endpoint](/docs/http/database#databaseschemaname_or_address-get).
`AlgebraicTypeRef`s are JSON-encoded as non-negative integers. These are indices into a typespace, like the one returned by the [`GET /v1/database/:name_or_identity/schema` HTTP endpoint](/docs/http/database#get-v1databasename_or_identityschema).
1 change: 0 additions & 1 deletion nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ const nav: Nav = {
page('HTTP', 'http', 'http/index.md'),
page('`/identity`', 'http/identity', 'http/identity.md'),
page('`/database`', 'http/database', 'http/database.md'),
page('`/energy`', 'http/energy', 'http/energy.md'),

section('Data Format'),
page('SATS-JSON', 'sats-json', 'sats-json.md'),
Expand Down