A plain-language walkthrough of the secrets consolidation and the cloud-webhook fix.
Last updated 2026-06-16
Two things happened, both about secrets (sensitive values like signing keys and webhook tokens that the worker needs but must never be hard-coded):
A secret is any sensitive value the digital worker needs at run time but that must stay hidden — for example:
Used to sign/verify tokens (a raw HMAC key). If leaked, anyone could forge a valid token.
A per-channel token (Telegram, Slack, etc.). Incoming messages carry it so the worker knows the call is genuine.
Greentic stores each secret under a structured address (a URI), so every part of the system can find the same value the same way:
The team slot uses a literal underscore _ as the "no specific team" placeholder — consistently everywhere. Making that consistent was one of the goals.
Three different programs all needed to build that address, normalize names, and generate random secret values:
| Program | Its job |
|---|---|
greentic-setup | The wizard that collects secrets from the operator. |
greentic-deployer | The tool that pushes a deployment to the cloud (AWS / Azure / GCP). |
greentic-start | The runtime that actually runs the flows and reads the secrets back. |
_" — the other two copies are now subtly wrong. Calls go to the wrong place. That is exactly how secret-address bugs were sneaking in.
All the shared logic moved into the foundation crate greentic-secrets. The three programs now call that one library instead of each carrying a copy:
What moved in: the name canonicalizer, the team placeholder (_), the address builder, the secret-value generator, and the secret:// ↔ secrets:// reference converter. Each program still parses its own pack files, but it parses them into the shared model.
This is the one that mattered most. A webhook secret for a chat channel worked perfectly when you ran everything on your own machine, but vanished on a cloud deploy.
When you deploy to the cloud, the deployer copies your secrets up to the cloud secret manager. To know which secrets to copy, it read each pack's list of "required secrets". But a per-channel webhook secret is special:
op messaging add.So the deployer's secret scan looked in the wrong place for a thing that wasn't on its list — and never found it. Result:
The deployer now does three small, surgical things during a cloud deploy:
webhook_secret_ref (it used to only read pack files).Deliberately not done: minting brand-new random secrets at deploy time (that would change the key on every deploy). The bug was "we never looked," not "we never generated." And no foundation-library changes were needed — the fix lives entirely in the deployer.
| PR | Repo | What it does | Status |
|---|---|---|---|
| #89 | greentic-secrets | Move all shared secret logic into the foundation library | MERGED + published |
| #316 | greentic-deployer | Use the shared library for naming | MERGED |
| #262 | greentic-start | Use the shared library for naming | MERGED |
| #148 | greentic-setup | Use the shared library for naming | MERGED |
| #317 | greentic-deployer | Upload per-channel webhook secrets on cloud deploy | OPEN — ready to merge |
PR #317 has been through an adversarial code review (Codex), every finding addressed or consciously skipped, a simplification pass, and the full local CI gate is green (format + lint + all tests; 31/31 in the affected module). It just needs your manual merge — auto-merge is intentionally off.
These are not bugs — they're deeper improvements we chose to defer so the urgent fix could land cleanly:
The consolidation is done and merged. The original cloud-webhook bug — the thing that kicked this off — is fixed, reviewed, hardened, and fully tested. The only remaining step is merging PR #317 (a one-click action you control). Everything beyond that is optional, deferred enhancement, not outstanding breakage.
feat/cloud-promote-endpoint-webhooks ·
consolidation publish greentic-secrets-* 1.1.0-dev.27563392344.