Distinguish MSP evaluation issuance from readiness

This commit is contained in:
rcourtman
2026-08-11 14:48:01 +01:00
parent 2bc4ed7254
commit c17664b3da
6 changed files with 42 additions and 33 deletions
+1 -1
View File
@@ -402,7 +402,7 @@ ensure_eval_license() {
--arg public_key "${public_key}" \
--arg email "${PULSE_PROVIDER_MSP_EVAL_EMAIL}" \
--arg signup_source "${PULSE_PROVIDER_MSP_SIGNUP_SOURCE}" \
'{entitlement_signing_public_key: $public_key}
'{entitlement_signing_public_key: $public_key, setup_stage: "images_ready"}
+ (if $email == "" then {} else {email: $email} end)
+ (if $signup_source == "" then {} else {signup_source: $signup_source} end)')"
response="$(curl -fsS --max-time 20 \
+8 -12
View File
@@ -293,15 +293,12 @@ sha256sum -c "${PULSE_MSP_BUNDLE}.sha256"
tar -xzf "${PULSE_MSP_BUNDLE}"
cd "pulse-provider-msp-${PULSE_VERSION}"
export PULSE_PROVIDER_MSP_EVAL_EMAIL=you@example.com
export PULSE_PROVIDER_MSP_SIGNUP_SOURCE=msp_docs
sudo -E bash ./setup.sh
```
`PULSE_PROVIDER_MSP_EVAL_EMAIL` is optional. Set it if you want setup help and
want an eventual paid upgrade matched to this deployment; omit it for an
anonymous evaluation. The signup-source value is a fixed attribution label,
not free-form telemetry.
The v6.2.1 evaluation request is anonymous. If you want setup help, start from
the [Pulse MSP evaluation page](https://pulserelay.pro/msp.html#evaluate) first;
that contact request remains separate from the licence activation.
The host needs Ubuntu 24.04 or similar, a domain you can point at it, and
ports 80 and 443 free. Install `curl`, `openssh-client`, `coreutils`, and `tar`
@@ -311,12 +308,11 @@ Traefik dnsChallenge provider works by setting `ACME_DNS_PROVIDER` in `.env`
and putting that provider's credential variables in `dns-credentials.env`.
Leave `CP_PROVIDER_MSP_LICENSE_FILE` blank and `setup.sh` self-issues a
2-client evaluation licence after configuration validation succeeds and the
immutable images are reachable. It sends only the public half of the signing
key generated on your host, the optional contact address above, and the fixed
signup-source label. The private key, client inventory, and credentials never
leave the machine. You can then onboard two real clients and confirm the
isolation boundary on your own infrastructure before buying.
2-client evaluation licence. The v6.2.1 bundle sends only the public half of
the signing key generated on your host. The private key, client inventory,
credentials, and contact details never leave the machine. You can then onboard
two real clients and confirm the isolation boundary on your own infrastructure
before buying.
The evaluation licence lasts 60 days and re-running `setup.sh` reuses the one
already on disk. On an air-gapped host set
@@ -3323,8 +3323,9 @@ The provider-hosted MSP acquisition funnel uses commercial records that already
belong to the boundary rather than reviving retired generic browser analytics
or adding client-workspace phone-home. An explicit landing-page evaluation
start is delivered to the support inbox with the fixed `msp_landing` source; a
persisted `msp_eval` licence is the activation stage and is issued only after
provider setup validates configuration and resolves the immutable images; a
persisted `msp_eval` licence is the evaluation-issuance stage, and becomes a
ready-host activation only when its audit carries the bounded `images_ready`
stage after provider setup validates configuration and resolves the immutable images; a
persisted `msp_starter`, `msp_growth`, or `msp_scale` licence is an assisted
licence stage, not proof of payment by itself. Administrative issuance must
record a bounded reason, and only the first `paid_conversion` reason may enter
@@ -3335,6 +3336,12 @@ evaluation licence ID may join an assisted upgrade to its activation, but no
stage may collect client inventory, credentials, private signing material, or
free-form runtime telemetry. Anonymous evaluation must remain available.
The activation interpretation requires the bounded `setup_stage=images_ready`
audit value. An evaluation without that value, including issuance from the
published v6.2.1 bundle, remains an issued evaluation rather than a proved
ready-host activation. Funnel aggregation must report both values separately
and must not infer readiness from plan version, contactability, or source.
Provider-hosted Starter remains assisted even though the signed evaluation
bundle is now public. A generic recurring Stripe checkout is not a valid
substitute: the provider licence is a static offline file, so self-service
@@ -3314,10 +3314,11 @@ unlicensed control plane starts, but release-build client runtimes reject its
unchained entitlement leases and the client workspaces run without the
capabilities being evaluated.
Evaluation issuance happens only after setup has validated the operator
configuration and confirmed that every immutable provider image is reachable.
That ordering makes a stored `msp_eval` issue an activation signal rather than
a download-intent signal created before the install can succeed. Setup may
Current setup code issues an evaluation only after validating the operator
configuration and confirming that every immutable provider image is reachable,
and records the fixed `setup_stage=images_ready` value. That combination makes
the stored `msp_eval` row an activation signal rather than a download-intent
signal created before the install can succeed. Setup may
include an optional evaluator email and a fixed signup-source label so support
can match an assisted paid upgrade to the deployment. Those fields must remain
optional and bounded; the request must never contain client inventory,
@@ -3325,6 +3326,14 @@ credentials, private keys, or free-form runtime telemetry. The returned public
evaluation licence ID may be carried in the upgrade URL as a non-secret
correlation key.
That ordering and attribution contract applies only when the request carries
the fixed `setup_stage=images_ready` marker. The immutable v6.2.1 provider
bundle predates the marker and requests its evaluation earlier, so its stored
`msp_eval` row proves issuance only, not install readiness, and remains
anonymous. Public v6.2.1 guidance must state that exact behavior. It must not
claim automatic contact correlation or post-image-ready activation until a
newer signed bundle containing the contract is published.
Self-issue must degrade rather than block. A missing signing key, an
unreachable licence server, or a response carrying no licence leaves the
install unlicensed with an explicit warning, and `PULSE_PROVIDER_MSP_SKIP_EVAL_LICENSE`
+8 -12
View File
@@ -293,15 +293,12 @@ sha256sum -c "${PULSE_MSP_BUNDLE}.sha256"
tar -xzf "${PULSE_MSP_BUNDLE}"
cd "pulse-provider-msp-${PULSE_VERSION}"
export PULSE_PROVIDER_MSP_EVAL_EMAIL=you@example.com
export PULSE_PROVIDER_MSP_SIGNUP_SOURCE=msp_docs
sudo -E bash ./setup.sh
```
`PULSE_PROVIDER_MSP_EVAL_EMAIL` is optional. Set it if you want setup help and
want an eventual paid upgrade matched to this deployment; omit it for an
anonymous evaluation. The signup-source value is a fixed attribution label,
not free-form telemetry.
The v6.2.1 evaluation request is anonymous. If you want setup help, start from
the [Pulse MSP evaluation page](https://pulserelay.pro/msp.html#evaluate) first;
that contact request remains separate from the licence activation.
The host needs Ubuntu 24.04 or similar, a domain you can point at it, and
ports 80 and 443 free. Install `curl`, `openssh-client`, `coreutils`, and `tar`
@@ -311,12 +308,11 @@ Traefik dnsChallenge provider works by setting `ACME_DNS_PROVIDER` in `.env`
and putting that provider's credential variables in `dns-credentials.env`.
Leave `CP_PROVIDER_MSP_LICENSE_FILE` blank and `setup.sh` self-issues a
2-client evaluation licence after configuration validation succeeds and the
immutable images are reachable. It sends only the public half of the signing
key generated on your host, the optional contact address above, and the fixed
signup-source label. The private key, client inventory, and credentials never
leave the machine. You can then onboard two real clients and confirm the
isolation boundary on your own infrastructure before buying.
2-client evaluation licence. The v6.2.1 bundle sends only the public half of
the signing key generated on your host. The private key, client inventory,
credentials, and contact details never leave the machine. You can then onboard
two real clients and confirm the isolation boundary on your own infrastructure
before buying.
The evaluation licence lasts 60 days and re-running `setup.sh` reuses the one
already on disk. On an air-gapped host set
@@ -363,6 +363,7 @@ func TestProviderMSPSetupScriptSupportsUnlicensedEvaluation(t *testing.T) {
"could not reach the license server",
"PULSE_PROVIDER_MSP_EVAL_EMAIL",
"PULSE_PROVIDER_MSP_SIGNUP_SOURCE",
`setup_stage: "images_ready"`,
"eval_license_id=",
)
if strings.LastIndex(script, "pull_provider_images\n") > strings.LastIndex(script, "ensure_eval_license\n") {
@@ -429,8 +430,8 @@ func TestProviderMSPEvaluationDocsUsePublishedSignedBundle(t *testing.T) {
"ssh-keygen -Y verify",
`-s "${PULSE_MSP_BUNDLE}.sshsig" < "${PULSE_MSP_BUNDLE}"`,
`sha256sum -c "${PULSE_MSP_BUNDLE}.sha256"`,
`PULSE_PROVIDER_MSP_EVAL_EMAIL=you@example.com`,
`PULSE_PROVIDER_MSP_SIGNUP_SOURCE=msp_docs`,
"The v6.2.1 evaluation request is anonymous",
"contact request remains separate from the licence activation",
`sudo -E bash ./setup.sh`,
)
assertNotContainsAny(t, doc,