← Back to portal

SSO JWT Portal — Integration Manual

How a Relying App under *.demo.dakok.net verifies tokens issued by sso.demo.dakok.net.

1. Overview

The SSO JWT Portal issues short-lived Access Tokens as JSON Web Tokens signed with RS256 (RSA, asymmetric). Your application — the Relying App — never needs the private key. Instead, you fetch the portal's public key and use it to cryptographically verify the signature, issuer, and expiry of each token presented to you.

PropertyValue
Signing algorithmRS256
Issuer (iss)sso.demo.dakok.net
Subject (sub)User identifier
Authorized apps (apps)Array of application ids the user may access
Access token lifetime15 minutes (exp - iat = 900)
Key identifier (kid)In the token header; selects the matching public key

2. Public key endpoints

Both endpoints are public (no authentication) and served over HTTPS. Pick whichever format your framework supports.

JWKS endpoint

GET https://sso.demo.dakok.net/.well-known/jwks.json

Returns a JSON Web Key Set. During key rotation it can contain more than one key, so always resolve the correct key by the token header's kid.

// example JWKS response
{
  "keys": [
    {
      "kty": "RSA",
      "use": "sig",
      "alg": "RS256",
      "kid": "2f1c...a9",
      "n": "<base64url modulus>",
      "e": "AQAB"
    }
  ]
}

PEM endpoint

GET https://sso.demo.dakok.net/api/keys/public.pem

Returns the active public key in PEM format (a -----BEGIN PUBLIC KEY----- block). Convenient for libraries that take a PEM string directly.

Key rotation: signing keys rotate over time. Prefer the JWKS endpoint with kid-based resolution and cache keys with a short TTL so newly rotated keys are picked up automatically. The previous public key stays published until all tokens it signed have expired (≤ 15 minutes).

3. Token & refresh model

As a Relying App you typically only verify the access token. Refresh and logout are handled by the portal itself; you do not need the private key or any secret to verify tokens.

4. Verify with JWKS (Node.js)

Using jose, which fetches and caches the JWKS and resolves the key by kid automatically:

// npm install jose
import { jwtVerify, createRemoteJWKSet } from 'jose';

const JWKS = createRemoteJWKSet(
  new URL('https://sso.demo.dakok.net/.well-known/jwks.json')
);

export async function verifyAccessToken(token) {
  const { payload } = await jwtVerify(token, JWKS, {
    issuer: 'sso.demo.dakok.net',   // checks iss
    algorithms: ['RS256'],            // pin the algorithm
  });
  // jwtVerify also validates exp (and nbf/iat) automatically.
  return payload; // { iss, sub, iat, exp, apps: [...] }
}

Alternatively, with jwks-rsa + jsonwebtoken:

// npm install jwks-rsa jsonwebtoken
const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');

const client = jwksClient({
  jwksUri: 'https://sso.demo.dakok.net/.well-known/jwks.json',
  cache: true,
  rateLimit: true,
});

function getKey(header, callback) {
  // resolve the signing key by the token header's kid
  client.getSigningKey(header.kid, (err, key) => {
    if (err) return callback(err);
    callback(null, key.getPublicKey());
  });
}

function verifyAccessToken(token) {
  return new Promise((resolve, reject) => {
    jwt.verify(
      token,
      getKey,
      { algorithms: ['RS256'], issuer: 'sso.demo.dakok.net' },
      (err, decoded) => (err ? reject(err) : resolve(decoded))
    );
  });
}

5. Verify with PEM (Node.js)

If you prefer the single active public key in PEM form:

// npm install jsonwebtoken
const jwt = require('jsonwebtoken');

async function loadPublicPem() {
  const res = await fetch('https://sso.demo.dakok.net/api/keys/public.pem');
  return res.text(); // -----BEGIN PUBLIC KEY----- ...
}

async function verifyAccessToken(token) {
  const publicPem = await loadPublicPem();
  return jwt.verify(token, publicPem, {
    algorithms: ['RS256'],
    issuer: 'sso.demo.dakok.net',
  });
}
Heads up: the PEM endpoint returns only the active key. If you cache it, refresh the cache periodically (or fall back to JWKS) so token verification keeps working across key rotations.

6. Generic verification checklist

Whatever language or library you use, a correct verification does all of the following:

  1. Parse the JWT header and read the kid.
  2. Fetch the public key set from the JWKS endpoint and select the key whose kid matches (or use the PEM active key).
  3. Verify the signature using RS256 — and pin the algorithm so a token can't downgrade it (reject alg: none and HMAC algorithms).
  4. Check iss equals sso.demo.dakok.net.
  5. Check exp is in the future (token not expired); reject if expired.
  6. Read sub (the user) and apps (authorized application ids) and enforce that your application id is present in apps.
Tip: always pin algorithms: ['RS256']. Accepting any algorithm is a common JWT vulnerability.

7. MCP server for AI integration

The portal exposes a Model Context Protocol (MCP) server at POST https://sso.demo.dakok.net/mcp (JSON-RPC) so tools like Kiro can integrate programmatically while building Relying Apps.

Tool typeAuthExamples
Read-only (open) No API key required Fetch public key (PEM), JWKS, application list, token-verification details (JWKS URL, PEM URL, alg=RS256, iss=sso.demo.dakok.net)
Write / management (gated) Requires a valid, non-expired API key Management operations that change state

To use write tools, sign in to the portal and claim an API key. The key:

Read-only tools never require a key, so AI integrations can always discover the verification details above without authenticating.