Onboarding and Host Configuration
Overview
v1.0.5 is an onboarding and host-configuration release on top of v1.0.4. Every ./ztd command now loads an owner-only repo-root .env holding user secrets and user-specific endpoints, make up-public and make gw-public start a Gateway reachable from other hosts, ztd gw start refuses to report success against a running Gateway whose startup configuration differs from the request, and an outbound Operator refuses to open a Gateway's runtime tree. The governance pipeline, protocol contracts, and storage layout are unchanged from v1.0.4.
Added
- Repo-root
.env— Every./ztdcommand loads.envfrom the working directory at startup throughconfig.LoadEnvFile(internal/cli/config/env_file.go). Only thesecretanduser_endpointkeys inprotocol/constants/env_vars.jsonare accepted; an unknown key or a line that is notKEY=VALUEstops the command (ErrEnvFileUnknownKey,ErrEnvFileMalformed). A variable already exported in the shell wins over the file, and an explicit flag wins over both. On Linux and macOS the file is opened without following symlinks or blocking on a FIFO, and must be a regular file owned by the user or root with mode0600or0400(ErrEnvFileInvalid). A missing.envloads nothing. See Configure.env. - Setup creates
.env—scripts/linux-setup.sh,scripts/macos-setup.sh, andscripts/windows-setup.ps1copy.env.exampleto.envafter building./ztd(mode0600on Linux and macOS) and keep an existing.env. Every template entry is commented, so the default flow loads no keys. ZTD_OLLAMA_ENDPOINT— A newuser_endpointregistry key that supplies--inference-ollama-endpointforztd gw start,ztd operator start, andztd operator modelcommands when the flag is blank. Set it in.envwhen the approved Ollama provider is not on the Gateway or Operator host.make up-publicandmake gw-public— Runmake upandmake gwwith--listen-host 0.0.0.0so Operators on other hosts can enroll.make upandmake gwstay loopback-only.- One-command onboarding —
curl -fsSL https://zerotrustdata.io/start.sh | sh(website/static/start.sh) installs the checksum-verified release binary into~/ztdthroughztd.sh, then starts or reuses a Gateway, signs the CLI in or reuses its identity, and runs a first governed action, the same steps asmake quickstart.ZTD_DIR,ZTD_VERSION,ZTD_OVERWRITE, andZTD_MASTER_KEY_FILEare honored; a missing OS key store or a busy Gateway port prints its remedy. It never uses sudo. - Releases pages —
https://zerotrustdata.io/releases/lists every published version, and/releases/v<version>/shows its binaries, sizes, SHA-256 digests,.sha256and Sigstore bundles, pinned install commands,sha256sumandcosign verify-blobsteps, and the release notes. The Worker renders them from theztd-releasesR2 bucket (website/src/releases.js); release notes are rendered at build time fromdocs/release_notes/(website/src/release-notes.js).
Changed
ztd gw startagainst a running Gateway — The running-process check now precedes network identity detection. Every startup flag the caller set explicitly (--capabilities,--posture,--listen-host,--http-port,--https-port,--model-storage-root,--inference-ollama-endpoint,--public-base-url,--cors-origin, and the passkey relying-party flags) is compared with the running launch profile. A match reuses the running Gateway; a difference prints the current and requested values and fails withErrGatewayAlreadyRunning. AZTD_OLLAMA_ENDPOINTvalue (exported or from.env) counts as requesting--inference-ollama-endpoint, so editing it and rerunningmake gwreports the difference instead of silently keeping the old endpoint. A baregw startwith no such value still reuses whatever Gateway is running. Previously the command reported "already running" and exited 0 while the old configuration stayed active.- Gateway startup output —
gw start,gw restart, andgw connectprint the detected network identity only when the listeners bind a routable interface. The post-start guidance is a single Console origin and a short command list (login/login webordered by posture, a same-host or remoteoperator startwith its own--working-dir,auth enroll pending,gw status).gw restartprints the same guidance asgw start. - Copy-paste-safe command output — Every command the CLI prints for the user to run sits alone on its own line, flush-left, with no quotes, prose, or indentation around it. This covers the loopback notice (
gw stop, thengw start --listen-host 0.0.0.0), thegw startnext steps (a purpose line, then the bare command), tunnel and swagger hints,--helptext and error messages that name a command (for exampleEnroll first with:followed by./ztd auth enroll user), the eval and vault hints, and the TUI status lines, where the command is unquoted at the end of the line. Stray duplicate and misspelled output, such asztd.operator stream --help, is fixed. - Enrollment approval hint — Application and Operator enrollment requests print
Approve on the Gateway host with:followed byztd auth enroll approve <id>on its own line. make status—make statusrunsztd gw statusonly, which already includes the Operator inventory and pending enrollments..env.example— Lists everysecretanduser_endpointregistry key, includingCLOUDFLARE_API_TOKEN; themake constants-checkexemption for that key is removed.- TLS bundle logging — Per-certificate
[TLS-DEBUG]bundle lines log at debug level instead of info. - Website reduced motion — With
prefers-reduced-motion: reduce, the homepage (website/src/index.html) drops shake, jitter, and slide offsets and slows the background grid and ticker instead of disabling every animation and transition. Reveal and trace rows still fade in, and the grid stops drawing while the page is hidden. - Install scripts run from
main—website/static/ztd.shruns entirely from amainfunction called on the last line, so a truncatedcurl | shdownload executes nothing. - Release set upload order —
scripts/release-r2.sh uploadwritesztd-binaries.jsonlast and refuses a set without it, so the manifest's presence marks a complete set for the Releases pages. - Deterministic OpenAPI —
.swaggooverrideswebauthncose.COSEAlgorithmIdentifierto an integer somake swagger-generateoutput no longer depends on map order, and swag errors are reported (--quiet) instead of discarded.
Removed
public_feed_outboxcollection constant —CollectionPublicFeedOutboxhad no readers or writers and is removed frominternal/constants/collections.go.make upfollow-up hints — The status and sign-in linesmake upprinted aftergw startare removed;gw startprints the guidance itself.
Fixed
- Operator in a Gateway runtime tree —
ztd operator startrefuses a runtime tree that holds the Gateway root CA (GatewayRuntimeMarker,pki/root/root_ca.crt) and exits with a configuration error naming--working-dir(ErrOperatorGatewayRuntime, INV-OP-STOR-03). An Operator launched from the Gateway directory without--working-dirpreviously opened the Gateway's audit database and vault.ztd operator reset-identityuses the same marker. - Local receipt reads in tests —
storage.ReadLocalActionReceiptis the single reader of a runtime's sealed local receipt. Release smoke and the deploy lifecycle E2E use it; the E2E previously parsed the encryptedreceipt_jsonas protojson. The lifecycle cancellation case omits--approveso only the worker dials the stalled HTTPS port. - Test isolation from
.env—ztd testrunners (unit, integration, E2E, coverage, release smoke, scale) start their child processes without thesecretanduser_endpointkeys (config.WithoutUserEnv). Because every./ztdcommand loads.env, test processes previously inherited the developer'sCLOUDFLARE_API_TOKENandZTD_OLLAMA_ENDPOINT, and the release smoke Gateway and worker inherited the developer's Ollama endpoint. auth enroll userhelp — Named a nonexistentauth enroll operatorcommand; it now points tooperator startandauth enroll approve.operator start --endpoint host:port— The global--endpointhelp acceptshost:port, butoperator startappended its own port, so the pub/sub URL becamewss://[host:port]:8443and the Operator could not connect. The endpoint port now sets the Gateway HTTP discovery port; a port that differs from an explicit--gateway-http-port, a URL scheme, or an invalid port fails at startup withErrGatewayEndpointInvalid. Workers deployed byoperator deploywith ahost:portendpoint had the same failure.- E2E environment keys —
ztd test scaleand the E2E suite exchanged twelveZTD_E2E_*keys (ZTD_E2E_RUNTIME_ROOT,ZTD_E2E_GATEWAY_HTTP_PORT,ZTD_E2E_GATEWAY_HTTPS_PORT,ZTD_E2E_MASTER_KEY_FILE, and theZTD_E2E_FLEET_*keys) through local string constants outsideenv_vars.json(INV-ENV-04). They are nowtestregistry keys read throughconstants.EnvVar, andTestProductionGoEnvReads_UseRegistryKeysalso rejects local string constants and coverstest/. - Collections registry —
protocol/constants/collections.jsonomitted tenCollectionNameconstants (consensus,enrollment_tokens,cli_recovery_requests, sixobserve_*projections, andeval_campaign_publication_state). They are listed, andTestCollectionsRegistryMatchesGoConstantsfails on drift in either direction.
Tests
Evidence: this section records the commands run from the final release commit and their results, and lists any command not run. The required commands are ./ztd test lint, ./ztd test unit, make console-lint console-test console-embed-check, make constants-check, make swagger-generate, and make doctrines-validate. The record is entered before tagging.
New coverage in this release: internal/cli/config/env_file_test.go (registry keys, comments, shell precedence, missing file, unknown and host keys, malformed lines, mode, and symlinks), TestUserEndpointEnvVars_MatchRegistryUserEndpoints, TestCollectionsRegistryMatchesGoConstants, TestResolveOperatorGateway, internal/cli/cmd/gw/gateway_start_running_test.go (running-Gateway reuse and conflict), TestRefuseGatewayRuntime, test_create_env_file_owner_only_and_kept in scripts/test-onboarding.sh, website/test/start.test.js (start.sh piped into sh, dash, busybox sh, and bash --posix against a stub release host and a fake ztd: reuse, environment variables, failure remedies, truncated downloads, stdin isolation, and shellcheck), website/test/releases.test.js, and the /releases/ cases in website/test/worker.test.js. website/smoke/live.sh runs after each website deploy against production.
Documentation
- Homepage (
website/src/index.html) quick start leads with thestart.shone-command install and matches the README (INV-DOC-GEN-04), the navigation and footer link to/releases/, and the First Run Report form lists the current entry points. - Website Runbook — Releases pages, the listing rule, release-note fragments, onboarding scripts, and their tests.
README.mdand.github/CONTRIBUTING.md—.envcreation,ZTD_OLLAMA_ENDPOINT,make up-public/make gw-public, the running-Gateway conflict behavior, runnable protocol examples, and current setup anchors.- Getting Started — New "Configure
.env" section and public-listener targets. - Unified Stack, Connect an Operator, Build an Operator, Build a Gateway, Reset Workload Identity, and Cloudflare Tunnel — Separate Operator working directories, public-listener targets,
.envkeys, and theztd loginre-enrollment flow. - Operator Architecture — INV-OP-STOR-03 and registry-based environment scrubbing. Gateway Architecture — running-Gateway startup comparison. Scripts — public-listener targets and the complete
internal/tools/catalog, which Code Map now links to instead of repeating. Operator Architecture owners nameinternal/services/ztdo.goandinternal/services/operatorcapability/in place of the nonexistentinternal/services/operator/; Gateway Architecture describesztd mcp agent listandshowas implemented. - Developer Guidelines INV-ENV-04, Testing Guide INV-TEST-ISO-06 (test child processes run without
.envkeys), Troubleshooting vault key, audit receipt, and protocol prerequisite paths, and Constants user endpoints, test-harness keys, and the complete collections registry.
Compliance Evidence
Evidence: this section records the signed operational evidence bundle for the Gateway build assessed at release. The bundle requires a running Gateway built from the final release HEAD, governed activity from that build in the assessment window, and the release owner's report-signing key. It is generated by running ./ztd compliance release-prepare on the release commit. This section then records the bundle path, verification result, checksum root, assessment window, and source revision. The generated v1.0.5-compliance-evidence.md and v1.0.5-compliance-evidence.csv files are committed beside these notes (INV-REL-COMP-01).
Deferred
- On Windows,
.envownership and mode are not checked, and setup copies the template without restricting its ACL.