Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/cmcp_gateway/startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@

logger = logging.getLogger(__name__)

# HW-001: allowlist of canonical TEE provider names that may appear in
# AttestationReport.provider. Mirrors the keys of _PROVIDER_MAP in
# audit/trace_claim.py — kept as a local constant to avoid a circular import.
_VALID_PROVIDERS: frozenset[str] = frozenset({
"sev-snp",
"tdx",
"opaque",
"tpm",
"software-only",
})


@dataclass
class GatewayContext:
Expand Down Expand Up @@ -110,6 +121,20 @@ def run_startup(config_path: str) -> GatewayContext:
attestation_report.measurement[:16],
)

# HW-001: reject unknown provider strings before they can propagate into
# TRACE Claims or Cedar policy context. A custom or misconfigured provider
# could set an arbitrary value in provider_name(); validate here at the
# boundary rather than relying on downstream consumers to handle it.
if attestation_report.provider not in _VALID_PROVIDERS:
_fatal(
"ATTESTATION_PROVIDER_INVALID",
f"TEE provider returned unknown platform string '{attestation_report.provider}'. "
f"Allowed values: {sorted(_VALID_PROVIDERS)}.",
provider=attestation_report.provider,
action="startup_aborted",
)
sys.exit(1)

# AUTH-001 (CRITICAL): require a bearer token in production to authenticate
# inbound MCP calls. Without it, any network client can invoke any tool.
if config.bearer_token is None and not config.dev_mode:
Expand Down
22 changes: 21 additions & 1 deletion tests/unit/test_startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import json
import os
from pathlib import Path
from unittest.mock import patch
from unittest.mock import MagicMock, patch

import pytest

Expand Down Expand Up @@ -162,3 +162,23 @@ def test_startup_fails_when_catalog_hash_unset_and_not_dev_mode(tmp_path, monkey
with patch.dict(os.environ, env, clear=True), pytest.raises(SystemExit) as exc_info:
run_startup(str(config_path))
assert exc_info.value.code == 1


def test_startup_fails_on_unknown_tee_provider_name(complete_setup):
"""HW-001: a provider that returns an unknown platform string must cause exit 1.

The mock bypasses AttestationReport.__post_init__ by returning a plain
MagicMock, simulating a custom or misconfigured provider that injects an
arbitrary string before the startup boundary check can catch it.
"""
fake_report = MagicMock()
fake_report.provider = "evil-custom-tee"
fake_report.measurement = "aabbcc" * 8

with patch(
"cmcp_gateway.tee.base.SoftwareOnlyProvider.get_attestation_report",
return_value=fake_report,
), pytest.raises(SystemExit) as exc_info:
run_startup(complete_setup)

assert exc_info.value.code == 1
Loading