diff --git a/dvc/config.py b/dvc/config.py index a43cb16f2f..193bb73321 100644 --- a/dvc/config.py +++ b/dvc/config.py @@ -149,6 +149,8 @@ class RelPath(str): "profile": str, "credentialpath": str, "endpointurl": str, + "access_key_id": str, + "secret_access_key": str, Optional("listobjects", default=False): Bool, Optional("use_ssl", default=True): Bool, "sse": str, diff --git a/dvc/tree/s3.py b/dvc/tree/s3.py index 17d58301f1..154c757992 100644 --- a/dvc/tree/s3.py +++ b/dvc/tree/s3.py @@ -54,6 +54,9 @@ def __init__(self, repo, config): self._append_aws_grants_to_extra_args(config) + self.access_key_id = config.get("access_key_id") + self.secret_access_key = config.get("secret_access_key") + shared_creds = config.get("credentialpath") if shared_creds: os.environ.setdefault("AWS_SHARED_CREDENTIALS_FILE", shared_creds) @@ -63,9 +66,14 @@ def __init__(self, repo, config): def s3(self): import boto3 - session = boto3.session.Session( - profile_name=self.profile, region_name=self.region - ) + session_opts = dict(profile_name=self.profile, region_name=self.region) + + if self.access_key_id: + session_opts["aws_access_key_id"] = self.access_key_id + if self.secret_access_key: + session_opts["aws_secret_access_key"] = self.secret_access_key + + session = boto3.session.Session(**session_opts) return session.client( "s3", endpoint_url=self.endpoint_url, use_ssl=self.use_ssl diff --git a/tests/unit/remote/test_s3.py b/tests/unit/remote/test_s3.py index 570371c0c7..f2e631b98c 100644 --- a/tests/unit/remote/test_s3.py +++ b/tests/unit/remote/test_s3.py @@ -6,6 +6,8 @@ bucket_name = "bucket-name" prefix = "some/prefix" url = f"s3://{bucket_name}/{prefix}" +key_id = "key-id" +key_secret = "key-secret" @pytest.fixture(autouse=True) @@ -57,3 +59,12 @@ def test_grants_mutually_exclusive_acl_error(dvc, grants): def test_sse_kms_key_id(dvc): tree = S3RemoteTree(dvc, {"url": url, "sse_kms_key_id": "key"}) assert tree.extra_args["SSEKMSKeyId"] == "key" + + +def test_key_id_and_secret(dvc): + tree = S3RemoteTree( + dvc, + {"url": url, "access_key_id": key_id, "secret_access_key": key_secret}, + ) + assert tree.access_key_id == key_id + assert tree.secret_access_key == key_secret