Skip to the content.

Back to main page

User guide

This page contains detailed end-user documentation. It describes how to use the manager.py script to start and stop topologies and to generate keys.

For an overview of what Distributed Symmetric Key Establishment (DSKE) is and what problem it solves see the introduction.

If you just want hands-on instructions on how to get started running the code and generating keys with a minimum of background information see the getting started guide.

For a detailed description of the DSKE protocol, see the protocol guide.

If you are a software developer and would like more details about the implementation, see the developer guide.

Configuration file

We first need a configuration YAML file which describes the topology of the network. It lists the names of the DSKE security hubs (hubs for short), the DSKE clients (clients for short), and the encryptors. .

The repository contains an example dske-config.yaml file, which is the default configuration. The comments in this file explain all the configurable attributes in the configuration file.

$ cat dske-config.yaml
# Configuration file for DSKE topology.

# base_port: 8100       # Base TCP port for the DSKE topology.
                        # The first hub uses TCP port base_port.
                        # The second hub uses TCP port base_port + 1, and so on.
                        # The first client uses TCP port base_port + N, etc.
                        # (where N is the number of hubs).
                        # Optional; default value is 8100.

# start_request_psrd_threshold: 500     # Threshold for starting PSRD requests.
                                        # If the pool size drops below this threshold, start
                                        # sending PSRD requests to replenish the pool.
                                        # Optional; default value is 500.

# stop_request_psrd_threshold: 2000     # Threshold for stopping PSRD requests.
                                        # If the pool size exceeds this threshold, stop
                                        # sending PSRD requests.
                                        # Optional; default value is 2000.

# get_psrd_block_size: 1000             # Block size for PSRD requests.
                                        # Optional; default value is 1000.

# min_nr_shares: 3                      # Minimum number of shares needed to reconstruct a key
                                        # from the key shares using Shamir's Secret Sharing (SSS).
                                        # Optional; default value is 3.

# share_timeout_secs: 60                # Timeout for shares in seconds. Shares stored on hubs are
                                        # deleted if the responder SAE does not retrieve them by
                                        # invoking the Get key with key IDs API call within this
                                        # timeout.
                                        # Optional; default value is 60 seconds.
                                        
hubs:                   # List of hubs (aka DSKE security hubs) in the DSKE topology.
  - name: hank          # Name of the hub.
  - name: helen
  - name: hilary
  - name: holly
  - name: hugo

clients:                # List of client (aka DSKE clients) in the DSKE topology.`
  - name: carol         # Name of the client node.
    encryptors:         # List of encryptors (aka Secure Application Entity SAE) directly connected to this client (carol).
      - name: sam       # Name of the encryptor.
  - name: celia
    encryptors:
      - name: serena
  - name: cindy         # A client with zero directly connected encryptors.
  - name: connie
    encryptors:
      - name: sofia
  - name: curtis
    encryptors:         # A client with more than one (namely two) directly connected encryptors.
      - name: sunny
      - name: susan

The topology manager

The script manager.py is used to:

Use the --help option to see the command line parameters:

$ ./manager.py --help
usage: manager.py [-h] [--config CONFIG_FILE] [--client CLIENT] [--hub HUB] {start,stop,status,etsi-qkd} ...

DSKE Manager

positional arguments:
  {start,stop,status,etsi-qkd}
    start               Start all hubs and clients
    stop                Stop all hubs and clients
    status              Report status for all hubs and clients
    etsi-qkd            ETSI QKD operations

options:
  -h, --help            show this help message and exit
  --config CONFIG_FILE  Configuration file name (default: dske-config.yaml)
  --client CLIENT       Filter on client name
  --hub HUB             Filter on hub name

Start the topology

To start all nodes in the DSKE topology, use the manager start command:

$ ./manager.py start
Waiting for all nodes to be stopped
Starting hub hank on port 8100
Starting hub helen on port 8101
Starting hub hilary on port 8102
Starting hub holly on port 8103
Starting hub hugo on port 8104
Starting client carol on port 8105
Starting client celia on port 8106
Starting client cindy on port 8107
Starting client connie on port 8108
Starting client curtis on port 8109
Waiting for all nodes to be started

The output reports that 10 nodes are started in total: 5 hub nodes (hank, helen, hilary, holly, and hugo) and 5 client nodes (carol, celia, cindy, connie, and curtis).

The reported port numbers (8100, 8101, etc.) are the TCP port numbers for the REST interface of each node.

