andrijapanicsb opened a new pull request, #213:
URL: https://github.com/apache/cloudstack-cloudmonkey/pull/213
# 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 allow `HmacSHA1`.
CloudMonkey profiles now support a profile-level `signaturealgorithm`
setting:
- `auto`
- `HmacSHA512`
- `HmacSHA1`
New and migrated profiles default to `auto`. In `auto` mode, CloudMonkey
probes the active endpoint with the read-only `listApis` API, trying
`HmacSHA512` first and falling back to `HmacSHA1` only 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 `HmacSHA1` and accepts modern `HmacSHA512` signatures. CloudMonkey
previously signed API key requests with `HmacSHA1` only, 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 `signaturealgorithm` is absent from an existing profile, CloudMonkey
writes:
```ini
signaturealgorithm = auto
```
### Auto detection
When API key and secret key authentication is used and the active profile is
set to `auto`, CloudMonkey:
1. Sends a read-only `listApis listall=true` probe signed with `HmacSHA512`.
2. If that succeeds, persists:
```ini
signaturealgorithm = HmacSHA512
```
3. If SHA-512 fails authentication/signature verification, retries the same
read-only probe with `HmacSHA1`.
4. If SHA-1 succeeds, persists:
```ini
signaturealgorithm = HmacSHA1
```
5. Executes the original user-requested API only after detection has
completed.
### Explicit configuration
If a profile explicitly sets `HmacSHA512` or `HmacSHA1`, CloudMonkey uses
only that configured algorithm and does not silently fall back.
### Prompt indicator
Profiles using `HmacSHA512` show a `-fips` marker in the interactive prompt.
For example:
```text
(localcloud-fips) cmk >
```
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:
- `HmacSHA1` signature generation against a fixed request string
- `HmacSHA512` signature generation against a fixed request string
- default profile uses `signaturealgorithm = auto`
- missing `signaturealgorithm` is migrated to `auto`
- explicit `HmacSHA512` does not silently try `HmacSHA1`
- `auto` persists `HmacSHA512` when the SHA-512 probe succeeds
- `auto` falls back and persists `HmacSHA1` when SHA-512 fails but SHA-1
succeeds
- `auto` does not retry the user-requested API directly, avoiding duplicate
execution risk for state-changing APIs
- prompt shows `-fips` when the active profile uses `HmacSHA512`
Command run:
```text
go test ./...
```
## Lab verification
Verified against a CloudStack lab environment.
With legacy algorithms enabled:
```text
api.legacy.algorithm.supported=true
```
- `auto` selected and persisted `HmacSHA512`
- read-only `sync` succeeded and discovered 878 APIs
With legacy algorithms disabled:
```text
api.legacy.algorithm.supported=false
```
Control checks:
- forced `signaturealgorithm = HmacSHA1` failed with HTTP 401 signature
verification error
- forced `signaturealgorithm = HmacSHA512` succeeded
- `signaturealgorithm = auto` succeeded and persisted `HmacSHA512`
Observed result:
```text
forced HmacSHA1:
HTTP 401: unable to verify user credentials and/or request signature
forced HmacSHA512:
Discovered 878 APIs
auto detection:
Discovered 878 APIs
signaturealgorithm = HmacSHA512
```
## 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
- Existing profiles without `signaturealgorithm` migrate to `auto`.
- Older CloudStack deployments that only support `HmacSHA1` remain supported
through auto fallback or explicit `HmacSHA1` configuration.
- CloudStack deployments with legacy algorithms disabled are supported
through `HmacSHA512`.
- Username/password session authentication is not changed.
## Notes
The detection probe intentionally uses `listApis` before executing the
user-requested API so that state-changing APIs are not retried as part of
algorithm detection.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]