Skip to main content

Getting started

This guide shows you how to easily get started with D1 Generic.

Running D1 Generic locally with Docker Compose

In this section, you will be guided through how to get started with D1 Generic in Docker. This guide will use gRPCurl to call the gRPC endpoints, but we also provide a Go client.

Requirements

By default D1 Generic reads its configuration from the TOML file config.toml, but it is possible to provide another configuration file or to overwrite specific configuration options. For more information, see the Configuration section in the user manual.

In the following we show how to use the built in Standalone ID Provider for user management. D1 Generic also supports using an external OIDC provider as an authentication/authorization mechanism. See the User Manual for more details.

Step 1: Start a local Docker Compose instance

Place the following Docker Compose file next to your config.toml. Note that we use Redis as the IO Provider in this example. For more details on how to configure various IO Providers see the User Manual.

services:
# D1 Generic
d1-service-generic:
image: cybercryptio/d1-service-generic:<version>
container_name: d1-service-generic
environment:
D1_IO_REDIS_ADDRESS: "redis:6379"
volumes:
- ${PWD}/config.toml:/config.toml
ports:
- 9000:9000
depends_on:
- redis
tty: true

# redis
redis:
image: redis:7.0.3-alpine
container_name: redis

To start the service call

docker compose up --detach

You now have a complete D1 Generic instance inside Docker. The gRPC API is available on localhost:9000. When running the following command,

docker ps

the output will show that two containers, d1-service-generic and redis, are running.

Step 2: Bootstrap an initial user

docker exec d1-service-generic /d1-service-generic create-user

This user is created without any scopes, since this user should only be used to create other users, and user management does not require any scopes. Optionally you can set an additional parameter to set the scopes for the initial user. For more details on scopes see the the Standalone User Management section in the user manual.

Note down the generated credentials: user_id and password from the output. They should be used to login to D1 Generic.

Step 3: Login as initial user

Login as the initial user with the user_id and password using the LoginUser endpoint:

grpcurl -plaintext \
-d '{
"user_id": <user_id>,
"password": <password>
}' \
localhost:9000 d1.authn.Authn.LoginUser

Output:

{
"accessToken": <access token>,
"expiryTime": "1653039503"
}

When logging in, an access token is returned. The user needs to pass this token as gRPC metadata in all future calls in order to be authorized.

Step 4: Create a second user

The initial user can create a second user. In the following example, the second user is given all possible scopes:

grpcurl -plaintext -H "authorization: bearer <access token>" \
-d '{
"scopes": ["READ", "CREATE", "GETACCESS", "MODIFYACCESS"]
}' \
localhost:9000 d1.authn.Authn.CreateUser

Output:

{
"user_id": "44c8fa82-f8ed-46b0-94d1-8921a19c0d62",
"password": "Vju86gvJTEKK9zBIZAHloa2K0y2Vw_eJC7icmmCP-jc"
}

Step 5: Use D1 Generic to encrypt an object

The new user can now encrypt an object using the Encrypt endpoint:

grpcurl -plaintext -H "authorization: bearer <access token>" \
-d '{
"plaintext": "1234",
"associated_data": "5678"
}' \
localhost:9000 d1.generic.Generic.Encrypt

Output:

{
"ciphertext": "Mpv3wlW0nHnBbXDtGT4Eqa24o57MpQpcxCiRj8M5SO1x56A=",
"associated_data": "5678",
"object_id": "a9a909b9-6019-488d-bfb4-b8b4243ae177"
}

Note that the associated_data in the output above is not encrypted, but it is authenticated and bound to the ciphertext. The user needs to keep the object_id in order to be able to decrypt the object later.

Step 6: Shut down the D1 Generic instance

The D1 Generic instance can be shut down by running:

docker compose down