Stop the topology

To stop all nodes in the topology, use the manager stop command:

$ ./manager.py stop
Stopping client curtis on port 8109
Stopping client connie on port 8108
Stopping client cindy on port 8107
Stopping client celia on port 8106
Stopping client carol on port 8105
Stopping hub hugo on port 8104
Stopping hub holly on port 8103
Stopping hub hilary on port 8102
Stopping hub helen on port 8101
Stopping hub hank on port 8100
Waiting for all nodes to be stopped

One background process per node

Starting a topology spawns one Python background process for each node. You can see these processes using ps command:

 $ ps | grep Python
42176 ttys000    0:01.28 Python -m hub hank --port 8100
42177 ttys000    0:01.27 Python -m hub helen --port 8101
42178 ttys000    0:01.27 Python -m hub hilary --port 8102
42179 ttys000    0:01.26 Python -m hub holly --port 8103
42180 ttys000    0:01.26 Python -m hub hugo --port 8104
42181 ttys000    0:01.67 Python -m client carol --port 8105 --encryptors sam --hubs http://127.0.0.1:8100/hub/hank http://127.0.0.1:8101/hub/helen http://127.0.0.1:8102/hub/hilary http://127.0.0.1:8103/hub/holly http://127.0.0.1:8104/hub/hugo
42182 ttys000    0:01.65 Python -m client celia --port 8106 --encryptors serena --hubs http://127.0.0.1:8100/hub/hank http://127.0.0.1:8101/hub/helen http://127.0.0.1:8102/hub/hilary http://127.0.0.1:8103/hub/holly http://127.0.0.1:8104/hub/hugo
42183 ttys000    0:01.65 Python -m client cindy --port 8107 --hubs http://127.0.0.1:8100/hub/hank http://127.0.0.1:8101/hub/helen http://127.0.0.1:8102/hub/hilary http://127.0.0.1:8103/hub/holly http://127.0.0.1:8104/hub/hugo
42184 ttys000    0:01.65 Python -m client connie --port 8108 --encryptors sofia --hubs http://127.0.0.1:8100/hub/hank http://127.0.0.1:8101/hub/helen http://127.0.0.1:8102/hub/hilary http://127.0.0.1:8103/hub/holly http://127.0.0.1:8104/hub/hugo
42185 ttys000    0:01.64 Python -m client curtis --port 8109 --encryptors sunny susan --hubs http://127.0.0.1:8100/hub/hank http://127.0.0.1:8101/hub/helen http://127.0.0.1:8102/hub/hilary http://127.0.0.1:8103/hub/holly http://127.0.0.1:8104/hub/hugo
...

Waiting for nodes to be started

It takes some time for each background process to startup and to get to the point that the process is ready to accept and process incoming requests over its REST interfaces. If we try to invoke any REST API before the node is fully started, we will get an error. This is why the start command explicitly waits for all nodes to be started (it reports Waiting for all nodes to be started at the end):

$ ./manager.py start
Waiting for all nodes to be stopped
Starting hub hank on port 8100
...
Starting client curtis on port 8109
Waiting for all nodes to be started

Waiting for nodes to be stopped

Similarly, it takes some time for each background process to completely stop and get to the point that the TCP port number can be used again for restarting a node on the same TCP port again. Even if the background process is completely stopped, the TCP port number can get stuck in state TIME_WAIT and it can take the operating system up to 60 seconds to release the TCP port. This is why the start command explicitly waits for all needed TCP ports to be available (it reports Waiting for all nodes to be stopped at the beginning).

$ ./manager.py start
Waiting for all nodes to be stopped
Starting hub hank on port 8100
...
Starting client curtis on port 8109
Waiting for all nodes to be started

If it takes longer than expected for a node to stop and for the TCP port to become available again (i.e. to exist from state TIME_WAIT) the stop command will periodically report that it is still waiting (this should not take longer than 60 seconds):

$ ./manager.py stop
Stopping client curtis on port 8109
...
Stopping hub hank on port 8100
Waiting for all nodes to be stopped
Still waiting for client connie to be stopped
Still waiting for client connie to be stopped
Still waiting for client connie to be stopped

The --client and --hub command line options

The manager command line option --client CLIENT can be used to apply a command to a single client node. For example, to start one individual client carol:

$ ./manager.py --client carol start
Waiting for client carol to be stopped
Starting client carol on port 8105
Waiting for client carol to be started

