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
4 changes: 4 additions & 0 deletions loopx/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ def _prefilter_fold(text: str) -> str:
"sk_test_",
"rk_live_",
"rk_test_",
"sk-proj-",
"sk-svcacct-",
"sk-admin-",
"sk-ant-",
"npm_",
"pypi-",
"eyj",
Expand Down
2 changes: 2 additions & 0 deletions loopx/public_safe_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@
r"\bxox[baprs]-[a-z0-9-]{10,}|"
r"\baiza[a-z0-9_-]{20,}|"
r"\b(?:sk|rk)_(?:live|test)_[a-z0-9]{12,}|"
r"\bsk-(?:proj|svcacct|admin)-[a-z0-9_-]{20,}|"
r"\bsk-ant-[a-z0-9_-]{20,}|"
r"\bnpm_[a-z0-9]{20,}|"
r"\bpypi-[a-z0-9_-]{20,}|"
r"\beyj[a-z0-9_-]{10,}\.[a-z0-9_-]{10,}\.[a-z0-9_-]{10,}\b"
Expand Down
10 changes: 9 additions & 1 deletion tests/control_plane/test_presentation_public_safety.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ def test_colon_prefixed_unix_paths_keep_the_existing_boundary() -> None:
"sk_live_51H8" + "aBcDeFgHiJkL",
"npm_" + "a1B2c3D4e5F6g7H8i9J0",
"pypi-AgEIcHlwaS5vcmc" + "AAAAAAAAAA",
"sk-proj-" + "A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0",
"sk-svcacct-" + "A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0",
"sk-admin-" + "A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0",
"sk-ant-api03-" + "A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0",
"eyJhbGciOiJIUzI1NiJ9" + ".eyJzdWIiOiIxMjM0NTY3ODkwIn0" + ".SflKxwRJSMeKKF2QT4f",
],
)
Expand All @@ -109,9 +113,13 @@ def test_unlabeled_provider_tokens_fail_the_boundary_scan(token: str) -> None:
"AWS key ids start AKIA and ASIA, then sixteen more characters",
"pypi- prefix alone is not a token",
"sk-proj-abcdefghijklmnop is an OpenAI project key shape",
"sk-svcacct-abcdefghijklmnop is a short example",
"sk-admin-abcdefghijklmnop is a short example",
"sk-ant-abcdefghijklmnop is a short example",
"sk-custom-" + "abcdefghijklmnopqrstuvwx",
],
)
def test_ordinary_prose_and_unclaimed_shapes_stay_public(text: str) -> None:
def test_ordinary_prose_and_short_provider_lookalikes_stay_public(text: str) -> None:
assert public_safety.scan_public_boundary_text(text) == {
"ok": True,
"warnings": [],
Expand Down
8 changes: 8 additions & 0 deletions tests/test_contract_credential_pattern_precision.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ def test_private_lark_tenant_urls_remain_blocked(tmp_path: Path, line: str) -> N
# second list here: this rule gates repository publication, and a list that
# recognized only some issuers certified the rest as public-safe.
PROVIDER_TOKEN_SAMPLES = [
"sk-proj-" + "A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0",
"sk-svcacct-" + "A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0",
"sk-admin-" + "A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0",
"sk-ant-api03-" + "A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0",
"ghp_" + "16C7e42F292c6912E7710c838347Ae178B4a",
"github_pat_" + "11ABCDEFG0123456789_abcdefghijklmnopqrstuvwxyz0123456789",
"xoxb-" + "123456789012-abcdefghijkl",
Expand Down Expand Up @@ -182,6 +186,10 @@ def test_a_short_provider_lookalike_stays_clean(tmp_path: Path) -> None:
PROVIDER_TOKENS_WITH_PLACEHOLDER_BODY = [
"ghp_" + "dummy" + "1234567890abcdefghijklmnop",
"npm_" + "example" + "1234567890abcdefghij",
"sk-proj-" + "example" + "1234567890abcdefghij",
"sk-svcacct-" + "example" + "1234567890abcdefghij",
"sk-admin-" + "example" + "1234567890abcdefghij",
"sk-ant-api03-" + "example" + "1234567890abcdefghij",
]


Expand Down
12 changes: 12 additions & 0 deletions tests/test_static_site_presentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,18 @@ def test_package_requires_visual_and_link_validation_receipts(
_package(site, tmp_path / "publish", tmp_path / "state", **{field: value})


@pytest.mark.parametrize("prefix", ["sk-proj-", "sk-svcacct-", "sk-admin-", "sk-ant-api03-"])
def test_package_rejects_unlabeled_ai_provider_tokens(tmp_path: Path, prefix: str) -> None:
site = _site(tmp_path)
token = prefix + "A1b2C3d4E5f6G7h8I9j0K1l2M3n4O5p6Q7r8S9t0"
(site / "notes.txt").write_text(f"provider output: {token}\n", encoding="utf-8")
destination = tmp_path / "publish"

with pytest.raises(StaticSiteContractError, match="public boundary scan failed"):
_package(site, destination, tmp_path / "state")
assert not destination.exists()


def test_package_rejects_reserved_paths_symlinks_and_public_boundary_leaks(
tmp_path: Path,
) -> None:
Expand Down
Loading