Skip to content

Commit a89e8c7

Browse files
authored
feat(telemetry): sign requests with HMAC-SHA256 (#179)
1 parent e535ced commit a89e8c7

5 files changed

Lines changed: 66 additions & 2 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,12 @@ jobs:
2626
run: cargo fmt --check
2727
- name: Clippy
2828
run: cargo clippy -- -D warnings
29+
env:
30+
FERRFLOW_HMAC_SECRET: ${{ secrets.FERRFLOW_HMAC_SECRET }}
2931
- name: Tests
3032
run: cargo test
33+
env:
34+
FERRFLOW_HMAC_SECRET: ${{ secrets.FERRFLOW_HMAC_SECRET }}
3135

3236
coverage:
3337
name: Coverage
@@ -40,6 +44,8 @@ jobs:
4044
run: cargo install cargo-tarpaulin
4145
- name: Generate coverage
4246
run: cargo tarpaulin --out xml --skip-clean
47+
env:
48+
FERRFLOW_HMAC_SECRET: ${{ secrets.FERRFLOW_HMAC_SECRET }}
4349
- uses: codecov/codecov-action@v6
4450
with:
4551
files: cobertura.xml

‎.github/workflows/release.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,13 @@ jobs:
5959
- name: Build (Linux)
6060
if: matrix.os == 'ubuntu-latest'
6161
run: cross build --release --target ${{ matrix.target }}
62+
env:
63+
FERRFLOW_HMAC_SECRET: ${{ secrets.FERRFLOW_HMAC_SECRET }}
6264
- name: Build (macOS / Windows)
6365
if: matrix.os != 'ubuntu-latest'
6466
run: cargo build --release --target ${{ matrix.target }}
67+
env:
68+
FERRFLOW_HMAC_SECRET: ${{ secrets.FERRFLOW_HMAC_SECRET }}
6569
- name: Package (Unix)
6670
if: matrix.os != 'windows-latest'
6771
run: |

‎Cargo.lock‎

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ path = "src/lib.rs"
2828

2929
[features]
3030
default = ["cli"]
31-
cli = ["dep:git2", "dep:ureq", "dep:clap", "dep:colored"]
31+
cli = ["dep:git2", "dep:ureq", "dep:clap", "dep:colored", "dep:hmac"]
3232

3333
[dependencies]
3434
serde = { version = "1", features = ["derive"] }
@@ -47,6 +47,7 @@ git2 = { version = "0.20", features = ["vendored-libgit2", "vendored-openssl"],
4747
ureq = { version = "3", features = ["json"], optional = true }
4848
sha2 = "0.11.0"
4949
hex = "0.4.3"
50+
hmac = { version = "0.13", optional = true }
5051

5152
[dev-dependencies]
5253
cargo-husky = { version = "1", default-features = false, features = ["user-hooks"] }

‎src/telemetry.rs‎

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1+
use hmac::{Hmac, KeyInit, Mac};
12
use serde::Serialize;
23
use sha2::Digest;
4+
use std::time::{SystemTime, UNIX_EPOCH};
5+
6+
type HmacSha256 = Hmac<sha2::Sha256>;
37

48
const DEFAULT_API_URL: &str = "https://api.ferrflow.com";
59

10+
fn hmac_secret() -> &'static str {
11+
option_env!("FERRFLOW_HMAC_SECRET").unwrap_or(env!("FERRFLOW_HMAC_SECRET"))
12+
}
13+
614
#[derive(Debug, Clone, Copy, Serialize)]
715
#[serde(rename_all = "snake_case")]
816
#[allow(dead_code)]
@@ -83,11 +91,30 @@ pub fn send_event(
8391
let url = format!("{}/events", api_url());
8492

8593
std::thread::spawn(move || {
94+
let body = match serde_json::to_string(&payload) {
95+
Ok(b) => b,
96+
Err(_) => return,
97+
};
98+
99+
let timestamp = SystemTime::now()
100+
.duration_since(UNIX_EPOCH)
101+
.unwrap()
102+
.as_secs()
103+
.to_string();
104+
105+
let message = format!("{timestamp}.{body}");
106+
let mut mac = HmacSha256::new_from_slice(hmac_secret().as_bytes())
107+
.expect("HMAC accepts any key length");
108+
mac.update(message.as_bytes());
109+
let signature = hex::encode(mac.finalize().into_bytes());
110+
86111
let agent = ureq::Agent::new_with_defaults();
87112
let _ = agent
88113
.post(&url)
89114
.header("Content-Type", "application/json")
90-
.send_json(&payload);
115+
.header("X-Timestamp", &timestamp)
116+
.header("X-Signature", &signature)
117+
.send(body.as_bytes());
91118
});
92119
}
93120

0 commit comments

Comments
 (0)