Skip to content

docs: document validateWebhook #259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,49 @@ await replicate.predictions.create({
// => {"id": "xyz", "status": "successful", ... }
```

## Verifying webhooks

To prevent unauthorized requests, Replicate signs every webhook and its metadata with a unique key for each user or organization. You can use this signature to verify the webhook indeed comes from Replicate before you process it.

This client includes a `validateWebhook` convenience function that you can use to validate webhooks.

To validate webhooks:

1. Check out the [webhooks guide](https://replicate.com/docs/webhooks) to get started.
1. [Retrieve your webhook signing secret](https://replicate.com/docs/webhooks#retrieving-the-webhook-signing-key) and store it in your enviroment.
1. Update your webhook handler to call `validateWebhook(request, secret)`, where `request` is an instance of a [web-standard `Request` object](https://developer.mozilla.org/en-US/docs/Web/API/object, and `secret` is the signing secret for your environment.

Here's an example of how to validate webhooks using Next.js:

```js
import { NextResponse } from 'next/server';
import { validateWebhook } from 'replicate';

export async function POST(request) {
const secret = process.env.REPLICATE_WEBHOOK_SIGNING_SECRET;

if (!secret) {
console.log("Skipping webhook validation. To validate webhooks, set REPLICATE_WEBHOOK_SIGNING_SECRET")
const body = await request.json();
console.log(body);
return NextResponse.json({ detail: "Webhook received (but not validated)" }, { status: 200 });
}

const webhookIsValid = await validateWebhook(request.clone(), secret);

if (!webhookIsValid) {
return NextResponse.json({ detail: "Webhook is invalid" }, { status: 401 });
}

// process validated webhook here...
console.log("Webhook is valid!");
const body = await request.json();
console.log(body);

return NextResponse.json({ detail: "Webhook is valid" }, { status: 200 });
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should cover what to do if your environment doesn't support Request, in which case you pass through the parts manually:

const requestData = {
  id: "123",          // the `Webhook-Id` header
  timestamp: 0123456, // the `Webhook-Timestamp` header
  signature: "xyz",   // the `Webhook-Signature` header
  body: "",           // the request body as a string, ArrayBuffer or ReadableStream 
};
const webhookIsValid = await validateWebhook(requestData, secret);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good point. I opened an issue to follow up on that: #261


## TypeScript

Currently in order to support the module format used by `replicate` you'll need to set `esModuleInterop` to `true` in your tsconfig.json.
Expand Down
Loading