Bind typed execution context across authorization requests
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
This commit is contained in:
parent
e24437607b
commit
d8edd9e516
6 changed files with 475 additions and 4 deletions
|
|
@ -19,6 +19,7 @@ from urllib.error import HTTPError, URLError
|
|||
from urllib.request import Request, urlopen
|
||||
|
||||
from secrets_engine.approval_auth import approval_auth_configured, approval_token, credential_urlopen
|
||||
from secrets_engine.execution_contract import ExecutionContract, require_execution_deadline
|
||||
from secrets_engine.approval_claim import observe_pdp_approval_claim, validate_approval_claim
|
||||
from secrets_engine.catalog import human_control_required
|
||||
from secrets_engine.decision_check import check_decision
|
||||
|
|
@ -148,6 +149,7 @@ def _expected_request(
|
|||
fields: tuple[str, ...] = (),
|
||||
policy_targets: tuple[str, ...] = (),
|
||||
auth_targets: tuple[str, ...] = (),
|
||||
execution_contract: ExecutionContract | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""Build the exact CheckRequest both steps must agree on.
|
||||
|
||||
|
|
@ -175,6 +177,7 @@ def _expected_request(
|
|||
fields=fields,
|
||||
policy_targets=policy_targets,
|
||||
auth_targets=auth_targets,
|
||||
execution_contract=execution_contract,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -230,6 +233,7 @@ def resolve_approval_observation(
|
|||
fields: tuple[str, ...] = (),
|
||||
policy_targets: tuple[str, ...] = (),
|
||||
auth_targets: tuple[str, ...] = (),
|
||||
execution_contract: ExecutionContract | None = None,
|
||||
opener: Callable[..., Any] | None = None,
|
||||
) -> ApprovalObservation | None:
|
||||
"""Observe a fresh fact and prepare the claim-bearing request (step 1).
|
||||
|
|
@ -238,20 +242,30 @@ def resolve_approval_observation(
|
|||
human control raises instead, so no stage/demo fallback can discharge it.
|
||||
Correspondence and a consume binding require authorize_action's PDP step.
|
||||
"""
|
||||
execution_request = None
|
||||
if action == "execute-ccr" or execution_contract is not None:
|
||||
execution_request = _expected_request(
|
||||
cfg, entry, action, fields=fields, policy_targets=policy_targets,
|
||||
auth_targets=auth_targets, execution_contract=execution_contract,
|
||||
)
|
||||
# The caller's descriptor is not authenticated principal/owner evidence.
|
||||
# This requirement cannot disappear on an unserved/demo lane.
|
||||
base_url = str(getattr(cfg, "approval_url", "") or "")
|
||||
auth_configured = approval_auth_configured(cfg)
|
||||
authorization_id = _authorization_id(entry, decision)
|
||||
required_human_control = human_control_required(entry)
|
||||
required_human_control = action == "execute-ccr" or human_control_required(entry)
|
||||
if not base_url or not auth_configured or not authorization_id:
|
||||
if required_human_control:
|
||||
raise DecisionError("human_control requires a served approval claim and exact action binding")
|
||||
return None
|
||||
|
||||
expected_request = _expected_request(
|
||||
expected_request = execution_request or _expected_request(
|
||||
cfg, entry, action,
|
||||
fields=fields, policy_targets=policy_targets, auth_targets=auth_targets,
|
||||
execution_contract=execution_contract,
|
||||
)
|
||||
|
||||
require_execution_deadline(expected_request, time_window=read_window(cfg))
|
||||
claim = fetch_approval_claim(
|
||||
base_url=base_url,
|
||||
token_provider=lambda: approval_token(cfg, scope="approval:read"),
|
||||
|
|
@ -260,6 +274,8 @@ def resolve_approval_observation(
|
|||
)
|
||||
observe_pdp_approval_claim(claim, approval_id=authorization_id,
|
||||
require_human_control=required_human_control, time_window=read_window(cfg))
|
||||
require_execution_deadline(expected_request, time_window=read_window(cfg),
|
||||
bounds=(claim["validity"]["expires_at"],))
|
||||
expected_request["context"]["approval"] = claim
|
||||
return ApprovalObservation(authorization_id, expected_request, claim)
|
||||
|
||||
|
|
@ -273,6 +289,7 @@ def authorize_action(
|
|||
fields: tuple[str, ...] = (),
|
||||
policy_targets: tuple[str, ...] = (),
|
||||
auth_targets: tuple[str, ...] = (),
|
||||
execution_contract: ExecutionContract | None = None,
|
||||
opener: Callable[..., Any] | None = None,
|
||||
pdp_opener: Callable[..., Any] | None = None,
|
||||
) -> AuthorizedAction | None:
|
||||
|
|
@ -288,6 +305,7 @@ def authorize_action(
|
|||
fields=fields,
|
||||
policy_targets=policy_targets,
|
||||
auth_targets=auth_targets,
|
||||
execution_contract=execution_contract,
|
||||
opener=opener,
|
||||
)
|
||||
if observation is None:
|
||||
|
|
@ -334,6 +352,8 @@ def authorize_action(
|
|||
require_human_control=expected_request["context"].get("human_control") is True,
|
||||
time_window=window,
|
||||
)
|
||||
require_execution_deadline(expected_request, time_window=window,
|
||||
bounds=(observation.claim["validity"]["expires_at"], validated.expires_at))
|
||||
if validated.action != action:
|
||||
raise DecisionError("access-engine decision does not bind this action")
|
||||
return AuthorizedAction(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue