KB-67A0

FIX7 Authority-Seal Red-Team Adversarial Suite (20 attacks)

11 min read Revision 1
tool-kiem-thufix7authority-sealred-teamharness20-attacks2026-06-10

#!/usr/bin/env python3

============================================================================

FIX7 AUTHORITY-SEAL -- RED-TEAM ADVERSARIAL SUITE (20 attacks)

Attacks the full N7->N8->P7 seal protocol + the spec/doc/governance layer.

Every required attack MUST be CAUGHT (fail-closed at encode, verify-mismatch,

drift-detected, or rejected by a governance guard). If ANY attack is NOT

caught (i.e. it could forge the canonical seal or slip past silently) the

suite exits nonzero and the contract is treated as DEFECTIVE.

Mechanism classes:

ENCODE_FAIL_CLOSED -- encoder raises the exact Reject status

VERIFY_MISMATCH -- produced digest != canonical => verify_pin/compare fails

DRIFT_DETECTED -- drift checker flags spec/code/doc disagreement

GUARD_REJECT -- a governance guard refuses the tampered artifact

CYCLE_DETECTED -- has_cycle() true on a tampered edge set

Usage: python3 authority_seal_redteam.py [rehearsal_dir]

============================================================================

import json, re, sys, os, hashlib, copy import authority_seal_encoder as E

REH = sys.argv[1] if len(sys.argv) > 1 else "../rehearsal"

results = [] def record(aid, desc, caught, mechanism, detail=""): results.append({"id": aid, "desc": desc, "caught": caught, "mechanism": mechanism, "detail": detail})

def reject_status(fn): try: fn(); return None except E.Reject as e: return e.status

canonical fixture seal chain (the values a forger would try to reproduce)

N7 = E.encode_node("N7", E.fixture_n7_pairs()) N8 = E.encode_node("N8", E.fixture_n8_pairs(N7)) P7 = E.seal_p7(E.fixture_p7_pairs(N7, N8))

---- 1. delete N7 required field ----

s = reject_status(lambda: E.encode_node("N7", E.fixture_n7_pairs()[:-1])) record(1, "delete N7 required field", s == "SEAL_INPUT_MISSING", "ENCODE_FAIL_CLOSED", s)

---- 2. add extra N7 field ----

s = reject_status(lambda: E.encode_node("N7", E.fixture_n7_pairs() + [("rogue", "x")])) record(2, "add extra N7 field", s == "SEAL_INPUT_EXTRA", "ENCODE_FAIL_CLOSED", s)

---- 3. reorder N7 field ----

sw = E.fixture_n7_pairs(); sw[2], sw[3] = sw[3], sw[2] s = reject_status(lambda: E.encode_node("N7", sw)) record(3, "reorder N7 field", s == "SEAL_FIELD_ORDER_MISMATCH", "ENCODE_FAIL_CLOSED", s)

---- 4. wrong N7 domain tag ----

s = reject_status(lambda: E.encode_node("N7", E.fixture_n7_pairs(), claimed_tag="EVIL_V1")) record(4, "wrong N7 domain tag", s == "SEAL_DOMAIN_TAG_MISMATCH", "ENCODE_FAIL_CLOSED", s)

---- 5. N7 tries to bind N8 (cycle) ----

s = reject_status(lambda: E.encode_node("N7", E.fixture_n7_pairs() + [("detached_seal_sha256", N8)])) record(5, "N7 binds N8 -> cycle", s == "SEAL_HASH_GRAPH_CYCLE", "ENCODE_FAIL_CLOSED", s)

---- 6. N8 missing N7 ----

n8_no_n7 = [p for p in E.fixture_n8_pairs(N7) if p[0] != "envelope_manifest_sha256"] s = reject_status(lambda: E.encode_node("N8", n8_no_n7)) record(6, "N8 missing N7", s == "SEAL_INPUT_MISSING", "ENCODE_FAIL_CLOSED", s)

---- 7. N8 wrong signer representation ----

7a structural injection (TAB byte in signer) -> fail-closed

inj = E.fixture_n8_pairs(N7) inj[6] = ("sealed_by", "CODEX\tINJECT") s7a = reject_status(lambda: E.encode_node("N8", inj))

7b byte-clean wrong signer -> different digest, cannot forge canonical N8

