Finding
A cross-component credential-validity audit found that several signed/MACed credentials carried issued_at but did not enforce it during verification:
- daemon operator tokens verified expiry but did not reject
now < issued_at;
- operator-agent sessions verified expiry but did not reject
now < issued_at;
- sovereign-admin operator-session validity ignored
issued_at;
- the browser-side agent-session freshness precheck ignored
issued_at.
Because issued_at is already covered by the credential signature/MAC, ignoring it wastes a meaningful authenticated time bound. Under wall-clock rollback, an already-issued credential could be treated as valid before its own signed issuance time.
Security contract
Credential validity is uniformly:
issued_at <= now < expires_at
This complements #147's exclusive expiry boundary. The left edge is inclusive; the right edge is exclusive.
Authored fix
Commit 6 in the ordered pre-Hyperstream security stack:
- commit:
56f4e66c8eaef461898377b936937e6dae9325c0
- subject:
fix(auth): enforce signed credential not-before times
- V22.1 base tree:
46464f1ad514bc55e9d1c4b7b0cdc95048f6d1a3
- cumulative six-commit result tree:
8beafa0941dcaeb3d965f08a14f30c08660a9305
Changes:
- daemon operator-token verification rejects
now < issued_at and still rejects now >= expires_at;
- operator-agent session verification adds a not-yet-valid error path and enforces the same interval;
- sovereign-admin
OperatorSession::is_valid requires issued_at <= now && now < expires_at;
- browser agent-session freshness refuses/clears sessions used before signed issuance time;
- Rust boundary tests cover the exact not-before instant;
scripts/check-auth-not-before-semantics.py enforces the cross-component invariant;
- six source-policy mutation tests prove any component dropping the left-bound check is rejected;
- the existing expiry checker was updated so the two guards coexist and independently enforce both halves of the interval.
Canonical cumulative qualification
Pre-Hyperstream Security Hardening v2:
- archive:
xenia-pre-hyperstream-security-hardening-v2-20260826.tar.gz
- SHA-256:
ad1211763841631414c743e4c60711c13703bc31e276e44644386fada2dcc5e9
- ordered commits: 6
- cumulative result tree:
8beafa0941dcaeb3d965f08a14f30c08660a9305
Fresh replay of that exact final archive from untouched V22.1:
- deterministic archive self-rebuild: PASS
- manifest / qualification ledger: PASS
- patches: 6/6 PASS
- exact result tree: PASS
- signed not-before checker: PASS
- exclusive-expiry checker: PASS
- complete Python validator suite: 50/50 PASS
- Xenia policy / CODEOWNERS / secure-default / Cargo-boundary / runtime-risk / reviewed-unsafe gates: PASS
- Python + shell syntax: PASS
git diff --check: PASS
- replay worktree: CLEAN
Native Rust/Nix qualification remains mandatory and is currently blocked by #143. Do not merge on static evidence alone.
Integration ordering
This belongs in the same pre-Hyperstream security baseline as #145, #146, #147, and the durability-first operator-admin fix. If that baseline lands first, Hyperstream V24.4's live-base freshness gate should intentionally invalidate the old V22.1 qualification and require a fresh rebase/requalification.
Finding
A cross-component credential-validity audit found that several signed/MACed credentials carried
issued_atbut did not enforce it during verification:now < issued_at;now < issued_at;issued_at;issued_at.Because
issued_atis already covered by the credential signature/MAC, ignoring it wastes a meaningful authenticated time bound. Under wall-clock rollback, an already-issued credential could be treated as valid before its own signed issuance time.Security contract
Credential validity is uniformly:
issued_at <= now < expires_atThis complements #147's exclusive expiry boundary. The left edge is inclusive; the right edge is exclusive.
Authored fix
Commit 6 in the ordered pre-Hyperstream security stack:
56f4e66c8eaef461898377b936937e6dae9325c0fix(auth): enforce signed credential not-before times46464f1ad514bc55e9d1c4b7b0cdc95048f6d1a38beafa0941dcaeb3d965f08a14f30c08660a9305Changes:
now < issued_atand still rejectsnow >= expires_at;OperatorSession::is_validrequiresissued_at <= now && now < expires_at;scripts/check-auth-not-before-semantics.pyenforces the cross-component invariant;Canonical cumulative qualification
Pre-Hyperstream Security Hardening v2:
xenia-pre-hyperstream-security-hardening-v2-20260826.tar.gzad1211763841631414c743e4c60711c13703bc31e276e44644386fada2dcc5e98beafa0941dcaeb3d965f08a14f30c08660a9305Fresh replay of that exact final archive from untouched V22.1:
git diff --check: PASSNative Rust/Nix qualification remains mandatory and is currently blocked by #143. Do not merge on static evidence alone.
Integration ordering
This belongs in the same pre-Hyperstream security baseline as #145, #146, #147, and the durability-first operator-admin fix. If that baseline lands first, Hyperstream V24.4's live-base freshness gate should intentionally invalidate the old V22.1 qualification and require a fresh rebase/requalification.