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.
RSTUF Command Line Interface (CLI) provides a feature for Key Generation (generate)
This command will generate cryptographic keys using the securesystemslib
library.
The user is requested to provide:
the key type, from the supported list of encryption algorithms
the key’s filename, whose path will be the current working directory
a password, to encrypt the private key file
After the above procedure, two files, the private and public key
(e.g., id_ed25519
and id_ed25519.pub
), will be generated in the current
working directory.
The generated keys may be used in the Repository Service for TUF Ceremony
process, for the online key or the TUF roles’ keys (root
, targets
, etc. keys).
❯ rstuf key generate
Choose key type [ed25519/ecdsa/rsa] (ed25519): ed25519
Enter the key's filename: (id_ed25519): id_ed25519
Enter password to encrypt private key file 'id_ed25519':
Confirm:
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Key ID ┃ Key Type ┃ Public Key ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ f2f9f111b4a8dfb3766c8066628c81bd3aef42b34… │ ed25519 │ bb713c55bbf9b13ff7f92193af55b2f65ae15e55… │
└────────────────────────────────────────────┴──────────┴───────────────────────────────────────────┘
Steps
Create a folder
local-keyvault
and add the online key
$ mkdir local-keyvault $ cp path/my/online.key 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_KEYVAULT_BACKEND: LocalKeyVault 42 RSTUF_LOCAL_KEYVAULT_PATH: /var/opt/repository-service-tuf/keyvault 43 RSTUF_LOCAL_KEYVAULT_KEYS: online.key,strongPass 44 RSTUF_BROKER_SERVER: redis://redis 45 RSTUF_REDIS_SERVER: redis://redis 46 RSTUF_SQL_SERVER: postgresql://postgres:secret@postgres:5432 47 48 depends_on: 49 - postgres 50 - redis 51 healthcheck: 52 test: "exit 0" 53 restart: always 54 tty: true 55 56 web-server: 57 image: python:3.10-slim-buster 58 command: python -m http.server -d /www 8080 59 volumes: 60 - rstuf-storage:/www 61 ports: 62 - "8080:8080" 63 64 rstuf-api: 65 image: ghcr.io/repository-service-tuf/repository-service-tuf-api:latest 66 volumes: 67 - rstuf-api-data:/data 68 ports: 69 - 80:80 70 - 443:443 71 environment: 72 RSTUF_BROKER_SERVER: redis://redis 73 RSTUF_REDIS_SERVER: redis://redis 74 depends_on: 75 - 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
Key Vault backend:
RSTUF_KEYVAULT_BACKEND
,RSTUF_LOCAL_KEYVAULT_PATH
,RSTUF_LOCAL_KEYVAULT_KEYS
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 -hA video demonstrating this process is available.
The 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
Root metadata expiration policy
Defines how long this metadata is valid, for example, 365 days (year). This metadata is invalid when it expires.
Root number of keys
It is the total number of root keys (offline keys) used by the TUF Root metadata. The number of keys implies that the number of identities is the TUF Metadata’s top-level administrator.
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 all Root key(s) during the Ceremony.
Note
RSTUF requires at least the threshold number of Root key(s) for Metadata Update.
Root key threshold
The minimum number of keys required to update and sign the TUF Root metadata.
Targets, BINS, Snapshot, and Timestamp metadata expiration policy
Defines how long this metadata is valid. The metadata is invalid when it expires.
Targets number of delegated hash bin roles
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.
Targets base URL
The base URL path for downloading all artifacts. Example: https://www.example.com/download/
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 (
payload.json
) file. The Bootstrap requires the payload.Note
The payload (
payload.json
) contains only public data, it does not contain 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 ceremonyThe 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 ceremony -bIf a Ceremony Connected is complete, skip this, as the RSTUF service is ready.
If a Ceremony Disconnected is complete, it requires running the Bootstrap from a computer connected to the RSTUF API.
❯ rstuf admin ceremony -b -u
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 \