Back to Blog
Engineering

Sarah Chen5 min
Ctrl+R

When your computer use agent runs a task, Coasty streams events via Server-Sent Events. You need to confirm those events are genuine and not forged. The webhook HMAC header provides that guarantee. This guide shows how to decode Coasty webhooks, verify the HMAC signature, and replay-safe handling for only the 18 reserve-and-replay operations.

How it works

Coasty sends an event payload via GET /v1/runs/{id}/events. The response body is Server-Sent Events. Each event line contains a header named Coasty-Signature with format t=unix,v1=hex. You must compute an HMAC using the event body as the message and your secret key. Compare the computed v1 value to the one sent by Coasty. If they match, the event is authentic.

python
import os
import hmac
import hashlib
import base64

COASTY_API_KEY = os.getenv('COASTY_API_KEY')

# Replace with your shared secret from https://coasty.ai/developers/keys
SECRET = os.getenv('COASTY_WEBHOOK_SECRET')

def verify_hmac(raw_body: bytes, signature_header: str) -> bool:
    # Signature format: t=unix,v1=hex
    parts = signature_header.split(',')
    timestamp = int(parts[0].split('=')[1])
    received_hmac = parts[1].split('=')[1]
    
    # Compute HMAC using SHA256
    computed = hmac.new(
        key=SECRET.encode('utf-8'),
        msg=raw_body,
        digestmod=hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(received_hmac, computed)

# Example: consuming an SSE event
import sys

def read_sse_line(f):
    line = ''
    while True:
        ch = f.read(1)
        if not ch:
            break
        line += ch
        if ch == '\n' and len(line) > 0 and line[-2] == '\r':
            return line.strip()

for event_line in sys.stdin:
    if not event_line.startswith('data: '):
        continue
    
    payload = event_line[6:]  # strip 'data: '
    
    # Extract HMAC header from the SSE line
    # Example line: "Coasty-Signature: t=1234567890,v1=a1b2c3d4e5f6g7h8i9j0"
    hmac_line = [h for h in event_line.split('\r\n') if h.startswith('Coasty-Signature:')]
    if not hmac_line:
        raise ValueError('Missing Coasty-Signature header')
    
    signature_header = hmac_line[0].split(':', 1)[1].strip()
    
    if verify_hmac(payload.encode('utf-8'), signature_header):
        print('Verified event:', payload)
    else:
        print('Invalid HMAC signature')

Replay and idempotency

  • Coasty webhooks are signed per event. Replay attacks require forging both the body and the HMAC.
  • Idempotency-Key only protects the 18 reserve-and-replay operations when present on the original request.
  • Use your own request IDs or database deduplication for idempotency beyond those 18 operations.
  • Rate limits are enforced at the API level. Exceeding them results in a 429 response.

Always verify HMAC on every event before acting.

Where this beats brittle automation

Traditional automation relies on brittle selectors and fixed API endpoints. Changes in UI or API contracts break your scripts. A computer use agent sees the screen, clicks, types, and scrolls. It adapts to layout shifts and new elements. By signing those events, you ensure only Coasty can drive your browser, desktop, or terminal. This keeps your workflows resilient and your actions verifiable.

Secure your computer use agent by verifying webhook HMAC signatures. Next, explore workflows and task runs to orchestrate complex workflows. Get your API key at https://coasty.ai/developers and start building reliable agents.

© 2026 Coasty

Backed byYCombinator