Files
ops-warden/tests/test_integration.py
tegwick f3547acd0b feat(warden): WARDEN-WP-0003 — test coverage, permissions, status --state-dir
- File permissions: os.chmod(cert, 0o600) after every sign in LocalCA and
  VaultCA; chmod(privkey, 0o600) and chmod(pubkey, 0o644) after generate_keypair
- Scorecard: add check_file_permissions() that flags world/group-readable
  cert and key files; run_scorecard now returns 6 checks
- warden status --state-dir: bypasses config loading entirely for operators
  who have a cert but no warden.yaml installed
- tests/test_vault.py: 11 VaultCA unit tests covering success, HTTP 403,
  RequestError, missing token, missing role, missing pubkey, TTL enforcement,
  eviction, signatures log, and cert mode 600
- tests/test_ca.py: generate_keypair tests (paths, args, overwrite, error,
  permissions) and cert mode 600 assertion after sign
- tests/test_scorecard.py: file_permissions check tests (pass, fail cert,
  fail keys dir); scorecard count updated to 6
- tests/test_cli.py: covers sign, issue, status, scorecard, inventory, log,
  cleanup commands using CliRunner and tmp config/inventory files
- tests/test_integration.py: @pytest.mark.integration tests against real
  ssh-keygen; excluded from default suite via pyproject addopts
- pyproject.toml: addopts = "-m 'not integration'", integration marker declared

All 100 unit tests pass; 3 integration tests pass; ruff clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 17:05:38 +02:00

105 lines
2.9 KiB
Python

"""Integration tests: real ssh-keygen, no mocking.
Run with: uv run pytest -m integration
Excluded from the default unit suite by pyproject.toml addopts.
"""
import shutil
import subprocess
from datetime import datetime, timezone
from pathlib import Path
import pytest
from warden.ca import LocalCA, parse_cert_metadata
from warden.models import ActorType, CertSpec
pytestmark = pytest.mark.integration
@pytest.fixture(autouse=True)
def require_ssh_keygen():
if shutil.which("ssh-keygen") is None:
pytest.skip("ssh-keygen not found in PATH")
def _generate_ca_key(tmp_path: Path) -> Path:
ca_key = tmp_path / "ca_key"
subprocess.run(
["ssh-keygen", "-t", "ed25519", "-f", str(ca_key), "-N", "", "-C", "test-ca"],
check=True,
capture_output=True,
)
return ca_key
def _generate_actor_key(tmp_path: Path) -> Path:
key = tmp_path / "actor_key"
subprocess.run(
["ssh-keygen", "-t", "ed25519", "-f", str(key), "-N", "", "-C", "actor"],
check=True,
capture_output=True,
)
return key
def test_local_ca_sign_real_ssh_keygen(tmp_path):
ca_key = _generate_ca_key(tmp_path)
actor_key = _generate_actor_key(tmp_path)
pubkey = Path(str(actor_key) + ".pub")
spec = CertSpec(
actor_name="agt-integration-test",
actor_type=ActorType.AGT,
pubkey_path=pubkey,
ttl_hours=1,
principals=["agt-integration-test"],
identity="agt-integration-test",
)
state_dir = tmp_path / "state"
ca = LocalCA(ca_key, state_dir)
record = ca.sign(spec)
assert record.cert_path.exists()
assert record.valid_before > datetime.now(timezone.utc)
assert record.identity == "agt-integration-test"
assert record.principals == ["agt-integration-test"]
# Re-parse without any mocking
meta = parse_cert_metadata(record.cert_path)
assert meta["identity"] == "agt-integration-test"
assert meta["valid_before"] > datetime.now(timezone.utc)
def test_local_ca_sign_cert_file_mode_600(tmp_path):
ca_key = _generate_ca_key(tmp_path)
actor_key = _generate_actor_key(tmp_path)
pubkey = Path(str(actor_key) + ".pub")
spec = CertSpec(
actor_name="agt-integration-test",
actor_type=ActorType.AGT,
pubkey_path=pubkey,
ttl_hours=1,
principals=["agt-integration-test"],
identity="agt-integration-test",
)
ca = LocalCA(ca_key, tmp_path / "state")
record = ca.sign(spec)
assert oct(record.cert_path.stat().st_mode & 0o777) == oct(0o600)
def test_generate_keypair_real_ssh_keygen(tmp_path):
ca_key = _generate_ca_key(tmp_path)
ca = LocalCA(ca_key, tmp_path / "state")
privkey, pubkey = ca.generate_keypair("agt-integration-test")
assert privkey.exists()
assert pubkey.exists()
assert oct(privkey.stat().st_mode & 0o777) == oct(0o600)
assert oct(pubkey.stat().st_mode & 0o777) == oct(0o644)
assert "ssh-ed25519" in pubkey.read_text()