feat(P04): nova-idp-jwks Lambda — JWKS endpoint (REQ-338, D-230, backend-engineer)
---ci--- project: acdl phase: 4 milestone: v1.28 status: execute persona: backend-engineer ---
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
"""Nova IdP JWKS endpoint Lambda (REQ-338, D-230).
|
||||
|
||||
Serves the KMS public key as a JWK in a standard JWKS response. The
|
||||
endpoint is a Lambda function URL with ``AuthType: NONE`` (JWKS is
|
||||
public-key only — configured in CloudFormation, not in code).
|
||||
|
||||
Response:
|
||||
* ``Content-Type: application/json``
|
||||
* ``Cache-Control: public, max-age=3600`` (1h — clients cache the JWKS)
|
||||
* ``Access-Control-Allow-Origin: *`` (JWKS is public)
|
||||
* ``body: {"keys": [<jwk>]}``
|
||||
|
||||
The JWK is built via :func:`core.kms_signing.get_jwk` from the KMS
|
||||
public key (DER SPKI → ``cryptography`` → JWK).
|
||||
|
||||
Dual-use (REQ-329): ``__main__`` CLI block for local testing
|
||||
(``--print-jwks``).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
OIDC_KMS_KEY_ID = os.environ.get("NOVA_OIDC_KMS_KEY_ID", "alias/nova-oidc-signing")
|
||||
|
||||
|
||||
def lambda_handler(event, context):
|
||||
"""AWS Lambda handler — serve the JWKS response (REQ-338)."""
|
||||
try:
|
||||
from core.kms_signing import get_jwk
|
||||
jwk = get_jwk(key_id=OIDC_KMS_KEY_ID)
|
||||
return {
|
||||
"statusCode": 200,
|
||||
"headers": {
|
||||
"Content-Type": "application/json",
|
||||
"Cache-Control": "public, max-age=3600",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
"body": json.dumps({"keys": [jwk]}),
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
"statusCode": 500,
|
||||
"headers": {"Content-Type": "application/json"},
|
||||
"body": json.dumps({"error": str(e)}),
|
||||
}
|
||||
|
||||
|
||||
def cli_main(argv=None):
|
||||
"""CLI entry point (REQ-329 dual-use). ``--print-jwks`` → stdout."""
|
||||
raw = argv if argv is not None else sys.argv[1:]
|
||||
if "--print-jwks" in raw:
|
||||
resp = lambda_handler({}, None)
|
||||
sys.stdout.write(resp["body"] + "\n")
|
||||
return resp.get("statusCode", 200) - 200
|
||||
print("Usage: python3 -m core.lambda.nova_idp_jwks --print-jwks", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover - CLI entry
|
||||
sys.exit(cli_main())
|
||||
Reference in New Issue
Block a user