Skip to main content

Rotate the provisioner webhook secret

The shared HMAC secret between the central dtedge install and the provisioner pods. Rotate when it leaks, when an employee with access leaves, or as part of a periodic security review. Done at Admin → Settings → Provisioner.

What this secret does​

The provisioner POSTs status updates to dtedge as the cluster install progresses (preflight done, k3s installed, stack installing, job succeeded). Each delivery is HMAC-signed with the shared secret. dtedge verifies the signature before accepting the update — without a valid signature the webhook is rejected.

If the secret leaks, an attacker could POST fake "job succeeded" events and corrupt cluster state in dtedge. Rotation closes that.

Steps​

  1. Generate a new secret (32+ chars, high entropy):

    openssl rand -hex 32
    # → 64-char hex string
  2. Update dtedge first. Admin → Settings → Provisioner:

    • The current secret is masked as ***.
    • Type the new secret into the field. Don't paste in the masked *** — that means "keep existing" to the API.
    • Click Save. dtedge now verifies inbound webhooks against the new secret. From this moment, every existing provisioner pod's webhook posts will fail validation until you update them in step 3.
  3. Update every provisioner pod. Each provisioner deployment carries WEBHOOK_SECRET env. Edit the Helm release values OR patch the Secret directly:

    kubectl -n provisioner edit secret provisioner-config
    # change WEBHOOK_SECRET to the new value
    kubectl -n provisioner rollout restart deploy/provisioner-server deploy/provisioner-worker

    If you manage multiple provisioner installs (one per edge cluster), repeat per cluster. The provisioner pods don't talk to each other — each one needs the new secret independently.

  4. Verify. Trigger any operation that produces a webhook:

    • Create a new edge instance (provisioner emits progress events)
    • Or trigger an existing cluster's node-add

    Backend log should show webhook-receive entries without signature errors. UI's Operations Center surfaces real-time progress — if you see progress, signatures are good.

What if I get the order wrong?​

  • dtedge updated first (intended): brief window where in-flight provisioner webhooks fail validation. The provisioner retries with backoff; once the provisioner pod is restarted with the new secret, retries succeed.
  • provisioner updated first: in-flight provisioner webhooks start posting with the new secret while dtedge still expects the old. They fail. Worse than the other direction — dtedge doesn't get progress updates and the UI shows "running" for jobs that may already have completed. Avoid this ordering.

Detection — when to rotate without waiting​

TriggerAction
The secret was committed to a public repoRotate now
An engineer with access to the Helm values leaves the teamRotate next sprint
A provisioner pod's logs were exposed in a support ticketInspect — the secret shouldn't appear in logs (we redact it), but verify the redaction worked
Annual rotation policySchedule, do it on a quiet day

See also​

  • Configure system settings — the parent settings page
  • The provisioner side's webhook config: see the provisioner repo's WEBHOOK_SECRET env var