Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Security tests

Each security requirement in design §5.9 is a release blocker with a named test. This page maps each requirement to its tests and the file they live in, so a reviewer can check that a requirement is enforced and see what runs when one of its tests fails.

A test is planned for the milestone that builds the surface it guards: M1 for the CAS, M2 for the Hub and Git, M5 for caches and the mirror. Pending rows name tests that are not written yet; their surface does not exist yet either.

scripts/check-security-tests-map.py checks this page in CI against the tests that actually run:

  • every mapped Rust test is listed by cargo nextest list exactly once, from the file the page names, and is not ignored;
  • every mapped compatibility test is collected by pytest from its file;
  • every test name in design §5.9 is in the table below;
  • every M0 or M1 row names a file; only M2 and later rows are pending.

Run them all with:

cargo nextest run --workspace
uv run --directory compat pytest tests/test_fixture_redaction.py
OPENXET_BIN=$PWD/target/debug/openxet uv run --directory compat pytest -m agent
OPENXET_BIN=$PWD/target/debug/openxet uv run --directory compat pytest -m storage_only
# The map check, against the tests that run:
cargo nextest list --workspace --message-format json > /tmp/tests.json
uv run --directory compat pytest --collect-only -q > /tmp/compat-tests.txt
scripts/check-security-tests-map.py --nextest /tmp/tests.json --pytest /tmp/compat-tests.txt

Every server the compatibility suite starts, in both the agent and the storage_only legs, has its log scanned at teardown for every credential its clients sent (assert_no_credential_in_log).

Requirements and their tests

ReqTestFileMilestone
1no_unauthenticated_readscrates/cas/tests/reconstruction.rsM1
1signed_url_bound_to_rangecrates/auth/tests/auth.rsM1
2credential_scoped_to_repocrates/cas/tests/reconstruction.rsM1 (CAS routes)
2credential_scoped_to_repo, Hub routespendingM2
2repo_create_authorized_per_namespacependingM2
3cache_keyed_by_callerpendingM5
3cache_fails_closedpendingM5
4dedup_response_hmac_keyedcrates/cas/tests/dedup.rsM1
4dedup_answer_never_contains_raw_hashes_or_file_infocrates/cas/tests/dedup.rsM1
4per_scope_dedup_isolates_tenantscrates/cas/tests/dedup.rsM1
4per_scope_multi_xorb_answer_hides_foreign_xorbscrates/cas/tests/dedup.rsM1
4per_scope_existence_checks_hide_other_tenantscrates/cas/tests/reconstruction.rsM1
5the S6 rule tests of verify_shardcrates/protocol/tests/reference_files.rsM0
5shard_with_missing_xorb_rejectedcrates/cas/tests/shards.rsM1
5shard_verify_work_cappedcrates/cas/tests/shards.rsM1
5verification_errors_reveal_no_server_derived_valuescrates/protocol/tests/verify_errors.rsM1
5foreign_writer_cannot_forge_shard_under_globalcrates/cas/tests/shards.rsM1
6lfs_download_action_has_no_tokenpendingM2
6responses_never_echo_credentialcrates/cas/tests/routes_misc.rsM1
6credentials_never_loggedcrates/openxet/tests/serve.rsM1
6test_fixture_redactioncompat/tests/test_fixture_redaction.pyM0
7acknowledged_xorb_write_is_visiblecrates/cas/tests/xorbs.rsM1
7acknowledged_shard_write_is_visiblecrates/cas/tests/shards.rsM1
7acked_write_survives_sigkillcrates/openxet/tests/serve.rsM1
8v2_want_unreachable_refusedpendingM2
8hub_read_by_sha_obeys_r22pendingM2
8writer_cannot_make_unreachable_reachablependingM2
8hub_ref_write_fencedpendingM2
8ref_log_in_cas_transactionpendingM2

Notes on what some tests cover:

  • no_unauthenticated_reads requests every CAS route without a credential, then every data URL the CAS emits without its exact range. In M2 it extends to the HTTP read gateway and LFS hrefs.
  • credential_scoped_to_repo sends another scope's read and write credentials to every CAS route, aimed at the first scope's data.
  • per_scope_existence_checks_hide_other_tenants checks that, to another scope, a per-scope server holding a tenant's data answers every CAS route exactly as an empty server would.
  • credentials_never_logged runs a server at trace level through uploads, downloads and every kind of refusal, then scans its whole log for each credential, signature and key. The compatibility suite repeats the scan for every server it starts (assert_no_credential_in_log below).

Supporting tests

These tests keep the requirements' tests complete, or check a part of a requirement that the named tests don't.

ReqTestFileWhat it adds
1, 2, 6every_served_route_is_in_routes_or_the_allowlistcrates/cas/tests/routes_misc.rsEvery route the CAS serves is in the route list the credential, scoping and echo matrices walk, or on the explicit allowlist: /healthz, /readyz and the signed transfer route.
1, 2, 6router_serves_exactly_its_endpointscrates/cas/tests/routes_misc.rsThe route list matches the methods the router really answers.
1transfer_requires_signaturecrates/cas/tests/reconstruction.rsA transfer URL's signature binds one xorb, one range and an expiry.
1probes_need_no_credential_and_name_no_datacrates/cas/tests/routes_misc.rsThe probes, the only unauthenticated routes, name nothing stored.
4head_under_per_scope_hides_other_scopes_xorbscrates/cas/tests/xorbs.rsHEAD of a xorb under per-scope.
4per_scope_shard_cannot_reference_foreign_xorbcrates/cas/tests/shards.rsShard verification's xorb lookups under per-scope.
6auth_errors_never_contain_the_credentialcrates/auth/tests/auth.rsCredential errors never carry the credential.
6signed_urls_are_never_loggedcrates/cas/tests/reconstruction.rsA transfer URL's signature never reaches the log.
6assert_no_credential_in_logcompat/conftest.pyThe log of every server the compatibility suite starts, in the agent and storage_only legs, is scanned for the credentials its clients sent.