---ci--- project: acdl phase: 4 milestone: v1.28 status: execute persona: security-engineer ---
2.0 KiB
KMS asymmetric key provisioning (C-1.1)
This document records the C-1.1 verification for the Nova OIDC signing
KMS key and the provisioning path used by nova idp setup.
C-1.1 verification (P4)
C-1.1 requires verifying KMS asymmetric key support before implementation. The verification command is:
aws kms create-key \
--key-spec ECC_NIST_P256 \
--key-usage SIGN_VERIFY \
--description nova-oidc-signing
Result on the P4 build host: AWS credentials are not available
(Unable to locate credentials), so the live verification could not
run. This is recorded as a P4 CI gate: the nova idp setup --check
command (Wave 8) performs this verification when AWS creds are present
and reports it as a missing prerequisite when they are not. The code
proceeds against the documented KMS API (REQ-337); tests use a test
ECDSA P-256 keypair + mocked boto3.client("kms") (no real AWS calls).
KMS asymmetric signing keys (ECC_NIST_P256 + SIGN_VERIFY) are GA
in all commercial regions (announced 2020-11). The
ECDSA_SHA_256 signing algorithm is supported. Confidence: high.
Key spec (REQ-337)
- Key spec:
ECC_NIST_P256(NIST P-256 / secp256r1) - Key usage:
SIGN_VERIFY - Signing algorithm:
ECDSA_SHA_256(JWSES256) - Alias:
alias/nova-oidc-signing - Rotation: manual, 90 days (matches D-069 CMK cadence). New key +
re-point alias + JWKS serves both
kids during overlap.
DER → raw ECDSA conversion (the #1 gotcha)
KMS sign() returns a DER-encoded ASN.1 ECDSA signature. JWS
(RFC 7515 §3.1.3) requires the raw r‖s concatenation, each
coordinate 32 bytes big-endian. The conversion (in
core/kms_signing.py:der_to_raw_ecdsa):
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
r, s = decode_dss_signature(der_sig)
raw = r.to_bytes(32, "big") + s.to_bytes(32, "big")
This is verified by tests/test_kms_signing.py and the CAP-037
round-trip test (tests/test_kms_roundtrip.py).