External Package Lifecycle
This guide shows the operator-facing baseline for taking a Cephalon module package from a published artifact to a trusted runtime load outside this repository.
Use it together with Module authoring when you are shipping independently distributed Cephalon packages.
For the repo-native replay of this full out-of-tree path, use pwsh ./scripts/validate-out-of-tree-package-adoption.ps1.
For the matching detached-signature and publisher or signer trust replay, use pwsh ./scripts/validate-signed-package-governance.ps1.
For the matching certificate-chain trust replay, use pwsh ./scripts/validate-signed-package-certificate-chain-governance.ps1.
What this proves
Section titled “What this proves”- a module can be packed as a published
.nupkg - the published artifact can be staged into a loadable package directory with
cephalon package stage - a host can load that staged package through
Engine:Discovery:PackageDirectories Engine:PackagePolicyandEngine:Trustcan govern the load- detached signatures can be required and verified through
Engine:Trust:TrustedSignaturePublicKeysorEngine:Trust:TrustedSignatureCertificatesplusEngine:Trust:TrustedSignatureCertificateAuthorities - tampered signed packages can be denied before their module code becomes active
/engine/packages,/engine/package-policy,/engine/trust-policy, and/engine/snapshotexpose the truth of what loaded
1. Publish the module artifact
Section titled “1. Publish the module artifact”Pack the reference module or your own module package:
dotnet pack ./samples/Cephalon.ReferenceModule.Operations/Cephalon.ReferenceModule.Operations.csproj ` -c Release ` -o ./artifacts/reference-packagesThe published .nupkg is the distribution artifact. It is not yet the directory shape that Engine:Discovery:PackageDirectories loads directly.
2. Stage the package into a loadable directory
Section titled “2. Stage the package into a loadable directory”Use the Cephalon CLI to materialize the manifest and selected lib/<tfm> files into a package directory:
cephalon package stage ` --package ./artifacts/reference-packages/Cephalon.ReferenceModule.Operations.1.0.0.nupkg ` --output ./plugins/reference-operationsIf you are working inside this repository before installing the tool package, run the same command through the project entry point:
dotnet run --project ./src/Cephalon.Cli -- package stage ` --package ./artifacts/reference-packages/Cephalon.ReferenceModule.Operations.1.0.0.nupkg ` --output ./plugins/reference-operationsThe staged directory now contains the package manifest and loadable assembly surface:
plugins/reference-operations/ cephalon.package.json Cephalon.ReferenceModule.Operations.dll Cephalon.ReferenceModule.Operations.xml PACKAGE.md3. Load it through package discovery
Section titled “3. Load it through package discovery”Point the host at a package directory instead of a repo-local assembly name:
{ "Engine": { "Blueprint": "ModularMonolith", "Transports": [ "RestApi" ], "Discovery": { "PackageDirectories": [ { "Path": "plugins", "IncludeSubdirectories": true } ] }, "PackagePolicy": { "AllowAssemblyPathPackages": false, "RequireVersion": true, "RequireMinimumEngineVersion": true, "RequireSupportedTargetFrameworks": true, "RequirePublisherId": true }, "Trust": { "RequireTrustedPackages": true, "TrustedPublishers": [ "cephalon-labs" ] } }}This keeps the load manifest-driven, requires the metadata that external operators care about, and lets trust policy stay explicit.
4. Run the host and inspect runtime truth
Section titled “4. Run the host and inspect runtime truth”After the host starts, inspect:
/api/operations/status/engine/packages/engine/package-policy/engine/trust-policy/engine/snapshot
What you should see:
/api/operations/statusreturns the module-owned response/engine/packagesshowsreference-operationswithkind: directory-manifest/engine/packagesshows the staged manifest path insourcePathand the staged DLL inpath/engine/package-policyshows the stricter metadata requirements that were applied/engine/trust-policyshowsRequireTrustedPackagesplus the trusted publisher rule/engine/snapshotshows the trusted package and its active module in the merged runtime view
5. Require detached signatures when provenance matters
Section titled “5. Require detached signatures when provenance matters”When a host needs cryptographic trust instead of publisher-only trust, tighten package policy and trust configuration so detached signatures become mandatory:
{ "Engine": { "PackagePolicy": { "AllowAssemblyPathPackages": false, "RequireVersion": true, "RequireMinimumEngineVersion": true, "RequireSupportedTargetFrameworks": true, "RequirePublisherId": true, "RequireSignatureFingerprint": true, "RequireSignatureKeyId": true, "RequireSignatureValue": true, "RequireSignatureVerification": true }, "Trust": { "RequireTrustedPackages": true, "TrustedSignaturePublicKeys": { "cephalon-labs-build": "keys/cephalon-labs-build.public.pem" } } }}This keeps package governance tied to the exact signing key instead of a broader publisher allow-list. Under that stricter posture:
/engine/packagesshould surface the publisher, signer,signatureKeyId,signatureFingerprint,isSignatureVerified,signatureVerificationReason, and trust reason for the loaded package/engine/trust-policyshould surface the trusted public-key map that made the verification possible/engine/snapshotshould mirror the same verified package truth in the merged runtime view- a tampered signed package should fail startup when
RequireSignatureVerificationis enabled
If you prefer certificate-chain trust instead of a trusted public-key file, keep the same package-policy settings but swap the trust block to:
{ "Engine": { "Trust": { "RequireTrustedPackages": true, "TrustedSignatureCertificates": { "cephalon-labs-signing-cert": "keys/cephalon-labs-signing-cert.pem" }, "TrustedSignatureCertificateAuthorities": [ "keys/cephalon-labs-root.pem" ] } }}Under that certificate-chain posture:
/engine/packagesshould surfaceverificationSource: trusted-certificate-chainplussignatureCertificateThumbprint/engine/trust-policyshould surface the trusted signing certificate map plus the trusted certificate-authority list/engine/snapshotshould mirror the sametrusted-certificate-chainand certificate-thumbprint truth in the merged runtime view
Operational notes
Section titled “Operational notes”- use
cephalon.package.jsonas the operator-readable contract for version, compatibility, publisher, provenance, signature, and integrity metadata - prefer
Engine:PackagePolicywhen hosts must reject ambiguous raw assembly loads - prefer
Engine:Trustpublisher, signer, certificate, or checksum rules when package governance matters - prefer
Engine:Trust:TrustedSignaturePublicKeysplusRequireSignatureVerificationwhen detached signing should be enforced through an explicit trusted signer key - prefer
Engine:Trust:TrustedSignatureCertificatesplusEngine:Trust:TrustedSignatureCertificateAuthoritieswhen detached signing should be enforced through a trusted signing certificate chain and surfaced astrusted-certificate-chainwith acertificateThumbprint - keep package directories explicit and stable so operators can reason about what the host is allowed to load
- if you republish a package and want to replace an existing staged directory, rerun
cephalon package stagewith--force