Skip to content

Create a Signing key

POST
/v1/namespaces/{namespace}/keys
curl --request POST \
--url https://app.caprid.com/v1/namespaces/acme/keys \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "label": "backend" }'

Creates an Organization signing key in this Namespace and returns it as a JWK, secret included. Keep the secret in your backend to sign Client tokens there without calling Switchboard.

The key’s scope is fixed when you create it and can’t be widened later. By default, a key covers your whole Namespace for both publishing and subscribing. Use path to root it lower down, and publish or subscribe to limit what the tokens it signs may grant. If you send only one of publish and subscribe, the key can’t sign tokens for the other role.

Relays look keys up by kid through Switchboard, never from the Client, so a relay accepts a token signed with this key only within its scope.

namespace
required

A Namespace’s name, which is the root of every path signed for it. It never changes. Use lowercase letters, digits and hyphens, and start and end with a letter or digit. Some names, like admin and default, are reserved, and so is every name that starts with trial-, which only Trial Organizations get.

string
>= 3 characters <= 32 characters /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/

Example

acme
Media typeapplication/json
object
label

Becomes part of the kid, which is <namespace>_<label>. Labels are unique within a Namespace. Defaults to a random 12-character hex string.

string
/^[A-Za-z0-9_-]{1,64}$/
path

A path relative to your Namespace, like room/42. Leading, trailing and repeated slashes are ignored. Segments can’t be . or .., or contain whitespace or control characters.

string
""
publish
One of:
string
subscribe
One of:
string

Examples

A key for the whole Namespace

{
"label": "backend"
}

The new key, secret included.

Media typeapplication/json

A Signing key in JSON Web Key form, with the scope extension moq relays understand. k is the secret. Anyone holding it can sign tokens within the scope.

object
alg
required
string
Allowed value: HS256
key_ops
required
Array<string>
kty
required
string
Allowed value: oct
k
required

The HMAC secret, base64url without padding.

string
kid
required
string
scope
required

What a Signing key may sign. put is publish and get is subscribe, as in the token claims. Both are relative to root.

object
root
string
put
Array<string>
get
Array<string>

Example

{
"alg": "HS256",
"key_ops": [
"sign",
"verify"
],
"kty": "oct",
"kid": "acme_backend",
"scope": {
"root": "acme"
}
}

The request is malformed or a field is invalid. The message says which.

Media typeapplication/json
object
error
required
string

Example

{
"error": "the requested grants exceed the key's scope"
}

No valid credential. Missing, expired and revoked credentials all get the same response, and so does an API key whose trial has lapsed. An Agent token from before a claim gets a 401 too, once the claim has made the trial a person’s, with a message saying to get a new token.

Media typeapplication/json
object
error
required
string

Example

{
"error": "the requested grants exceed the key's scope"
}
WWW-Authenticate
string
Example
Bearer realm="switchboard"

Sent with an API key limited to some Namespaces, to a Namespace outside its limit, or to a route that acts on the Organization as a whole. A limited key can never create API keys.

Media typeapplication/json
object
error
required
string

Example

{
"error": "this API key is limited to the Namespaces acme-staging, and acme isn't one of them"
}

No such thing, or not yours. Another customer’s Organization or Namespace is a 404 too, so nobody can tell which ones exist.

Media typeapplication/json
object
error
required
string

Example

{
"error": "the requested grants exceed the key's scope"
}

The Namespace already has a key with this label.

Media typeapplication/json
object
error
required
string

Example

{
"error": "the requested grants exceed the key's scope"
}