#!/usr/bin/env python3 from __future__ import annotations import argparse import os import re import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] RUNTIME_DIR = ROOT / "deployments" / "offline" / "runtime" sys.path.insert(0, str(RUNTIME_DIR)) from common import ( # noqa: E402 DeployError, named_credential_master_key_sha256, ) SHA256_RE = re.compile(r"[0-9a-f]{64}") def verify_master_key_fingerprint( master_key_b64: str, expected_prod_fingerprint: str, *, mode: str, ) -> str: expected = expected_prod_fingerprint.strip().lower() if not SHA256_RE.fullmatch(expected): raise DeployError( "prod NamedCredential master-key fingerprint must be 64 lowercase hex characters" ) observed = named_credential_master_key_sha256(master_key_b64) if mode == "staging-isolated": if observed == expected: raise DeployError( "staging NEXUSCRM_NC_MASTER_KEY must differ from prod" ) elif mode == "prod-match": if observed != expected: raise DeployError( "prod NEXUSCRM_NC_MASTER_KEY does not match the configured prod fingerprint" ) else: raise DeployError(f"unsupported master-key fingerprint verification mode: {mode}") return observed def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser( description=( "Fail closed unless the active NamedCredential master key matches " "the environment isolation contract" ), ) parser.add_argument( "--key-env", default="NEXUSCRM_NC_MASTER_KEY", help="environment variable containing the base64 key; never pass the key on argv", ) parser.add_argument( "--prod-fingerprint-env", default="NEXUSCRM_NC_MASTER_KEY_PROD_SHA256", help="environment variable containing the non-secret prod SHA-256 fingerprint", ) parser.add_argument( "--mode", required=True, choices=("staging-isolated", "prod-match"), ) return parser.parse_args() def main() -> int: args = parse_args() master_key = os.environ.get(args.key_env, "").strip() if not master_key: raise DeployError(f"missing NamedCredential master key in {args.key_env}") prod_fingerprint = os.environ.get(args.prod_fingerprint_env, "").strip() if not prod_fingerprint: raise DeployError( f"missing prod NamedCredential master-key fingerprint in " f"{args.prod_fingerprint_env}" ) verify_master_key_fingerprint( master_key, prod_fingerprint, mode=args.mode, ) print(f"verified NamedCredential master-key fingerprint contract: mode={args.mode}") return 0 if __name__ == "__main__": try: raise SystemExit(main()) except DeployError as exc: print( f"NamedCredential master-key fingerprint verification failed: {exc}", file=sys.stderr, ) raise SystemExit(1)