How to Secure Webhook Trigger URL with API Key and Dataset Key?

This topic was automatically generated from Slack. You can find the original thread here.

team, help me out pls…:slightly_smiling_face:
at the time of creating webhook trigger with custom response, it provides one https url which is going to be used to trigger the workflow.
my question is- Is their any way we can have api key, dataset key of the created url, which will make the particular url more secure, so that just one url must not enough to trigger the workflow. added snapshot below for webhook API

Hi , the closest thing I can think of is applying Filters to stop your workflow early when the request does not have the information you required (.e.g. the header Authorization does not have the value you required).

On another note, it would be great if you could create a ticket, stating your specific suggestion

Thanks I have added Authorization in header, api_key(randomly generated),dataset_key(randomly generated) and written 3 steps in workflow for checking one by one.(optimise- all can be clubbed in 1 step using customised code step)
3 major problem here
i) eating up time of the workflow
ii) In Filter, it stops the execution with
"$.respond() not called for invocation" ---> there has to be a way to customise the response if filter steps doesn't get executed.
iii) sharing webhook endpoint would be difficult

Posted thread to Discourse: How can we add API key and dataset key to the webhook trigger URL to increase security?

Hello As pipedream doesn’t support authorization built into the native HTTP trigger yet.
could you please help me to write the custom source that exposes an HTTP interface.

Sure, here’s an example of a custom Pipedream source that exposes an HTTP interface and checks for an API key in the request headers: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { apiKey: { type: "string", label: "API Key", description: "The API key required to access this endpoint", }, }, async run(event) { const { headers } = event; // Check if the API key is present in the request headers if (headers.authorization === `Bearer ${this.apiKey}`) { // Your custom logic here console.log("Authorized request"); // Return a custom response this.$respond({ status: 200, body: { message: "Authorized request", }, }); } else { // Return an unauthorized response this.$respond({ status: 401, body: { message: "Unauthorized request", }, }); } }, }); This custom source checks if the Authorization header in the incoming request matches the expected API key. If it does, the source returns a 200 status with a custom message. If not, it returns a 401 status with an “Unauthorized request” message. You can customize the logic within the run method to suit your specific use case.

Looks good!

the response you gave helps a lot. Can you tweak it to use an environment variable for the API_KEY?

Sure, here’s the modified custom Pipedream source that uses an environment variable for the API key: import { axios } from "@pipedream/platform"; export default defineComponent({ async run(event) { const { headers } = event; const apiKey = process.env.API_KEY; // Access the API key from the environment variable // Check if the API key is present in the request headers if (headers.authorization === `Bearer ${apiKey}`) { // Your custom logic here console.log("Authorized request"); // Return a custom response this.$respond({ status: 200, body: { message: "Authorized request", }, }); } else { // Return an unauthorized response this.$respond({ status: 401, body: { message: "Unauthorized request", }, }); } }, }); To set the environment variable API_KEY in your Pipedream workflow, you can follow the instructions in the Environment Variables documentation.

also can you add DATASET_KEY as well.

1 Like

Here’s the modified custom Pipedream source that uses environment variables for both the API key and the dataset key: import { axios } from "@pipedream/platform"; export default defineComponent({ async run(event) { const { headers, query } = event; const apiKey = process.env.API_KEY; // Access the API key from the environment variable const datasetKey = process.env.DATASET_KEY; // Access the dataset key from the environment variable // Check if the API key is present in the request headers and the dataset key is present in the query parameters if (headers.authorization === `Bearer ${apiKey}` && query.dataset_key === datasetKey) { // Your custom logic here console.log("Authorized request"); // Return a custom response this.$respond({ status: 200, body: { message: "Authorized request", }, }); } else { // Return an unauthorized response this.$respond({ status: 401, body: { message: "Unauthorized request", }, }); } }, }); This custom source checks if the Authorization header in the incoming request matches the expected API key and if the dataset_key query parameter matches the expected dataset key. If both match, the source returns a 200 status with a custom message. If not, it returns a 401 status with an “Unauthorized request” message.