Scanner PoE Dev Harness
Audience: Scanner and Signer developers validating the PoE-to-Signer contract on a local workstation. This is a development harness, not a production or CI procedure — see Boundaries.
This runbook exercises Scanner Worker Proof-of-Exposure (PoE) against the real Signer service in local compose. It is opt-in and does not enable PoE in the default development stack.
What It Proves
- Scanner Worker starts with
PoE:Enabled=true. - Scanner Worker uses the HTTP Signer DSSE binding, not a local/null signer.
- Signer receives a configured proof of entitlement (
dev_poe) from its own entitlement registry. - Signer release verification trusts the actual local
stellaops/scanner-worker:devimage ID (sha256:<64 hex>) computed from Docker. - The helper requests a DPoP-bound
signer:signtoken from the localscanner-poe-devAuthority client and sends a fresh, access-token-bound DPoP proof to Signer.
Prerequisites
- The local Stella Ops compose stack can run
authority,signer, andscanner-worker. authority.stella-ops.localresolves to127.1.0.4fromdevops/compose/hosts.stellaops.local; the compose stack publishes the Authority host endpoint onhttp://authority.stella-ops.local:8440.- Docker has a local
stellaops/scanner-worker:devimage. - The local Authority configuration includes the dev-only
scanner-poe-devclient with audiencesigner, scopesigner:sign, andsenderConstraint: dpop. Local compose seeds this throughetc/authority/plugins/standard.yaml; root Authority config samples carry the same client for non-compose profiles.
Fast Path
Use the local dev Authority client:
powershell -ExecutionPolicy Bypass -File .\devops\compose\scripts\scanner-poe-dev.ps1 -Action config -NoTokenFetch -PrintEnvironment
powershell -ExecutionPolicy Bypass -File .\devops\compose\scripts\scanner-poe-dev.ps1 -Action up
Run the deterministic Signer smoke against live local services:
powershell -ExecutionPolicy Bypass -File .\devops\compose\scripts\scanner-poe-dev.ps1 -Action smoke
To persist the Signer response for a later DSSE/Finding-bundle review, provide an output path. To bind the smoke predicate to a Findings evidence bundle, provide the regenerated bundle hash:
powershell -ExecutionPolicy Bypass -File .\devops\compose\scripts\scanner-poe-dev.ps1 `
-Action smoke `
-BundleHash "sha256:<findings bundle hash>" `
-OutputResponsePath .\artifacts\signer-poe-findings-bundle-response.json
The script writes or reuses a local ES256 DPoP private key at devops/compose/offline/scanner-poe-dev/dpop-es256-private.pem when the local PowerShell/.NET runtime supports PEM import/export. Older Windows PowerShell runtimes fall back to an ephemeral ES256 key for that run and print a warning. In both cases it uses one key for the Authority and Signer proofs, retries once with a nonce claim when Authority returns DPoP-Nonce, derives a fresh Signer DPoP proof for POST /api/v1/signer/sign/dsse with ath over the access token, computes SCANNER_POE_WORKER_IMAGE_DIGEST from Docker, and injects the resulting environment into:
devops/compose/docker-compose.scanner-poe-dev.ymlscanner-workerPoE signer settingssignerentitlement and trusted Scanner digest settings
The default entitlement token key is dev_poe instead of dev-poe because the Signer container starts through a POSIX shell entrypoint. Environment variable names containing hyphens are discarded by that shell before dotnet starts.
-Action up starts local Authority first when it must mint a token, starts Signer with the trusted local Scanner digest, runs the deterministic DSSE smoke against Signer, and only then starts Scanner Worker with PoE:Enabled=true. -BundleHash is optional for the base Scanner-to-Signer smoke, but should be used when the response is evidence for a concrete Findings bundle. The hash is included in the signed predicate; Findings verification still validates the downloaded bundle hash independently before accepting the DSSE envelope.
For offline compose rendering without live Authority, use either an explicit token or no-fetch config rendering:
$env:SCANNER_POE_BEARER_TOKEN = "<access token with signer:sign>"
powershell -ExecutionPolicy Bypass -File .\devops\compose\scripts\scanner-poe-dev.ps1 -Action config -PrintEnvironment
powershell -ExecutionPolicy Bypass -File .\devops\compose\scripts\scanner-poe-dev.ps1 -Action config -NoTokenFetch -PrintEnvironment
The second command uses placeholder auth values only to render compose configuration. Do not use it for up or smoke.
Manual Compose
If you do not use the helper, set these values yourself:
$env:SCANNER_POE_WORKER_IMAGE_DIGEST = "sha256:<docker image id for stellaops/scanner-worker:dev>"
$env:SCANNER_POE_BEARER_TOKEN = "<access token with signer:sign>"
$env:SCANNER_POE_DPOP_PROOF = "<DPoP proof for POST http://signer.stella-ops.local:8441/api/v1/signer/sign/dsse>"
Then run:
cd .\devops\compose
docker compose `
-f docker-compose.stella-infra.yml `
-f docker-compose.stella-services.yml `
-f docker-compose.scanner-poe-dev.yml `
up -d signer scanner-worker
Expected Failure Modes
- Missing
SCANNER_POE_WORKER_IMAGE_DIGEST: compose refuses to render the overlay. - Digest not trusted by Signer: DSSE signing returns release verification failure.
- Missing bearer token and unavailable Authority client credentials:
upandsmokeexit before contacting Signer;config -NoTokenFetchstill renders compose with placeholders. - Missing DPoP proof: Scanner Worker fails startup validation before accepting jobs.
- Expired or replayed DPoP material: regenerate it by rerunning the helper.
Boundaries
This is a development harness, not a release manifest substitute. The local Docker image ID is enough to test the Scanner-to-Signer contract in dev. A release pipeline must still use registry manifest digests and deployment-managed Authority clients, DPoP key custody, and secret distribution. The committed scanner-poe-dev client secret is local/dev fixture material only and must not be reused in CI, staging, production, or shared environments.
