Skip to content

Eyevinn/node-cat

Repository files navigation

Node library for Common Access Token

Node library for Common Access Token (CTA-5007)

npm github release license

PRs welcome made with hearth by Eyevinn Slack

This is a Node library for generating and validating Common Access Tokens (CTA-5007)

Claims Validation Support

Core Claims

Claim Validate
Issuer (iss) Yes
Audience (aud) Yes
Expiration (exp) Yes
Not Before (nbf) Yes
CWT ID (cti) No
Common Access Token Replay (catreplay) No
Common Access Token Probability of Rejection (catpor) No
Common Access Token Version (catv) No
Common Access Token Network IP (catnip) No
Common Access Token URI (catu) No
Common Access Token Methods (catm) No
Common Access Token ALPN (catalpn) No
Common Access Token Header (cath) No
Common Access Token Geographic ISO3166 (catgeoiso3166) No
Common Access Token Geographic Coordinate (catgeocoord) No
Geohash (geohash) No
Common Access Token Altitude (catgeoalt) No
Common Access Token TLS Public Key (cattpk) No

Requirements

  • Node version 22+

Installation / Usage

% npm install --save @eyevinn/cat

Validate CTA Common Access Token in HTTP incoming message

import { HttpValidator } from '@eyevinn/cat';

const httpValidator = new HttpValidator({
  keys: [
    {
      kid: 'Symmetric256',
      key: Buffer.from(
        '403697de87af64611c1d32a05dab0fe1fcb715a86ab435f1ec99192d79569388',
        'hex'
      )
    }
  ],
  tokenMandatory: true // Optional (default: true)
  issuer: 'eyevinn',
  audience: ['one', 'two'] // Optional
});

const server = http.createServer((req, res) => {
  const result = await httpValidator.validateHttpRequest(
    req
  );
  res.writeHead(result.status, { 'Content-Type': 'text/plain' });
  res.end(result.message || 'ok');
});
server.listen(8080, '127.0.0.1', () => {
  console.log('Server listening');
});
% curl -v -H 'CTA-Common-Access-Token: 2D3RhEOhAQWhBFBha2FtYWlfa2V5X2hzMjU2U6MEGmfXP_YGGmfXQAsFGmfXQAtYINTT_KlOyhaV6NaSxFXkqJWfBagSkPkem10dysoA-C0w' http://localhost:8080/
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.7.1
> Accept: */*
> CTA-Common-Access-Token: 2D3RhEOhAQWhBFBha2FtYWlfa2V5X2hzMjU2U6MEGmfXP_YGGmfXQAsFGmfXQAtYINTT_KlOyhaV6NaSxFXkqJWfBagSkPkem10dysoA-C0w
>
* Request completely sent off
< HTTP/1.1 401 Unauthorized
< Content-Type: text/plain
< Date: Sun, 16 Mar 2025 23:11:03 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
< Transfer-Encoding: chunked
<
* Connection #0 to host localhost left intact
Token has expired

Validate CTA Common Access Token in a CloudFront request

import {
  Context,
  CloudFrontResponseEvent,
  CloudFrontResponseCallback
} from 'aws-lambda';
import { HttpValidator } from '@eyevinn/cat';

export const handler = async (
  event: CloudFrontResponseEvent,
  context: Context,
  callback: CloudFrontResponseCallback
) => {
  const httpValidator = new HttpValidator({
    keys: [
      {
        kid: 'Symmetric256',
        key: Buffer.from(
          '403697de87af64611c1d32a05dab0fe1fcb715a86ab435f1ec99192d79569388',
          'hex'
        )
      }
    ],
    issuer: 'eyevinn'
  });
  const request = event.Records[0].cf.request;
  const response = event.Records[0].cf.response;
  const result = await httpValidator.validateCloudFrontRequest(request);
  response.status = result.status;
  response.statusDescription = result.message;
  callback(null, response);
};

Verify token

import { CAT } from '@eyevinn/cat';

const validator = new CAT({
  keys: {
    Symmetric256: Buffer.from(
      '403697de87af64611c1d32a05dab0fe1fcb715a86ab435f1ec99192d79569388',
      'hex'
    )
  }
});
const base64encoded =
  '0YRDoQEEoQRMU3ltbWV0cmljMjU2eKZkOTAxMDNhNzAxNzU2MzZmNjE3MDNhMmYyZjYxNzMyZTY1Nzg2MTZkNzA2YzY1MmU2MzZmNmQwMjY1NmE2ZjZlNjE3MzAzNzgxODYzNmY2MTcwM2EyZjJmNmM2OTY3Njg3NDJlNjU3ODYxNmQ3MDZjNjUyZTYzNmY2ZDA0MWE1NjEyYWViMDA1MWE1NjEwZDlmMDA2MWE1NjEwZDlmMDA3NDIwYjcxSKuCk/+kFmlY';
try {
  const cat = await validator.validate(base64encoded, 'mac', {
    issuer: 'coap://as.example.com'
  });
  console.log(cat.claims);
} catch (err) {
  // Not valid
  console.log(err);
}

Generate token

import { CAT } from '@eyevinn/cat';

const generator = new CAT({
  keys: {
    Symmetric256: Buffer.from(
      '403697de87af64611c1d32a05dab0fe1fcb715a86ab435f1ec99192d79569388',
      'hex'
    )
  }
});
const base64encoded = await generator.generate(
  {
    iss: 'coap://as.example.com',
    sub: 'jonas',
    aud: 'coap://light.example.com',
    exp: 1444064944,
    nbf: 1443944944,
    iat: 1443944944,
    cti: '0b71'
  },
  {
    type: 'mac',
    alg: 'HS256',
    kid: 'Symmetric256'
  }
);

Development

Contributing

See CONTRIBUTING

License

This project is licensed under the MIT License, see LICENSE.

Support

Join our community on Slack where you can post any questions regarding any of our open source projects. Eyevinn's consulting business can also offer you:

  • Further development of this component
  • Customization and integration of this component into your platform
  • Support and maintenance agreement

Contact [email protected] if you are interested.

About Eyevinn Technology

Eyevinn Technology is an independent consultant firm specialized in video and streaming. Independent in a way that we are not commercially tied to any platform or technology vendor. As our way to innovate and push the industry forward we develop proof-of-concepts and tools. The things we learn and the code we write we share with the industry in blogs and by open sourcing the code we have written.

Want to know more about Eyevinn and how it is to work here. Contact us at [email protected]!

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages