Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
153 lines
8.8 KiB
Python
153 lines
8.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Protected signer CAS primitive. Disposable owner fixture only; no live entry.
|
|
|
|
This module deliberately cannot admit production custody. A reviewed native CCR,
|
|
protected executor, fencing and founder scope are prerequisites for that adapter.
|
|
"""
|
|
from __future__ import annotations
|
|
from dataclasses import dataclass,field
|
|
from datetime import datetime,timezone
|
|
import base64
|
|
import hashlib
|
|
import hmac
|
|
import http.client
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import re
|
|
import secrets
|
|
import subprocess
|
|
|
|
from cryptography.hazmat.primitives import serialization
|
|
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
|
|
from task_execution_journal import Journal,Refused
|
|
from task_execution_native_fixture import _absolute_budget
|
|
from task_execution_recovery import _json_unique,_invalid_constant
|
|
|
|
PATH='platform/data/workloads/flex-auth/envelope-signing'
|
|
FIELDS={'ED25519_PRIVATE_KEY','ED25519_PUBLIC_KEY','kid'}
|
|
BINDINGS={'proposal_sha256','executed_revision_sha256','deployment_sha256','image_sha256','policy_sha256','trust_sha256'}
|
|
|
|
|
|
def encoded(value):return json.dumps(value,sort_keys=True,separators=(',',':'),allow_nan=False).encode()
|
|
def b64(value):return base64.urlsafe_b64encode(value).decode().rstrip('=')
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class FixtureWriterAdmission:
|
|
port:int
|
|
owner_token:str=field(repr=False)
|
|
server_process:subprocess.Popen=field(repr=False)
|
|
fenced:bool=False
|
|
|
|
|
|
class SignerWriter:
|
|
"""Single attempted operation; failed/unknown writes never retry or remint.
|
|
|
|
File permissions are accidental-disclosure guards, not same-UID isolation.
|
|
The receipt directory must be independent owner custody in a native adapter.
|
|
Python cannot promise seed zeroization; process lifetime is the boundary.
|
|
"""
|
|
def __init__(self,admission:FixtureWriterAdmission,directory:Path,operation_id:str,*,kid:str,expected_version:int,bindings:dict):
|
|
if (type(admission) is not FixtureWriterAdmission or type(admission.port) is not int
|
|
or not 1<=admission.port<=65535 or type(admission.owner_token) is not str
|
|
or not admission.owner_token or type(admission.fenced) is not bool or not admission.fenced):
|
|
raise Refused('exact fenced fixture custody required')
|
|
process=admission.server_process
|
|
if (type(process) is not subprocess.Popen or process.poll() is not None or type(process.args) is not list
|
|
or '-dev' not in process.args or '-dev-no-store-token' not in process.args
|
|
or '-dev-listen-address=127.0.0.1:'+str(admission.port) not in process.args):
|
|
raise Refused('live owner-spawned disposable dev process required')
|
|
self.admission=admission
|
|
self._initialize_receipt(directory,operation_id,kid=kid,expected_version=expected_version,bindings=bindings)
|
|
|
|
def _initialize_receipt(self,directory,operation_id,*,kid,expected_version,bindings):
|
|
if (type(operation_id) is not str or not re.fullmatch(r'[a-zA-Z0-9_-]{1,80}',operation_id)
|
|
or type(kid) is not str or not re.fullmatch(r'[a-zA-Z0-9_-]{1,80}',kid)
|
|
or type(expected_version) is not int or not 0<=expected_version<2**31
|
|
or type(bindings) is not dict or set(bindings)!=BINDINGS
|
|
or any(type(v) is not str or not re.fullmatch(r'sha256:[0-9a-f]{64}',v) for v in bindings.values())):
|
|
raise Refused('exact signer operation contract required')
|
|
if directory.absolute()!=directory.resolve() or directory.is_symlink():raise Refused('indirect receipt custody refused')
|
|
Journal._private(directory.stat(),directory=True)
|
|
self.directory=directory;self.path=directory/(operation_id+'.json')
|
|
self.expected_version=expected_version;self.kid=kid;self.attempted=False
|
|
self.receipt={'schema':'railiance-platform.signer-cas-receipt.v1','operation_id':operation_id,
|
|
'bindings':dict(bindings),'writer_sha256':'sha256:'+hashlib.sha256(Path(__file__).read_bytes()).hexdigest(),
|
|
'actor':'synthetic-owner-fixture','created_at':datetime.now(timezone.utc).isoformat(),'path':PATH,'expected_version':expected_version,'kid':kid,
|
|
'status':'prepared','production_admission':False,'rollback':'forward-recovery-only',
|
|
'public_key':None,'public_fingerprint':None,'kv_version':None,'exact_readback':False}
|
|
self._save(initial=True)
|
|
|
|
def _save(self,*,initial=False):
|
|
raw=encoded(self.receipt)
|
|
if len(raw)>65536:raise Refused('receipt bound exceeded')
|
|
if initial:
|
|
target=self.path
|
|
else:
|
|
fd=os.open(self.path,os.O_RDONLY|os.O_NOFOLLOW|os.O_NONBLOCK)
|
|
try:Journal._private(os.fstat(fd))
|
|
finally:os.close(fd)
|
|
target=self.directory/('.pending-'+secrets.token_hex(16))
|
|
fd=os.open(target,os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o600)
|
|
try:
|
|
with os.fdopen(fd,'wb',closefd=False) as stream:stream.write(raw);stream.flush();os.fsync(fd)
|
|
finally:os.close(fd)
|
|
if not initial:os.replace(target,self.path)
|
|
fd=os.open(self.directory,os.O_RDONLY|os.O_DIRECTORY|os.O_NOFOLLOW)
|
|
try:os.fsync(fd)
|
|
finally:os.close(fd)
|
|
|
|
def _http(self,method,path,body=None):
|
|
# Fixed loopback owner process and fixed data path; never arbitrary URL.
|
|
if self.admission.server_process.poll() is not None:raise Refused('fixture custody backend unavailable')
|
|
with _absolute_budget(2.0):
|
|
conn=http.client.HTTPConnection('127.0.0.1',self.admission.port,timeout=2)
|
|
try:
|
|
conn.request(method,'/v1/'+path,body=None if body is None else encoded(body),headers={
|
|
'X-Vault-Token':self.admission.owner_token,'Content-Type':'application/json'})
|
|
response=conn.getresponse();raw=response.read(1048577)
|
|
if len(raw)>1048576:raise Refused('backend response bound exceeded')
|
|
value=json.loads(raw,object_pairs_hook=_json_unique,parse_constant=_invalid_constant) if raw else {}
|
|
return response.status,value
|
|
finally:conn.close()
|
|
|
|
def write(self):
|
|
if self.attempted:raise Refused('signer operation already attempted')
|
|
self.attempted=True
|
|
# All source/receipt checks precede generation; no seed import, argv,
|
|
# environment, temporary file or public output interface exists.
|
|
private=Ed25519PrivateKey.generate()
|
|
seed=b64(private.private_bytes(serialization.Encoding.Raw,serialization.PrivateFormat.Raw,serialization.NoEncryption()))
|
|
public=b64(private.public_key().public_bytes(serialization.Encoding.Raw,serialization.PublicFormat.Raw))
|
|
document={'ED25519_PRIVATE_KEY':seed,'ED25519_PUBLIC_KEY':public,'kid':self.kid}
|
|
self.receipt.update(status='write-intent-unknown',public_key=public,
|
|
public_fingerprint='sha256:'+hashlib.sha256(public.encode()).hexdigest())
|
|
self._save() # A durable intent must exist before any possible effect.
|
|
try:
|
|
status,result=self._http('POST',PATH,{'options':{'cas':self.expected_version},'data':document})
|
|
if status!=200 or type(result) is not dict:raise Refused('signer write unconfirmed')
|
|
version=result.get('data',{}).get('version')
|
|
if type(version) is not int or version!=self.expected_version+1:raise Refused('signer write version unconfirmed')
|
|
self.receipt['kv_version']=version
|
|
status,result=self._http('GET',PATH+'?version='+str(version))
|
|
if status!=200 or type(result) is not dict:raise Refused('signer readback unconfirmed')
|
|
data=result.get('data',{});stored=data.get('data') if type(data) is dict else None
|
|
metadata=data.get('metadata') if type(data) is dict else None
|
|
if (type(stored) is not dict or set(stored)!=FIELDS or any(type(v) is not str for v in stored.values())
|
|
or type(metadata) is not dict or type(metadata.get('version')) is not int or metadata['version']!=version
|
|
or any(not hmac.compare_digest(stored[name],document[name]) for name in FIELDS)):
|
|
raise Refused('signer readback mismatch')
|
|
self.receipt.update(status='custody-verified-pending-independent-public-admission',exact_readback=True)
|
|
self._save()
|
|
return dict(self.receipt)
|
|
except BaseException:
|
|
# Persist only closed metadata; unknown never implies absence or retry.
|
|
# If receipt storage fails, the durable earlier intent remains unknown.
|
|
self.receipt.update(status='write-intent-unknown',exact_readback=False)
|
|
self._save()
|
|
raise Refused('signer custody outcome unconfirmed') from None
|
|
|
|
|
|
if __name__=='__main__':
|
|
raise SystemExit('production signer custody unadmitted; no live entry point')
|