···3737# JWT signing token
3838#
3939# Set this to the Base64 encoding of some random data.
4040+# You can also set it via the `ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64` environment
4141+# variable.
4042token-hs256-secret-base64 = "%token_hs256_secret_base64%"
41434244# Database connection
+18
server/src/config.rs
···2525/// This is useful for deploying to certain application platforms like Fly.io
2626const ENV_CONFIG_BASE64: &str = "ATTIC_SERVER_CONFIG_BASE64";
27272828+/// Environment variable storing the Base64-encoded HS256 JWT secret.
2929+const ENV_TOKEN_HS256_SECRET_BASE64: &str = "ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64";
3030+2831#[derive(Clone)]
2932pub struct JwtKeys {
3033 pub decoding: JwtDecodingKey,
···100103 /// Set this to the base64 encoding of a randomly generated secret.
101104 #[serde(rename = "token-hs256-secret-base64")]
102105 #[serde(deserialize_with = "deserialize_base64_jwt_secret")]
106106+ #[serde(default = "JwtKeys::load_from_env")]
103107 #[derivative(Debug = "ignore")]
104108 pub token_hs256_secret: JwtKeys,
105109}
···183187 #[serde(rename = "default-retention-period")]
184188 #[serde(with = "humantime_serde", default = "default_default_retention_period")]
185189 pub default_retention_period: Duration,
190190+}
191191+192192+impl JwtKeys {
193193+ fn load_from_env() -> Self {
194194+ let s = env::var(ENV_TOKEN_HS256_SECRET_BASE64)
195195+ .expect("The HS256 secret must be specified in either token_hs256_secret or the ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64 environment.");
196196+197197+ let decoding = JwtDecodingKey::from_base64_secret(&s)
198198+ .expect("Failed to load as decoding key");
199199+ let encoding = JwtEncodingKey::from_base64_secret(&s)
200200+ .expect("Failed to load as decoding key");
201201+202202+ Self { decoding, encoding }
203203+ }
186204}
187205188206impl CompressionConfig {