Skip to content

feat(stage2): bind Lab2 authorization before replay - #84

Merged
Robinlee0929 merged 1 commit into
mainfrom
codex/stage2-lab2-s2-ro-05-authorization-replay-binding
Sep 12, 2026
Merged

Robinlee0929 merged 1 commit into
mainfrom
codex/stage2-lab2-s2-ro-05-authorization-replay-binding

Conversation

@Robinlee0929

Copy link
Copy Markdown
Owner

1. Summary / scope

Extend ONLY S2-RO-05 authorization-envelope and pre-replay binding policy to exactly two approved target/credential pairs.

Changed files exactly:

  • validation_framework/stage2_authorization_envelope_ledger.py
  • tests/stage2/test_authorization_envelope_ledger.py
  • docs/automation_readiness/stage2_vrrp_readonly_s2_ro_05_authorization_envelope_ledger.md

No S2-RO-01 through S2-RO-04 or S2-RO-06 or later production module is changed. No workflow, dependency metadata, or AGENTS.md change.

Base: 496eb5d (tree 050dd06f6bdd3dc20a442e3b4106fed2dca4cbc9).
Head: 44aead1 (tree 2a3305b0c9a95a86d0e654e9d78dd5ca9e456cd6).
Exactly one commit above base.

2. Exact authority model

  • Lab1: target.mikrotik.lab01 + credential.mikrotik.lab01.
  • Lab2: target.mikrotik.lab02 + credential.mikrotik.lab02.

S2-RO-03 resolve_for_target(...) remains the canonical target/credential pair authority. No duplicate independent pair authority was introduced. There is no wildcard, fallback, normalization, or default-to-Lab1. Caller-supplied bindings cannot override the resolver.

3. Pre-replay fail-closed property

Any Lab1/Lab2 mixed or invalid pairing rejects BEFORE replay-ledger I/O.

Covered rejection cases include:

  • Lab1 request + Lab2 envelope.
  • Lab2 request + Lab1 envelope.
  • Lab1 target + Lab2 credential.
  • Lab2 target + Lab1 credential.
  • Cross-Lab supplied credential binding.
  • Unknown target or unknown credential, including all-unknown combinations.
  • Request SHA mismatch and authorization_ref mismatch.
  • Operation mismatch.
  • Alias, prefix-confused, case-confused, whitespace-modified, and noncanonical values.

For invalid binding paths, tests prove:

  • _path_identity calls = 0.
  • Filesystem ledger access = 0.
  • sqlite3.connect calls = 0.
  • BEGIN calls = 0.
  • INSERT calls = 0.
  • Durable replay mutation = 0.

Synthetic ledger bytes, size, mtime, and directory entries remain unchanged after rejection. Binding validation precedes envelope time validation.

4. Valid path

Lab1 exact binding remains valid. Lab2 exact binding is valid with the same policy semantics.

Disposable, pre-provisioned synthetic ledgers prove:

  • Lab1: first consume succeeds; second consume rejects REPLAY.
  • Lab2: first consume succeeds; second consume rejects REPLAY.
  • Same authorization ID with changed envelope rejects REPLAY, including cross-Lab reuse.

5. Replay engine unchanged

Replay/storage machinery below the binding boundary is unchanged.

No change to SQLite schema, authorization UUID replay key, envelope SHA as audit metadata, BEGIN IMMEDIATE, synchronous=EXTRA, trusted_schema=OFF, foreign_keys=ON, DELETE journal, normal locking, busy_timeout=0, plain parameterized INSERT, commit semantics (including COMMIT_UNCERTAIN), permanent consumption, capacity handling, or the documented anti-rollback limitation.

No retry, reconnect, UPSERT, UPDATE, DELETE, reset, unconsume, reclaim, or pruning was introduced. There is no new ledger initializer or fallback ledger.

6. Owner / execution authority boundary

SCHEMA_VERSION remains 1.0. Owner payload domain remains unchanged:
Network_Automation_Lab/S2-RO-05/authorization-envelope/v1 followed by the original NUL byte.

owner_verification_payload remains DOMAIN + canonical envelope bytes.

S2-RO-05 still does NOT authenticate Owner, verify a signature, access a trust root, or grant execution authority.

Both remain:

  • Stage2AuthorizationEnvelope.execution_authorized = False.
  • Stage2ConsumptionRecord.execution_authorized = False.

A valid envelope is not Owner approval; successful consumption is not execution authority.

7. Real authority / private data boundary

No real replay ledger was accessed. No real authorization was consumed. No real authorization package was accessed.

No Windows Credential Manager access or real CredReadW call occurred in Stage-2/Lab implementation or validation. No private key or Owner trust-root data was accessed. No Lab1/Lab2 live device was contacted. No SSH, NETCONF, or RESTCONF occurred.

No Lab IP, private runtime path, real replay UUID, real authorization ID, or real credential is included. Test data is synthetic. No real credential or authorization material is included in this PR.

GitHub operations use only the existing Git/GitHub CLI authentication mechanism; credential stores and its underlying storage implementation were not inspected. No token, environment dump, or raw traceback is included.

8. Validation

Fresh pre-PR Safe CI #34683914652:

  • HEAD: 44aead1.
  • Status: completed; conclusion: SUCCESS.
  • Python (python -m pytest): 3975 collected, 3973 passed, 2 skipped, 0 failed.
  • Node (npm run test:unit): 128 passed across 9 test files.
  • Typecheck (npm run typecheck): PASS.
  • Lint (npm run lint): PASS.
  • Build (npm run build): PASS.
  • Report-index (python network_lab.py --task report-index): 1 pass, 13 optional missing, 0 fail; accepted WARN.
  • Tracked mutation (git diff --exit-code): PASS.

The two Linux platform-condition skips are unchanged and are not candidate-induced weakening.

Independent review: PASS. Findings: NONE.
Separate offline review validation: focused S2-RO-05 166 passed; Stage-2 1849 passed; full pytest 3975 passed, 0 failed; report-index accepted WARN; candidate diff check PASS. These local results do not substitute for the fresh CI evidence above. No skip/xfail, assertion weakening, or collection weakening was introduced.

9. Open warnings

Unresolved:

  • npm: 5 vulnerabilities (2 moderate, 2 high, 1 critical).
  • Next.js/Turbopack: 7 filesystem-tracing warnings.
  • report-index: 13 optional missing artifacts.

No remediation is included in this PR.

10. Deferred scope

Explicitly deferred:

  • S2-RO-06 Owner verification work.
  • S2-RO-07 known-host work.
  • S2-RO-10 runtime composition.
  • S2-RO-11 live entrypoint changes.
  • Real Lab2 credential provisioning.
  • Real replay / Owner authorization use.
  • Lab2 live validation.
  • Dual-device aggregation.
  • Stage 3.

This PR does not authorize any live attempt, merge, auto-merge, or later slice. Independent PR review and any later merge require separate Owner authorization.

@Robinlee0929
Robinlee0929 merged commit 16ae887 into main Sep 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant