diff --git a/Cargo.lock b/Cargo.lock index 5ba27d6..9420b28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,7 +28,7 @@ dependencies = [ [[package]] name = "ambient-id" -version = "0.0.4" +version = "0.0.5" dependencies = [ "reqwest", "reqwest-middleware", diff --git a/Cargo.toml b/Cargo.toml index 6710eca..7531472 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ambient-id" -version = "0.0.4" +version = "0.0.5" authors = ["William Woodruff "] edition = "2024" description = "Detects ambient OIDC credentials in a variety of environments" diff --git a/src/github.rs b/src/github.rs index bd06d28..d2d3d6a 100644 --- a/src/github.rs +++ b/src/github.rs @@ -1,27 +1,21 @@ +//! GitHub Actions OIDC token detection. + use reqwest_middleware::ClientWithMiddleware; use crate::{DetectionState, DetectionStrategy}; +/// Possible errors during GitHub Actions OIDC token detection. #[derive(Debug, thiserror::Error)] pub enum Error { /// The GitHub Actions environment lacks necessary permissions. + /// + /// This is typically resolved by adding `id-token: write` to the + /// job's `permissions` block. + #[error("insufficient permissions: {0}")] InsufficientPermissions(&'static str), - /// The HTTP request to fetch the ID token failed (in middleware). - Middleware(#[from] reqwest_middleware::Error), - /// The HTTP request to fetch the ID token failed (in reqwest). - Request(#[from] reqwest::Error), -} - -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Error::InsufficientPermissions(what) => { - write!(f, "insufficient permissions: {what}") - } - Error::Middleware(err) => write!(f, "HTTP request failed: {err}"), - Error::Request(err) => write!(f, "HTTP request failed: {err}"), - } - } + /// The HTTP request to fetch the ID token failed. + #[error("HTTP request failed: {0}")] + Request(#[from] reqwest_middleware::Error), } /// The JSON payload returned by GitHub's ID token endpoint. @@ -68,9 +62,11 @@ impl DetectionStrategy for GitHubActions { .query(&[("audience", audience)]) .send() .await? - .error_for_status()? + .error_for_status() + .map_err(reqwest_middleware::Error::Reqwest)? .json::() - .await?; + .await + .map_err(reqwest_middleware::Error::Reqwest)?; Ok(crate::IdToken(resp.value.into())) } diff --git a/src/gitlab.rs b/src/gitlab.rs index 898e5cc..f613433 100644 --- a/src/gitlab.rs +++ b/src/gitlab.rs @@ -1,18 +1,15 @@ +//! GitLab CI OIDC token detection. + use crate::{DetectionState, DetectionStrategy}; +/// Possible errors during GitLab CI OIDC token detection. #[derive(Debug, thiserror::Error)] pub enum Error { + /// The expected environment variable for the ID token was not found. + #[error("ID token variable not found: {0}")] Missing(String), } -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Error::Missing(what) => write!(f, "ID token variable not found: {what}"), - } - } -} - pub(crate) struct GitLabCI; impl GitLabCI { diff --git a/src/lib.rs b/src/lib.rs index c0eac33..0709547 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,9 @@ use secrecy::{ExposeSecret, SecretString}; mod github; mod gitlab; +pub use github::Error as GitHubError; +pub use gitlab::Error as GitLabError; + /// A detected ID token. /// /// This is a newtype around a [`SecretString`] that ensures zero-on-drop @@ -49,10 +52,10 @@ impl IdToken { pub enum Error { /// An error occurred while detecting GitHub Actions credentials. #[error("GitHub Actions detection error")] - GitHubActions(#[from] github::Error), + GitHubActions(#[from] GitHubError), /// An error occurred while detecting GitLab CI credentials. #[error("GitLab CI detection error")] - GitLabCI(#[from] gitlab::Error), + GitLabCI(#[from] GitLabError), } #[derive(Default)]