"""Pin the cross-account principal surface of the CDK app. The SHOC integration deliberately trusts EXACTLY ONE foreign principal: ``arn:aws:iam::396287094661:role/shoc-backend-dev`` (read API resource policy in procurement_api_stack.py, HMAC secret + KMS grants in wo_stack.py). Future shoc-backend-staging/-prod roles are each a deliberate, individually-reviewed policy addition — so any new foreign account id or role ARN appearing in cdk/ must consciously update this pin (and go through the mandatory GPT-4.1 cross-family IAM review). Raised as a QUESTION in the 2026-07-24 cross-family review of the webhook emitter policy surface: "how is the exact-one-principal invariant enforced over time?" — this test is the answer. """ import re from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] CDK_DIR = REPO_ROOT / "cdk" # The one foreign principal the app may reference, and the only files # allowed to reference it. ALLOWED_FOREIGN_PRINCIPAL = "arn:aws:iam::396287094661:role/shoc-backend-dev" ALLOWED_FILES = {"procurement_api_stack.py", "wo_stack.py"} # Accounts that are not "foreign": seahaven-prod (the deploy target). HOME_ACCOUNTS = {"011934824531"} _IAM_ARN_RE = re.compile(r"arn:aws:iam::(\d{12}):\S*?(?=[\"'\s])") def _cdk_sources(): return sorted(CDK_DIR.glob("*.py")) def test_only_the_pinned_foreign_principal_appears_in_cdk_sources(): findings = [] for path in _cdk_sources(): for match in _IAM_ARN_RE.finditer(path.read_text()): account = match.group(1) if account in HOME_ACCOUNTS: continue findings.append((path.name, match.group(0))) unexpected = [ (name, arn) for name, arn in findings if arn != ALLOWED_FOREIGN_PRINCIPAL or name not in ALLOWED_FILES ] assert not unexpected, ( "Unexpected foreign IAM principal(s) in cdk/ — every cross-account " f"trust addition must update this pin deliberately: {unexpected}" ) # Both grant sites must still reference the pinned role (deleting one # half of the secret/KMS grant pair fails silently at the receiver). assert {name for name, _ in findings} == ALLOWED_FILES