For the complete documentation index, see llms.txt. This page is also available as Markdown.

OAuth2

A guide on how to implement an OAuth2 flow for authenticating to our REST APIs.

Overview

This guide explains how to authenticate a Service Account for REST API integrations. Our OAuth2 implementation is based on the RFC7523 JWT bearer grant flow.

The recommended signing algorithm is RS256. With RS256, you keep the RSA private key in your application and upload the matching public key when creating the Service Account key. HS256 is still supported for legacy shared-secret integrations.

Migration Guide

Key Changes

  1. Algorithm support

    • RS256 is recommended for new Service Account keys.

    • HS256 is supported for legacy shared-secret keys.

    • The JWT header alg must match the Service Account key type.

    • RS256 keys cannot be used with Basic Auth.

  2. Key expiration

    • Service Account keys can have an optional expiration date.

    • Expired keys cannot be used to exchange JWT assertions for access tokens.

    • Create a new key before the old key expires to avoid integration downtime.

  3. JWT claims

    • aud (Audience): Must be set to the token endpoint URL (https://app.neowit.io/api/auth/oauth/token).

    • iss (Issuer): Must be set to your service account ID.

    • sub (Subject): Must be set to your service account ID.

    • exp (Expiration): Required.

    • iat (Issued at): Recommended.

    • jti (JWT ID): Recommended for replay protection. If supplied, the same jti cannot be reused before the JWT expires.

  4. Response body format

    • The response uses snake_case field names per OAuth2 specification.

    • Use access_token instead of accessToken.

    • token_type is Bearer.

    • expires_in is the remaining access-token lifetime in seconds.

Migration Checklist

Prerequisites

A Service Account must be created in the organization before continuing. For RS256, the Service Account key must be created with a public RSA key, and your application must keep the corresponding private key. The key may also have an optional expiration date; after that date, token exchange with that key fails.

Example

The example code in this page is provided as is. It may not work unchanged in your environment and should be used as a quick implementation guide rather than production-ready code.

Environment Setup

Source Code

HS256 Legacy Signing

For legacy HS256 keys, sign with the Service Account key secret instead of an RSA private key. The JWT header must use alg: "HS256", and the kid must point to an HS256 key.

Code Walkthrough

Authenticating a client is a three-step process:

  1. Create and sign a JWT assertion.

  2. Exchange the JWT assertion for an access token.

  3. Use the access token to call the REST API.

1. Create The JWT

The JWT must contain a header with the signing algorithm and key ID:

The JWT payload must identify the Service Account and token endpoint:

The exp claim is required. It must be in the future, expressed as a Unix timestamp in seconds. The OAuth2 endpoint signs the returned access token with the same expiration deadline, and the response expires_in value is calculated from that deadline.

Use a short exp value and refresh by creating a new JWT assertion. The examples use one hour. If you include a jti, generate a fresh value for every token exchange; replaying the same jti before expiration is rejected.

2. Exchange For Access Token

Send a POST request to https://app.neowit.io/api/auth/oauth/token with a Form URL-Encoded body:

  1. assertion: The encoded JWT string.

  2. grant_type: urn:ietf:params:oauth:grant-type:jwt-bearer.

The request must have Content-Type: application/x-www-form-urlencoded.

The response has this format:

expires_in is the number of seconds until the access token expires.

3. Access The REST API

Include the returned access token in the Authorization header for REST API calls:

Refreshing The Access Token

Access tokens cannot be refreshed directly. To get a new access token, create and sign a new JWT assertion with a future exp, then repeat the token exchange. Refresh before expires_in reaches zero or when the API returns 401 Unauthorized.

Service Account Key Expiration

A Service Account key can also have its own optional expiration. If the key has expired, the OAuth2 token endpoint rejects JWT assertions that reference that key, even if the JWT assertion itself has a future exp.

Key expiration is configured when the key is created. In the REST API this is represented as expiresAt, a Unix timestamp in seconds. In the app, use the key expiration date field when creating the key.

To rotate credentials, create a new key before the current key expires, deploy the new private key or secret to your integration, confirm token exchange works, and then delete the old key.

Last updated