net-kingdom/sso-mfa/bootstrap/sops-custody-fd.py
tegwick 4f65e41ac5
Some checks failed
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
Identity provider journey acceptance / provider (push) Failing after 20s
Build and Publish identity-provisioner / build-and-push (push) Successful in 8s
fix(identity): retain group provenance and prepare sealed recovery custody
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1468b-63fa-7710-85dc-8f2e16b3ebfa
2026-10-17 00:28:17 +02:00

54 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""Attended custody through a sealed anonymous Linux descriptor, never a key path."""
import argparse
import fcntl
import getpass
import os
import re
import subprocess
import sys
import warnings
SEALS=fcntl.F_SEAL_WRITE|fcntl.F_SEAL_GROW|fcntl.F_SEAL_SHRINK|fcntl.F_SEAL_SEAL
class Refused(Exception):pass
def sealed_key(material):
if not isinstance(material,bytes) or not 1<=len(material)<=16384 or not re.fullmatch(b'AGE-SECRET-KEY-1[A-Z0-9]+\n?',material):raise Refused()
fd=os.memfd_create('netkingdom-custody',os.MFD_CLOEXEC|os.MFD_ALLOW_SEALING)
try:
os.fchmod(fd,0o600)
with os.fdopen(os.dup(fd),'wb') as out:out.write(material);out.flush()
os.lseek(fd,0,os.SEEK_SET)
fcntl.fcntl(fd,fcntl.F_ADD_SEALS,SEALS)
if fcntl.fcntl(fd,fcntl.F_GET_SEALS)!=SEALS:raise Refused()
return fd
except BaseException:os.close(fd);raise
def run(material,recipient,command):
if not re.fullmatch(r'age1[023456789acdefghjklmnpqrstuvwxyz]{58}',recipient) or not command:raise Refused()
fd=sealed_key(material)
try:
result=subprocess.run(['age-keygen','-y',f'/proc/self/fd/{fd}'],pass_fds=(fd,),stdout=subprocess.PIPE,stderr=subprocess.DEVNULL,timeout=10)
if result.returncode or result.stdout.strip()!=recipient.encode():raise Refused()
# The key must not compete with any ambient custody source. Children
# receive only this exact inherited descriptor, with close-on-exec elsewhere.
env={k:v for k,v in os.environ.items() if k not in ('NETKINGDOM_CUSTODY_AGE_KEY_FILE','NETKINGDOM_CUSTODY_AGE_KEY_FD','SOPS_AGE_KEY_FILE','SOPS_AGE_KEY','SOPS_AGE_KEY_CMD')}
env['NETKINGDOM_CUSTODY_AGE_KEY_FD']=str(fd)
return subprocess.run(command,env=env,pass_fds=(fd,)).returncode
finally:os.close(fd)
def main():
p=argparse.ArgumentParser(description=__doc__);p.add_argument('--expected-recipient',required=True);p.add_argument('command',nargs=argparse.REMAINDER);args=p.parse_args()
command=args.command[1:] if args.command[:1]==['--'] else args.command
try:
if (not all(os.isatty(fd) for fd in (0,1,2)) or not command
or not re.fullmatch(r'age1[023456789acdefghjklmnpqrstuvwxyz]{58}',args.expected_recipient)):raise Refused()
with warnings.catch_warnings():
warnings.simplefilter('error',getpass.GetPassWarning)
material=getpass.getpass('Paste custody age private key line (input hidden): ').encode()+b'\n'
return run(material,args.expected_recipient,command)
except Exception:
print('ERROR: sealed custody input or execution refused; private diagnostics suppressed.',file=sys.stderr);return 1
if __name__=='__main__':raise SystemExit(main())