Security
A Ha Tang integration holds several secrets: API keys, webhook signing secrets, the chat identity secret and the Payments secret key. This page is a checklist for keeping each one safe, limiting what a leaked one can do, and verifying everything that reaches your servers.
Know your credentials
| Credential | Looks like | Where it lives | Secret? |
|---|---|---|---|
| API key | ht_... | Your server only | Yes |
| Webhook signing secret | whsec_... | Your server only | Yes |
| Chat identity secret | shown once on the website's page | Your server only | Yes |
| Payments secret key | sk_... | Your server only | Yes |
| Chat site id | site_... | Your web pages and apps | No, it is public |
| Mobile app key | hak_... | Inside your app build | No, but revocable |
Anything marked secret must never appear in browser JavaScript, a mobile app, a public plugin, a Git repository or a support ticket. Keep it in environment variables or a secret manager.
API keys
- Give each key only the scopes it needs. A server that only sends email needs
email:send, not*(Authentication). - Use one key per service or environment, named after where it runs. You can then revoke one without touching the others, and the Last used column tells you which ones are still in use.
- Restrict keys. Lock an email key to one Sending domain. Only if a key must run in a browser, fill in Browser origins; requests from any other origin are refused (Restricted keys).
- Rotate keys when someone who knew them leaves, after a suspected leak, and on a schedule: create the new key, deploy it, then revoke the old one. A revoked key stops working within a minute.
- Audit usage. Email → Logs lists every API request with the key that made it, the user agent, the status and the bodies. Unexpected callers or endpoints are a sign of a leak.
Keys are shown only once when created. Ha Tang stores only a hash, so a lost key cannot be recovered; create a new one.
Webhooks
- Verify every delivery. Check the signature over the raw body and reject deliveries whose timestamp is more than 300 seconds old (Webhooks). Deliveries are authenticated by their signature, not by where they come from. The
user-agent: hatang-webhooks/1.0header is informative only. - Use HTTPS endpoints. Ha Tang only delivers to public
httpsURLs and does not follow redirects. - Rotate the signing secret if it may have leaked. For 24 hours after a rotation, deliveries carry signatures from both the old and the new secret, so you can deploy without dropping events.
- Deduplicate on
svix-idso a replayed or retried delivery cannot trigger the same action twice. - Payments IPN calls to your
ipn_urlare signed separately, withHatang-Signatureand the environment's secret key. See Verify IPN.
Chat identity
- Verify identities. When your site or app tells the chat who a user is, include the
hash(HMAC-SHA256 of the user id with the site's identity secret) computed on your server. Without it, anyone could claim to be another customer and read their history (Identity verification). - Keep the identity secret on your server, and rotate it with Rotate & reveal if it may have leaked. Hashes made with the old secret stop verifying at once.
- Limit where the widget runs. The widget only starts on your website's domain, its subdomains and the Extra allowed origins you list. Remove preview and localhost origins you no longer use.
- Revoke mobile app keys you no longer ship, after releasing an app version with a new key.
Payments
- Keep the secret key of each environment on your server and check
environmenton every Payments event and IPN, so a development payment never fulfils a real order. - A
ht_test_key can never reach production data. Production access is chosen per request withHatang-Environment(Payments environments).
SMTP relay
The SMTP relay at smtp.hatang.dev:5870 uses STARTTLS, with the username hatang and an API key as the password. Give that key only the email:send scope. After 10 failed sign-in attempts from one IP address, the relay refuses further attempts from that address for 15 minutes.
Your team
- Give employees the lowest access level that lets them do their job, and keep Developer access, which can create API keys and webhooks, to the people who need it (Team and roles).
- Remove people who leave from Settings → Employees, and rotate the API keys and secrets they knew. Their keys keep working until you revoke them, because keys do not belong to a person.
If a secret leaks
- API key: revoke it in Settings → API Keys, create a replacement, and check Email → Logs for calls you did not make.
- Webhook secret: rotate it and deploy the new one within 24 hours.
- Identity secret: click Rotate & reveal and update your servers.
- Payments secret key: replace it in Payments settings → Integration keys and update your servers.