Skip to content

The Spin adapter cannot build application state, so it answers every request except the health probe with 503 #1101

Description

@jwrosewell

crates/trusted-server-adapter-spin/src/app.rs builds its settings by compiling the shipped example configuration into the binary, with Settings::from_toml(include_str!("../../../trusted-server.example.toml")).

That template sets the admin handler password to replace-with-admin-password-32-bytes, which is the first entry in PASSWORD_PLACEHOLDERS in settings.rs. from_toml calls validate_admin_handler_passwords() unconditionally, so it always returns an error, build_state never returns successfully, and every request except the health probe fails. The health route keeps answering 200 even while state construction is failing, matching the Fastly and Axum behavior.

Reproduced before changing anything, because calling build_state() fails with
this configuration error, quoted verbatim:

Handler `^/_ts/admin` uses a placeholder password; configure a strong secret

Why no test caught it

Every Spin test enters through routes_with_settings and supplies its own settings, so the one path a deployed component actually takes is the one path never exercised. This is worth more attention than the defect itself, because the same shape would hide the same fault again.

How it is fixed in this stack

Settings now load from the platform config store at run time, the same as the Fastly, Axum and Cloudflare adapters, and the compiled-in template is gone. A new SpinPlatformConfigStore reads Spin component variables directly rather than through the per-request handle, because application state is built before any request exists. Component variables are ambient rather than request-scoped, which is already how the secret store adapter reads secrets, and both paths map keys through the existing spin_variable_name so start-up and the request path read the same variable for the same key.

One limit stated plainly, which is that outside the Spin runtime there are no component variables, so build_state() still cannot succeed under cargo test, on any adapter. The test therefore requires that any failure be the absence of a config store and nothing else, and asserts the message does not mention a password. Restoring the old body fails it.


Produced with AI assistance and needs human review. Verified against upstream/main.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions