feat: add API-only preflight signing delivery and rotation acceptance
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ed7-828d-7ca0-a8d4-0c3e5a0c4102
This commit is contained in:
parent
485275d868
commit
e96ef197cf
4 changed files with 101 additions and 0 deletions
38
tests/test_preflight_signing_rotation.py
Normal file
38
tests/test_preflight_signing_rotation.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
"""Single-key invalidation guarantees needed by the platform rotation fence."""
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
import pytest
|
||||
|
||||
from api.config import settings
|
||||
from api.services.repository_rename import (
|
||||
RenamePreconditionFailed, RenameServiceUnavailable,
|
||||
_sign_preflight, _verify_preflight_token,
|
||||
)
|
||||
|
||||
|
||||
def test_rotation_invalidates_predecessor_and_accepts_successor(monkeypatch):
|
||||
payload = {'expires_at': (datetime.now(timezone.utc) + timedelta(minutes=15)).isoformat()}
|
||||
monkeypatch.setattr(settings, 'repository_rename_preflight_secret', 'fixture-old-key')
|
||||
predecessor = _sign_preflight(payload)
|
||||
assert _verify_preflight_token(predecessor) == payload
|
||||
monkeypatch.setattr(settings, 'repository_rename_preflight_secret', 'fixture-new-key')
|
||||
with pytest.raises(RenamePreconditionFailed):
|
||||
_verify_preflight_token(predecessor)
|
||||
assert _verify_preflight_token(_sign_preflight(payload)) == payload
|
||||
|
||||
|
||||
def test_tamper_expiry_and_no_key_fail_closed(monkeypatch):
|
||||
monkeypatch.setattr(settings, 'repository_rename_preflight_secret', 'fixture-key')
|
||||
future = {'expires_at': (datetime.now(timezone.utc) + timedelta(minutes=15)).isoformat()}
|
||||
token = _sign_preflight(future)
|
||||
encoded, signature = token.split('.')
|
||||
with pytest.raises(RenamePreconditionFailed):
|
||||
_verify_preflight_token(encoded + '.' + ('A' if signature[0] != 'A' else 'B') + signature[1:])
|
||||
past = {'expires_at': (datetime.now(timezone.utc) - timedelta(seconds=1)).isoformat()}
|
||||
with pytest.raises(RenamePreconditionFailed, match='expired'):
|
||||
_verify_preflight_token(_sign_preflight(past))
|
||||
monkeypatch.setattr(settings, 'repository_rename_preflight_secret', None)
|
||||
with pytest.raises(RenameServiceUnavailable):
|
||||
_sign_preflight(future)
|
||||
with pytest.raises(RenameServiceUnavailable):
|
||||
_verify_preflight_token(token)
|
||||
Loading…
Add table
Add a link
Reference in a new issue