secrets-engine/tests/test_verification_negative.py

62 lines
1.8 KiB
Python
Raw Permalink Normal View History

import copy
import os
import pytest
from secrets_engine.catalog import validate_entry
from secrets_engine.errors import ProvisioningError
from secrets_engine.openbao import read_strict_token_file
from secrets_engine.verify import verify_negative
from tests.test_catalog import VALID
def _entry():
return validate_entry(copy.deepcopy(VALID))
class NegativeClient:
def __init__(self, can_read):
self.can_read = can_read
self.tokens = []
def kv_can_read(self, _mount, _path, *, token):
self.tokens.append(token)
return self.can_read
def test_negative_check_fails_closed_without_real_unrelated_token():
client = NegativeClient(can_read=False)
result = verify_negative(client, _entry(), unrelated_token=None)
assert result.passed is False
assert "not proven" in result.detail["reason"]
assert client.tokens == []
def test_negative_check_uses_real_token_and_detects_policy_overlap():
denied = NegativeClient(can_read=False)
assert verify_negative(
denied, _entry(), unrelated_token="test-unrelated-token"
).passed
assert denied.tokens == ["test-unrelated-token"]
overlapping = NegativeClient(can_read=True)
result = verify_negative(
overlapping, _entry(), unrelated_token="test-overlapping-token"
)
assert result.passed is False
assert "LEAK RISK" in result.detail["reason"]
def test_negative_token_file_requires_mode_0600(tmp_path):
path = tmp_path / "unrelated.token"
path.write_text("test-unrelated-token", encoding="utf-8")
os.chmod(path, 0o644)
with pytest.raises(ProvisioningError, match="must be 0600"):
read_strict_token_file(path, purpose="negative verification token")
os.chmod(path, 0o600)
assert (
read_strict_token_file(path, purpose="negative verification token")
== "test-unrelated-token"
)