@taktikal/s2s
TypeScript icon, indicating that this package has built-in type declarations

2.1.2 • Public • Published

@taktikal/s2s

What is this package for?

"S2S" stands for service-to-service. This package is concerned with communication between different Taktikal services. We are using Auth0 Machine to Machine Authorization for communication between Taktikal services.

Take an example where service A wants to make use of service B. Service B does not allow unauthenticated calls to it, so service A needs to let B know that it's allowed to talk to it.

This package would be used by service A to make talking to service B easy.

Getting started

The first thing to do is register the services that you want to talk to. Create a custom.d.ts file at the root of the project and extend the TaktikalServices interface like so:

declare module "@taktikal/s2s" {
  export interface TaktikalServices {
    AdminApi: string;
  }
}

Now we need to register the service. There are two aspects to a service:

  • baseURL
  • audience

The baseURL is where the network requests actually go. The audience is an identifier for the service. You can find this identifier within Auth0.

The audience is typically an URL, but may also just be any old string.

You provide these two values to @taktikal/s2s via s2s.registerServices:

import s2s from "@taktikal/s2s";

s2s.registerServices({
  AdminApi: {
    baseURL: "https://taktikal-admin-api.example.com/api",
    audience: "adminapi",
  },
});

Usage

getClient()

Given that we want to fetch some data from the Admin API:

GET https://taktikal-admin-api.example.com/api/storage/big-data

We can perform this request like so:

const client = await s2s.getClient((s) => s.AdminApi);

const { data } = await client.get<Data>(`/storage/big-data`);

s2s.getClient receives a fn which provides the registered services as an argument. You just return the config for the service you want to talk to.

The return value of s2s.getClient is Promise<AxiosInstance>. This AxiosInstance will have the Authorization header set up correctly and the baseURL of the instance will be the one you provided for the service.

getConfig()

Alternatively, you can just get the Axios config like so:

const config = await s2s.getConfig((s) => s.AdminApi);

const { data } = await Axios.get<Data>(`/storage/big-data`, config);

getUrl()

You can get the baseURL for a service with getUrl. This fn is synchronous.

const baseURL = s2s.getUrl((url) => url.AdminApi);

getHeaders()

You can get the headers for communication with a service with getHeaders.

const headers = await s2s.getHeaders((url) => url.AdminApi);

Authentication middleware

The default s2s export is concerned with service A that wants to talk to service B.

If we are service B in this example, we can make use of createAuthMiddleware to authenticate calls from service A to create middleware for Express.

import express from "express";
import { createAuthMiddleware } from "@taktikal/s2s";

const server = express();

server.use(
  createAuthMiddleware({
    audience,
    issuer,
    jwksUri,
  }),
);

The audience should be the same audience that's specified in s2s.registerServices.

The issuer is most likely in the form:

https://{TENANT}.eu.auth0.com/

And the jwksUri is most likely in the form:

{issuer}.well-known/jwks.json

Given that the audience of our service is test_api and that our tentant is test-tenant, the middleware would created like so:

createAuthMiddleware({
  audience: "test_api",
  issuer: "https://test-tenant.eu.auth0.com/",
  jwksUri: "https://test-tenant.eu.auth0.com/.well-known/jwks.json",
});

Disable S2S

You can disable S2S by setting DISABLE_S2S="true" in your Environment Variables. This makes getClient return the default Axios instance.

Readme

Keywords

none

Package Sidebar

Install

npm i @taktikal/s2s

Weekly Downloads

1

Version

2.1.2

License

ISC

Unpacked Size

13 kB

Total Files

4

Last publish

Collaborators

  • alexharri
  • bjark