railiance-platform/tests/test_task_execution_trusted_whole.py
codex 7be8b6e76d
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Prove trusted task chain and prepare bounded signer custody
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
2026-10-16 17:29:12 +02:00

195 lines
13 KiB
Python

"""Exact actual source successor path; legacy fixture evidence remains separate."""
from contextlib import contextmanager
from dataclasses import replace
from datetime import datetime,timedelta,timezone
import json
from pathlib import Path
import signal
import sys
import threading
import time
from types import SimpleNamespace
import uuid
import pytest
sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'scripts'))
from test_task_execution_native_fixture import owner,bao_dev,compiler
from task_execution_trusted_servers import trusted_providers,install_exact_owner_descriptor,http,private
import task_execution_trusted_servers as providers_source
from task_execution_mediator import run_native_fixture_task
from task_execution_native_fixture import NativeFixtureAdapter,_absolute_budget
from task_execution_journal import Refused
from secrets_engine.approval_claim import binding_from_check_request
from secrets_engine.approval_consume import _expected_request
from secrets_engine.authorization import approval_binding_digest
from secrets_engine.execution_contract import ExecutionContract
@contextmanager
def whole(owner,directory,*,window_seconds=60):
# OpenBao, Approval HTTPS, TokenReview TLS and actual Access CLI are all up
# before proposing an immutable descriptor/deadline or issuing approval.
with trusted_providers(directory) as provider:
native,journal,binding,call,compiler,descriptor=install_exact_owner_descriptor(owner,window_seconds=window_seconds)
snapshot={path:compiler.read(Path(path)) for path in compiler.pins}
entry=compiler._catalogue_entry(snapshot)
approval_id=str(uuid.uuid4())
entry=replace(entry,approval={**entry.approval,'authorization_id':approval_id})
request=_expected_request(provider.cfg,entry,'execute-ccr',execution_contract=ExecutionContract.parse(descriptor))
from secrets_engine.task_execution_handoff import prepare_task_approval
preparation=prepare_task_approval(provider.cfg,entry,execution_contract=ExecutionContract.parse(descriptor))
normalization=preparation.as_owner_handoff()
assert normalization['original_request']==request
assert 'attributes' not in request['subject']
assert normalization['approval_binding_digest']!=normalization['submitted_request_digest']
now=datetime.now(timezone.utc)
body={'id':approval_id,'binding':normalization['native_binding'],'pdp_digest':normalization['approval_binding_digest'],
'pdp_path':True,'human_control':True,'required_count':1,
'validity':{'not_before':(now-timedelta(minutes=1)).isoformat(),'expires_at':(now+timedelta(minutes=3)).isoformat()}}
assert http(provider.cfg.approval_url,'POST','/v1/approvals',body,'synthetic-whole-service')[0]==201
assert http(provider.cfg.approval_url,'POST','/v1/approvals/'+approval_id+'/entries',{},provider.human_token)[0]==200
yield SimpleNamespace(native=native,journal=journal,call=call,compiler=compiler,descriptor=descriptor,
entry=entry,provider=provider,cfg=provider.cfg,approval_id=approval_id,request=request,normalization=normalization,preparation=preparation)
def invoke(fixture):
return run_native_fixture_task(compiler=fixture.compiler,journal=fixture.journal,
plan_request=fixture.native.meta['request'],owner_descriptor=fixture.native.admission.descriptor,
secrets_cfg=fixture.cfg,entry=fixture.entry,confirmation=fixture.provider.confirmation,
native_admission=fixture.native.admission)
def untouched(fixture):
assert fixture.call('GET','sys/policies/acl/'+fixture.native.policy_name)==(404,{'errors':[]})
for ordinal in [1,4]:
path=fixture.compiler.before_call(fixture.native.plan,ordinal).path
assert fixture.call('GET',path)==(404,{'errors':[]})
def test_actual_successor_allow_strict_cas_confirm_six_calls_readback_cleanup(owner,tmp_path,monkeypatch):
with whole(owner,tmp_path) as fixture:
from secrets_engine.task_execution_handoff import consume_task_execution
with pytest.raises(Exception):consume_task_execution(fixture.cfg,fixture.preparation)
assert not any(item==('consumer','POST','/v1/approvals/'+fixture.approval_id+'/consume') for item in fixture.provider.calls)
trace=[];private_task=[];issued_native=[]
original=NativeFixtureAdapter._http
def observed(native,method,path,token,body=b''):
result=original(native,method,path,token,body)
trace.append((method,path,result[0]))
if method=='POST' and path=='auth/token/create' and result[0]==200:
private_task.append((result[1]['auth']['accessor'],result[1]['auth']['client_token']))
issued_native.append(native)
return result
monkeypatch.setattr(NativeFixtureAdapter,'_http',observed)
try:result=invoke(fixture)
except Exception as error:
from urllib.error import HTTPError
cause=error.__cause__
if isinstance(cause,HTTPError):
raw=cause.read(4097)
known={b'trusted Approval source refused\n':'approval-source-correspondence',
b'service task execution input refused\n':'service-input-correspondence'}
diagnostic={'status':cause.code,'constant_reason':known.get(raw,'other-closed-classification'),
'native_operations':fixture.journal.db.execute('SELECT COUNT(*) FROM operations').fetchone()[0]}
(tmp_path/'closed-source-refusal.json').write_text(json.dumps(diagnostic))
print(json.dumps(diagnostic))
raise
assert result['native_apply']=='verified' and result['native_calls_completed']==6
assert result['cleanup_confirmed'] and result['business_state']=='cleanup-confirmed'
assert fixture.provider.engine.get(fixture.approval_id).status=='consumed'
records=[json.loads(line) for line in fixture.provider.record.read_bytes().splitlines()]
assert len(records)==2 and [x['effect'] for x in records]==['deny','allow']
assert all(x['signature']['mode']=='signed' for x in records)
normalization_record,record=records
assert normalization_record['id']==fixture.normalization['decision_id']
assert record['id']==result['decision_id']
assert record['lifetime']['expires_at']==fixture.descriptor['operation_deadline']
assert record['provenance']['policy_package']=='secrets-engine.task-execution.service-pilot'
assert record['provenance']['policy_version']=='v2'
assert record['provenance']['approval_observation']['source_id']=='synthetic-whole-actual-approval'
assert record['binding']['context']['execution_contract']==fixture.descriptor
native_calls=fixture.journal.db.execute('SELECT ordinal,outcome FROM calls ORDER BY ordinal').fetchall()
assert native_calls[:2]==[(0,'complete'),(1,'complete')] and len(native_calls)==13
assert all(value=='complete' for _,value in native_calls)
assert fixture.provider.calls.count(('consumer','POST','/v1/approvals/'+fixture.approval_id+'/consume'))==1
assert fixture.provider.calls.count(('consumer','GET','/v1/approvals/'+fixture.approval_id))==1
assert any(item==('source','GET','/v1/approvals/'+fixture.approval_id+'/claim') for item in fixture.provider.calls)
expected=fixture.compiler.proposal()['operations']
assert [(method,path) for method,path,_ in trace if path in {item['path'] for item in expected}]==[(x['method'],x['path']) for x in expected]
assert len(private_task)==1
assert issued_native[0]._task_wall_deadline<issued_native[0].deadline
assert issued_native[0]._task_monotonic_deadline<issued_native[0].monotonic_deadline
for accessor in [private_task[0][0],fixture.native.admission.identity_session.accessor]:
assert fixture.call('POST','auth/token/lookup-accessor',{'accessor':accessor})[0]==400
assert fixture.call('GET','sys/policies/acl/'+fixture.native.policy_name)==(404,{'errors':[]})
raw=(fixture.journal.directory/'journal.sqlite').read_bytes()
for secret in [*private_task[0],fixture.native.admission.owner_token,fixture.native.admission.identity_session.token]:assert secret.encode() not in raw
before=list(trace)
with pytest.raises(Exception):invoke(fixture)
assert trace==before
assert fixture.provider.calls.count(('consumer','POST','/v1/approvals/'+fixture.approval_id+'/consume'))==1
# Public evidence is an allowlist: never serialize native admission,
# credentials, private handles, arbitrary errors or provider config.
evidence={'schema':'railiance-platform.disposable-wholechain-proof.v1',
'source_effects':[x['effect'] for x in records],
'signed_source_records':all(x['signature']['mode']=='signed' for x in records),
'retained_registry_normalized':fixture.normalization['approval_binding_digest']!=fixture.normalization['submitted_request_digest'],
'approval_state':fixture.provider.engine.get(fixture.approval_id).status,
'consume_count':1,'independent_confirmation_get_count':1,
'native_calls_completed':result['native_calls_completed'],
'business_state':result['business_state'],'cleanup_confirmed':result['cleanup_confirmed'],
'durable_completed_calls':len(native_calls),'retry_refused':True,
'credential_expiry_narrows_operation_deadline':True,
'private_material_absent_from_public_journal':True,
'immediate_cas':True,'artificial_clock_or_cas_wait':False,
'production_admission':False}
(tmp_path/'wholechain-public-receipt.json').write_text(json.dumps(evidence,indent=2)+'\n')
@pytest.mark.parametrize('case',['source-drift','foreign-caller','revoked','source-reader-denied','registry-drift'])
def test_actual_successor_refusals_never_consume_or_touch_backend(owner,tmp_path,case):
with whole(owner,tmp_path) as fixture:
expected_paths=[fixture.compiler.before_call(fixture.native.plan,x).path for x in [1,4]]
if case=='source-drift':
fixture.compiler.validator.write_bytes(fixture.compiler.validator.read_bytes()+b'\n# changed source\n')
elif case=='foreign-caller':fixture.provider.state.principal='system:serviceaccount:other:other'
elif case=='revoked':
assert http(fixture.cfg.approval_url,'POST','/v1/approvals/'+fixture.approval_id+'/revoke',{},fixture.provider.human_token)[0]==200
elif case=='source-reader-denied':private(fixture.provider.reader_file,'synthetic-unknown-reader')
elif case=='registry-drift':fixture.provider.restart_registry()
with pytest.raises(Exception):invoke(fixture)
assert not any(item==('consumer','POST','/v1/approvals/'+fixture.approval_id+'/consume') for item in fixture.provider.calls)
assert fixture.journal.db.execute('SELECT COUNT(*) FROM operations').fetchone()[0]==0
records=[json.loads(line) for line in fixture.provider.record.read_bytes().splitlines()]
assert [x['effect'] for x in records]==['deny']
assert fixture.call('GET','sys/policies/acl/'+fixture.native.policy_name)==(404,{'errors':[]})
for path in expected_paths:assert fixture.call('GET',path)==(404,{'errors':[]})
def test_actual_revoke_between_prepare_and_cas_keeps_native_untouched(owner,tmp_path,monkeypatch):
import secrets_engine.task_execution_handoff as strict
with whole(owner,tmp_path) as fixture:
original=strict.consume_task_execution
def revoked(cfg,authorization):
assert http(cfg.approval_url,'POST','/v1/approvals/'+fixture.approval_id+'/revoke',{},fixture.provider.human_token)[0]==200
return original(cfg,authorization)
monkeypatch.setattr(strict,'consume_task_execution',revoked)
with pytest.raises(Refused,match='confirmation unconfirmed'):invoke(fixture)
assert fixture.journal.db.execute('SELECT state FROM operations').fetchone()[0]=='unknown'
untouched(fixture)
assert fixture.provider.engine.get(fixture.approval_id).status=='revoked'
assert [json.loads(line)['effect'] for line in fixture.provider.record.read_bytes().splitlines()]==['deny','allow']
def test_expired_contract_refuses_preparation_before_approval_or_native(owner,tmp_path):
from secrets_engine.task_execution_handoff import prepare_task_approval
with trusted_providers(tmp_path) as provider:
native,journal,binding,call,compiler,descriptor=install_exact_owner_descriptor(owner,window_seconds=-1)
snapshot={path:compiler.read(Path(path)) for path in compiler.pins}
entry=compiler._catalogue_entry(snapshot)
with pytest.raises(Exception):prepare_task_approval(provider.cfg,entry,execution_contract=ExecutionContract.parse(descriptor))
assert not provider.record.exists() or not provider.record.read_bytes()
assert not any(len(item)==3 and item[1]=='POST' for item in provider.calls)
assert journal.db.execute('SELECT COUNT(*) FROM operations').fetchone()[0]==0
assert call('GET','sys/policies/acl/'+native.policy_name)==(404,{'errors':[]})