Similarly, the manager command line option --hub HUB can be used to apply a command to a single hub node. For example, to stop one individual hub hugo:

$ ./manager.py --hub hugo stop
Stopping hub hugo on port 8104
Waiting for hub hugo to be stopped

You can use the --client and --hub command line options multiple times. For example:

$ ./manager.py --client carol --client corrie --hub hank start
Waiting for client carol, client corrie, hub hank to be stopped
Starting hub hank on port 8100
Starting client carol on port 8105
Waiting for client carol, client corrie, hub hank to be started

Starting and stopping nodes directly

Behind the scenes, the manager.py script spawns a separate Python process each client node and for each hub node. If you so desire, you can also start these Python processes manually.

The Python module client implements the client node process. Use the --help option to see its usage:

$ python -m client --help
usage: client [-h] [--port PORT] [--start-request-psrd_threshold START_REQUEST_PSRD_THRESHOLD] [--stop-request-psrd-threshold STOP_REQUEST_PSRD_THRESHOLD]
              [--get-psrd-block-size GET_PSRD_BLOCK_SIZE] [--min-nr-shares MIN_NR_SHARES] [--hubs HUBS [HUBS ...]] [--encryptors ENCRYPTORS [ENCRYPTORS ...]]
              name

DSKE Client

positional arguments:
  name                  Client name

