Use bounded Railiance time for protected validity checks
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a09cbb-87c6-7900-a145-4ce53ba9f1a6
This commit is contained in:
tegwick 2026-09-15 22:16:31 +02:00
parent 5841d8e88a
commit f4b4dd6b17
8 changed files with 514 additions and 14 deletions

View file

@ -28,6 +28,7 @@ from secrets_engine.authorization import (
wait_for_decision_start,
)
from secrets_engine.errors import DecisionError
from secrets_engine.application_time import read_window, recheck_binding
from secrets_engine.openbao import read_strict_token_file
from secrets_engine.pep_stance import demo_exception_enabled
@ -43,6 +44,8 @@ class ConsumeBinding:
request_digest: str
decision_id: str = ""
human_control: bool = False
decision_not_before: str = ""
decision_expires_at: str = ""
@dataclass(frozen=True)
@ -256,7 +259,7 @@ def resolve_approval_observation(
opener=opener or credential_urlopen,
)
observe_pdp_approval_claim(claim, approval_id=authorization_id,
require_human_control=required_human_control)
require_human_control=required_human_control, time_window=read_window(cfg))
expected_request["context"]["approval"] = claim
return ApprovalObservation(authorization_id, expected_request, claim)
@ -313,19 +316,23 @@ def authorize_action(
request=expected_request,
opener=pdp_opener or urlopen,
)
wait_for_decision_start(envelope)
if not getattr(cfg, "clock_trust_file", None):
wait_for_decision_start(envelope)
window = read_window(cfg)
validated = validate_decision_envelope(
envelope,
expected_request,
accepted_policy_packages={package},
accepted_policy_versions={version},
expected_approval_binding_digest=observation.claim["binding"]["pdp_digest"],
time_window=window,
)
# Recheck freshness after the network call before issuing a consume binding.
validate_approval_claim(
observation.claim, approval_id=observation.approval_id,
expected_pdp_digest=envelope["binding"]["approval_binding_digest"],
require_human_control=expected_request["context"].get("human_control") is True,
time_window=window,
)
if validated.action != action:
raise DecisionError("access-engine decision does not bind this action")
@ -335,6 +342,8 @@ def authorize_action(
request_digest=validated.request_digest,
decision_id=validated.decision_id,
human_control=observation.claim["binding"].get("human_control") is True,
decision_not_before=envelope["lifetime"].get("not_before") or "",
decision_expires_at=validated.expires_at,
),
decision_id=validated.decision_id,
expires_at=validated.expires_at,
@ -462,6 +471,7 @@ def require_production_consume(
"production OpenBao call requires approval-engine consume; "
"SECRETS_ENGINE_APPROVAL_TOKEN_FILE or _CLIENT_SECRET_FILE is unset"
)
recheck_binding(cfg, binding)
consumed = consume_approval(
base_url=base_url,
token_provider=lambda: approval_token(cfg, scope="approval:consume"),
@ -470,6 +480,7 @@ def require_production_consume(
)
if evidence is not None and hasattr(evidence, "mark_consumed"):
evidence.mark_consumed(consumed)
recheck_binding(cfg, binding)
return consumed