Skip to content

Commit fee3867

Browse files
committed
Update code examples with MultiLanguage and clarify server-to-frontend flow
- Use MultiLanguage component for Node.js/Python examples - Clarify hash must be generated server-side and passed to frontend - Add separate section showing how to use the hash with JS SDK in browser - Emphasize never exposing the shared secret in client-side code
1 parent 4659979 commit fee3867

File tree

1 file changed

+48
-24
lines changed

1 file changed

+48
-24
lines changed

contents/docs/cdp/transformations/secure-event-validation.md

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,46 +43,70 @@ When an event arrives, this transformation:
4343

4444
## Client-side implementation
4545

46-
To use this transformation, you need to generate the verification hash on your server and include it when identifying users or sending events.
46+
To use this transformation, you need to generate the verification hash **on your server** and pass it to the frontend. The hash must be generated server-side to keep your shared secret secure — never expose the secret in client-side code.
4747

48-
Example in Node.js:
48+
### Generating the hash server-side
4949

50-
```javascript
50+
<MultiLanguage>
51+
52+
```js file=Node.js
5153
import crypto from 'crypto'
5254

53-
const sharedSecret = process.env.POSTHOG_SHARED_SECRET
54-
const distinctId = 'user_123'
55+
function generateVerificationHash(distinctId) {
56+
const sharedSecret = process.env.POSTHOG_SHARED_SECRET
57+
return crypto
58+
.createHmac('sha256', sharedSecret)
59+
.update(distinctId)
60+
.digest('hex')
61+
}
5562

56-
const verificationHash = crypto
57-
.createHmac('sha256', sharedSecret)
58-
.update(distinctId)
59-
.digest('hex')
63+
// When rendering your page or handling an API request,
64+
// generate the hash and pass it to the frontend
65+
const distinctId = 'user_123'
66+
const verificationHash = generateVerificationHash(distinctId)
6067

61-
posthog.identify(distinctId, {
62-
$verification_hash: verificationHash
63-
})
68+
// Pass these values to your frontend (e.g., via template variables, API response, etc.)
6469
```
6570

66-
Example in Python:
67-
68-
```python
71+
```python file=Python
6972
import hmac
7073
import hashlib
71-
72-
shared_secret = os.environ['POSTHOG_SHARED_SECRET']
74+
import os
75+
76+
def generate_verification_hash(distinct_id):
77+
shared_secret = os.environ['POSTHOG_SHARED_SECRET']
78+
return hmac.new(
79+
shared_secret.encode(),
80+
distinct_id.encode(),
81+
hashlib.sha256
82+
).hexdigest()
83+
84+
# When rendering your page or handling an API request,
85+
# generate the hash and pass it to the frontend
7386
distinct_id = 'user_123'
87+
verification_hash = generate_verification_hash(distinct_id)
7488

75-
verification_hash = hmac.new(
76-
shared_secret.encode(),
77-
distinct_id.encode(),
78-
hashlib.sha256
79-
).hexdigest()
89+
# Pass these values to your frontend (e.g., via template context, API response, etc.)
90+
```
91+
92+
</MultiLanguage>
93+
94+
### Using the hash in the browser
95+
96+
Once you've passed the verification hash from your server to the frontend, use it when identifying users with the PostHog JavaScript SDK:
8097

81-
posthog.identify(distinct_id, {
82-
'$verification_hash': verification_hash
98+
```js
99+
// These values come from your server (e.g., embedded in the page or fetched via API)
100+
const distinctId = window.__USER_ID__
101+
const verificationHash = window.__VERIFICATION_HASH__
102+
103+
posthog.identify(distinctId, {
104+
$verification_hash: verificationHash
83105
})
84106
```
85107

108+
All subsequent events captured by PostHog will include this verification hash and can be validated by the transformation.
109+
86110
## Rotating secrets
87111

88112
This transformation supports a secondary shared secret for key rotation. When rotating secrets:

0 commit comments

Comments
 (0)