Summary
Follow-up from #869 / PR #870. Several config fields fail open at ts config validate / deploy validation: template placeholder values (or trivially-fake values) pass validation and only fail later at runtime / key-rotation time. The secret placeholders (EC passphrase, proxy_secret, admin handler password, partner API tokens) are already rejected; these are the remaining gaps.
None of these are security holes on their own — a wrong domain or fake pub_id simply won't work at runtime — but rejecting them at config-push time gives operators a much faster, clearer failure.
Gaps
-
Reserved example publisher hosts pass validation (High).
[publisher] domain = "example.com", cookie_domain = ".example.com", origin_url = "https://origin.example.com" validate OK. An operator who changes the three secret placeholders but forgets the publisher block deploys against example.com.
- Tension to resolve: CLAUDE.md mandates
example.com in all examples, and the test suite uses example.com pervasively. Any rejection must distinguish "unedited template default" from legitimate test/example usage (e.g. only reject in validate_settings_for_deploy, and/or a dedicated reserved-host list mirroring the secret-placeholder approach). Needs its own tests.
-
ApsConfig.pub_id has no non-empty/placeholder validation (Medium).
With [integrations.aps] enabled = true, pub_id = "your-aps-publisher-id" validates (only custom deserialization runs, no #[validate]). Add a non-empty + placeholder check.
-
RequestSigning has no Validate derive / placeholder rejection (Low).
config_store_id / secret_store_id accept any string (e.g. <management-config-store-id>), so a misconfigured request-signing block validates and fails later at key rotation instead of at push.
Acceptance
ts config validate / deploy validation rejects each of the above with a clear message, without breaking the many example.com-based tests or the example config embedded in the Cloudflare/Spin adapters.
- Once rejection lands, update
trusted-server.example.toml comments accordingly (the template currently notes these as fail-open).
Context
- Placeholder-secret rejection lives in
Settings::reject_placeholder_secrets / validate_settings_for_deploy (config.rs) and the per-type *_PLACEHOLDERS lists (settings.rs).
- Handler password rejection:
Handler::PASSWORD_PLACEHOLDERS.
- GTM already validates its container id via
GTM_CONTAINER_ID_PATTERN — a good model for pub_id.
Summary
Follow-up from #869 / PR #870. Several config fields fail open at
ts config validate/ deploy validation: template placeholder values (or trivially-fake values) pass validation and only fail later at runtime / key-rotation time. The secret placeholders (EC passphrase, proxy_secret, admin handler password, partner API tokens) are already rejected; these are the remaining gaps.None of these are security holes on their own — a wrong domain or fake pub_id simply won't work at runtime — but rejecting them at config-push time gives operators a much faster, clearer failure.
Gaps
Reserved example publisher hosts pass validation (High).
[publisher]domain = "example.com",cookie_domain = ".example.com",origin_url = "https://origin.example.com"validate OK. An operator who changes the three secret placeholders but forgets the publisher block deploys againstexample.com.example.comin all examples, and the test suite usesexample.compervasively. Any rejection must distinguish "unedited template default" from legitimate test/example usage (e.g. only reject invalidate_settings_for_deploy, and/or a dedicated reserved-host list mirroring the secret-placeholder approach). Needs its own tests.ApsConfig.pub_idhas no non-empty/placeholder validation (Medium).With
[integrations.aps] enabled = true,pub_id = "your-aps-publisher-id"validates (only custom deserialization runs, no#[validate]). Add a non-empty + placeholder check.RequestSigninghas noValidatederive / placeholder rejection (Low).config_store_id/secret_store_idaccept any string (e.g.<management-config-store-id>), so a misconfigured request-signing block validates and fails later at key rotation instead of at push.Acceptance
ts config validate/ deploy validation rejects each of the above with a clear message, without breaking the manyexample.com-based tests or the example config embedded in the Cloudflare/Spin adapters.trusted-server.example.tomlcomments accordingly (the template currently notes these as fail-open).Context
Settings::reject_placeholder_secrets/validate_settings_for_deploy(config.rs) and the per-type*_PLACEHOLDERSlists (settings.rs).Handler::PASSWORD_PLACEHOLDERS.GTM_CONTAINER_ID_PATTERN— a good model for pub_id.