Skip to content
/ senke Public

A transparently encrypted cache accessible via a simple HTTP API. By default, all data is encrypted at rest, and access is controlled through simple, policy-based access control lists.

License

Notifications You must be signed in to change notification settings

hw0lff/senke

Repository files navigation

Senke

Store Entities Neatly, Kept Encrypted

What is this?

Senke (/ˈzɛŋkə/) is a transparently encrypted cache accessible via a simple HTTP API. By default, all data is encrypted at rest, and access is controlled through simple, policy-based access control lists.

Concepts

There are a few words repeatedly used:

  • entity: a single data item stored in the cache. It exists under a (domain, resource) namespace.
  • resource: an identifier representing a logical or historical collection of related entities.
  • domain: a grouping of resources — essentially a namespace or scope.
  • action: what a user can do to entities within a domain. One of: create, read, delete.
  • policy: a permission tuple: (domain, user, action). Policies define who can perform what action on which domain.
  • user: an authenticated actor granted one or more policies. Multiple users can have overlapping access.

How do I use this?

Build it first. See below how.

Create a .env file like seen in example.env. The file senke uses can be overriden by setting the environment variable ENV_FILE to the path with your config file (e.g. ENV_FILE=/path/to/my-config.env).

This assumes you used the example.env as configuration.

mkdir -p local-db

# display help, every subcommand has this
senke -h

# create a domain
senke domain add ab.example.com # can be any string

# create users
senke user add alice # enter password for alice (e.g. secret1)
senke user add bob # enter password for bob (e.g. secret2)
senke user add candace # enter password for candace (e.g. secret3)
# use the PASSWORD env variable to skip the prompt

# add policies to allow users access to actions at the domain
senke policy add ab.example.com alice create
senke policy add ab.example.com bob read
senke policy add ab.example.com candace delete

# or create users and domains together with the policy
# the PASSWORD env variable works here too
PASSWORD=secret1 senke policy add --create ab.example.com alice create
PASSWORD=secret2 senke policy add --create ab.example.com bob read
PASSWORD=secret3 senke policy add --create ab.example.com candace delete

# start the server
senke serve

Using the HTTP API of the cache with curl would go like this:

# generate some random data
dd if=/dev/urandom bs=64 count=2 | base64 > /tmp/random-data.txt;

# upload data
curl --request PUT --header 'content-type: application/octet-stream' --user alice:secret1 --data-binary '@/tmp/random-data.txt' 'http://localhost:8080/api/domains/ab.example.com/my-custom-resource' --verbose

# retrieve data
curl --request GET --user bob:secret2 'http://localhost:8080/api/domains/ab.example.com/my-custom-resource' --verbose
# look at the content-location header to get the URL for deleting this entity

# delete data
curl --request DELETE --user candace:secret3 'http://localhost:8080/api/domains/ab.example.com/my-custom-resource/archive/2b539ce91c1c34656a5ae19e2c46113eecfc0b1a8b561e7c9b18a6f55ed6a9ac'

The three actions create, read and delete map to the HTTP methods (PUT or POST), GET and DELETE.

alice cannot read nor delete on ab.example.com.
bob cannot create nor delete on ab.example.com.
candace cannot create nor read on ab.example.com.

Building it

Either build it statically with docker, with the nix package manager or by hand on your local system.

Docker

Use the just command runner.

just docker
ls -lah target/senke

Nix

nix build
ls -lah result/bin

By Hand

Dependencies

  • cargo
  • libsodium
  • sqlite
  • clang
  • mold (because mold is cool)
  • make
  • musl (only for static linking against musl libc)

Installing dependencies examples

Archlinux:

pacman -Sy --noconfirm make clang rustup cargo libsodium sqlite mold musl

Alpine:

apk add build-base clang make mold musl-dev libsodium-dev sqlite-dev

Building with glibc

cargo build --release --target x86_64-unknown-linux-gnu

Building and linking statically with musl

cargo build --release --target x86_64-unknown-linux-musl

Security Notice

Caution

This project has not been audited and may contain security vulnerabilities.

Use this software at your own risk.

It is provided "as is", without any warranty or guarantee of fitness for any particular purpose.

The author(s) accept no responsibility or liability for any damages, losses, or issues resulting from the use of this code.

Thank you and have fun!

Big thanks go to libsodium for providing such an awesome cryptographic library and alkali for making it so easy to use it with rust!

This is just a small project of mine to easily automate sharing arbitrary data or even secrets across hosts.

I had lots of fun with this project and learned many new things.

Maybe it will be useful to you too :D

Cheers

About

A transparently encrypted cache accessible via a simple HTTP API. By default, all data is encrypted at rest, and access is controlled through simple, policy-based access control lists.

Resources

License

Stars

Watchers

Forks