clean = E.fixture_n8_pairs(N7); clean[6] = ("sealed_by", "ATTACKER-NOT-CODEX") forged = E.encode_node("N8", clean) caught7 = (s7a == "SEAL_FIELD_FORBIDDEN_BYTE") and (forged != N8) record(7, "N8 wrong signer representation", caught7, "ENCODE_FAIL_CLOSED+VERIFY_MISMATCH", f"inject={s7a}; clean_forged_eq_canonical={forged == N8}")

---- 8. N8 wrong timestamp format ----

8a structural injection (backslash) -> fail-closed

inj8 = E.fixture_n8_pairs(N7); inj8[7] = ("sealed_at", "2026\06\10") s8a = reject_status(lambda: E.encode_node("N8", inj8))

8b byte-clean wrong format -> different digest (tamper-evident). NOTE: semantic

timestamp-FORMAT validation is intentionally OUT OF CONTRACT SCOPE (Codex

supplies the authority timestamp); the contract guarantees tamper-evidence,

not format policing. A wrong-but-clean timestamp simply yields a non-canonical

seal that fails verify against the expected pin.

clean8 = E.fixture_n8_pairs(N7); clean8[7] = ("sealed_at", "10/06/2026 wrong") forged8 = E.encode_node("N8", clean8) caught8 = (s8a == "SEAL_FIELD_FORBIDDEN_BYTE") and (forged8 != N8) record(8, "N8 wrong timestamp format", caught8, "ENCODE_FAIL_CLOSED+VERIFY_MISMATCH", f"inject={s8a}; clean_forged_eq_canonical={forged8 == N8}; " f"semantic-format-validation=OUT_OF_CONTRACT_SCOPE(Codex-supplied)")

---- 9. P7 missing canonicalizer hash ----

p7_no_canon = [p for p in E.fixture_p7_pairs(N7, N8) if p[0] != "pinned_canonicalizer_sha256"] s = reject_status(lambda: E.encode_node("P7", p7_no_canon)) record(9, "P7 missing canonicalizer hash", s == "SEAL_INPUT_MISSING", "ENCODE_FAIL_CLOSED", s)

---- 10. P7 mutated canonicalizer hash ----

mut = E.fixture_p7_pairs(N7, N8); mut[5] = ("pinned_canonicalizer_sha256", "0"*64) record(10, "P7 mutated canonicalizer hash", not E.verify_pin(P7, mut), "VERIFY_MISMATCH")

---- 11. P7 mutated Packet V3 tree ----

mut2 = E.fixture_p7_pairs(N7, N8); mut2[6] = ("pinned_packet_v3_tree_sha256", "0"*64) record(11, "P7 mutated Packet V3 tree", not E.verify_pin(P7, mut2), "VERIFY_MISMATCH")

---- 12. prose-only P7 pin ----

s = reject_status(lambda: E.seal_p7(E.fixture_p7_pairs(N7, N8), prose_only=True)) record(12, "prose-only P7 pin", s == "SEAL_PROSE_ONLY_PIN_REJECTED", "ENCODE_FAIL_CLOSED", s)

---- 13. spec.json drift from encoder ----

tamper a copy of the spec rosters; the equality compare must flag drift

sj = json.load(open(os.path.join(os.path.dirname(file) or ".", "authority-seal-encoder-spec.json"))) tampered = copy.deepcopy(sj); tampered["rosters"]["N7"][2] = "tampered_field" record(13, "spec.json drift from encoder", E.ROSTERS == sj["rosters"] and E.ROSTERS != tampered["rosters"], "DRIFT_DETECTED", "clean matches, tampered differs")

---- 14. spec.md claims a field not in encoder ----

md = open(os.path.join(os.path.dirname(file) or ".", "authority-seal-encoder-spec.md"), encoding="utf-8").read() def md_roster_n7(text): i = text.index("## 3. N7"); j = text.index("## 4. N8") return [m.group(1) for line in text[i:j].splitlines() for m in [re.match(r"\s*|\s*\d+\s*|\s*([a-z0-9_]+)", line)] if m] clean_md = md_roster_n7(md) tampered_md = clean_md[:3] + ["ghost_field"] + clean_md[3:] record(14, "spec.md claims a field not in encoder", clean_md == E.ROSTERS["N7"] and tampered_md != E.ROSTERS["N7"], "DRIFT_DETECTED", "clean matches encoder, +ghost_field differs")

---- 15. encoder extra authority field not in spec ----

enc_extra = E.ROSTERS["N7"] + ["secret_backdoor_field"] record(15, "encoder extra authority field not in spec", enc_extra != sj["rosters"]["N7"], "DRIFT_DETECTED", "an encoder roster with an extra field would not equal spec.json")

