security: record verified SOPS write and custody handoff repair
This commit is contained in:
parent
a0a9087790
commit
1d9814b887
2 changed files with 172 additions and 0 deletions
|
|
@ -0,0 +1,149 @@
|
|||
{
|
||||
"observed_at": "2026-10-13T19:05:24.270622+00:00",
|
||||
"result": "source-repair-verified; native-recovery-unverified",
|
||||
"workplan": "NK-WP-0049",
|
||||
"task": "NK-WP-0049-T02",
|
||||
"source_commit": "8f808577d6b322a2443d9ac922446c4838bf0d5d",
|
||||
"source_files": [
|
||||
{
|
||||
"path": "Makefile",
|
||||
"sha256": "335e22f57158bf566d3696d26c9bc4554745c2cec88f261107a77dbebe4f6260",
|
||||
"tested_sha256": "335e22f57158bf566d3696d26c9bc4554745c2cec88f261107a77dbebe4f6260"
|
||||
},
|
||||
{
|
||||
"path": ".sops.yaml",
|
||||
"sha256": "c3cdf6285a9491f1d10a1c12f7becf064603d0fd3580378c756a10d8bc3b9045",
|
||||
"tested_sha256": "a3e69c76984c7d601fc006a9b2af4a41cde05e87a7db2b90ebc945aa099eb349"
|
||||
},
|
||||
{
|
||||
"path": "sso-mfa/bootstrap/sops-private.py",
|
||||
"sha256": "113d17ee4cd7ad405e73cc51e1823dc02bd2e618e7fa67c1b624f0226e334ec6",
|
||||
"tested_sha256": "113d17ee4cd7ad405e73cc51e1823dc02bd2e618e7fa67c1b624f0226e334ec6"
|
||||
},
|
||||
{
|
||||
"path": "sso-mfa/bootstrap/sops-write.py",
|
||||
"sha256": "5a785e9c8e6a40ca9120a668d93992ea5c3115566ada21933536cc2d931f1ddf",
|
||||
"tested_sha256": "5a785e9c8e6a40ca9120a668d93992ea5c3115566ada21933536cc2d931f1ddf"
|
||||
},
|
||||
{
|
||||
"path": "tests/test_sops_write.py",
|
||||
"sha256": "3d4b26080c9a6328caaf82072363d40d27b2c96b07c441c7922c164f29fcfbd9",
|
||||
"tested_sha256": "3d4b26080c9a6328caaf82072363d40d27b2c96b07c441c7922c164f29fcfbd9"
|
||||
},
|
||||
{
|
||||
"path": "docs/security-bootstrap-age-custody.md",
|
||||
"sha256": "854a31d80b08cb0d789623de861c4927a3c049c1f0e385b357946b12bae2dddf",
|
||||
"tested_sha256": "854a31d80b08cb0d789623de861c4927a3c049c1f0e385b357946b12bae2dddf"
|
||||
},
|
||||
{
|
||||
"path": "sso-mfa/bootstrap/README.md",
|
||||
"sha256": "4d9a7f25ecb71a6e65bfe62dda6b15979c951483cad57b7b5ff5d76883190626",
|
||||
"tested_sha256": "4d9a7f25ecb71a6e65bfe62dda6b15979c951483cad57b7b5ff5d76883190626"
|
||||
},
|
||||
{
|
||||
"path": "workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md",
|
||||
"sha256": "da98f4f5870754989d8be2b25bb73a6db33c9f64084bfacaa36b0f1c0c075373",
|
||||
"tested_sha256": "da98f4f5870754989d8be2b25bb73a6db33c9f64084bfacaa36b0f1c0c075373"
|
||||
}
|
||||
],
|
||||
"knowledge": {
|
||||
"version": "0.2.6",
|
||||
"package_digest": "8d1d6a9d4d07fec7b619618de7dfe2be2254c1790f85f4198c7fe19db9751c02",
|
||||
"status": "withheld; source changed; orientation only",
|
||||
"basis": "Current source review, existing NK-WP-0049 scope and user-authorized local repairs; no live authority inferred."
|
||||
},
|
||||
"findings": [
|
||||
"Direct Make file arguments permitted shell and Make-function evaluation.",
|
||||
"Custody COMMAND quote escaping could execute before the helper handoff.",
|
||||
"Native data-key rotation could rewrap to an extra age recipient injected into unauthenticated document metadata.",
|
||||
"Old write paths inherited ambient custody/editor state and did not enforce private regular-file or tracked-plaintext boundaries.",
|
||||
"Documentation incorrectly described data-key rotation as applying recipient changes."
|
||||
],
|
||||
"changes": [
|
||||
"Make exports raw argument values without expanding them or interpolating them into shell source before custody handoff.",
|
||||
"Encryption uses the registered public recipient with private untracked JSON/YAML input and no private identity.",
|
||||
"Edit consumes private replacement input outside Git, verifies the original MAC and preserves encryption policy; no ambient editor is launched.",
|
||||
"Edit and data-key rotation require the explicit matching custody key and exactly the independently registered recipient.",
|
||||
"Key inputs reject hardlinks, symlink ancestors and FIFOs; child diagnostics are suppressed and verification plaintext discarded.",
|
||||
"Private ciphertext staging, cooperative locking and source version comparison precede atomic replacement.",
|
||||
"Current NK-WP-0049 checklist names remaining diagnostic, key-export, LDAP, realm-repair and full inventory/recovery work."
|
||||
],
|
||||
"verification": {
|
||||
"baseline": {
|
||||
"source_commit": "b01a30bd49036f5df8bf400fb89af4f5fbee08ed",
|
||||
"command": "PATH=/tmp/netkingdom-sops-tools:$PATH python3 -m pytest -q tests/test_sops_write.py -k 'not edit' --tb=no",
|
||||
"failed": 13,
|
||||
"passed": 3,
|
||||
"deselected": 12,
|
||||
"scope": "Immutable old-source checkout with the initial regression file; edit cases excluded to avoid old interactive-editor waits.",
|
||||
"log_sha256": "c6044ed022abbfa01a6425ef3801beeb576b1c3cec1e9c595cfd8f4d4154afe3"
|
||||
},
|
||||
"preparation_limit": "The earlier initial baseline reported 15 failures but overlapped staged source edits; it is not accepted as old-source proof. The separate immutable baseline above replaces it.",
|
||||
"expanded_suite_preparation": {
|
||||
"failed": 1,
|
||||
"passed": 578,
|
||||
"skipped": 7,
|
||||
"source_unchanged_during_run": true,
|
||||
"cause": "Existing posture-feedback test requires repository basename net-kingdom; recovery checkout was named nk-sops-write. Six integration skips lacked sibling InfoTechCanon schema. Re-run uses identical source in a correctly named checkout with existing owner schema; no test or implementation relaxed.",
|
||||
"log_sha256": "867c8a01d515acd00260f2b34d5cd3124a9b7ed59adda529a6c989bd7f64f75c"
|
||||
},
|
||||
"owner_schema": {
|
||||
"path": "info-tech-canon/infospace/schemas/emission-cadence.schema.yaml",
|
||||
"sha256": "6d52692eb1e4d1325e0d6062d95acded98beddaae5bcfe24c6f0e91f1b6be6ae"
|
||||
},
|
||||
"focused": {
|
||||
"passed": 75,
|
||||
"elapsed_seconds": 17.02,
|
||||
"scope": "Real-SOPS write/decrypt and custody-entrypoint suites, all using disposable inputs."
|
||||
},
|
||||
"final": {
|
||||
"command": [
|
||||
"python3",
|
||||
"-m",
|
||||
"pytest",
|
||||
"-q",
|
||||
"tests",
|
||||
"tools",
|
||||
"sso-mfa/k8s/keycape",
|
||||
"--tb=short",
|
||||
"-rs"
|
||||
],
|
||||
"source_base": "b01a30bd49036f5df8bf400fb89af4f5fbee08ed",
|
||||
"exit_code": 0,
|
||||
"elapsed_seconds": 95.73,
|
||||
"source_unchanged_during_run": true,
|
||||
"passed": 585,
|
||||
"skipped": 1,
|
||||
"skip_reason": "privacyIDEA Python module unavailable; all real-SOPS cases and six owner-schema integration cases ran."
|
||||
},
|
||||
"final_log_tail": [
|
||||
"........................................................................ [ 98%]",
|
||||
"......... [100%]",
|
||||
"=========================== short test summary info ============================",
|
||||
"SKIPPED [1] tests/test_admin_bootstrap_privacyidea.py:14: could not import 'privacyidea': No module named 'privacyidea'",
|
||||
"585 passed, 1 skipped in 95.14s (0:01:35)"
|
||||
],
|
||||
"final_log_sha256": "9ceab901acd163c9e21029893d5220e0333e977b2317bac48be4a269b599248a",
|
||||
"full_source_binding_sha256": "c60ae8fc10db27341f1410377fbb2eaed635ba63c9ea1b6b53cf8a1ac748d6ad",
|
||||
"applied_executable_source_matches_test_binding": true,
|
||||
"post_test_documentation_refinement": {
|
||||
"file": ".sops.yaml",
|
||||
"change": "Removed the redundant public-recipient fingerprint comment after pre-commit generic-api-key match on line 5. Creation rules and parsed YAML are unchanged; no scanner exemption or bypass.",
|
||||
"all_other_files_match_test_binding": true
|
||||
},
|
||||
"sops": {
|
||||
"version": "3.13.3",
|
||||
"sha256": "e5bec3346a873ae91d871550f3e698c1aad962aff462a080e40f25fde17fef6b",
|
||||
"basis": "Disposable binary matches the official-release-checksum receipt docs/evidence/2026-10-12-netkingdom-security/sops-make-entrypoints.json; no detached signature verification or installed-toolchain admission claimed."
|
||||
}
|
||||
},
|
||||
"limits": [
|
||||
"No production custody key was retrieved and no live decryption, Secret write or deployment change was performed.",
|
||||
"Synthetic local cryptographic tests do not prove installed-toolchain admission or owner-approved native off-host recovery.",
|
||||
"Snapshot stat and rename are separate operations; cooperative locks are not an atomic compare-and-swap against noncooperating same-UID writers or ancestor-directory substitution.",
|
||||
"A directory fsync error after rename can report failure after publication; inspect state before retry. SIGKILL may leave temporary files.",
|
||||
"Input/recovered plaintext cleanup and independent key/snapshot custody remain the approved operator procedure.",
|
||||
"Recipient migration, historical revocation, coordinated service rotation and native consumer acceptance remain open.",
|
||||
"The selected remaining caller findings are not an exhaustive audit; reconcile the full attended-procedure inventory and current Make/bootstrap/root-output callers."
|
||||
]
|
||||
}
|
||||
|
|
@ -386,6 +386,29 @@ progress for other diagnostics/bootstrap/SOPS callers and lifecycle requirements
|
|||
T03 remains its owner-scoped recovery gate. Evidence:
|
||||
`docs/evidence/2026-10-13-netkingdom-security/service-secret-callers.json`.
|
||||
|
||||
2026-10-13 SOPS write caller repair: NetKingdom `8f80857` removes Make/shell
|
||||
argument execution before custody handoff, uses public-only encryption of private
|
||||
untracked JSON/YAML, and replaces editor-based updates with explicit private
|
||||
replacement input outside Git. Edit/rotate require the matching temporary key
|
||||
and exactly the registered recipient; extra recipient metadata is refused.
|
||||
Original MAC and replacement ciphertext are verified, encryption policy is
|
||||
preserved, and child diagnostics/plaintext are suppressed. Source checks and
|
||||
atomic ciphertext replacement do not provide isolation from hostile same-UID
|
||||
writers. Data-key rotation is explicitly distinct from recipient migration.
|
||||
|
||||
Final unchanged-source suite: 585 passed, one unavailable privacyIDEA module
|
||||
skip; all real-SOPS cases ran. The initial expanded run's checkout-name failure
|
||||
and missing sibling-schema skips are retained, then resolved by correcting the
|
||||
test workspace without changing source. A pre-commit generic-key match on the
|
||||
redundant public-recipient comment was resolved by removing that comment; parsed
|
||||
configuration is unchanged, and the normal eight-blob scan passed. Executable
|
||||
source matches the final test binding. NK-WP-0049-T02 now names the remaining
|
||||
key-export, MFA diagnostic, LDAP and realm-repair callers plus the complete
|
||||
inventory reconciliation; T03 still requires exact owner-approved native recovery.
|
||||
No production custody key was retrieved and no live decryption, Secret write or
|
||||
deployment change was performed. Evidence:
|
||||
`docs/evidence/2026-10-13-netkingdom-security/sops-write-callers.json`.
|
||||
|
||||
## Verify native closure against every requirement
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue