Docker
This deployment uses Docker Engine and Docker Compose yaml file to deploy RSTUF.
Warning
There are limitations to scaling this deployment strategy, as all nodes are running in the same host.
This deployment is recommended for Tests, Development, POC and POV.
This deployment does not use secrets for sensitive credentials.
Note
See the complete Deployment Configuration for in-depth details.
Requirements
Software and tools
Docker Engine (with docker-compose)
Python >= 3.10
pip
Online Key
This deployment requires the Online Key. See the chapter Signing Keys
Skip this section if an online key has already been generated.
Steps
Create a folder
local-keyvault
and add the online key
$ mkdir local-keyvault $ cp path/my/keys/0d9d3d4bad91c455bc03921daa95774576b86625ac45570d0cac025b08e65043 local-keyvault/
Create a Docker Compose (functional example below)
docker-compose.yml
1version: "3.7" 2 3volumes: 4 rstuf-api-data: 5 rstuf-mq-data: 6 rstuf-storage: 7 rstuf-redis-data: 8 rstuf-pgsql-data: 9 10services: 11 redis: 12 image: redis:4.0 13 volumes: 14 - rstuf-redis-data:/data 15 healthcheck: 16 test: "exit 0" 17 restart: always 18 tty: true 19 20 postgres: 21 image: postgres:15.1 22 ports: 23 - "5433:5432" 24 # DO NOT USE IT IN PRODUCTION. Check the Postgres best practices 25 environment: 26 - POSTGRES_PASSWORD=secret 27 volumes: 28 - "rstuf-pgsql-data:/var/lib/postgresql/data" 29 healthcheck: 30 test: ["CMD", "pg_isready", "-U", "postgres", "-d", "postgres"] 31 interval: 1s 32 33 rstuf-worker: 34 image: ghcr.io/repository-service-tuf/repository-service-tuf-worker:latest 35 volumes: 36 - rstuf-storage:/var/opt/repository-service-tuf/storage 37 - ./local-keyvault/:/var/opt/repository-service-tuf/keyvault/ # map the path where is your key 38 environment: 39 RSTUF_STORAGE_BACKEND: LocalStorage 40 RSTUF_LOCAL_STORAGE_BACKEND_PATH: /var/opt/repository-service-tuf/storage 41 RSTUF_ONLINE_KEY_DIR: /var/opt/repository-service-tuf/keyvault 42 RSTUF_BROKER_SERVER: redis://redis 43 RSTUF_REDIS_SERVER: redis://redis 44 RSTUF_SQL_SERVER: postgresql://postgres:secret@postgres:5432 45 46 depends_on: 47 - postgres 48 - redis 49 healthcheck: 50 test: "exit 0" 51 restart: always 52 tty: true 53 54 web-server: 55 image: python:3.10-slim-buster 56 command: python -m http.server -d /www 8080 57 volumes: 58 - rstuf-storage:/www 59 ports: 60 - "8080:8080" 61 62 rstuf-api: 63 image: ghcr.io/repository-service-tuf/repository-service-tuf-api:latest 64 volumes: 65 - rstuf-api-data:/data 66 ports: 67 - 80:80 68 - 443:443 69 environment: 70 RSTUF_BROKER_SERVER: redis://redis 71 RSTUF_REDIS_SERVER: redis://redis 72 depends_on: 73 - rstuf-worker
The general explanation about this Docker Compose yaml file:
It uses Docker Volume for the persistent data and Volumes
rstuf-storage
: public TUF Metadata. Using RSTUF Worker with LocalKeyVault storage backend.
rstuf-redis-data
: Persistent Redis data
rstuf-pgsql-data
: Persistent PostgresSQL data
It uses Redis for the task results and RSTUF configuration.
It uses a simple python container as the webserver to expose the public TUF metadata from
rstuf-storage
volumeIt provisions the
repository-service-tuf-api
configuration as environment variables: - Broker Server:RSTUF_BROKER_SERVER
- Redis Server:RSTUF_REDIS_SERVER
It provisions the
repository-service-tuf-worker
configuration as environment variables:
Storage backend:
RSTUF_STORAGE_BACKEND
,RSTUF_LOCAL_STORAGE_BACKEND_PATH
Online Key directory:
RSTUF_ONLINE_KEY_DIR
Broker Server:
RSTUF_BROKER_SERVER
Redis Server:
RSTUF_REDIS_SERVER
SQL (Postgres) Server:
RSTUF_SQL_SERVER
Run using Docker stack
$ docker stack deploy -c docker-compose.yml rstuf Ignoring unsupported options: restart Creating network rstuf_default Creating service rstuf_redis Creating service rstuf_postgres Creating service rstuf_rstuf-worker Creating service rstuf_web-server Creating service rstuf_rstuf-api
Check if all services are running and health
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f3eb8e38c244 postgres:15.1 "docker-entrypoint.s…" 59 seconds ago Up 58 seconds (healthy) 5432/tcp rstuf_postgres.1.n9bculkxiikst502oneq2y1tl 00831512a35d redis:4.0 "docker-entrypoint.s…" About a minute ago Up About a minute (healthy) 6379/tcp rstuf_redis.1.gy8owq16qa0fbgyklr6ji1hyy a15dc8f6f3c9 ghcr.io/repository-service-tuf/repository-service-tuf-api:latest "bash entrypoint.sh" About a minute ago Up About a minute rstuf_rstuf-api.1.o8zmoccz2n4vnxemczlrrg3o9 40d410b9c6ff python:3.10-slim-buster "python -m http.serv…" About a minute ago Up About a minute rstuf_web-server.1.s29tparemtrj5tut6l41in8ah 5762860c1ccc ghcr.io/repository-service-tuf/repository-service-tuf-worker:latest "bash entrypoint.sh" About a minute ago Up About a minute (healthy) rstuf_rstuf-worker.1.aq20wunul0z9lla0nkpo303znVerify
rstuf_rstuf-worker
logsdocker service logs rstuf_rstuf-worker --raw
RSTUF Ceremony and Bootstrap
Repository Service for TUF (RSTUF) has two specific processes as part of the initial setup: Ceremony and Bootstrap.
Note
The setup and configuration requirements:
Set of root key(s) and online key for signing
RSTUF service deployed
Note
It is a one-time process to setup the RSTUF service. If this process is completed during the deployment do not run it again.
RSTUF Command Line Interface provides a guided process for the Ceremony and Bootstrap.
To make this process easier, the Repository Service for TUF CLI provides an interactive guided process to perform the Ceremony.
Note
Required RSTUF CLI installed (See Installation)
❯ rstuf admin ceremony -hThe Ceremony defines the RSTUF settings/configuration and generates the initial signed TUF root metadata.
It does not activate the RSTUF service. It generates the required JSON payload to bootstrap the RSTUF service.
The Ceremony can be done Connected as a specific step or Disconnected, combined with Bootstrap.
This process generates the initial metadata and defines some settings of the TUF service.
See settings details
Timestamp, Snapshot, and Targets metadata expiration policy
Defines how many days this metadata is valid. The metadata is invalid when it expires.
Delegations
Bins (online key only)
The target metadata file might contain a large number of artifacts. The target role delegates trust to the hash bin roles to reduce the metadata overhead for clients.
This metadata is signed using the online key.
Custom Delegations (online/offline keys)
Allows the RSTUF admin to create custom delegation that can use the online key or offline key(s) to sign the metadata. The custom delegation can be used to define the roles and paths for the target metadata.
Root metadata expiration policy
Defines how long this metadata is valid, for example, 365 days (year). This metadata is invalid when it expires.
Root threshold
It defines the number of keys required to sign the Root metadata before it’s considered trusted and will be published.
That’s the minimum number of keys required to update and sign the TUF Root metadata. It’s required to be at least 2.
Note
Updating the Root metadata with new expiration, changing/updating keys or the number of keys, threshold, or rotating a new online key and sign requires following the Metadata Update process.
Note
RSTUF requires at least a threshold number of Root key(s) defined to finish the ceremony. The same applies when performing Metadata Update.
Signing
This process will also require the Online Key and Root Key(s) (offline) for signing the initial root TUF metadata.
The settings are guided during Ceremony.
The disconnected Ceremony will only generate the required JSON payload (
ceremony-payload.json
) file. The Bootstrap requires the payload.Note
The payload (
ceremony-payload.json
) contains only public data, it does not contain any private keys.This process is appropriate when performing the Ceremony on a disconnected computer to RSTUF API to perform the Bootstrap later as a separate step.
❯ rstuf admin ceremony --out Saved result to 'ceremony-payload.json'If the Ceremony is done disconnected, the next step is to perform the bootstrap.
The connected Ceremony generates the JSON payload file and run the Bootstrap request to RSTUF API.
This process is appropriate when performing the Ceremony on a computer connected to RSTUF API. It does not require a Bootstrap step.
❯ rstuf admin --api-server https://rstuf-api-url ceremonyIf a Ceremony Connected is complete, skip this, as the RSTUF service is ready.
To perform the boostrap you require the payload generated during the Bootstrap.
You can do it using the rstuf admin-legacy
❯ rstuf admin --api-server http://rstuf-api-url send bootstrap ceremony-payload.json Starting online bootstrap Bootstrap status: ACCEPTED (c1d2356d25784ecf90ce373dc65b05c7) Bootstrap status: STARTED Bootstrap status: SUCCESS Bootstrap completed using `ceremony-payload.json`. 🔐 🎉
Remove RSTUF deployment
Remove the Stack
$ docker stack rm rstuf
Removing service rstuf_rstuf-worker
Removing service rstuf_rstuf-api
Removing service rstuf_redis
Removing service rstuf_web-server
Removing network rstuf_default
Remove all data
$ docker volume rm rstuf_repository-service-tuf-worker-data \
rstuf_rstuf-storage \
rstuf_rstuf-keystorage \
rstuf_rstuf-redis-data \