---- 16. fixture labelled as real seal ----

def guard_not_a_seal(artifact): n = artifact.get("NOT_A_SEAL", {}) if n.get("ARTIFACT_CLASS") != "REHEARSAL_ONLY_NOT_A_SEAL": raise E.Reject("SEAL_FIXTURE_CLASS_MISSING", "no NOT_A_SEAL banner") if any(n.get(k) for k in ("is_real_n7", "is_real_n8", "is_real_p7", "is_owner_final_seal", "is_codex_seal")): raise E.Reject("SEAL_FIXTURE_CLAIMS_REAL", "fixture flagged as real seal") return True art = json.load(open(os.path.join(REH, "n7-rehearsal-artifact.json"))) clean_ok = guard_not_a_seal(art) forged_art = copy.deepcopy(art); forged_art["NOT_A_SEAL"]["is_real_n7"] = True s = reject_status(lambda: guard_not_a_seal(forged_art)) record(16, "fixture labelled as real seal", clean_ok and s == "SEAL_FIXTURE_CLAIMS_REAL", "GUARD_REJECT", s)

---- 17. owner authorization expanded to implementation ----

bad = E.fixture_n7_pairs(); bad[-1] = ("approval_scope", "IMPLEMENTATION_ALLOWED") s = reject_status(lambda: E.encode_node("N7", bad)) record(17, "owner authorization expanded to implementation", s == "SEAL_CONSTANT_FIELD_MISMATCH", "ENCODE_FAIL_CLOSED", s)

---- 18. production gate removed from checklist ----

def guard_checklist(text): required = ["Codex/authority seal complete", "Owner approval of the implementation macro", "Forbidden mutations (standing)", "Rollback requirement"] missing = [r for r in required if r not in text] if missing: raise E.Reject("SEAL_PRODUCTION_GATE_MISSING", f"{missing}") return True chk = open(os.path.join(os.path.dirname(file) or ".", "fix7-implementation-precondition-checklist.md"), encoding="utf-8").read() clean_chk = guard_checklist(chk) tampered_chk = chk.replace("Forbidden mutations (standing)", "Allowed everything") s = reject_status(lambda: guard_checklist(tampered_chk)) record(18, "production gate removed from checklist", clean_chk and s == "SEAL_PRODUCTION_GATE_MISSING", "GUARD_REJECT", s)

---- 19. unknown dependency edge added ----

ev = {k: list(v) for k, v in E.EDGES.items()}; ev["N7"] = ev["N7"] + ["N8"] record(19, "unknown dependency edge added (N7->N8)", (not E.has_cycle(E.EDGES)) and E.has_cycle(ev), "CYCLE_DETECTED", "clean acyclic, injected edge -> cycle")

---- 20. hash manifest tamper ----

build a manifest of the rehearsal artifacts, tamper one line, re-verify

files = sorted(f for f in os.listdir(REH) if os.path.isfile(os.path.join(REH, f))) manifest = {f: hashlib.sha256(open(os.path.join(REH, f), "rb").read()).hexdigest() for f in files} tampered_manifest = dict(manifest) victim = files[0] tampered_manifest[victim] = "0"*64

verifier recomputes and compares

def verify_manifest(man): return all(man[f] == hashlib.sha256(open(os.path.join(REH, f), "rb").read()).hexdigest() for f in man) record(20, "hash manifest tamper", verify_manifest(manifest) and not verify_manifest(tampered_manifest), "VERIFY_MISMATCH", f"tampered {victim}")

---------- report ----------

caught = sum(1 for r in results if r["caught"]) for r in results: flag = "CAUGHT" if r["caught"] else "*** ESCAPED ***" print(f" [{flag}] A{r['id']:<2} {r['desc']} ({r['mechanism']})" + (f" {r['detail']}" if r["detail"] else "")) print(f"RED-TEAM: {caught}/{len(results)} attacks caught; escaped={len(results)-caught}") out = {"caught": caught, "total": len(results), "attacks": results, "canonical_fixture": {"N7": N7, "N8": N8, "P7": P7}} json.dump(out, open(os.path.join(REH, "redteam-results.json"), "w"), indent=2) sys.exit(0 if caught == len(results) else 1)

Back to Knowledge Hub knowledge/dev/laws/tool-kiem-thu/packets/fix7-authority-closure-2026-06-10/authority_seal_redteam.py