Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/github_actions/codecov/codecov-ac…
Browse files Browse the repository at this point in the history
…tion-4.1.0
  • Loading branch information
MVrachev authored Mar 15, 2024
2 parents 360ce96 + 71b74ec commit 209c23e
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 97 deletions.
10 changes: 5 additions & 5 deletions docker-compose-aws.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ services:
environment:
- DATA_DIR=./data
- RSTUF_STORAGE_BACKEND=AWSS3
- RSTUF_AWSS3_STORAGE_BUCKET=tuf-metadata
- RSTUF_AWSS3_STORAGE_ACCESS_KEY=access_key
- RSTUF_AWSS3_STORAGE_SECRET_KEY=secret_key
- RSTUF_AWS_STORAGE_BUCKET=tuf-metadata
- RSTUF_AWS_ACCESS_KEY_ID=access_key
- RSTUF_AWS_SECRET_ACCESS_KEY=secret_key
# region and endpoint_url are required by localstack
- RSTUF_AWSS3_STORAGE_REGION=us-east-1
- RSTUF_AWSS3_STORAGE_ENDPOINT_URL=http://localstack:4566
- RSTUF_AWS_DEFAULT_REGION=us-east-1
- RSTUF_AWS_ENDPOINT_URL=http://localstack:4566
- RSTUF_KEYVAULT_BACKEND=LocalKeyVault
- RSTUF_LOCAL_KEYVAULT_PATH=/opt/repository-service-tuf-worker/tests/files/key_storage
- RSTUF_LOCAL_KEYVAULT_KEYS=online.key,strongPass:online-rsa.key,strongPass,rsa
Expand Down
31 changes: 12 additions & 19 deletions docs/source/guide/Docker_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ Here are some things you need to know:
[Secure Systems Library](https://github.com/secure-systems-lab/securesystemslib).
If you do not have a key we suggest you use the [RSTUF CLI tool to generate the key](https://repository-service-tuf.readthedocs.io/en/latest/guide/repository-service-tuf-cli/index.html).
* This key must be the same one used during the [RSTUF CLI ceremony](https://repository-service-tuf.readthedocs.io/en/latest/guide/repository-service-tuf-cli/index.html#ceremony-ceremony).
* This key must be available to RSTUF Worker using the `RSTUF_KEYVAULT_BACKEND`.

For more information read the [Deployment documentation](https://repository-service-tuf.readthedocs.io/en/latest/guide/deployment/index.html).

Expand All @@ -41,10 +40,7 @@ For more information read the [Deployment documentation](https://repository-serv

```shell
docker run --env="RSTUF_STORAGE_BACKEND=LocalStorage" \
--env="RSTUF_LOCAL_STORAGE_BACKEND_PATH=storage" \
--env="RSTUF_KEYVAULT_BACKEND=LocalKeyVault" \
--env="RSTUF_LOCAL_KEYVAULT_PATH=keyvault" \
--env="RSTUF_LOCAL_KEYVAULT_KEYS=online.key,strongPass" \
--env="RSTUF_LOCAL_STORAGE_BACKEND_PATH=/metadata" \
--env="RSTUF_BROKER_SERVER=guest:guest@rabbitmq:5672" \
--env="RSTUF_REDIS_SERVER=redis://redis" \
--env="RSTUF_SQL_SERVER=postgresql://postgres:secret@postgres:5432" \
Expand Down Expand Up @@ -132,31 +128,31 @@ Available types:

##### `AWSS3` (AWS S3)

* (Required) ``RSTUF_AWSS3_STORAGE_BUCKET``
* (Required) ``RSTUF_AWS_STORAGE_BUCKET``

The name of the region associated with the S3.
The name of s3 bucket to use.

* (Required) ``RSTUF_AWSS3_STORAGE_ACCESS_KEY``
* (Required) ``RSTUF_AWS_ACCESS_KEY_ID``

The access key to use when creating the client session to the S3.

This environment variable supports container secrets when the ``/run/secrets``
volume is added to the path.
Example: `RSTUF_AWSS3_STORAGE_ACCESS_KEY=/run/secrets/S3_ACCESS_KEY`
Example: `RSTUF_AWS_ACCESS_KEY_ID=/run/secrets/S3_ACCESS_KEY`

* (Required) ``RSTUF_AWSS3_STORAGE_SECRET_KEY``
* (Required) ``RSTUF_AWS_SECRET_ACCESS_KEY``

The secret key to use when creating the client session to the S3.

This environment variable supports container secrets when the ``/run/secrets``
volume is added to the path.
Example: ``RSTUF_AWSS3_STORAGE_ACCESS_KEY=/run/secrets/S3_SECRET_KEY``
Example: ``RSTUF_AWS_SECRET_ACCESS_KEY=/run/secrets/S3_SECRET_KEY``

* (Optional) ``RSTUF_AWSS3_STORAGE_REGION``
* (Optional) ``RSTUF_AWS_DEFAULT_REGION``

The name of the region associated with the S3.

* (Optional) ``RSTUF_AWSS3_STORAGE_ENDPOINT_URL``
* (Optional) ``RSTUF_AWS_ENDPOINT_URL``

The complete URL to use for the constructed client. Normally, the
client automatically constructs the appropriate URL to use when
Expand All @@ -177,13 +173,12 @@ In most use cases, the timeout of 60.0 seconds is sufficient.

#### `RSTUF_KEYVAULT_BACKEND`

Select a supported type of Key Vault Service.
Available types:
Select a supported type of Key Vault Service.

* `LocalKeyVault` (container volume)

**_NOTE:_** You can start the worker
service without a keyvault backend, but you need to configure one before the
service without a keyvault backend, but you need to configure one before the
[bootstrap ceremony](https://repository-service-tuf.readthedocs.io/en/latest/guide/repository-service-tuf-cli/index.html#ceremony-ceremony).

##### `LocalKeyVault` (container volume)
Expand Down Expand Up @@ -232,7 +227,7 @@ service without a keyvault backend, but you need to configure one before the

Example: ``RSTUF_LOCAL_KEYVAULT_KEYS=/run/secrets/ONLINE_KEY_1:/run/secrets/ONLINE_KEY_2``

#### (Optional, *experimental*) `RSTUF_ONLINE_KEY_DIR`
#### (Optional) `RSTUF_ONLINE_KEY_DIR`

Directory path for online signing key file. Expected file format is unencrypted PKCS8/PEM.

Expand All @@ -246,8 +241,6 @@ Example:
- RSTUF worker expects related private key under `/run/secrets/<file name>`




#### (Optional) `RSTUF_WORKER_ID`

Custom Worker ID. Default: `hostname` (Container hostname)
Expand Down
2 changes: 1 addition & 1 deletion repository_service_tuf_worker/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
#
# SPDX-License-Identifier: MIT

version = "0.13.0b1"
version = "0.14.0b1"
copyright = "Copyright (c) 2024 Repository Service for TUF Contributors"
author = "Kairo de Araujo"
54 changes: 36 additions & 18 deletions repository_service_tuf_worker/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
)
from tuf.api.metadata import ( # noqa
SPECIFICATION_VERSION,
TOP_LEVEL_ROLE_NAMES,
Delegations,
Metadata,
MetaFile,
Expand Down Expand Up @@ -471,34 +472,51 @@ def save_settings(self, root: Metadata[Root], settings: Dict[str, Any]):
settings: payload settings
"""
logging.info("Saving settings")
for role in Roles:
rolename = role.value.upper()
sorted_roles = sorted(list(TOP_LEVEL_ROLE_NAMES))
for role in sorted_roles:
role_upp = role.upper()
threshold = 1
num_of_keys = 1
if rolename == Roles.ROOT.value.upper():
if role == Root.type:
# get treshold and number of keys from given root metadata
threshold = root.signed.roles[role.value].threshold
threshold = root.signed.roles[role].threshold
num_of_keys = len(root.signatures)

self.write_repository_settings(
f"{rolename}_EXPIRATION",
settings["expiration"][role.value],
f"{role_upp}_EXPIRATION",
settings["roles"][role]["expiration"],
)
self.write_repository_settings(f"{rolename}_THRESHOLD", threshold)
self.write_repository_settings(f"{rolename}_NUM_KEYS", num_of_keys)
self.write_repository_settings(f"{role_upp}_THRESHOLD", threshold)
self.write_repository_settings(f"{role_upp}_NUM_KEYS", num_of_keys)

self.write_repository_settings(
"NUMBER_OF_DELEGATED_BINS",
settings["services"]["number_of_delegated_bins"],
)
# For now targets always uses online key.
self.write_repository_settings("TARGETS_ONLINE_KEY", True)

self.write_repository_settings(
"TARGETS_BASE_URL", settings["services"]["targets_base_url"]
)
if settings["roles"].get("bins"):
info = settings["roles"]["bins"]
self.write_repository_settings(
"BINS_EXPIRATION", info["expiration"]
)
self.write_repository_settings("BINS_THRESHOLD", 1)
self.write_repository_settings("BINS_NUM_KEYS", 1)
self.write_repository_settings(
"NUMBER_OF_DELEGATED_BINS",
info["number_of_delegated_bins"],
)

self.write_repository_settings(
"TARGETS_ONLINE_KEY", settings["services"]["targets_online_key"]
)
else:
delegated_roles = settings["roles"]["delegated_roles"]
for deleg_name, deleg_info in delegated_roles.items():
name = deleg_name.upper()
self.write_repository_settings(
f"{name}_EXPIRATION", deleg_info["expiration"]
)
self.write_repository_settings(f"{name}_THRESHOLD", 1)
self.write_repository_settings(f"{name}_NUM_KEYS", 1)
self.write_repository_settings(
f"{name}_PATH_PATTERNS",
delegated_roles[deleg_name]["path_patterns"],
)

def _bootstrap_online_roles(self, root: Metadata[Root]):
"""
Expand Down
20 changes: 10 additions & 10 deletions repository_service_tuf_worker/services/storage/awss3.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ def __init__(

@classmethod
def configure(cls, settings: Dynaconf) -> "AWSS3":
access_key = parse_if_secret(settings.AWSS3_STORAGE_ACCESS_KEY)
secret_access_key = parse_if_secret(settings.AWSS3_STORAGE_SECRET_KEY)
region = settings.get("AWSS3_STORAGE_REGION")
endpoint = settings.get("AWSS3_STORAGE_ENDPOINT_URL")
access_key = parse_if_secret(settings.AWS_ACCESS_KEY_ID)
secret_access_key = parse_if_secret(settings.AWS_SECRET_ACCESS_KEY)
region = settings.get("AWS_DEFAULT_REGION")
endpoint = settings.get("AWS_ENDPOINT_URL")

s3_session = boto3.Session(
aws_access_key_id=access_key,
Expand All @@ -58,7 +58,7 @@ def configure(cls, settings: Dynaconf) -> "AWSS3":
endpoint_url=endpoint,
)
buckets = [bucket.name for bucket in s3_resource.buckets.all()]
bucket_name = settings.AWSS3_STORAGE_BUCKET
bucket_name = settings.AWS_STORAGE_BUCKET
if bucket_name not in buckets:
raise ValueError(f"Bucket '{bucket_name}' not found.")

Expand All @@ -78,23 +78,23 @@ def configure(cls, settings: Dynaconf) -> "AWSS3":
def settings(cls) -> List[ServiceSettings]:
return [
ServiceSettings(
names=["AWSS3_STORAGE_BUCKET"],
names=["AWS_STORAGE_BUCKET"],
required=True,
),
ServiceSettings(
names=["AWSS3_STORAGE_ACCESS_KEY"],
names=["AWS_ACCESS_KEY_ID"],
required=True,
),
ServiceSettings(
names=["AWSS3_STORAGE_SECRET_KEY"],
names=["AWS_SECRET_ACCESS_KEY"],
required=True,
),
ServiceSettings(
names=["AWSS3_STORAGE_REGION"],
names=["AWS_DEFAULT_REGION"],
required=False,
),
ServiceSettings(
names=["AWSS3_STORAGE_ENDPOINT_URL"],
names=["AWS_ENDPOINT_URL"],
required=False,
),
]
Expand Down
23 changes: 17 additions & 6 deletions repository_service_tuf_worker/signer.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ class FileNameSigner(CryptoSigner):
Provide method to load **unencrypted** PKCS8/PEM private key from file.
File path is constructed by joining base path in environment variable
``RSTUF_ONLINE_KEY_DIR`` with file in ``priv_key_uri``.
``ONLINE_KEY_DIR`` with file in ``priv_key_uri``.
NOTE: Make sure to use the secrets management service of your deployment
platform to protect your private key!
Example::
RSTUF_ONLINE_KEY_DIR (env) "/run/secrets"
ONLINE_KEY_DIR (env) "/run/secrets"
priv_key_uri (arg): "fn:foo"
File path: "/run/secrets/foo"
Raises:
KeyError: RSTUF_ONLINE_KEY_DIR environment variable not set
KeyError: ONLINE_KEY_DIR environment variable not set
OSError: file cannot be loaded
ValueError: uri has no file name, or private key cannot be decoded,
or type does not match public key
Expand All @@ -47,7 +47,7 @@ class FileNameSigner(CryptoSigner):
"""

SCHEME = "fn"
DIR_VAR = "RSTUF_ONLINE_KEY_DIR"
DIR_VAR = "ONLINE_KEY_DIR"

@classmethod
def from_priv_key_uri(
Expand Down Expand Up @@ -94,6 +94,16 @@ def isolated_env(env: dict[str, str]):
os.environ.update(orig_env)


# List of Dyanconf settings needed in the signer environment
_AMBIENT_SETTING_NAMES = [
"ONLINE_KEY_DIR",
"AWS_ACCESS_KEY_ID",
"AWS_SECRET_ACCESS_KEY",
"AWS_ENDPOINT_URL",
"AWS_DEFAULT_REGION",
]


class SignerStore:
"""Generic signer store.
Expand All @@ -104,8 +114,9 @@ class SignerStore:
def __init__(self, settings: Dynaconf):
# Cache known ambient settings
self._ambient_settings: dict[str, str] = {}
if key_dir := settings.get("ONLINE_KEY_DIR"):
self._ambient_settings[FileNameSigner.DIR_VAR] = key_dir
for name in _AMBIENT_SETTING_NAMES:
if value := settings.get(name):
self._ambient_settings[name] = value

# Cache KEYVAULT setting as fallback
self._vault = settings.get("KEYVAULT")
Expand Down
8 changes: 8 additions & 0 deletions tests/files/aws/init-kms.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
awslocal kms create-key \
--key-spec RSA_4096 \
--key-usage SIGN_VERIFY

awslocal kms create-alias \
--alias-name alias/aws-test-key \
--target-key-id $(awslocal kms list-keys --query "Keys[0].KeyId" --output text)
Loading

0 comments on commit 209c23e

Please sign in to comment.