@taktikal/s2s
v2.1.2
Published
Utilities for Taktikal service-to-service communication.
Downloads
1
Readme
@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.