Skip to content

Add SIP for target world validation #3217

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
75 changes: 75 additions & 0 deletions docs/content/sips/022-validate-target-environment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
title = "SIP 022 - Target Environment Validation"
template = "main"
date = "2025-08-07T00:00:00Z"
---

Summary: Provide a mechanism to validate that a Spin application is compatible with its intended deployment environment(s).

Owner(s): [email protected]

Created: Aug 7, 2025

## Background

When developing a Spin application, developers might use features that are only available in a specific Spin environment. For example, an application might use a custom trigger or a host capability that is only available in a specific deployment environment, or in a self-hosted Spin instance with specific plugins.

Currently, there is no way to declare the intended deployment environment for an application and have Spin validate that the application is compatible with it. This can lead to situations where an application builds successfully but fails at runtime in the target environment due to missing dependencies, unsupported features, or other incompatibilities.

This SIP proposes a new mechanism to address this problem by allowing developers to specify the target environments for their applications and have Spin validate the compatibility of the application with those environments at build time.

## Proposal

The proposal is to introduce a new `targets` field in the `[application]` section of the `spin.toml` manifest file. This field will contain a list of identifiers for the target environments. Spin will use these identifiers to fetch environment definition files and validate the application against them.

### The `targets` field in `spin.toml`

The `targets` field is a list of strings or tables that identify the target environments. It can be specified in the `[application]` section of `spin.toml` like this:

```toml
[application]
name = "my-app"
version = "1.0.0"
targets = ["spin-up:3.3", "spinkube:0.4", { registry = "ghcr.io/my-org/environments", id = "my-env:1.0" }, { path = "local-env.toml" }]
```

Each entry in the list can be:
- A string that identifies an environment in the default registry (e.g., `"spin-up:3.3"`).
- A table with `registry` and `id` keys to identify an environment in a custom OCI registry.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should permit wkg registry names (bare domain) here with the /.well-known/wasm-pkg/registry.json indirection.

Copy link
Collaborator

@lann lann Aug 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively we could specify a slightly different syntax that implies this lookup, like

targets = ["my.org/[email protected]"]

This would look up the oci prefix at https://my.org/.well-known/wasm-pkg/registry.json and use it to construct an oci reference like ghcr.io/my-org/my-env:1.0. If we wanted to mechanically avoid conflicts between environments and regular wasm packages we could stick another substring in there e.g. ghcr.io/my-org/my-env:spin-env-1.0 or ghcr.io/my-org/spin-env/my-env:1.0 or something.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lann These entries point to TOML documents not WIT documents. (The TOML documents then point onward to WIT documents, which are typically wkg package references.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure; I'm suggesting that we could reuse the domain -> OCI mapping that wkg already implements to allow nicer specifications of targets from registries.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry thanks for the clarification

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like a convenience feature we could add without breaking back compat if the feature achieves traction? Or are we sufficiently confident that other folks will be publishing environment TOMLs that we need to offer this in the first drop?

- A table with a `path` key to specify a local environment definition file.

### Environment Definition Files

An environment definition is a TOML file that describes the capabilities of a Spin environment. It specifies the triggers that are available in the environment, and for each trigger, the WIT worlds that are compatible with it and the host capabilities that it supports.

Here is an example of an environment definition file:

```toml
# spin-up.3.2.toml
[triggers.http]
worlds = ["spin:up/[email protected]", "spin:up/[email protected]"]
capabilities = ["local_service_chaining"]

[triggers.redis]
worlds = ["spin:up/[email protected]"]
Comment on lines +52 to +53
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me wonder if we should accept e.g. { trigger_type = "redis", world = "spin:up/[email protected]" } as a valid target.

Copy link
Collaborator

@lann lann Aug 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess a slightly more verbose but flexible way to get the same effect would be allowing inline environment definitions. 🤷

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe the target could be just the world reference? While that wouldn't have explicit trigger types those can be sort of inferred from the manifest itself. 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lann I am wary of that for two reasons:

  1. It breaks down as soon as multi-trigger-type enters play - you find yourself needing to infer which world corresponds to which trigger type. We tried that and it was terrible.
  2. It breaks the "I want to make sure I can deploy to..." abstraction. The goal here is for the developer to say "I want this to run on Wasmtime 35, Spin 3.2, and SpinKube 3.1." If I want to target spin:up/[email protected], and figure out for myself whether that's compatible with SpinKube 3.1, then I have the tools to do that. The idea is to take care of "knowing which worlds a host supports" for you.

I'm not opposed to inline environments as an escape hatch, but I'd like them to be defined in the same way as other environments, and at that point I don't see a vast amount of value compared to putting them in a my-environment.toml file.

```

This file defines an environment that supports the `http` and `redis` triggers. The `http` trigger is compatible with two different WIT worlds and supports the `local_service_chaining` capability. The `redis` trigger is compatible with one WIT world and has no specific capabilities.

### Validation at Build Time

When the user runs `spin build`, Spin will perform the following steps if the `targets` field is present in `spin.toml`:

1. For each target environment specified in the `targets` field, Spin will fetch the corresponding environment definition file.
2. For each component in the application, Spin will check if its trigger is supported in the target environment.
3. If the trigger is supported, Spin will check if the component's WIT world is compatible with one of the worlds defined for that trigger in the environment definition.
4. Spin will also check if all the capabilities required by the component are supported by the environment.

If any of these checks fail for any of the target environments, the build will fail with an error message indicating the incompatibility.

The user can bypass the validation by using the `--skip-target-checks` flag with the `spin build` command.

## Future work

- **Per-component target environments:** We could allow overriding the `targets` field on a per-component basis. This would be useful for applications that end up being deployed into multiple environments in a modular fashion.
- **Tooling for environment authors:** We could provide tools to help authors create and publish environment definition files.
- **Using environment definitions for bindings generation:** With this SIP, we propose to use target worlds in a validation predicate. Building on this, we could also use them to better support authors in targeting the right environment to begin with.
Loading