Skip to content

QKMS Authentication Bug Report #509

@ngmisl

Description

@ngmisl

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions