Authentication & Iframe Governance
Secure your application with OAuth 2.0 and manage seamless Iframe embedding within the DonutWork dashboard.
Authentication & Embedding
DonutWork uses a robust security model to ensure that third-party applications can securely access data while providing a unified user experience. This guide covers the Dual-Auth workflow and the requirements for enterprise-grade Iframe embedding.
1. The OAuth 2.0 Workflow
Applications use a standard OAuth 2.0 Authorization Code flow to obtain scoped access to a company's data.
Step 1: Authorization Request
Redirect the user to the DonutWork authorization server. This occurs when a user first installs or accesses your app.
Endpoint: GET /i3/oauth/authorize
Parameters:
client_id: Your unique application identifier.redirect_uri: The endpoint where the code will be sent.response_type: Alwayscode.scope: Space- or comma-separated list of permissions in canonical formatresource:action(e.g.,customers:read charges:write).scopeminimum requirement: include at leastcompany:readto complete a valid OAuth connection flow for app integrations.state: A unique string to prevent CSRF attacks.
Step 2: Token Exchange
Once the user approves the request, DonutWork redirects them to your redirect_uri with a code. Exchange this code for an access token immediately.
Endpoint: POST /i3/oauth/token (Form-Encoded)
Body:
client_id: Your application identifier.client_secret: Your secure application secret.code: The authorization code received in the redirect.redirect_uri: Must match the URI used in Step 1.
Step 3: Persistence
Store the returned access_token and refresh_token securely. These tokens allow your app to make direct API calls to DonutWork (e.g., to /2026-02-01/customers.json).
2. Iframe Context & Security
When an application is rendered inside the DonutWork dashboard, it is embedded via an Iframe. Every request to your application's entry point includes a security signature.
Request Parameters
DonutWork appends the following query parameters to your application URL:
company: The unique identifier of the active company.hmac: A cryptographic signature of the request.timestamp: The Unix timestamp of the request.
Signature Verification (HMAC-SHA256)
To verify that the request is authentic and originated from DonutWork, you must validate the hmac parameter using your client_secret.
Verification Procedure:
- Remove the
hmacparameter from the key-value pairs. - Sort the remaining parameters alphabetically by key.
- Concatenate the sorted keys and values into a query string (e.g.,
company=C123×tamp=1740000000). - Calculate the HMAC-SHA256 of this string using your
client_secretas the key. - Compare the result with the provided
hmac.
const crypto = require('crypto');
function verifyHmac(queryParams, clientSecret) {
const { hmac, ...params } = queryParams;
const message = Object.keys(params)
.sort()
.map(key => `${key}=${params[key]}`)
.join('&');
const expectedHmac = crypto
.createHmac('sha256', clientSecret)
.update(message)
.digest('hex');
return hmac === expectedHmac;
}1. ARGS = QueryString.Remove("hmac")
2. SORTED_MSG = ARGS.SortByKey().Join("&")
3. SIGNATURE = HMAC_SHA256(SORTED_MSG, APP_CLIENT_SECRET)
4. VALIDATE(SIGNATURE == QueryString["hmac"])3. UI Integration Requirements
Because the application runs in a cross-site Iframe, standard browser security policies apply.
Session Management
Modern browsers block third-party cookies by default. To maintain a session within the Iframe, your session cookies must use the following attributes:
SameSite=None: Allows the cookie to be sent in a cross-site context.Secure=true: Required whenSameSite=Noneis used.
If your cookies do not have SameSite=None; Secure, users will be logged out immediately after redirection or when navigating within the app.
Content Security Policy (CSP)
Ensure your server headers allow DonutWork to embed your application:
Content-Security-Policy: frame-ancestors 'self' https://hub.donutwork.com;
X-Frame-Options: ALLOW-FROM https://hub.donutwork.com4. Capability Discovery
As the final step of the authentication flow, your application should declare its "capabilities" to the platform. This allows DonutWork to proxy requests to your app (Actions).
Action: PUT /2026-02-01/integrations.json
This declaration should include your app_token (used by DonutWork to call you) and a manifest of supported endpoints. Refer to the Application Discovery Guide for details.
For uninstall flow details (DELETE uninstall_url with company_id + HMAC verify), refer to How to Build.