Support FIPS-compatible API signing#213
Open
andrijapanicsb wants to merge 1 commit into
Open
Conversation
Signed-off-by: andrijapanicsb <andrija.panic@gmail.com>
|
✅ Build complete for PR #213. 📦 Binary artifacts are available in the workflow run (expires on June 12, 2026).
|
There was a problem hiding this comment.
Pull request overview
Adds FIPS-compatible CloudStack API request signing to CloudMonkey by introducing HmacSHA512 support with an auto mode that probes listApis to select and persist the working algorithm per profile.
Changes:
- Add
signaturealgorithmprofile setting (auto,HmacSHA512,HmacSHA1) with normalization and migration toauto. - Implement request signing with HmacSHA512 and autodetection via
listApisprobe before executing user commands. - Update prompt to show a
-fipsmarker when the active profile uses HmacSHA512; add unit tests covering config migration, signing, and autodetection behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
config/prompt.go |
Adds -fips prompt marker when the active profile is using HmacSHA512. |
config/config.go |
Introduces signature algorithm constants, profile field, normalization, and migration/persistence behavior. |
config/config_test.go |
Adds tests for default/migrated signaturealgorithm and prompt indicator behavior. |
cmd/set.go |
Adds signaturealgorithm to set subcommands and updates validation behavior. |
cmd/network.go |
Adds HmacSHA512 signing, autodetection probe flow, and refactors API request building/response parsing. |
cmd/network_test.go |
Adds tests for SHA1/SHA512 signatures and autodetection/fallback/persistence semantics. |
Comments suppressed due to low confidence (1)
cmd/set.go:72
- The
setcommand bypasses argument validation forsignaturealgorithm, which means invalid values won’t cause the command to fail consistently (other subcommands return an error). Consider validating via NormalizeSignatureAlgorithm so case/whitespace are accepted, but invalid values still return an error and a non-zero exit status.
validArgs := r.Command.SubCommands[subCommand]
if len(validArgs) != 0 && subCommand != "timeout" && subCommand != "signaturealgorithm" {
if !config.CheckIfValuePresent(validArgs, value) {
return errors.New("Invalid value set for " + subCommand + ". Supported values: " + strings.Join(validArgs, ", "))
}
}
r.Config.UpdateConfig(subCommand, value, true)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+377
to
+379
| body, _ := ioutil.ReadAll(response.Body) | ||
| config.Debug("Signature algorithm probe response body:", string(body)) | ||
| if _, err := parseAPIResponse(body); err == nil { |
Comment on lines
+383
to
+390
| } else { | ||
| lastErr = err | ||
| if isAuthenticationFailure(response.StatusCode, err) { | ||
| config.Debug("API signature algorithm probe failed authentication for ", algorithm, ": ", err) | ||
| } else { | ||
| config.Debug("API signature algorithm probe failed with non-authentication error for ", algorithm, ": ", err) | ||
| } | ||
| } |
Comment on lines
+536
to
538
| func processAPIResponse(r *Request, response *http.Response, isAsync bool) (map[string]interface{}, error) { | ||
| body, _ := ioutil.ReadAll(response.Body) | ||
| config.Debug("NewAPIRequest response body:", string(body)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Support FIPS-compatible API request signing in CloudMonkey
Summary
This change adds support for CloudStack API key request signing with
HmacSHA512, while preserving compatibility with older CloudStack deployments that still require or allowHmacSHA1.CloudMonkey profiles now support a profile-level
signaturealgorithmsetting:autoHmacSHA512HmacSHA1New and migrated profiles default to
auto. Inautomode, CloudMonkey probes the active endpoint with the read-onlylistApisAPI, tryingHmacSHA512first and falling back toHmacSHA1only if the SHA-512 probe fails authentication/signature verification. Once a probe succeeds, the concrete algorithm is persisted to the active profile before the user-requested API command is executed.This avoids retrying user-requested APIs directly and prevents duplicate execution of state-changing commands during signature algorithm detection.
Motivation
When legacy algorithms are disabled, CloudStack rejects API requests signed with
HmacSHA1and accepts modernHmacSHA512signatures. CloudMonkey previously signed API key requests withHmacSHA1only, so API key authentication failed against such deployments.This change allows CloudMonkey to work with FIPS-compatible CloudStack environments while keeping existing legacy deployments usable without manual trial and error.
Behavior
New or migrated profiles
If
signaturealgorithmis absent from an existing profile, CloudMonkey writes:signaturealgorithm = autoAuto detection
When API key and secret key authentication is used and the active profile is set to
auto, CloudMonkey:Sends a read-only
listApis listall=trueprobe signed withHmacSHA512.If that succeeds, persists:
signaturealgorithm = HmacSHA512If SHA-512 fails authentication/signature verification, retries the same read-only probe with
HmacSHA1.If SHA-1 succeeds, persists:
signaturealgorithm = HmacSHA1Executes the original user-requested API only after detection has completed.
Explicit configuration
If a profile explicitly sets
HmacSHA512orHmacSHA1, CloudMonkey uses only that configured algorithm and does not silently fall back.Prompt indicator
Profiles using
HmacSHA512show a-fipsmarker in the interactive prompt. For example:The marker indicates that CloudMonkey is using the FIPS-compatible CloudStack API signing algorithm. It does not imply full end-to-end FIPS validation of the local environment.
Debug logging
Auto-detection probe attempts are logged only when debug mode is enabled. Normal interactive output is not noisy when fallback succeeds.
Debug output includes which signature algorithm probe is attempted, which probe fails, and which algorithm is selected.
Testing
Automated tests added:
HmacSHA1signature generation against a fixed request stringHmacSHA512signature generation against a fixed request stringsignaturealgorithm = autosignaturealgorithmis migrated toautoHmacSHA512does not silently tryHmacSHA1autopersistsHmacSHA512when the SHA-512 probe succeedsautofalls back and persistsHmacSHA1when SHA-512 fails but SHA-1 succeedsautodoes not retry the user-requested API directly, avoiding duplicate execution risk for state-changing APIs-fipswhen the active profile usesHmacSHA512Command run:
Lab verification
Verified against a CloudStack lab environment.
With legacy algorithms enabled:
autoselected and persistedHmacSHA512syncsucceeded and discovered 878 APIsWith legacy algorithms disabled:
Control checks:
signaturealgorithm = HmacSHA1failed with HTTP 401 signature verification errorsignaturealgorithm = HmacSHA512succeededsignaturealgorithm = autosucceeded and persistedHmacSHA512Observed result:
Performance note
I also compared SHA-1 and SHA-512 signing overhead during local validation.
Local signer-only measurement showed SHA-512 signing is slower than SHA-1 in isolation, but still on the order of microseconds per request. Lab API request latency was dominated by network and CloudStack server round-trip time, with no meaningful API-level bottleneck observed from using
HmacSHA512.Benchmark tooling and result artifacts are not included in this PR.
Compatibility
signaturealgorithmmigrate toauto.HmacSHA1remain supported through auto fallback or explicitHmacSHA1configuration.HmacSHA512.Notes
The detection probe intentionally uses
listApisbefore executing the user-requested API so that state-changing APIs are not retried as part of algorithm detection.