Summary
All QKMS API calls fail with NotAuthorizedException from both the QConsole frontend and direct API calls with AWS SigV4 signing. The same credentials work correctly against QStorage.
Environment
- QConsole web UI (qconsole.quilibrium.com)
- Direct curl against qkms.quilibrium.com
- IAM: Root user with AdministratorAccess policy
- Access Key: AKIA... (active, verified working against QStorage)
Issue 1: QConsole frontend sends no auth headers
The makeKmsApiCall function in the QConsole frontend (index-C7PkJe3z.js:12377) performs a plain window.fetch to https://qkms.quilibrium.com/ without attaching any authentication headers (no Authorization, no X-Amz-Date, no SigV4 signature).
Affected operations: CreateKey, RegisterSidecar (likely all QKMS calls)
Call stack:
window.fetch
makeKmsApiCall @ index-C7PkJe3z.js:12377
createKey @ index-C7PkJe3z.js:12377
mutationFn @ index-C7PkJe3z.js:12377
Request payload sent by UI (from dev tools):
{
"KeyUsage": "ENCRYPT_DECRYPT",
"KeySpec": "SYMMETRIC_DEFAULT",
"Description": "test-key-1",
"Threshold": 2,
"TotalParties": 2,
"Participants": ["service"]
}
Response:
{
"__type": "NotAuthorizedException",
"message": "Request is missing required authentication parameters"
}
Note: The payload also has a mismatch: Threshold: 2 and TotalParties: 2 but only one participant (["service"]) is selected. The UI shows "1/2 participants selected" in orange, but still allows submission.
Issue 2: Direct API calls with SigV4 also fail
Properly signed SigV4 requests sent via curl are also rejected by the QKMS endpoint. The same credentials and signing method work against QStorage.
Working QStorage call (same credentials):
curl -X GET https://qstorage.quilibrium.com/ \
--aws-sigv4 "aws:amz:us-east-1:s3" \
--user "$ACCESS_KEY:$SECRET_KEY" \
-H "X-Amz-Content-Sha256: UNSIGNED-PAYLOAD"
# Returns: AccessDenied (auth works, just no ListBuckets permission)
Failing QKMS call:
curl -X POST https://qkms.quilibrium.com/ \
--aws-sigv4 "aws:amz:us-east-1:kms" \
--user "$ACCESS_KEY:$SECRET_KEY" \
-H "Content-Type: application/x-amz-json-1.1" \
-H "X-Amz-Target: TrentService.CreateKey" \
-H "X-Amz-Content-Sha256: UNSIGNED-PAYLOAD" \
-d '{"KeyUsage":"ENCRYPT_DECRYPT","KeySpec":"SYMMETRIC_DEFAULT","Description":"test-key-1"}'
# Returns: 400 NotAuthorizedException
Verbose output confirms the Authorization header is present and well-formed:
Authorization: AWS4-HMAC-SHA256
Credential=AKIA.../20260216/us-east-1/kms/aws4_request,
SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target,
Signature=5ea52e...
Variations tested (all return same error):
| Variation |
Result |
Service name kms |
NotAuthorizedException |
Service name qkms |
NotAuthorizedException |
With X-Amz-Content-Sha256: UNSIGNED-PAYLOAD |
NotAuthorizedException |
| With actual SHA-256 body hash |
NotAuthorizedException |
With empty X-Amz-Security-Token header |
NotAuthorizedException |
| ListKeys instead of CreateKey |
NotAuthorizedException |
Conclusion
The QKMS backend does not appear to be processing SigV4 authentication at all. The endpoint is live behind Cloudflare (TLS works, CORS headers are set correctly, it returns structured JSON errors), but the auth validation layer is not wired up. QStorage auth works fine with the same credentials, confirming the issue is specific to QKMS.
Summary
All QKMS API calls fail with
NotAuthorizedExceptionfrom both the QConsole frontend and direct API calls with AWS SigV4 signing. The same credentials work correctly against QStorage.Environment
Issue 1: QConsole frontend sends no auth headers
The
makeKmsApiCallfunction in the QConsole frontend (index-C7PkJe3z.js:12377) performs a plainwindow.fetchtohttps://qkms.quilibrium.com/without attaching any authentication headers (no Authorization, no X-Amz-Date, no SigV4 signature).Affected operations: CreateKey, RegisterSidecar (likely all QKMS calls)
Call stack:
Request payload sent by UI (from dev tools):
{ "KeyUsage": "ENCRYPT_DECRYPT", "KeySpec": "SYMMETRIC_DEFAULT", "Description": "test-key-1", "Threshold": 2, "TotalParties": 2, "Participants": ["service"] }Response:
{ "__type": "NotAuthorizedException", "message": "Request is missing required authentication parameters" }Note: The payload also has a mismatch:
Threshold: 2andTotalParties: 2but only one participant (["service"]) is selected. The UI shows "1/2 participants selected" in orange, but still allows submission.Issue 2: Direct API calls with SigV4 also fail
Properly signed SigV4 requests sent via curl are also rejected by the QKMS endpoint. The same credentials and signing method work against QStorage.
Working QStorage call (same credentials):
Failing QKMS call:
Verbose output confirms the Authorization header is present and well-formed:
Variations tested (all return same error):
kmsqkmsX-Amz-Content-Sha256: UNSIGNED-PAYLOADX-Amz-Security-TokenheaderConclusion
The QKMS backend does not appear to be processing SigV4 authentication at all. The endpoint is live behind Cloudflare (TLS works, CORS headers are set correctly, it returns structured JSON errors), but the auth validation layer is not wired up. QStorage auth works fine with the same credentials, confirming the issue is specific to QKMS.