Skip to content

Learn · Integrations

Authentication for integrations

API keys, OAuth 2.0 grants, bearer tokens, and webhook signatures.

Checked against the product on · written for people writing code

Four kinds of credential appear across the platform. Each one has a place it lives and a way it is replaced.

Where each credential lives.
CredentialProvesHeld inReplaced by
API keyA call is yours.Your systems.Making a new key and revoking the old one.
OAuth 2.0 grantYou authorized us to reach an account of yours.The sealed secret store, scoped to one feed.Reconnecting the account, or revoking the grant.
Bearer token on a feedA telemetry stream is yours.The sealed secret store.Rotating the token on the feed.
Webhook signing secretA delivery came from us, or a post came from your tool.Both ends.Rolling the secret on the endpoint.

API keys

A key carries a mode and a set of scopes. A sandbox key runs against test data and bills nothing. A live key runs against your real work areas.

HEADERAuthorization: Bearer ck_live_…

Every call authenticates this way. A browser session never authenticates an SDK call.

OAuth 2.0

A polled-endpoint feed can hold an authorization-code grant, so it reaches an account you own without a static token. The application registration belongs to the platform. The grant belongs to you, sits scoped to one feed, and is sealed beside that feed’s other secrets.

  • Slack — authorization-code grant with refresh.
  • Google Workspace — authorization-code grant with refresh.
  • Microsoft Graph — authorization-code grant with refresh.
  • GitHub — authorization-code grant with refresh.
  • Salesforce — authorization-code grant with refresh.
  • Jira / Atlassian — authorization-code grant with refresh.
  • Zendesk — authorization-code grant with refresh.
  • ServiceNow — authorization-code grant with refresh.
  • Okta — authorization-code grant with refresh.
Note. The connect picker reports which providers this deployment holds an application registration for. A provider without one is shown as unavailable.

Connect an account

  1. Open the feed and select Connect account.

  2. Pick the provider and, when it asks, enter your host.

    Zendesk, ServiceNow and Okta run on your own host, so each needs it.

  3. Approve the scopes on the provider’s screen.

    You land back on the feed with the grant stored.

  4. Select Test connection.

    The test uses the stored grant and refreshes it when it has expired.

Safe by default. Deleting a feed revokes its grant with the provider. Refresh runs single-flight, so several steps racing on one expired grant produce one refresh.

Verifying a webhook we send you

Every outbound delivery carries a signature over the raw body and a timestamp. Verify both before you read the body.

  1. Read the signature header and the timestamp header off the request.

  2. Reject a timestamp outside your tolerance window.

    Five minutes is a common choice. This stops a captured delivery being replayed.

  3. Compute the signature over the raw body with your endpoint secret.

  4. Compare in constant time, then read the body.

from dmzagent.webhook import verify_webhook_signature

# False for a bad signature, a malformed header, or a timestamp outside
# the tolerance window. It never raises, so one branch covers every case.
if not verify_webhook_signature(
    raw_body, request.headers["DMZAgent-Signature"], secret
):
    return 400

payload = json.loads(raw_body)

All four SDKs ship this helper. It returns a boolean and never raises, so one branch covers a bad signature, a malformed header, and a stale timestamp alike.