options:
  -h, --help            show this help message and exit
  --port PORT           Port number
  --start-request-psrd_threshold START_REQUEST_PSRD_THRESHOLD
                        Start request PSRD threshold (default: 500)
  --stop-request-psrd-threshold STOP_REQUEST_PSRD_THRESHOLD
                        Stop request PSRD threshold (default: 2000)
  --get-psrd-block-size GET_PSRD_BLOCK_SIZE
                        Request PSRD block size (default: 2000)
  --min-nr-shares MIN_NR_SHARES
                        Minimum number of shares (default: 3)
  --hubs HUBS [HUBS ...]
                        Base URLs for hubs (e.g., http://127.0.0.1:8100)
  --encryptors ENCRYPTORS [ENCRYPTORS ...]
                        Names (SAE IDs) of encryptors consuming keys from this client (KME).

The typical usage is to provide the client name, the port number, a list of base URLs for the hubs in the network, and a list of encryptors attached to the client: For example:

$ python -m client carol --port 8105 --hubs http://127.0.0.1:8100/hub/hank http://127.0.0.1:8101/hub/helen http://127.0.0.1:8102/hub/hilary http://127.0.0.1:8103/hub/holly http://127.0.0.1:8104/hub/hugo --encryptors sam

Similarly, the Python module hub implements the client node process. Use the --help option to see its usage:

$ python -m hub --help
usage: hub [-h] [-p PORT] [--share-timeout-secs SHARE_TIMEOUT_SECS] name

DSKE Hub

positional arguments:
  name                  Hub name

options:
  -h, --help            show this help message and exit
  -p, --port PORT       Port number
  --share-timeout-secs SHARE_TIMEOUT_SECS
                        Share timeout in seconds (default: 60)

The typical usage is to provide the hub name and the port number.

$ python -m hub helen --port 8101

As you can see, manually starting clients and hubs involves typing long error-prone commands and requires some book-keeping about which node uses which TCP port number. This is why the manager.py script exists; it collects all the necessary information from the topology file and starts all the nodes with the correct (long) command-line arguments.

ETSI QKD 014 Get key

Use the manager get-key sub-command under the etsi-qkd command to invoke the ETSI QKD 014 “Get Key” API to retrieve a key for a pair of SAEs on the master SAE.

The get-key sub-command has the following command-line options:

$ ./manager.py etsi-qkd sam sunny get-key --help
usage: manager.py configfile etsi-qkd master_sae_id slave_sae_id get-key [-h] [--size SIZE]

options:
  -h, --help   show this help message and exit
  --size SIZE  Key size in bits

In the following example we invoke the Get Key API for the QKD link between master SAE Sam and slave SAE Serena:

 $ ./manager.py etsi-qkd sam serena get-key
Invoke ETSI QKD Get Key API on client (KME) carol port 8105 master encryptor (SAE) sam slave encryptor (SAE) serena:
{
  "keys": {
    "key_ID": "f1f2cf55-9569-4e8f-8805-f80c8f600d48",
    "key": "+bXUKbPwVSdpS23JXGLSRA=="
  }
}

The master / slave terminology comes from ETSI QKD 014 version 1 and will be revised in version 2.

ETSI QKD 014 Get key with key IDs

Use the manager get-key-with-key-ids sub-command under the etsi-qkd command to invoke the ETSI QKD 014 “Get Key” API to retrieve a key for a pair of SAEs on the slave SAE.

The get-key sub-command has the following command-line options:

$ ./manager.py etsi-qkd sam serena get-key-with-key-ids --help
usage: manager.py configfile etsi-qkd master_sae_id slave_sae_id get-key-with-key-ids [-h] key_id

positional arguments:
  key_id      Key ID

options:
  -h, --help  show this help message and exit

In the following example we invoke the Get Key with Key IDs API for the QKD link between master SAE Sam and slave SAE Serena, where the Key ID is d6a116f1-104e-4213-8cf1-0557cf33cb29 (this is the Key ID returned by the Get Key API call above):

$ ./manager.py etsi-qkd sam serena get-key-with-key-ids 6a116f1-104e-4213-8cf1-0557cf33cb29
Invoke ETSI QKD Get Key with Key IDs API on client (KME) celia port 8106 master encryptor (SAE) sam slave encryptor (SAE) serena:
{
  "keys": [
    {
      "key_ID": "f1f2cf55-9569-4e8f-8805-f80c8f600d48",
      "key": "+bXUKbPwVSdpS23JXGLSRA=="
    }
  ]
}

ETSI QKD 014 Get key pair

As a matter of convenience, there is also a get-key-pair sub-command to combine both the “Get key” and the “Get key with key IDs” calls.

The get-key-pair sub-command has the following command-line options:

$ ./manager.py etsi-qkd carol curtis get-key-pair --help
usage: manager.py configfile etsi-qkd master_sae_id slave_sae_id get-key-pair [-h] [--size SIZE]

options:
  -h, --help   show this help message and exit
  --size SIZE  Key size in bits

In the following example, we ask for a key pair between master SAE Sam and slave SAE Sunny:

$ ./manager.py etsi-qkd sam sunny get-key-pair
Invoke ETSI QKD Get Key API on client (KME) carol port 8105 master encryptor (SAE) sam slave encryptor (SAE) sunny:
{
  "keys": {
    "key_ID": "4b700076-9691-4935-9e9b-707c1425fd29",
    "key": "JmaqM91DsWC/qlawABoVOw=="
  }
}
Invoke ETSI QKD Get Key with Key IDs API on client (KME) curtis port 8109 master encryptor (SAE) sam slave encryptor (SAE) sunny:
{
  "keys": [
    {
      "key_ID": "4b700076-9691-4935-9e9b-707c1425fd29",
      "key": "JmaqM91DsWC/qlawABoVOw=="
    }
  ]
}
Key values match

And, finally, there is a status subcommand to invoke the “Status” ETSI QKD 014 API:

$ ./manager.py etsi-qkd sam sunny get-status
Invoke ETSI QKD Status API on client (KME) carol port 8105 master encryptor (SAE) sam slave encryptor (SAE) sunny:
{
  "source_kme_id": "carol",
  "target_kme_id": "",
  "master_sae_id": "sam",
  "slave_sae_id": "sunny",
  "key_size": 128,
  "stored_key_count": 100,
  "max_key_count": 1000,
  "max_key_per_request": 1,
  "max_key_size": 16777216,
  "min_key_size": 32,
  "max_sae_id_count": 0
}

Report the topology status

Use the manager status command (not to be confused with the etsi-qkd status command) to report the status of each node in the topology:

$ ./manager.py status
Status for hub hank on port 8100
{
  "name": "hank",
  "peer_clients": [
    {
      "client_name": "carol",
      "local_pool": {
        "blocks": [
          {
            "uuid": "4cb97ab1-0e3f-4f48-a0d7-90de58e85d53",
            "size": 2000,
            "data": "AAAAAAAAAAAAAA==...",
            "nr_used_bytes": 32,
            "nr_unused_bytes": 1968
          }
        ],
        "owner": "local"
      },
      "peer_pool": {
        "blocks": [
          {
            "uuid": "c142de3a-8464-440f-bbfd-78937481732a",
            "size": 2000,
            "data": "AAAAAAAAAAAAAA==...",
            "nr_used_bytes": 48,
            "nr_unused_bytes": 1952
          }
        ],
        "owner": "peer"
      }
    },
    ... snip ...
  ]
}

You can also use the --client or --hub command-line option to only report the status of a single client or hub node, for example:

$ ./manager.py --client celia status
Status for hub hank on port 8100
{
  "name": "hank",
  "peer_clients": [
    {
      "client_name": "carol",
      "encryptor_names": [
        "sam"
      ],
      "local_pool": {
        "blocks": [
          {
            "uuid": "192c0144-ffec-4f95-9a9f-7d7a82310be7",
            "size": 2000,
            "data": "AAAAAAAAAAAAAA==...",
            "nr_used_bytes": 192,
            "nr_unused_bytes": 1808
          }
        ],
        "owner": "local"
      },
      "peer_pool": {
        "blocks": [
          {
            "uuid": "46627eb9-7e0d-4d40-8d67-8747f32a92f5",
            "size": 2000,
            "data": "AAAAAAAAAAAAAA==...",
            "nr_used_bytes": 288,
            "nr_unused_bytes": 1712
          }
        ],
        "owner": "peer"
      }
    },
    ... snip ...
  ]
}

A useful trick is to use the tail -n +2 command to skip the first line of output, and to pipe the remaining output (which is JSON) through the jq command to colorize the JSON output:

$ ./manager.py --client carol status | tail -n +2 | jq
{
  "name": "carol",
  "encryptor_names": [
    "sam"
  ],
  "peer_hubs": [
    {
      "hub_name": "hank",
      "registered": true,
      "local_pool": {
        "blocks": [
          {
            "uuid": "46627eb9-7e0d-4d40-8d67-8747f32a92f5",
            "size": 2000,
            "data": "AAAAAAAAAAAAAA==...",
            "nr_used_bytes": 288,
            "nr_unused_bytes": 1712
          }
        ],
        "owner": "local"
      },
      "peer_pool": {
        "blocks": [
          {
            "uuid": "192c0144-ffec-4f95-9a9f-7d7a82310be7",
            "size": 2000,
            "data": "AAAAAAAAAAAAAA==...",
            "nr_used_bytes": 192,
            "nr_unused_bytes": 1808
          }
        ],
        "owner": "peer"
      }
    },
    ... snip ...
  ]
}

Even better, you can use the pq command with a query to look for specific fields in the JSON output. In the following example we display the information about the local pool for peer-hub hank on client carol:

$ ./manager.py --client carol status | tail -n +2 | jq '(.peer_hubs[] | select(.hub_name == "hank") .local_pool)'
{
  "blocks": [
    {
      "uuid": "46627eb9-7e0d-4d40-8d67-8747f32a92f5",
      "size": 2000,
      "data": "AAAAAAAAAAAAAA==...",
      "nr_used_bytes": 288,
      "nr_unused_bytes": 1712
    }
  ],
  "owner": "local"
}

Log files

Each node produces an .out log file for debugging purposes. The information in this log file will vary wildly as the implementation progresses. For example, the log file for client carol is client-carol.out:

$ cat client-carol.out
INFO:     Started server process [24907]
INFO:     Waiting for application startup.
INFO:     Begin register task for peer hub None
INFO:     Begin register task for peer hub None
INFO:     Begin register task for peer hub None
INFO:     Begin register task for peer hub None
INFO:     Begin register task for peer hub None
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8105 (Press CTRL+C to quit)
INFO:     Call PUT http://127.0.0.1:8100/hub/hank/dske/oob/v1/registration 200
INFO:     Finish register task for peer hub None
INFO:     Call PUT http://127.0.0.1:8103/hub/holly/dske/oob/v1/registration 200
INFO:     Call PUT http://127.0.0.1:8102/hub/hilary/dske/oob/v1/registration 200
INFO:     Call PUT http://127.0.0.1:8104/hub/hugo/dske/oob/v1/registration 200
INFO:     Call PUT http://127.0.0.1:8101/hub/helen/dske/oob/v1/registration 200
INFO:     Begin request PSRD task for peer hub hank and pool owner local
INFO:     Begin request PSRD task for peer hub hank and pool owner peer
INFO:     Finish register task for peer hub None
INFO:     Finish register task for peer hub None
INFO:     Finish register task for peer hub None
INFO:     Finish register task for peer hub None
INFO:     Begin request PSRD task for peer hub holly and pool owner local
INFO:     Begin request PSRD task for peer hub holly and pool owner peer
INFO:     Begin request PSRD task for peer hub hilary and pool owner local
INFO:     Begin request PSRD task for peer hub hilary and pool owner peer
INFO:     Begin request PSRD task for peer hub hugo and pool owner local
INFO:     Begin request PSRD task for peer hub hugo and pool owner peer
INFO:     Begin request PSRD task for peer hub helen and pool owner local
INFO:     Begin request PSRD task for peer hub helen and pool owner peer
INFO:     Call GET http://127.0.0.1:8100/hub/hank/dske/oob/v1/psrd?client_name=carol&pool_owner=client&size=2000 200
INFO:     Finish request PSRD task for peer hub hank and pool owner local
INFO:     Call GET http://127.0.0.1:8100/hub/hank/dske/oob/v1/psrd?client_name=carol&pool_owner=hub&size=2000 200
INFO:     Finish request PSRD task for peer hub hank and pool owner peer
INFO:     Call GET http://127.0.0.1:8104/hub/hugo/dske/oob/v1/psrd?client_name=carol&pool_owner=client&size=2000 200
INFO:     Finish request PSRD task for peer hub hugo and pool owner local
... snip ...

REST interfaces

The nodes communicate with each other over REST interfaces, implemented using FastAPI. There are four types of REST interfaces:

  1. api REST interfaces model the actual DSKE protocol specified in the draft. Note that the draft currently only describes the protocol at the semantic level, and not (yet) the message encoding. We do not intend to imply that REST is the best encoding for the message encoding; a leaner binary encoding may be more appropriate for this type of protocol. We only chose REST to make prototyping and studying the protocol easier the semantic level.

  2. oob REST interfaces model the out-of-band actions mentioned in the draft, for example delivering a block of pre-shared random data (PSRD). In real life, this would not be done over a REST interface but using some other mechanism (e.g. physically shipping a tamper-proof device with gigabytes of random data). In this code we use REST interface to model these actions so that we can automate the scripting of entire end-to-end testing scenarios.

  3. esti REST interfaces are implement the ETSI QKD 014 interface (a subset at this time) on the DSKE clients to deliver the produced keys to the Secure Application Entity (SAE) consumers.

  4. mgmt management REST interfaces to control and debug the various nodes (e.g. to stop them and to retrieve operational status to “look inside” of them to see what is happening).

REST interface documentation

The REST interface for each node is available at the reported port number when the topology was started.

In the above example, the REST interface for hub “Hank” is available at http://127.0.0.1:8100

In addition to the REST interface itself, documentation is also available at http://127.0.0.1:8100/docs and http://127.0.0.1:8100/redoc. You can also manually invoke the REST APIs from the documentation page (click on an API endpoint and then click on “Try it out”).

Here is an example of the automatically generated documentation at http://127.0.0.1:8105/docs for a client node:

Client REST API documentation

Here is an example of the automatically generated documentation at http://127.0.0.1:8100/docs for a hub node:

Hub REST API documentation

When you click on the row for POST /dske/hub/api/v1/key-share you see the detailed documentation for that particular REST endpoint:

Hub POST key-share details documentation

Invoking the REST interface

Here is an example of invoking the API to get the status of

In this example, we pipe the output of curl through jq (JSON query) to pretty-print the JSON REST response:

$ curl --silent http://127.0.0.1:8100/hub/hank/mgmt/v1/status | jq
{
  "name": "hank",
  "peer_clients": [
    {
      "client_name": "carol",
      "encryptor_names": [
        "sam"
      ],
      "local_pool": {
        "blocks": [
          {
            "uuid": "192c0144-ffec-4f95-9a9f-7d7a82310be7",
            "size": 2000,
            "data": "AAAAAAAAAAAAAA==...",
            "nr_used_bytes": 192,
            "nr_unused_bytes": 1808
          }
        ],
        "owner": "local"
      },
      "peer_pool": {
        "blocks": [
          {
            "uuid": "46627eb9-7e0d-4d40-8d67-8747f32a92f5",
            "size": 2000,
            "data": "AAAAAAAAAAAAAA==...",
            "nr_used_bytes": 288,
            "nr_unused_bytes": 1712
          }
        ],
        "owner": "peer"
      }
    },
    ...snip...
  }  
}

Note 1: The status REST API is intended for debugging and understanding the protocol; it exposes information that should not be exposed in a production environment.

Note 2: There is currently no authentication on any of the REST interfaces. It is my understanding (but I could be wrong) that the DSKE protocol does not require the API interfaces to be authenticated nor encrypted to be secure.