In FlowBoost webhooks, use x-user headers to hide secrets from non-admins
One of FlowBoost’s überpowers is calling the Marketo REST API* from Marketo itself, which is impossible without a webhook. (As you probably know, lots of things can’t be done in a native flow step but can be done via the API: inserting Custom Objects, cross-lead field sync, and merging duplicates are just a few.)
You set up an API-only user and Launchpoint custom service, then provide the credentials to FlowBoost. The credentials are typically sent in the payload, i.e. the JS code that FlowBoost executes:
Works fine. But the problem is that Marketo will show those values in the details of the Call Webhook activity.
It’s otherwise good that Marketo provides a robust log for webhook debugging, since you can see how {{lead.tokens}} and {{my.tokens}} were replaced with their values at runtime. But not so good for sensitive data like this, which allows an everyday, least-privileged Marketo user to see the credentials.
Prior to the current version FlowBoost v22, there wasn’t an alternative unless you encrypted the credentials and then decrypted them using FBCrypto
. Not that I ever told anyone how to do that, but it was possible!**
Now, you can easily keep those secret values secret. Pass them as Custom Headers (which Marketo does not show in the Activity Log) and then read them from the FBInfo.request.headers
object:
The only restriction is your header names must begin with the prefix x-user-
. (So we can reserve other headers for internal use.)
Notes
* Or any external API, of course. FlowBoost can turn webhook-incompatible APIs into webhooks, and even run multiple API calls in parallel, which Marketo won’t do.
** You’d store the decryption key using FBCounter
(which can, as I often mention, store any data, not just increment counters). Do this one-time task via Postman so no Marketo users will see the value. Then you can read the key and use it to decrypt within your FlowBoost JS. Since no one can execute FlowBoost JS without the X-Api-Key
— and that’s always hidden in the Custom Headers — no one can get at the data. But this is the old-school way!