---
title: "How to Build Secure Okta Node.js Integrations with DPoP"
description: "Okta management API integrations can use a Node.js service app with OAuth 2.0 client credentials, but a bearer access token can be replayed by anyone who obtains it during its one-hour lifetime. The tutorial configures Okta for private_key_jwt authentication, grants the okta.users.read scope and Read-only Administrator role, and builds a Node.js service that requests and caches an access token. It then enables Demonstrating Proof of Possession (DPoP), handles an initial use_dpop_nonce response by retrying the token request with a nonce-bound proof, and generates a fresh proof for each API call. Each request binds the proof to the access token through the SHA-256-based ath value and uses DPoP rather than Bearer authorization. The demonstrated service successfully lists users through Okta Admin Management API endpoints."
---

# How to Build Secure Okta Node.js Integrations with DPoP

[Okta](https://yomu.fyi/company/okta) · Ram Gandhi · Oct 23, 2024

**Type:** Tutorial

## Summary

Okta management API integrations can use a Node.js service app with OAuth 2.0 client credentials, but a bearer access token can be replayed by anyone who obtains it during its one-hour lifetime. The tutorial configures Okta for private\_key\_jwt authentication, grants the okta.users.read scope and Read-only Administrator role, and builds a Node.js service that requests and caches an access token. It then enables Demonstrating Proof of Possession (DPoP), handles an initial use\_dpop\_nonce response by retrying the token request with a nonce-bound proof, and generates a fresh proof for each API call. Each request binds the proof to the access token through the SHA-256-based ath value and uses DPoP rather than Bearer authorization. The demonstrated service successfully lists users through Okta Admin Management API endpoints.

## Context

The integration uses the OAuth 2.0 client credentials flow for a service principal. Without sender constraints, a token remains usable by any client during its one-hour validity; DPoP ties requests to proof generated by the client that requested the token.

## Approach / What changed

The service app is configured in Okta with public key/private key client authentication, a generated PEM private key, the okta.users.read scope, and a Read-only Administrator assignment. Node.js code signs a private key JWT, requests an access token, retries with a DPoP nonce when Okta requires one, and adds a per-request DPoP proof containing the access-token hash (ath).

## Takeaways

- Okta requires private\_key\_jwt authentication for this service-app client credentials flow, and the example grants okta.users.read plus the Read-only Administrator role.
- When DPoP is enabled, the token request may first return a use\_dpop\_nonce error; the service reads dpop-nonce, creates a proof for the token endpoint, and retries the request.
- Management API calls use Authorization: DPoP with a DPoP header. The proof includes an ath value computed from the access token using SHA-256 and base64url-style encoding.

## FAQ

### Why does the example add DPoP to a bearer-token integration?

A bearer access token can be used by any client that obtains it during its one-hour validity. DPoP constrains the token to the sender by requiring proof from the client that initially requested it.

### What happens when Okta requires a DPoP nonce?

The token request returns a 400 response with the use\_dpop\_nonce error and a dpop-nonce response header. The service uses that nonce to generate a proof for the token endpoint, then retries the token request.

### What must each Okta API request include after DPoP is enabled?

Each request needs a newly generated DPoP proof and an Authorization header using DPoP rather than Bearer. The proof is bound to the access token through its ath hash value.

**Tags:** [DPoP](https://yomu.fyi/topic/dpop), [Node.js](https://yomu.fyi/topic/node-js), [OAuth 2.0](https://yomu.fyi/topic/oauth-2-0), [Okta](https://yomu.fyi/topic/okta)

- Source: [Okta](https://developer.okta.com/blog/2024/10/23/dpop-oauth-node)
- Source URL: https://developer.okta.com/blog/2024/10/23/dpop-oauth-node
- Ingested by Yomu: 2026-09-17T14:06:22.097Z

[Read original post](https://developer.okta.com/blog/2024/10/23/dpop-oauth-node)
