Send organization_id when the MAS gate lists the application's API keys.
The attended mint run on 2026-11-03 got HTTP 400 from the key listing before any key was minted. A Console session needs organization_id there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 4541@bnt-lap001 Assistant-Session: 2099b3aa-d7d9-49a9-ab4e-fa8b7d0e39e8
This commit is contained in:
parent
fbc4830aa0
commit
de13931c75
3 changed files with 24 additions and 9 deletions
|
|
@ -671,11 +671,16 @@ def write_pair(pair):
|
|||
return summary
|
||||
|
||||
|
||||
def _app_keys(api):
|
||||
value = api(
|
||||
"GET",
|
||||
"/iam/v1alpha1/api-keys?application_id=" + APPLICATION_ID + "&page_size=100",
|
||||
)
|
||||
def _app_keys(api, organization):
|
||||
"""List the application's keys. A Console session needs organization_id or gets HTTP 400."""
|
||||
from urllib.parse import urlencode
|
||||
|
||||
query = urlencode({
|
||||
"organization_id": organization,
|
||||
"application_id": APPLICATION_ID,
|
||||
"page_size": 100,
|
||||
})
|
||||
value = api("GET", "/iam/v1alpha1/api-keys?" + query)
|
||||
keys = value.get("api_keys") if isinstance(value, dict) else None
|
||||
if not isinstance(keys, list) or value.get("total_count") != len(keys):
|
||||
raise GateError("key_inventory_rejected")
|
||||
|
|
@ -699,9 +704,10 @@ def mint_workload_pair(api, prove, write, sleep=time.sleep):
|
|||
"""
|
||||
receipt = {"application_id": APPLICATION_ID, "values_recorded": False}
|
||||
app = api("GET", "/iam/v1alpha1/applications/" + APPLICATION_ID)
|
||||
if app.get("name") != POLICY_NAME:
|
||||
organization = app.get("organization_id")
|
||||
if app.get("name") != POLICY_NAME or not isinstance(organization, str) or not organization:
|
||||
raise GateError("application_binding_refused")
|
||||
before = _app_keys(api)
|
||||
before = _app_keys(api, organization)
|
||||
receipt["keys_before"] = _key_view(before)
|
||||
if len(before) != 1 or before[0].get("default_project_id") != PROJECT_ID:
|
||||
raise GateError("supplier_key_state_requires_review", receipt["keys_before"])
|
||||
|
|
@ -745,7 +751,7 @@ def mint_workload_pair(api, prove, write, sleep=time.sleep):
|
|||
detail = dict(exc.detail or {}) if isinstance(exc, GateError) and isinstance(exc.detail, dict) else {}
|
||||
detail["minted_key_deleted"] = deleted
|
||||
raise GateError(code, detail) from None
|
||||
receipt["keys_after"] = _key_view(_app_keys(api))
|
||||
receipt["keys_after"] = _key_view(_app_keys(api, organization))
|
||||
receipt["status"] = "passed"
|
||||
return receipt
|
||||
|
||||
|
|
|
|||
|
|
@ -269,8 +269,9 @@ class _FakeConsole:
|
|||
def __call__(self, method, path, data=None):
|
||||
self.calls.append((method, path))
|
||||
if method == "GET" and path.startswith("/iam/v1alpha1/applications/"):
|
||||
return {"name": self.name}
|
||||
return {"name": self.name, "organization_id": "org-1"}
|
||||
if method == "GET" and path.startswith("/iam/v1alpha1/api-keys?"):
|
||||
assert "organization_id=org-1" in path and "application_id=" + gate.APPLICATION_ID in path
|
||||
return {"api_keys": list(self.keys), "total_count": len(self.keys)}
|
||||
if method == "POST":
|
||||
assert data["application_id"] == gate.APPLICATION_ID
|
||||
|
|
|
|||
|
|
@ -104,6 +104,14 @@ The supplier key stays founder custody and can be revoked separately.
|
|||
Tests cover the mint, retry, deletion and refusal paths. The attended
|
||||
run is still pending.
|
||||
|
||||
2026-11-03 05:36 CET: the first attended `--mint-workload` run exited with
|
||||
`provider_http_error`, a GET returning HTTP 400, before any key was minted.
|
||||
The denials receipt was not rewritten and the pair stayed empty. Cause: the
|
||||
API-key listing omitted `organization_id`, which a Console session requires.
|
||||
`mas_evidence_iam_grant.py` already sends it. Fix: the gate takes
|
||||
`organization_id` from the application read and sends it on both key
|
||||
listings. The next attended run is the same command.
|
||||
|
||||
## Admit delivery and place the node file
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue