Skip to main content

Pomerium JavaScript SDK

Learn how to use Pomerium's JavaScript SDK to verify and parse JWTs issued by the authorization service.

Background

Pomerium is designed to sit in front of internal backend applications and services so that it can provide context-aware access management in a uniform way.

Although you can configure Pomerium to secure upstream applications with assertion headers (X-Pomerium-JWT-Assertion) and Pomerium’s well-known JWKS endpoint (/.well-known/pomerium/jwks.json), it’s not immediately obvious or easy for application developers to implement.

Pomerium’s JavaScript SDK offers both client- and server-side solutions that make it easier for developers to verify JWT assertion headers in upstream applications.

How to use the JavaScript SDK

The JavaScript SDK is available as an NPM package.

To use the JavaScript SDK, you need:

  • Node.js (version 18+)
  • NPM (to install Node.js and Yarn)
  • Yarn (preferred package manager)

Secure a React app with Pomerium

  1. Bootstrap a React application using Create React App
npx create-react-app react-app
cd react-app
  1. Add dependencies
yarn add
  1. Install the JavaScript SDK
yarn add @pomerium/js-sdk
  1. Go to App.js and add the following code
import { useEffect, useState } from 'react';
import { PomeriumVerifier, signOut } from '@pomerium/js-sdk';

function App() {

const [jwt, setJwt ] = useState('');

useEffect(() => {
const jwtVerifier = new PomeriumVerifier({
issuer: 'react.localhost.pomerium.io',
audience: 'react.localhost.pomerium.io',
expirationBuffer: 1000
});
jwtVerifier.verifyBrowserUser()
.then(r => setJwt(r))
.catch(e => console.log(e));
}, [])

return (
<div style={{margin: '20px'}}>
<pre>{JSON.stringify(jwt, null, 2)}</pre>
<div style={{marginTop: '20px'}}>
<button onClick={() => signOut('https://www.pomerium.io')} type="button">Sign Out Test</button>
</div>
</div>
);
}

export default App;
Trust on first use (TOFU)

The issuer and audience parameters are optional. If you don’t define them, PomeriumVerifier applies firstUse by default to the JWT provided by the identity provider. PomeriumVerifier verifies subsequent requests with these claims.

If you define the issuer and audience parameters, PomeriumVerifier verifies their values against the claims provided by the identity provider.

The issuer and audience will both be set to the URL of the upstream application without the prefixed protocol (for example, httpbin.corp.example.com).

  1. Run yarn start

You should see your React app in the browser.

React app in browser

Configure a route in Pomerium

Add a route in Pomerium.

pomerium core
routes:
- from: https://react.localhost.pomerium.io:4443
to: http://localhost:3000
pass_identity_headers: true
policy:
- allow:
or:
- email:
is: user@example.com
Note:

If you're using more than one machine, deploy your React app and use the associated IP address instead of localhost.

Verify the JWT

In your browser, navigate to the relevant URL:

  • https://react.localhost.pomerium.io:4443
  • https://express.localhost.pomerium.io:443/tofu

If your JWT is valid, you should see a JSON payload with the following claims:

{
"payload": {
"aud": "react.localhost.pomerium.io",
"email": /* redacted */
"exp": 1685477549,
"groups": [],
"iat": 1685477249,
"iss": "react.localhost.pomerium.io",
"jti": "d6e514e9-f8a6-49bb-a5c4-258391d19e4d",
"name": /* redacted */
"sid": "d6e514e9-f8a6-49bb-a5c4-258391d19e4d",
"sub": "00u1gkwtecq0Mj1u04x7",
"user": "00u1gkwtecq0Mj1u04x7"
},
"protectedHeader": {
"alg": "ES256",
"kid": "997cf46e7e54de7e077419a5bf467dc1f711a96b2bf71d6de2ba35d07f29c3a2",
"typ": "JWT"
},
"key": {}
}

If the JWT is not valid or something wasn't implemented correctly, you should receive an error:

JWT error in browser


Resources: