Skip to main content

Machine service clients

Authress service clients provide the way to programmatically interact with Authress and throughout your internal software. Any programmatic entity can be a service client. In most cases service clients will represent a service API your team is running. In the case of the Document Repository, this is the Document Repository service itself.

What is a service clientโ€‹

A service client is an Authress resource that represents a programmatic entity. In Authress this is tracked as a Service Client.

Example service clients

Each service client is identified by a specific Client ID which starts with sc_ followed by an alphanumeric sequence of characters.

Types of machine communicationโ€‹

Service clients exist so that you can keep track of which service has access to what resources. In other places this communication is known as machine-to-machine authentication. The common examples of machine communication are:

  • Your service client requests to Authress to configure access records and perform Authorization checks.
  • Your service makes an API request to another service in your platform
  • Your customers make API requests to your service
  • Impersonating your users to migrate from a legacy authentication system

We'll discuss each of these patterns (the last one is discussed in a separate Legacy OAuth migration guide).

tip

Authress automatically works with your existing service clients. That means if you already have a system that generates OIDC compliant JWTs, you can enable Authress to work with those out of the box, via OIDC Trusted identities. After setting up your OIDC Trusted identity, skip down down to Granting Access permissions a service client.

Authress communicationโ€‹

For more details on how the access key process works see the in-depth access key guide.

Service clients are used to configure Authress. They are mechanism to secure the communication between your service and the changes you want to make in your production environment. An example would be on the creation of a new resource, you might want to create a new access record. To do this, your service client would authenticate against Authress using its access key. Up to 5 access keys can be used at a time per service client, and can be generated using the Add key button in the Service Client edit screen:

Create an access key

On clicking Add key, the access key will be displayed one time and then discarded. Or use the Authress SDK or API to request a private key programmatically.

Then the access key can be passed into the Authress SDKs or used with the API directly. In this example, the authressClient is instantiated with a service client access key. This access is used to make API calls to Authress. We can see the stub to generate an access record, and the full details of the Authress SDKs are available for how to make additional API calls.

Service Client setup example
import { AuthressClient } from '@authress/sdk';

const serviceClientSecretAccessKey = 'sc_aaa.acc_001.secret';
const authressClient = new AuthressClient({ authressApiUrl: 'https://auth.yourdomain.com' }, serviceClientSecretAccessKey);

await authressClient.accessRecords.createRecord({...});

Machine-To-Machine authenticationโ€‹

Machine to Machine authentication involves one of your services calling or communicating with another API or service in your platform or software. This communication should be secured with TLS (HTTPS) but that only makes sure that the right client is communicating with the right service.

  • That doesn't help you identify who the client is: Authentication
  • And whether they have access to perform the request they are making: Authorization

To identify the service client caller to the dependent service, Use the Authress SDK to automatically generate a JWT that proves the client is who they say they are:

Use an Authress token to call another service
import { ServiceClientTokenProvider } from '@authress/sdk';

// Configure the custom domain: https://authress.io/app/#/settings?focus=domain
const serviceClientSecretAccessKey = 'sc_aaa.acc_001.secret';
const authressCustomDomainUrl = 'https://auth.yourdomain.com';

class OtherServiceHttpClient {
async getResource() {
const serviceClient = new ServiceClientTokenProvider(serviceClientSecretAccessKey, authressCustomDomainUrl);
const token = await serviceClient.getToken();
const headers = { Authorization: `Bearer ${token}` };
const response = await httpClient.get('https://other-service.yourdomain.com/v1/resources/id_001', headers);
return response;
}
}

This generates the service client token and passes it to the httpClient client to authenticate against that other service. The dependent service would receive that token and now need to validate that incoming request:

Verify incoming machine-to-machine API requestsโ€‹

Verify incoming request
import { AuthressClient } from '@authress/sdk';
const authressClient = new AuthressClient({ authressApiUrl: 'https://auth.yourdomain.com' });
try {
// Grab authorization cookie from the request
// * the best way to do this will be framework specific.
const userToken = request.headers.Authorization.split(' ')[1];
const userIdentity = await authressClient.verifyToken(userToken);
} catch (error) {
console.log('User is unauthorized', error);
return { statusCode: 401 };
}

Enabling your users to call your APIsโ€‹

info

Is some cases, not all clients will be able to use an SDK or a programming language to generate the necessary JWT. In these circumstances, Authress offers the use of static private keys instead. In those cases, see alternative usages of the private access key.

Some software applications, solutions, and platforms enable their users to make requests directly to their APIs. If you have technical users that interact with your API, you'll need a way to secure that communication. Authress directly supports this via service clients. Each of your users can generate their own service client and access keys to go along with those clients using your Authress account. and then you can verify these tokens the same way you verify internal tokens. There's very little difference between this set up and Machine-to-machine authentication.

To enable this communication, you'll want to create a service client for your customer and request an access key for that service client. Then give the access key to your customer. Once they have that access key, then can pass it into your SDK or CLI. This code snippet works best to be distributed in your SDK. See building your own client SDK with Authress access keys.

In your SDK after the temporary JWT access token bound to the customer is created, you can pass that token into all API calls to your service.

[Your SDK] Generate a customer-bound access token
import { ServiceClientTokenProvider } from '@authress/sdk';

// Configure the custom domain: https://authress.io/app/#/settings?focus=domain
const usersPersonalServiceClientAccessKey = 'sc_aaa.acc_001.secret';
const authressCustomDomainUrl = 'https://auth.yourdomain.com';

class OtherServiceHttpClient {
async generateApiToken() {
const serviceClient = new ServiceClientTokenProvider(usersPersonalServiceClientAccessKey, authressCustomDomainUrl);
const token = await serviceClient.getToken();
return token;
}
}

Verify incoming customer API requestsโ€‹

The next step is to verify the incoming tokens. You should be successfully receiving a customer-bound JWT from the above process (through your SDK). Next we verify. To do this, we can use the Authress SDK and call the verifyToken method on that incoming token.

Verify incoming tokens
import { AuthressClient } from '@authress/sdk';
const authressClient = new AuthressClient({ authressApiUrl: 'https://auth.yourdomain.com' });

try {
// Grab authorization cookie from the request
// * the best way to do this will be framework specific.
const userToken = request.headers.Authorization.split(' ')[1];
const userIdentity = await authressClient.verifyToken(userToken);
} catch (error) {
console.log('User is unauthorized', error);
return { statusCode: 401 };
}

Granting Access permissions a service clientโ€‹

Service clients by default have no permissions. The access key you generated enables the service client to identify itself, but it doesn't grant it any permissions. That means to call Authress, interact with other services in your software or platform or enable your customers and third party developers access to your APIs you need to grant those service clients permissions.

To do this in the UI, click the assign client permissions button in the Service Client edit screen:

Grant permissions to a service client

You will see the Access Record edit screen for that service client. Specifying the permissions here will grant them to the service client. In the case of a service client that interacts with Authress, make sure to specify Authress:โœถ or Authress:SpecificResourceType if you want to grant access to Authress resources. Upon clicking the button the Authress Management Portal already makes a suggestion of what permissions to grant it (Remember the recommendation is grant the permissions as restrictive as possible):

Access record permissions