Skip to content

Commit 1a9392a

Browse files
Sarunikssylvestre
authored andcommitted
Add possibility to specify credentials for S3 explicitly
1 parent 9958e7c commit 1a9392a

File tree

5 files changed

+57
-6
lines changed

5 files changed

+57
-6
lines changed

docs/Configuration.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ endpoint = "s3-us-east-1.amazonaws.com"
9292
use_ssl = true
9393
key_prefix = "s3prefix"
9494
server_side_encryption = false
95+
access_key_id = "aws_access_key_id"
96+
secret_access_key = "aws_secret_access_key"
9597

9698
[cache.webdav]
9799
endpoint = "http://192.168.10.42:80/some/webdav.php"
@@ -154,6 +156,8 @@ configuration variables
154156
* `SCCACHE_REGION` s3 region, required if using AWS S3
155157
* `SCCACHE_S3_USE_SSL` s3 endpoint requires TLS, set this to `true`
156158
* `SCCACHE_S3_KEY_PREFIX` s3 key prefix (optional)
159+
* `SCCACHE_AWS_ACCESS_KEY_ID` AWS access key (optional). If not specified, sccache will attempt to load credentials from other sources (see [S3 credentials](S3.md#credentials))
160+
* `SCCACHE_AWS_SECRET_ACCESS_KEY` AWS secret key (optional). If not specified, sccache will attempt to load credentials from other sources (see [S3 credentials](S3.md#credentials))
157161

158162
The endpoint used then becomes `${SCCACHE_BUCKET}.s3-{SCCACHE_REGION}.amazonaws.com`.
159163
If you are not using the default endpoint and `SCCACHE_REGION` is undefined, it

docs/S3.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ Cloudflare R2 is an S3-compatible object storage and works with the same configu
2323

2424
## Credentials
2525

26-
Sccache is able to load credentials from various sources. Including:
26+
You can specify credentials using environment variables (`SCCACHE_AWS_ACCESS_KEY_ID` and `SCCACHE_AWS_SECRET_ACCESS_KEY`) or [file configuration](Configuration.md#file) (`access_key_id` and `secret_access_key`).
27+
28+
If credentials are not specified, sccache will attempt to load credentials from various other sources, including:
2729

2830
- Static: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
2931
- Profile: `~/.aws/credentials` and `~/.aws/config`. The AWS_PROFILE environment variable can be used to select a specific profile if multiple profiles are available.

src/cache/cache.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,8 @@ pub fn storage_from_config(
685685
c.endpoint.as_deref(),
686686
c.use_ssl,
687687
c.server_side_encryption,
688+
c.access_key_id.as_deref(),
689+
c.secret_access_key.as_deref(),
688690
)
689691
.map_err(|err| anyhow!("create s3 cache failed: {err:?}"))?;
690692

src/cache/s3.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::errors::*;
2121
pub struct S3Cache;
2222

2323
impl S3Cache {
24+
#[allow(clippy::too_many_arguments)]
2425
pub fn build(
2526
bucket: &str,
2627
region: Option<&str>,
@@ -29,12 +30,22 @@ impl S3Cache {
2930
endpoint: Option<&str>,
3031
use_ssl: Option<bool>,
3132
server_side_encryption: Option<bool>,
33+
access_key_id: Option<&str>,
34+
secret_access_key: Option<&str>,
3235
) -> Result<Operator> {
3336
let mut builder = S3::default();
3437
builder.http_client(set_user_agent());
3538
builder.bucket(bucket);
3639
builder.root(key_prefix);
3740

41+
if let Some(access_key_id) = access_key_id {
42+
builder.access_key_id(access_key_id);
43+
}
44+
45+
if let Some(secret_access_key) = secret_access_key {
46+
builder.secret_access_key(secret_access_key);
47+
}
48+
3849
if let Some(region) = region {
3950
builder.region(region);
4051
}

src/config.rs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,8 @@ pub struct S3CacheConfig {
315315
pub endpoint: Option<String>,
316316
pub use_ssl: Option<bool>,
317317
pub server_side_encryption: Option<bool>,
318+
pub access_key_id: Option<String>,
319+
pub secret_access_key: Option<String>,
318320
}
319321

320322
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
@@ -640,6 +642,8 @@ fn config_from_env() -> Result<EnvConfig> {
640642
let server_side_encryption = bool_from_env_var("SCCACHE_S3_SERVER_SIDE_ENCRYPTION")?;
641643
let endpoint = env::var("SCCACHE_ENDPOINT").ok();
642644
let key_prefix = key_prefix_from_env_var("SCCACHE_S3_KEY_PREFIX");
645+
let access_key_id = env::var("SCCACHE_AWS_ACCESS_KEY_ID").ok();
646+
let secret_access_key = env::var("SCCACHE_AWS_SECRET_ACCESS_KEY").ok();
643647

644648
Some(S3CacheConfig {
645649
bucket,
@@ -649,14 +653,18 @@ fn config_from_env() -> Result<EnvConfig> {
649653
endpoint,
650654
use_ssl,
651655
server_side_encryption,
656+
access_key_id,
657+
secret_access_key,
652658
})
653659
} else {
654660
None
655661
};
656662

657663
if s3.as_ref().map(|s3| s3.no_credentials).unwrap_or_default()
658664
&& (env::var_os("AWS_ACCESS_KEY_ID").is_some()
659-
|| env::var_os("AWS_SECRET_ACCESS_KEY").is_some())
665+
|| env::var_os("AWS_SECRET_ACCESS_KEY").is_some()
666+
|| env::var_os("SCCACHE_AWS_ACCESS_KEY_ID").is_some()
667+
|| env::var_os("SCCACHE_AWS_SECRET_ACCESS_KEY").is_some())
660668
{
661669
bail!("If setting S3 credentials, SCCACHE_S3_NO_CREDENTIALS must not be set.");
662670
}
@@ -1309,7 +1317,27 @@ fn config_overrides() {
13091317

13101318
#[test]
13111319
#[serial]
1312-
fn test_s3_no_credentials_conflict() {
1320+
fn test_s3_no_credentials_conflict_0() {
1321+
env::set_var("SCCACHE_S3_NO_CREDENTIALS", "true");
1322+
env::set_var("SCCACHE_BUCKET", "my-bucket");
1323+
env::set_var("SCCACHE_AWS_ACCESS_KEY_ID", "aws-access-key-id");
1324+
env::set_var("SCCACHE_AWS_SECRET_ACCESS_KEY", "aws-secret-access-key");
1325+
1326+
let error = config_from_env().unwrap_err();
1327+
assert_eq!(
1328+
"If setting S3 credentials, SCCACHE_S3_NO_CREDENTIALS must not be set.",
1329+
error.to_string()
1330+
);
1331+
1332+
env::remove_var("SCCACHE_S3_NO_CREDENTIALS");
1333+
env::remove_var("SCCACHE_BUCKET");
1334+
env::remove_var("SCCACHE_AWS_ACCESS_KEY_ID");
1335+
env::remove_var("SCCACHE_AWS_SECRET_ACCESS_KEY");
1336+
}
1337+
1338+
#[test]
1339+
#[serial]
1340+
fn test_s3_no_credentials_conflict_1() {
13131341
env::set_var("SCCACHE_S3_NO_CREDENTIALS", "true");
13141342
env::set_var("SCCACHE_BUCKET", "my-bucket");
13151343
env::set_var("AWS_ACCESS_KEY_ID", "aws-access-key-id");
@@ -1479,8 +1507,10 @@ region = "us-east-2"
14791507
endpoint = "s3-us-east-1.amazonaws.com"
14801508
use_ssl = true
14811509
key_prefix = "s3prefix"
1482-
no_credentials = true
1510+
no_credentials = false
14831511
server_side_encryption = false
1512+
access_key_id = "some_access_key_id"
1513+
secret_access_key = "some_secret_access_key"
14841514
14851515
[cache.webdav]
14861516
endpoint = "http://127.0.0.1:8080"
@@ -1543,8 +1573,10 @@ no_credentials = true
15431573
endpoint: Some("s3-us-east-1.amazonaws.com".to_owned()),
15441574
use_ssl: Some(true),
15451575
key_prefix: "s3prefix".into(),
1546-
no_credentials: true,
1547-
server_side_encryption: Some(false)
1576+
no_credentials: false,
1577+
server_side_encryption: Some(false),
1578+
access_key_id: Some("some_access_key_id".to_owned()),
1579+
secret_access_key: Some("some_secret_access_key".to_owned()),
15481580
}),
15491581
webdav: Some(WebdavCacheConfig {
15501582
endpoint: "http://127.0.0.1:8080".to_string(),

0 commit comments

Comments
 (0)