"""Source-only builder tests; mocks confer no real grant or principal admission.""" import copy from dataclasses import replace import json from datetime import datetime, timedelta, timezone import pytest from secrets_engine.approval_consume import consume_approval, _expected_request, authorize_action, resolve_approval_observation from secrets_engine.authorization import approval_binding_digest, build_action_request, request_digest from secrets_engine.catalog import validate_entry from secrets_engine.errors import DecisionError from secrets_engine.execution_contract import ExecutionContract, catalog_target_digest from tests.test_catalog import VALID from tests.test_consume_binding_join import _Cfg, _token, _opener, APPROVAL_ID from tests.authorization_stub import AuthorizationStub H = 'sha256:' + 'a' * 64 def entry(): raw = copy.deepcopy(VALID) raw['stage'] = 'prod' raw['approval'] = {'model': 'bootstrap-only', 'authorization_id': APPROVAL_ID, 'purpose': 'metadata-test'} return validate_entry(raw) def descriptor(e): baseline = build_action_request(e, 'apply', subject_id='secrets-engine', subject_type='service', purpose='metadata-test') return { 'contract_version': 'SECRETS-EXEC-20261011-v1', 'operation_id': 'cbfbced0-09d5-48c8-a1e7-a2ea4dc69153', 'operation': 'metadata-apply-ccr', 'execution_actor': 'service:secrets-engine', 'ccr_id': 'CCR-2099-0001', 'ccr_immutable_sha256': H, 'execution_grant_ccr_id': 'CCR-2099-0002', 'grant_immutable_sha256': H, 'catalog_sha256': catalog_target_digest(baseline['context']['catalog_target']), 'source_bundle': {name: {'path': '/owner/'+name+'.py', 'sha256': H} for name in ['engine_dispatcher', 'platform_mediator', 'typed_ccr', 'policy_auth']}, 'backend_origin': 'http://127.0.0.1:18200', 'cluster_uid': 'test-estate-not-live', 'operations': [{'method': 'GET', 'path': 'sys/policies/acl/test-policy', 'payload_sha256': H}, {'method': 'PUT', 'path': 'auth/netkingdom/role/test-role', 'payload_sha256': H}], 'operation_deadline': (datetime.now(timezone.utc)+timedelta(seconds=60)).isoformat(), 'backend_budget': {'ttl_seconds': 120, 'uses': 12}, 'expected_before': H, 'expected_after': H, } def request(e, contract): return build_action_request(e, 'execute-ccr', subject_id='secrets-engine', subject_type='service', purpose='metadata-test', execution_contract=contract) def served(pdp): claim = pdp.claim() claim['binding']['human_control'] = True return claim def test_four_builders_preserve_context_and_binding(tmp_path): e = entry(); raw = descriptor(e); contract = ExecutionContract.parse(raw) cfg = _Cfg(_token(tmp_path), authorization_subject_id='secrets-engine', authorization_subject_type='service') expected = request(e, contract) assert expected['context']['human_control'] is True assert _expected_request(cfg,e,'execute-ccr',execution_contract=contract) == expected pdp = AuthorizationStub(approval_id=APPROVAL_ID, package=cfg.authorization_policy_package, version=cfg.authorization_policy_version) pdp.bind_request(expected); claim = served(pdp) observed = resolve_approval_observation(cfg,e,'execute-ccr',None,execution_contract=contract,opener=_opener(claim)) assert observed.request['context']['execution_contract'] == raw assert approval_binding_digest(observed.request) == request_digest(expected) assert request_digest(observed.request) != request_digest(expected) submitted=[] def check(req, timeout=None): value=json.loads(req.data); submitted.append(value) return _opener(pdp.decision(value))(req) authorized = authorize_action(cfg,e,'execute-ccr',execution_contract=contract,opener=_opener(claim),pdp_opener=check) assert authorized.binding.request_digest == request_digest(submitted[0]) assert submitted[0] == observed.request from tests.test_approval_consume import _Response consume_bodies = [] def consume(req, timeout=None): value = json.loads(req.data); consume_bodies.append(value) return _Response(200, {'status':'consumed', 'approval_id':APPROVAL_ID, 'request_digest':value['request_digest'], 'decision_id':value['decision_id'], 'consumed_at':datetime.now(timezone.utc).isoformat(), 'idempotent':False}) confirmed = consume_approval(base_url=cfg.approval_url, token_file=cfg.approval_token_file, binding=authorized.binding, opener=consume) assert consume_bodies == [{'request_digest':request_digest(submitted[0]), 'decision_id':authorized.decision_id}] assert confirmed.request_digest != request_digest(expected) raw['operations'][0]['path']='sys/policies/acl/changed' observed.request['context']['execution_contract']['source_bundle']['typed_ccr']['path']='/changed.py' assert contract.as_dict()['operations'][0]['path']=='sys/policies/acl/test-policy' assert contract.as_dict()['source_bundle']['typed_ccr']['path']=='/owner/typed_ccr.py' @pytest.mark.parametrize('change', ['operation_id','ccr','grant','source','body','method','path','budget','deadline','state','cluster']) def test_changed_binding_cannot_use_original_claim(tmp_path,change): e=entry(); original=descriptor(e); cfg=_Cfg(_token(tmp_path),authorization_subject_id='secrets-engine',authorization_subject_type='service') pdp=AuthorizationStub(approval_id=APPROVAL_ID,package=cfg.authorization_policy_package,version=cfg.authorization_policy_version) pdp.bind_request(request(e,ExecutionContract.parse(original))); claim=served(pdp) changed=copy.deepcopy(original) if change=='operation_id': changed[change]='775ab8f4-4731-47c8-bd98-342af22885dd' elif change=='ccr': changed['ccr_immutable_sha256']='sha256:'+'b'*64 elif change=='grant': changed['grant_immutable_sha256']='sha256:'+'b'*64 elif change=='source': changed['source_bundle']['typed_ccr']['sha256']='sha256:'+'b'*64 elif change=='body': changed['operations'][1]['payload_sha256']='sha256:'+'b'*64 elif change=='method': changed['operations'][0]['method']='PUT' elif change=='path': changed['operations'][0]['path']='sys/policies/acl/changed' elif change=='budget': changed['backend_budget']['uses']=11 elif change=='deadline': changed['operation_deadline']=(datetime.now(timezone.utc)+timedelta(seconds=50)).isoformat() elif change=='state': changed['expected_before']='sha256:'+'b'*64 elif change=='cluster': changed['cluster_uid']='different-estate' typed=ExecutionContract.parse(changed) assert approval_binding_digest(request(e,typed)) != pdp._pdp_digest def check(req,timeout=None): return _opener(pdp.decision(json.loads(req.data)))(req) with pytest.raises(DecisionError,match='digest'): authorize_action(cfg,e,'execute-ccr',execution_contract=typed,opener=_opener(claim),pdp_opener=check) @pytest.mark.parametrize('mutation', ['unknown','extra_nested','missing','wrong_actor','boolean_budget','oversize_budget','sibling_endpoint','path_traversal','source_relative','wrong_hash','bad_deadline','method_object']) def test_closed_schema_refuses(mutation): raw=descriptor(entry()) if mutation=='unknown': raw['approved']=True elif mutation=='extra_nested': raw['backend_budget']['renewable']=True elif mutation=='missing': del raw['source_bundle']['typed_ccr'] elif mutation=='wrong_actor': raw['execution_actor']='user:admin' elif mutation=='boolean_budget': raw['backend_budget']['uses']=True elif mutation=='oversize_budget': raw['backend_budget']['ttl_seconds']=121 elif mutation=='sibling_endpoint': raw['operations'][0]['path']='secret/data/x' elif mutation=='path_traversal': raw['operations'][0]['path']='auth/a/role/../x' elif mutation=='source_relative': raw['source_bundle']['typed_ccr']['path']='foo.py' elif mutation=='wrong_hash': raw['expected_after']='unsafe' elif mutation=='bad_deadline': raw['operation_deadline']='2026-10-11T10:00:00' elif mutation=='method_object': raw['operations'][0]['method']={} with pytest.raises(DecisionError): ExecutionContract.parse(raw) @pytest.mark.parametrize('action', ['apply','rotate','exec','execute-ccr']) def test_invalid_action_or_absent_contract_refuses_before_claim(tmp_path,action): e=entry(); cfg=_Cfg(_token(tmp_path),authorization_subject_id='secrets-engine',authorization_subject_type='service'); calls=[] def fetch(*args,**kwargs): calls.append('claim'); raise AssertionError contract=None if action=='execute-ccr' else ExecutionContract.parse(descriptor(e)) with pytest.raises(DecisionError): authorize_action(cfg,e,action,execution_contract=contract,opener=fetch,pdp_opener=fetch) assert calls==[] def test_catalog_mismatch_and_unserved_execution_refuse(tmp_path): e=entry(); typed=ExecutionContract.parse(descriptor(e)); e=replace(e,path='changed/path') cfg=_Cfg(_token(tmp_path),authorization_subject_id='secrets-engine',authorization_subject_type='service'); calls=[] with pytest.raises(DecisionError,match='catalog'): resolve_approval_observation(cfg,e,'execute-ccr',None,execution_contract=typed,opener=lambda *a,**k:calls.append('claim')) assert not calls e=entry(); cfg.approval_url='' with pytest.raises(DecisionError,match='human_control'): resolve_approval_observation(cfg,e,'execute-ccr',None,execution_contract=ExecutionContract.parse(descriptor(e))) def test_expired_contract_refuses_before_claim(tmp_path): e=entry(); raw=descriptor(e); raw['operation_deadline']=(datetime.now(timezone.utc)-timedelta(seconds=1)).isoformat() cfg=_Cfg(_token(tmp_path),authorization_subject_id='secrets-engine',authorization_subject_type='service'); calls=[] with pytest.raises(DecisionError,match='expired'): authorize_action(cfg,e,'execute-ccr',execution_contract=ExecutionContract.parse(raw),opener=lambda *a,**k:calls.append('claim')) assert not calls @pytest.mark.parametrize('changed', ['subject', 'purpose', 'catalog', 'tenant', 'stage']) def test_request_correspondence_changes_refuse_before_authorization(tmp_path, changed): e = entry(); contract = ExecutionContract.parse(descriptor(e)) cfg = _Cfg(_token(tmp_path),authorization_subject_id='secrets-engine',authorization_subject_type='service') pdp = AuthorizationStub(approval_id=APPROVAL_ID,package=cfg.authorization_policy_package,version=cfg.authorization_policy_version) pdp.bind_request(request(e,contract)); claim = served(pdp) if changed == 'subject': cfg.authorization_subject_id = 'foreign-service' elif changed == 'purpose': e = replace(e,approval={**e.approval, 'purpose':'different-purpose'}) elif changed == 'catalog': e = replace(e,path='changed/path') elif changed == 'stage': e = replace(e,stage='test') calls = [] def check(req,timeout=None): calls.append('check'); return _opener(pdp.decision(json.loads(req.data)))(req) with pytest.raises(DecisionError): if changed == 'tenant': build_action_request(e,'execute-ccr',subject_id='secrets-engine',subject_type='service',purpose='metadata-test',tenant='tenant:foreign',execution_contract=contract) else: authorize_action(cfg,e,'execute-ccr',execution_contract=contract,opener=_opener(claim),pdp_opener=check) if changed in {'catalog','stage','tenant'}: assert not calls def test_raw_dictionary_and_direct_invalid_type_cannot_bypass_validation(): e = entry() with pytest.raises(DecisionError): request(e,descriptor(e)) with pytest.raises(DecisionError): request(e,ExecutionContract('{}')) def test_deadline_beyond_claim_refuses_before_pdp(tmp_path): e=entry(); raw=descriptor(e); raw['operation_deadline']=(datetime.now(timezone.utc)+timedelta(hours=2)).isoformat() contract=ExecutionContract.parse(raw); cfg=_Cfg(_token(tmp_path),authorization_subject_id='secrets-engine',authorization_subject_type='service') pdp=AuthorizationStub(approval_id=APPROVAL_ID,package=cfg.authorization_policy_package,version=cfg.authorization_policy_version) pdp.bind_request(request(e,contract)); calls=[] with pytest.raises(DecisionError,match='exceeds served authority'): authorize_action(cfg,e,'execute-ccr',execution_contract=contract,opener=_opener(served(pdp)),pdp_opener=lambda *a,**k:calls.append('check')) assert not calls # Reuse admitted native producer signing, never bypass responder verification. from tests.test_consume_binding_join import admitted_native_signer from tests.signature_support import signature_tools def test_execution_service_declaration_is_fixed_before_issue(): e=entry();contract=ExecutionContract.parse(descriptor(e)) built=request(e,contract) assert built['context']['service_actor_binding']=={ 'version':'proposed-service-task-caller/v1', 'transport_principal':'system:serviceaccount:secrets-engine:secrets-engine', 'subject_id':'secrets-engine','subject_type':'service','tenant':'tenant:platform'} assert built['subject']=={'id':'secrets-engine','type':'service','tenant':'tenant:platform'} assert built['resource']['tenant']=='tenant:platform' assert 'service_actor_binding' not in build_action_request(e,'apply',subject_id='secrets-engine',subject_type='service',purpose='metadata-test')['context'] @pytest.mark.parametrize('subject_id,subject_type',[('other','service'),('secrets-engine','Human'),('user:alice','Human')]) def test_execution_declaration_cannot_assert_foreign_service(subject_id,subject_type): e=entry();contract=ExecutionContract.parse(descriptor(e)) with pytest.raises(DecisionError,match='service subject'): build_action_request(e,'execute-ccr',subject_id=subject_id,subject_type=subject_type,purpose='metadata-test',execution_contract=contract)