Skip to content

Commit

Permalink
chore(docker): Run pyoci as non-root user (#64)
Browse files Browse the repository at this point in the history
I also tweaked some dependency features that were not in use.
  • Loading branch information
AllexVeldman authored Oct 7, 2024
1 parent ad8dec0 commit 1cea1b7
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 78 deletions.
68 changes: 2 additions & 66 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ strip = "symbols"

[features]
default = ["otlp"]
# TODO: check if otlp can be disabled
otlp = [
"dep:opentelemetry-proto",
"dep:opentelemetry",
Expand All @@ -31,15 +30,14 @@ otlp = [


[dependencies]
bytes = "1.7.2"
exitcode = "1.1.2"
oci-spec = { version = "0.6.8", default-features = false, features = ["image", "distribution"] }
url = "2.5.2"
regex = "1.10.6"
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["time", "env-filter", "fmt", "json"] }
reqwest = { version = "0.12.8", default-features = false, features = ["json", "stream", "rustls-tls"] }
askama = "0.12.1"
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "fmt"] }
reqwest = { version = "0.12.8", default-features = false, features = ["json", "rustls-tls"] }
askama = { version = "0.12.1", default-features = false }
base64 = "0.22.1"
serde = { version = "1.0.202", features = ["derive"] }
serde_json = "1.0.128"
Expand Down Expand Up @@ -72,3 +70,5 @@ indoc = "2.0.5"
mockito = "1.5.0"
test-case = "3.3.1"
tokio = { version = "1.40.0", features = ["test-util"]}
bytes = "1.7.2"
reqwest = { version = "0.12.8", default-features = false, features = ["stream"] }
6 changes: 6 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ FROM rust:1.81.0 AS builder
RUN rustup target add x86_64-unknown-linux-musl
RUN apt update && apt install -y musl-tools musl-dev

RUN useradd -u 10001 pyoci

WORKDIR /app

# Build the dependencies as a separate step so they get cached.
Expand All @@ -19,11 +21,15 @@ RUN cargo build --release --target x86_64-unknown-linux-musl

FROM scratch

COPY --from=builder /etc/passwd /etc/passwd

ENV PORT=8080
EXPOSE $PORT

# Copy the binary from the builder stage
WORKDIR /app
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/pyoci pyoci

USER pyoci

CMD ["./pyoci"]
7 changes: 3 additions & 4 deletions src/pyoci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl Blob {
}
}

fn digest(data: &[u8]) -> String {
fn digest(data: impl AsRef<[u8]>) -> String {
let sha = <Sha256 as Digest>::digest(data);
format!("sha256:{}", hex_encode(&sha))
}
Expand Down Expand Up @@ -592,9 +592,8 @@ impl PyOci {
}
Manifest::Manifest(manifest) => {
let data = serde_json::to_string(&manifest)?;
let sha = <Sha256 as Digest>::digest(&data);
let digest = format!("sha256:{}", hex_encode(&sha));
let url = build_url!(&self, "/v2/{}/manifests/{}", name, &digest);
let data_digest = digest(&data);
let url = build_url!(&self, "/v2/{}/manifests/{}", name, &data_digest);
(url, data, "application/vnd.oci.image.manifest.v1+json")
}
};
Expand Down
6 changes: 3 additions & 3 deletions src/service/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,13 @@ where
tracing::debug!("Received 401 response, authenticating");
if this.request.is_none() {
// No clone of the original request, can't retry after authentication
tracing::debug!("No request to retry, skipping authentication");
tracing::info!("No request to retry, skipping authentication");
return Poll::Ready(Ok(response));
}
// Take the basic token, we are only expected to trade it once
let Some(basic_token) = this.auth.basic.take() else {
// No basic token to trade for a bearer token
tracing::debug!("No basic token, skipping authentication");
tracing::info!("No basic token, skipping authentication");
return Poll::Ready(Ok(response));
};

Expand Down Expand Up @@ -357,7 +357,7 @@ mod tests {
assert_eq!(response.text().await.unwrap(), "Hello, world!");
}

// The if the original response it returned if the request can't be cloned.
// Test if the original response it returned if the request can't be cloned.
// Without a clone we can't retry after authentication.
#[tokio::test]
async fn auth_service_missing_clone() {
Expand Down

0 comments on commit 1cea1b7

Please sign in to comment.