> ## Documentation Index
> Fetch the complete documentation index at: https://docs.penciled.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Verification

> Secure your webhook via HMAC signature verification

## Middleware

In order to not expose your webhook endpoint to the public, you can verify the signature of the incoming payload and
cross-reference it with your signing key you got from the dashboard. For details on HMAC security, review [this Wikipedia page.](https://en.wikipedia.org/wiki/HMAC#Security)

<Note>
  Make sure not to share your signing key with anyone. If you believe your signing key has been compromised, be sure to refresh it
  from the [Penciled dashboard.](https://app.penciled.com)
</Note>

#### Example webhook endpoint

```typescript theme={null}
router.post('/webhook', securityMiddleware, async (req: Request, res: Response) => {
  console.log("/webhook req.body: ", req.body);
  // save recording, transcript, outcome, etc
})
```

#### Example middleware

```typescript theme={null}
export const securityMiddleware = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const signingKey = process.env.PENCILED_SIGNING_KEY; // from the dashboard

    const signature = req.headers['x-penciled-signature'] as string;

    const verified: boolean = verifyWebhookSignature(signingKey, JSON.stringify(req.body), signature);

    if (!verified) {
      console.error('Webhook verification failed');
      return res.status(401).json({ error: 'Unauthorized' });
    }

    console.log('Webhook payload verified');

    next();

  } catch (error) {
    console.error('Error verifying webhook:', error);
    res.status(401).send('Unauthorized');
  }
};
```

#### Verify Webhook Signature

```typescript theme={null}
import crypto from 'crypto';

/**
 * Verifies the signature of a webhook payload using the provided key.
 * 
 * @param secretKey - The key on-hand to verify the signature. Located in environment variables
 * @param data - The body of the request
 * @param signature - The signature that came in the request headers
 * @returns A boolean indicating whether the signature is valid
 */
export function verifyWebhookSignature(secretKey: string, data: any, signature: string): boolean {
  const expectedSignature = crypto.createHmac('sha256', secretKey)
    .update(data)
    .digest('hex');

  return expectedSignature === signature;
}
```

<CardGroup cols={2}>
  <Card title="Getting an API Key" icon="pen-to-square" href="/quickstart">
    Get your docs set up locally for easy development
  </Card>

  <Card title="Access your dashboard" icon="image" href="https://app.penciled.com">
    Preview your changes before you push to make sure they're perfect
  </Card>
</CardGroup>
