diff --git a/Makefile b/Makefile index 1e7893c311fa..e85d88322ba4 100644 --- a/Makefile +++ b/Makefile @@ -125,6 +125,11 @@ resetdb: .state/docker-build-base initdb: .state/docker-build-base .state/db-populated $(MAKE) reindex +inittuf: .state/db-migrated + docker compose up -d rstuf-api + docker compose up -d rstuf-worker + docker compose run --rm web rstuf admin ceremony -b -u -f dev/rstuf/bootstrap.json --api-server http://rstuf-api + runmigrations: .state/docker-build-base docker compose run --rm web python -m warehouse db upgrade head diff --git a/dev/rstuf/bootstrap.json b/dev/rstuf/bootstrap.json new file mode 100644 index 000000000000..fd7792424a86 --- /dev/null +++ b/dev/rstuf/bootstrap.json @@ -0,0 +1,92 @@ +{ + "settings": { + "roles": { + "root": { + "expiration": 365 + }, + "targets": { + "expiration": 365 + }, + "snapshot": { + "expiration": 1 + }, + "timestamp": { + "expiration": 1 + }, + "bins": { + "expiration": 1, + "number_of_delegated_bins": 4 + } + } + }, + "metadata": { + "root": { + "signatures": [ + { + "keyid": "c6d8bf2e4f48b41ac2ce8eca21415ca8ef68c133b47fc33df03d4070a7e1e9cc", + "sig": "19dd6b1d5da8149b5a490efc8137beedb85ae036255244b2eba909efe05561636e56c0f9a3fe219601602c142b74cc9d2ab5ba18016cb1f3fb81f16f4cb89100" + } + ], + "signed": { + "_type": "root", + "version": 1, + "spec_version": "1.0.31", + "expires": "2025-02-21T13:58:51Z", + "consistent_snapshot": true, + "keys": { + "50d7e110ad65f3b2dba5c3cfc8c5ca259be9774cc26be3410044ffd4be3aa5f3": { + "keytype": "ecdsa", + "scheme": "ecdsa-sha2-nistp256", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcLYSZyFGeKdWNt5dWFbnv6N9NyHC\noUNLcG6GZIxLwN8Q8MUdHdOOxGkDnyBRSJpIZ/r/oDECSTwfCYhdogweLA==\n-----END PUBLIC KEY-----\n" + }, + "x-rstuf-key-name": "my ecdsa root key" + }, + "c6d8bf2e4f48b41ac2ce8eca21415ca8ef68c133b47fc33df03d4070a7e1e9cc": { + "keytype": "ed25519", + "scheme": "ed25519", + "keyval": { + "public": "4f66dabebcf30628963786001984c0b75c175cdcf3bc4855933a2628f0cd0a0f" + }, + "x-rstuf-key-name": "my ed25519 root key" + }, + "2f685fa7546f1856b123223ab086b3def14c89d24eef18f49c32508c2f60e241": { + "keytype": "rsa", + "scheme": "rsassa-pss-sha256", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwhX6rioiL/cX5Ys32InF\nU52H8tL14QeX0tacZdb+AwcH6nIh97h3RSHvGD7Xy6uaMRmGldAnSVYwJHqoJ5j2\nynVzU/RFpr+6n8Ps0QFg5GmlEqZboFjLbS0bsRQcXXnqJNsVLEPT3ULvu1rFRbWz\nAMFjNtNNk5W/u0GEzXn3D03jIdhD8IKAdrTRf0VMD9TRCXLdMmEU2vkf1NVUnOTb\n/dRX5QA8TtBylVnouZknbavQ0J/pPlHLfxUgsKzodwDlJmbPG9BWwXqQCmP0DgOG\nNIZ1X281MOBaGbkNVEuntNjCSaQxQjfALVVU5NAfal2cwMINtqaoc7Wa+TWvpFEI\nWwIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "x-rstuf-online-key-uri": "fn:2f685fa7546f1856b123223ab086b3def14c89d24eef18f49c32508c2f60e241" + } + }, + "roles": { + "root": { + "keyids": [ + "50d7e110ad65f3b2dba5c3cfc8c5ca259be9774cc26be3410044ffd4be3aa5f3", + "c6d8bf2e4f48b41ac2ce8eca21415ca8ef68c133b47fc33df03d4070a7e1e9cc" + ], + "threshold": 1 + }, + "targets": { + "keyids": [ + "2f685fa7546f1856b123223ab086b3def14c89d24eef18f49c32508c2f60e241" + ], + "threshold": 1 + }, + "timestamp": { + "keyids": [ + "2f685fa7546f1856b123223ab086b3def14c89d24eef18f49c32508c2f60e241" + ], + "threshold": 1 + }, + "snapshot": { + "keyids": [ + "2f685fa7546f1856b123223ab086b3def14c89d24eef18f49c32508c2f60e241" + ], + "threshold": 1 + } + } + } + } + } +} \ No newline at end of file diff --git a/dev/rstuf/keys/online/2f685fa7546f1856b123223ab086b3def14c89d24eef18f49c32508c2f60e241 b/dev/rstuf/keys/online/2f685fa7546f1856b123223ab086b3def14c89d24eef18f49c32508c2f60e241 new file mode 100644 index 000000000000..82406424dc8a --- /dev/null +++ b/dev/rstuf/keys/online/2f685fa7546f1856b123223ab086b3def14c89d24eef18f49c32508c2f60e241 @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQDCFfquKiIv9xfl +izfYicVTnYfy0vXhB5fS1pxl1v4DBwfqciH3uHdFIe8YPtfLq5oxGYaV0CdJVjAk +eqgnmPbKdXNT9EWmv7qfw+zRAWDkaaUSplugWMttLRuxFBxdeeok2xUsQ9PdQu+7 +WsVFtbMAwWM2002Tlb+7QYTNefcPTeMh2EPwgoB2tNF/RUwP1NEJct0yYRTa+R/U +1VSc5Nv91FflADxO0HKVWei5mSdtq9DQn+k+Uct/FSCwrOh3AOUmZs8b0FbBepAK +Y/QOA4Y0hnVfbzUw4FoZuQ1US6e02MJJpDFCN8AtVVTk0B9qXZzAwg22pqhztZr5 +Na+kUQhbAgMBAAECggEAFZPH+NDqWBbKa1Sc8s/uRit/T7mwaEIl2OTPImtSdhe0 +A5aIvDef2um44SMrbpM3YzoJQmKP25FfbM7OHwjcdwmztqOzkqRCJTzs+ReEJCCy +n24rRZpZk1uudnNb6/B/3XUV14P66+BjMpsWz3cx3WWimBfJyhyd4j2YfBeRJfw7 +GLCJ0Jeplj0hKEC4Yo6Dvppnl0DJn8NnsnXLRTwepjwB/EpSxnrpzwBBwzsMTcx/ +2zKC9sZhTE1RDsgbw2IIUiBk1enAhZtmiS/BFT9Y4jWaeXTkkVSnFXPZLYPkdB9W +sHgKGiWOSX/1j90IHaKsSKRFUdn3FHtDTde7o4kGQQKBgQDtdS+WBHfVvBH9iQgw +GWc3KKJPcKHC1m4+GOHhIElb0f5l/y6OTZkvK/bPtKJ8bpufsr9jBVQYubIVfJ2j +ZmO0ukclkzIjzwvY9sSHbnWzFfKbjqNG1zGaZYNe0WM/Lx51pG69hxlVzivLAObf +fqYR0+dt5imD/46FcfHFkTQdCwKBgQDRPchsq4zxxvqMYGxzMfyp7l8y1lLcORHS +j2qkOB0n973DggW2sLIEl3uqf/schpbYO8zFs/1YKrJ5LNnYF14GduugmS5znpnb +YvMJyTXFAqmcbl48ahVUvyOrgxTAOJOfFLRXwZiIVzaAaOop+Ph6A4hEYvXWJ8FW +j6lVr7mz8QKBgFYabArly95At/VLPyDR1U92+IP9v2o6/vadZyqO3org9nJdua/4 +C1fDhVeDlHeyU9PwqN1rDTd5/k00RqT9d6IM+cdyPHgnl5AwysqhDyTFDJfDfQku +9tmZfa1gF7DNkSnvWgh3eIRYoiCWTyEzd1x3ji+Xie5HOJLC4nxVTqRJAoGAZQb6 +rZWLAPX85ShtVJVvFDFW37nh2hjoBQ1gBRhe43xXsH0n+xSHb3YgrKsMeLJ3RMJi +1ZZZHWfIMn+4UwC9Uku66xjq98I9MVMuW6w9/PiTIkeb0nm6AOgk9dvdeg4XILkj +djewSSwq0YdWgJuIhYkNE0/guN0LGZtVvFyTQlECfy3l4m4VwlaPRSSYUxUzULs7 +xc34lL1mf09pWxWebZw4ILQQ90DGWOSD/Zgq6CryRfYgsYqXmGNgDbUFRTWh2DMq +6IoLG3wiqrKSW2oFQL3UOzws0ag7C+6aqKnydpQoEtaP5X+DfAWdAOqnsOP1Ry+W +VTrmtVm4yLiMPBnsw3I= +-----END PRIVATE KEY----- diff --git a/dev/rstuf/keys/root/root1 b/dev/rstuf/keys/root/root1 new file mode 100644 index 000000000000..d7b5a7f7300a --- /dev/null +++ b/dev/rstuf/keys/root/root1 @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgIP90wnfOXb44C0fH +xubol3Vc2jsIYgBTQq0Oh84d3RWhRANCAARwthJnIUZ4p1Y23l1YVue/o303IcKh +Q0twboZkjEvA3xDwxR0d047EaQOfIFFImkhn+v+gMQJJPB8JiF2iDB4s +-----END PRIVATE KEY----- diff --git a/dev/rstuf/keys/root/root2 b/dev/rstuf/keys/root/root2 new file mode 100644 index 000000000000..d197b99c99a8 --- /dev/null +++ b/dev/rstuf/keys/root/root2 @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIGiI3w9x2HZ9UKGi51USN5JN2wtppaYVCRIBTp8ESaj3 +-----END PRIVATE KEY----- diff --git a/docker-compose.yml b/docker-compose.yml index c525be9c8855..3174b31cdecb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -141,6 +141,7 @@ services: - packages-archive:/var/opt/warehouse/packages-archive - sponsorlogos:/var/opt/warehouse/sponsorlogos - simple:/var/opt/warehouse/simple + - rstuf-metadata:/var/opt/warehouse/tuf-metadata ports: - "9001:9001" @@ -160,21 +161,28 @@ services: SIMPLE_BACKEND: "warehouse.packaging.services.LocalSimpleStorage path=/var/opt/warehouse/simple/ url=http://files:9001/simple/{path}" rstuf-api: - image: ghcr.io/repository-service-tuf/repository-service-tuf-api:v0.9.0b1 + image: ghcr.io/repository-service-tuf/repository-service-tuf-api:v0.12.0b1 ports: - 8001:80 + stop_signal: SIGKILL environment: - RSTUF_BROKER_SERVER=redis://redis/1 - RSTUF_REDIS_SERVER=redis://redis - RSTUF_REDIS_SERVER_DB_RESULT=1 - RSTUF_REDIS_SERVER_DB_REPO_SETTINGS=2 + depends_on: + redis: + condition: service_started rstuf-worker: - image: ghcr.io/repository-service-tuf/repository-service-tuf-worker:v0.11.0b1 + image: ghcr.io/repository-service-tuf/repository-service-tuf-worker:v0.14.0b1 volumes: - rstuf-metadata:/var/opt/repository-service-tuf/storage + - ./dev/rstuf/keys/online:/keyvault + stop_signal: SIGKILL environment: - RSTUF_STORAGE_BACKEND=LocalStorage + - RSTUF_ONLINE_KEY_DIR=/keyvault - RSTUF_LOCAL_STORAGE_BACKEND_PATH=/var/opt/repository-service-tuf/storage - RSTUF_BROKER_SERVER=redis://redis/1 - RSTUF_REDIS_SERVER=redis://redis @@ -184,6 +192,8 @@ services: depends_on: db: condition: service_healthy + redis: + condition: service_started static: build: diff --git a/docs/dev/development/getting-started.rst b/docs/dev/development/getting-started.rst index d6cddaf02582..f68a780873b2 100644 --- a/docs/dev/development/getting-started.rst +++ b/docs/dev/development/getting-started.rst @@ -242,6 +242,43 @@ or that the ``static`` container has finished compiling the static assets: or maybe something else. +Bootstrapping the TUF Metadata Repository +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable PyPI Index Signing (`PEP 458 `_), +you have to first bootstrap the TUF metadata repository. + +.. code-block:: console + + make inittuf + +You should see the following line at the bottom of the output: + +.. code-block:: console + + Bootstrap completed using `dev/rstuf/bootstrap.json`. 🔐 🎉 + + +This command sends a static *bootstrap payload* to the RSTUF API. The payload +includes the TUF trust root for development and other configuration. + +By calling this API, RSTUF creates the TUF metadata repository, installs the +TUF trust root for development, and creates the initial set of TUF metadata. + +.. note:: + + The RSTUF API is exposed only for development purposes and will not be + available in production. Currently, no upload hooks or automatic metadata + update tasks are configured to interact with RSTUF. + + Take a look at the `RSTUF API documentation + `_ + to see how you can simulate artifact upload or removal, and how they affect + the TUF metadata repository: + + * RSTUF API: http://localhost:8001 + * TUF Metadata Repository: http://localhost:9001/tuf-metadata/ + Resetting the development database ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/requirements/dev.txt b/requirements/dev.txt index d233587fc74f..b9b34ac968f8 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -3,3 +3,4 @@ hupper>=1.9 pip-tools>=1.0 pyramid_debugtoolbar>=2.5 pip-api +repository-service-tuf \ No newline at end of file