Skip to content

Source Type and Verification are editable and "saved" but never applied when an existing source is adopted #14

Description

@leggetter

Summary

When the trigger adopts an existing source, Source Type, Verification and Webhook
Secret
stay editable, save without complaint, and redisplay when the node is reopened — but
never reach Hookdeck. The only signal is a line in the n8n server log, which nobody is
watching while filling in a form.

The underlying behaviour is correct and should not be reverted (see Background). The problem
is that the UI presents controls that do nothing, and offers no way to tell "saved in n8n"
from "applied to Hookdeck".

How it bites, from a real session

  1. Source → Get or Create (the action node) creates source stripe as type WEBHOOK.

  2. The trigger, in the same workflow, is set to Source Type = Stripe with a webhook
    secret. n8n saves it. Reopening shows the values still there.

  3. Publish. The source in Hookdeck is still:

    name: stripe   type: WEBHOOK   auth_type: null   verification: NONE
    

No Stripe signature verification is happening. The workflow appears to work, because a
source with no verification accepts everything — so the failure is silent, and you only find
out by querying the API.

Finding Update Existing Source (hidden under Add Options) and ticking it does not fix it
either, because source settings are only pushed by create(), which runs on publish.
Nothing anywhere says so.

The design question this raises

The safety rule exists to avoid changing a source that other connections share. But the node
cannot tell these apart:

  • a source created by a colleague, feeding several other connections
  • a source this very workflow created moments ago via the Get or Create action node

The second is the case that bit us, and it is a natural thing to build: create the source in a
workflow, then point the trigger at it. Both nodes are individually right — the action node's
own comment calls overwriting "the exact damage the trigger was changed to stop doing" — but
composed, they produce a source the workflow owns and cannot configure.

Suggested reframing: stop asking "who created this?" and ask "what else would this affect?"

Provenance is not reliably knowable and is not what the safety rule is actually protecting.
b0fa298 justifies itself in terms of other connections fed by the source. That is directly
queryable:

GET /connections?source_id=<id>     ->  200

Measured on the affected project, source stripe:

connections fed by this source: 3
   n8n-pQYxZBBy5lw1X2Ib-d697582a…         <- the current trigger
   n8n-pQYxZBBy5lw1X2Ib-2c659975…         <- orphan: trigger node that was replaced
   n8n-pQYxZBBy5lw1X2Ib-c68056ff…-test    <- orphan: expired test connection

All three belong to the same workflow. The node withheld the user's settings to protect other
connections, and there were none — only its own, plus its own leftovers.

So:

  • No connections other than this node's → nothing else can be affected → apply the
    settings, or at minimum say plainly that it is safe to.
  • Other connections exist → keep today's protective behaviour, and name which ones would
    be affected rather than saying nothing.

This depends on #13. The orphan-connection leak inflates the count: two of the three above
are this node's own abandoned connections. A blast-radius check built on today's data would
answer "2 others are affected" when the true answer is zero. #13 should land first, or the
check has to filter to n8n-<workflowId>- prefixes and accept that it cannot see orphans from
deleted workflows.

Suggested UI changes

The source parameter is a resourceLocator with modes list and name. sourceType,
verification and platformSecret already use displayOptions, just not keyed on that mode.
Nothing currently keys off source.mode.

  1. When mode is list the source definitively exists, so those fields are known-inert at
    config time. Hide them (or disable them) and show a notice in their place:

    This source already exists. Its type and verification are managed in Hookdeck.
    Turn on Update Existing Source to change them from here.

    Ticking Update Existing Source brings the fields back, because then they apply.

  2. When mode is name it is genuinely unknown until publish. Keep the server-log warning
    for that path.

  3. Say that source settings apply on publish — this affects everyone, not just the adopt
    case. Even when creating a brand-new source, nothing indicates the settings are pending:

    Source settings are applied to Hookdeck when you publish this workflow.

  4. Optional: surface the real type in the resourceLocator label —
    stripe — WEBHOOK — https://hkdk.events/… — so a mismatch between what Hookdeck has and
    what the node is set to is visible at a glance.

Background — do not revert the underlying behaviour

b0fa298 ("Adopt an existing source instead of rewriting it") fixed a genuine security bug:

Provisioning described the source inline in the connection upsert, which is keyed on source
name. Any source of that name already in the project therefore had this node's Source Type
and Verification applied to it — and to every other connection fed by it. Since Source Type
defaults to WEBHOOK and Verification to none, the documented path of picking an existing
source from the list stripped its verification on publish.

That is worth keeping. Note the failure mode has changed character, though: the old bug was
loud (verification vanished, deliveries broke). The current one is silent — you believe
verification is configured and it is not. For a package being submitted for verified community
node status, a security setting that appears applied but is not is worth treating as a bug in
its own right.

Notes

Found while preparing a live demo, which is the worst possible moment. Documented in
README.md ("An existing source is adopted, not rewritten") — but documentation does not help
someone looking at an editable field that says it saved.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions