updated changelog

This commit is contained in:
Mick Grove 2026-01-30 08:07:12 -08:00
commit 5eb743711b
4 changed files with 14 additions and 17 deletions

View file

@ -2,6 +2,13 @@
All notable changes to this project will be documented in this file.
## [v1.77.0]
- Added `kingfisher revoke` subcommand for revoking leaked credentials directly with the provider.
- Added optional `revocation` section to rules to support credential revocation (currently supporting AWS, GCP, GitHub, GitLab, and Slack).
- Added `kingfisher validate` subcommand to validate credentials without running a full scan.
- Refactored project into multiple crates for better modularity and maintainability.
- Ensured more CLI arguments are global and available across all subcommands.
## [v1.76.0]
- Fixed validation deduplication for rules with nested unnamed captures (e.g. `(?<REGEX>...(ABC|DEF)...)`) to use the primary capture for grouping, ensuring each unique match triggers a separate validation request.
- Added trace-level (`-vv`) logging for internal validation dedup keys and grouping to aid debugging.

View file

@ -93,7 +93,7 @@ fn main() -> anyhow::Result<()> {
Command::SelfUpdate => 1, // Self-update doesn't need a thread pool
Command::Rules(_) => num_cpus::get(), // Default for Rules commands
Command::Validate(_) => 1, // Single validation request
Command::Revoke(_) => 1, // Single revocation request
Command::Revoke(_) => 1, // Single revocation request
Command::AccessMap(_) => 1,
Command::View(_) => 1,
};
@ -212,8 +212,7 @@ async fn async_main(args: CommandLineArgs) -> Result<()> {
}
}
Command::Revoke(revoke_args) => {
let results =
direct_revoke::run_direct_revocation(&revoke_args, &global_args).await?;
let results = direct_revoke::run_direct_revocation(&revoke_args, &global_args).await?;
let use_color = global_args.use_color(std::io::stdout());
direct_revoke::print_results(&results, &revoke_args.format, use_color);
// Exit with code 0 if any result revoked, 1 if all failed

View file

@ -8,8 +8,8 @@ pub mod rule {
}
// Re-export everything from the rules module
pub use kingfisher_rules::rules::{Rules, RulesError};
pub use kingfisher_rules::rule::Revocation;
pub use kingfisher_rules::rules::{Rules, RulesError};
pub use kingfisher_rules::{
ChecksumActual, ChecksumRequirement, Confidence, DependsOnRule, HttpRequest, HttpValidation,
MultipartConfig, MultipartPart, PatternRequirementContext, PatternRequirements,

View file

@ -108,9 +108,7 @@ pub async fn revoke_gcp_service_account_key(
}
if project_id.is_empty() || client_email.is_empty() || key_id.is_empty() {
return Err(anyhow!(
"Missing required GCP fields: project_id/client_email/private_key_id"
));
return Err(anyhow!("Missing required GCP fields: project_id/client_email/private_key_id"));
}
let ctx = validator.get_access_token_from_sa_json(gcp_json).await?;
@ -122,18 +120,11 @@ pub async fn revoke_gcp_service_account_key(
encode(&key_id),
);
let response = validator
.client()
.delete(url)
.bearer_auth(&ctx.access_token)
.send()
.await?;
let response = validator.client().delete(url).bearer_auth(&ctx.access_token).send().await?;
let status = response.status();
let body = response
.text()
.await
.unwrap_or_else(|e| format!("Failed to read response body: {}", e));
let body =
response.text().await.unwrap_or_else(|e| format!("Failed to read response body: {}", e));
let message = if body.trim().is_empty() { status.to_string() } else { body };
Ok(GcpRevocationOutcome {