Skip to content

Filesystem Keystore

Andreas Auernhammer edited this page Apr 17, 2023 · 25 revisions

This guide shows how to setup a KES server that uses the filesystem as persistent key store.

                         ╔══════════════════════════════════════════╗
┌────────────┐           ║  ┌────────────┐          ┌────────────┐  ║
│ KES Client ├───────────╫──┤ KES Server ├──────────┤ Filesystem │  ║
└────────────┘           ║  └────────────┘          └────────────┘  ║
                         ╚══════════════════════════════════════════╝

A plain filesystem does not provide any protection for the stored keys. It should only be used for testing purposes.


KES Server Setup

1. Generate KES Server Private Key & Certificate

First, we need to generate a TLS private key and certificate for our KES server. A KES server can only be run with TLS - since secure-by-default. Here we use self-signed certificates for simplicity.

The following command generates a new TLS private key (private.key) and a self-signed X.509 certificate (public.crt) issued for the IP 127.0.0.1 and DNS name localhost:

$ kes identity new --key private.key --cert public.crt --ip "127.0.0.1" localhost

Your API key:

   kes:v1:AMc8rEojXTssUN/G+2PgcbRN5AKTb5xN3n8PhMemajjr

This is the only time it is shown. Keep it secret and secure!

Your Identity:

   4742f46c0eecff4fee621d0401c91e670b8330cf32e8fc47dd89f06555103c10

The identity is not a secret. It can be shared. Any peer
needs this identity in order to verify your API key.

The generated TLS private key is stored at: private.key
The generated TLS certificate is stored at: public.crt

The identity can be computed again via:

    kes identity of kes:v1:AMc8rEojXTssUN/G+2PgcbRN5AKTb5xN3n8PhMemajjr
    kes identity of public.crt

If you already have a TLS private key & certificate - e.g. from a WebPKI or internal CA - you can use them instead. Remember to adjust the tls config section later on.

2. Generate Client Credentials

The client application needs some credentials to access the KES server. The following command generates a new API key with an associated identity:

$ kes identity new

Your API key:

   kes:v1:ABPiS2yeh1OkyUr3pEDipBCSisq/J9Rg2CkgVXc038Ot

This is the only time it is shown. Keep it secret and secure!

Your Identity:

   f829b905ac119229bc75a60eab4fa9172f3cbba179df0b5601f8ed8168b9a9d5

The identity is not a secret. It can be shared. Any peer
needs this identity in order to verify your API key.

The identity can be computed again via:

    kes identity of kes:v1:ABPiS2yeh1OkyUr3pEDipBCSisq/J9Rg2CkgVXc038Ot

The identity f829b905ac119229bc75a60eab4fa9172f3cbba179df0b5601f8ed8168b9a9d5 is an unique fingerprint of the API key and you can re-compute anytime:

$ kes identity of kes:v1:ABPiS2yeh1OkyUr3pEDipBCSisq/J9Rg2CkgVXc038Ot

  Identity:  f829b905ac119229bc75a60eab4fa9172f3cbba179df0b5601f8ed8168b9a9d5
3. Configure KES Server

Next, we can create the KES server configuration file: config.yml. Please, make sure that the identity in the policy section matches your client.crt identity.

address: 0.0.0.0:7373 # Listen on all network interfaces on port 7373

admin:
  identity: disabled  # We disable the admin identity since we don't need it in this guide 
   
tls:
  key: private.key    # The KES server TLS private key
  cert: public.crt    # The KES server TLS certificate
   
policy:
  my-app: 
    allow:
    - /v1/key/create/my-key*
    - /v1/key/generate/my-key*
    - /v1/key/decrypt/my-key*
    identities:
    - f829b905ac119229bc75a60eab4fa9172f3cbba179df0b5601f8ed8168b9a9d5 # Use the identity of your API key
   
keystore:
  fs:
    path: ./keys # Choose a directory for the secret keys
4. Start KES Server

Now, we can start a KES server instance:

$ kes server --config config.yml --auth off

On linux, KES can use the mlock syscall to prevent the OS from writing in-memory data to disk (swapping). This prevents leaking senstive data accidentality. The following command allows KES to use the mlock syscall without running with root privileges:

$ sudo setcap cap_ipc_lock=+ep $(readlink -f $(which kes))

Then, we can start a KES server instance with memory protection:

$ kes server --config config.yml --auth off --mlock

KES CLI Access

1. Set KES_SERVER Endpoint

The KES CLI needs to know to which server it should talk to:

$ export KES_SERVER=https://127.0.0.1:7373
2. Use Client Credentials

Further, the KES CLI needs some access credentials to talk to a KES server:

$ export KES_API_KEY=kes:v1:ABPiS2yeh1OkyUr3pEDipBCSisq/J9Rg2CkgVXc038Ot
3. Perform Operations

Now, we can perform any API operation that is allowed based on the policy we assigned above. For example we can create a key:

$ kes key create my-key-1

If you are running KES locally for testing purpose use -k or --insecure flag to create a key

$ kes key create my-key-1 -k

Then, we can use that key to generate a new data encryption key:

$ kes key dek my-key-1
{
  plaintext : UGgcVBgyQYwxKzve7UJNV5x8aTiPJFoR+s828reNjh0=
  ciphertext: eyJhZWFkIjoiQUVTLTI1Ni1HQ00tSE1BQy1TSEEtMjU2IiwiaWQiOiIxMTc1ZjJjNDMyMjNjNjNmNjY1MDk5ZDExNmU3Yzc4NCIsIml2IjoiVHBtbHpWTDh5a2t4VVREV1RSTU5Tdz09Iiwibm9uY2UiOiJkeGl0R3A3bFB6S21rTE5HIiwiYnl0ZXMiOiJaaWdobEZrTUFuVVBWSG0wZDhSYUNBY3pnRWRsQzJqWFhCK1YxaWl2MXdnYjhBRytuTWx0Y3BGK0RtV1VoNkZaIn0=
}

If you are running KES locally for testing purpose use -k or --insecure flag to generate new data encryption key

$ kes key dek my-key-1 -k
{
  plaintext : UGgcVBgyQYwxKzve7UJNV5x8aTiPJFoR+s828reNjh0=
  ciphertext: eyJhZWFkIjoiQUVTLTI1Ni1HQ00tSE1BQy1TSEEtMjU2IiwiaWQiOiIxMTc1ZjJjNDMyMjNjNjNmNjY1MDk5ZDExNmU3Yzc4NCIsIml2IjoiVHBtbHpWTDh5a2t4VVREV1RSTU5Tdz09Iiwibm9uY2UiOiJkeGl0R3A3bFB6S21rTE5HIiwiYnl0ZXMiOiJaaWdobEZrTUFuVVBWSG0wZDhSYUNBY3pnRWRsQzJqWFhCK1YxaWl2MXdnYjhBRytuTWx0Y3BGK0RtV1VoNkZaIn0=
}

References