Service account

Get a token with Service Account

Service account authentication is used primarily for machine to machine use cases where systems need to access the infrastructure for critical information. If you don’t have customer credentials (username & password) or they are in your own database, outside of the scope of MasStack , you will need to be able to generate an assertion token to authenticate and obtain the proper JWT access token to make requests to MasStack APIs. This assertion must be created with the RSA keys provided by Authn when registering this Service Account.

Authentication flow

In this graph can be seen all the differents flows involved in obtaining the token.

MasStackAuthNApplicationMasStackAuthNApplicationCreate and sign JWTToken JWTreturn JWT (access_token)Call API request: Authorization: JWTresponse

warningWarning

To use this authentication method, a Service Account must be created. Service accounts are provided by the MasStack
team after carefully auditing each use case, so please contact your MasStack
representative to obtain your service account credentials.

How to obtain the token

Step 1 Obtain the MasStack Service Account (SA)

Service accounts are provided by MasStack Owners. This team must be contacted in order to have access to MasStack environment.

When a service account is created, Authn Team will provide a json like this:

content_copy
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
    "private_key_id": "7524f047-83e4-4194-988e-9eb772e51405",
    "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEApB8CNN7RyN4vo7O3J9iR+3JUAj0AlHbMPZKXxOgkc6LbvjZX\nFuSUVQL4wppw8iI0ZIkTt42L/NIIA2M/u/6Jewgi7MCn0ClrnS2Wr/evPSJ0lxR/\nQLK6HSTEoKf7Ea7f9pkVrhiRD8lc6igmSUJJKFTPCuO5/iKufd+xaNTMGvRTTIFr\nSKHBMPVgbP2aVjGziD9IZD0iW8zhPekFwUnPYRNrLc62MJfQNG/4m6g3XSEnMlhe\n7okUYV9rLORXMWWDuaD7kmP+hgXbDMV7EyJehJR8DhFNRBgQyaTpsk+QM15m7rwP\ntTOI3miUO2wbHo........ib746MjJrtK05oVi2/Q==\n-----END RSA PRIVATE KEY-----\n",
    "client_email": "thirdparty@gMj7jdyiF8xefBgLJnU1.auth.masmovil.com",
    "client_id": "gMj7jdyiF8xefBgLJnU1",
    "type": "service_account",
    "token_uri": "https://authn.masstack.com/v1/oauth/token",
    "auth_uri": "https://authn.masstack.com/v1/oauth/authorize",
    "project_id": "addfakQlgpccgrWHTzht"
}

A good practice is to store this parameters in different variables to have quickly access to this information because it will be needed in next steps.

warningWarning

This JSON contains a private key, so this information must be encoded. This JSON should not be shared without being encoded or appear in any log. If attackers find this information, they will be able to get tokens and make requests in your place.

In case that your service account or private key were compromised, please contact Authn’s Team.

Step 2 Use SA to create and sign and assertion token

To limit access to resources Oauth scopes are defined to potentially limit access to the resource through the specific API. These scopes could be included in the assertion as a claim that the instance or app creates.

The assertion you must create to obtain access token is a JWT. This JWT should be generated with following steps:

2.1 Build JWT header

This is the header object of the JWT and the params

Name Description
alg Encryption algorithm. Always RS256
typ Type of token. Always JWT
kid Specify your service account’s private key ID. You can find this value in the "private_key_id" field of your service account JSON file.
content_copy
1
2
3
4
5
{
    "alg": "RS256", 
    "typ": "JWT",
    "kid": "{{private_key_id}}"
}

2.2 Build JWT payload / claim-set

An example of the payload with the different objects can be seen as follows:

Name Description
iss The email address (client_email) of the service account. You can find this value in the "client_email" field within the service account JSON file previously provided by the Authn team.
aud A descriptor of the intended target of the assertion. You can find this value in the "token_uri" field within the service account JSON file previously provided by the Authn team.
exp The expiration time of the assertion, specified as seconds since 00:00:00 UTC, January 1, 1970. This value has a maximum of 1 hour after the issued time.
iat The time the assertion was issued, specified as seconds since 00:00:00 UTC, January 1, 1970.
content_copy
1
2
3
4
5
6
{
  "iss": "{{client_email}}",
  "aud": "{{token_uri}}",
  "exp": 1675952137,
  "iat": 1675948537,
}

2.3 Adapt private key if necessary

Some editors need to adapt the private_key with external libraries. This object has RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function so it is necessary to convert this private_key to PKCS8 o JWT format.

2.4 Sign and create the assertion token

To sign the assertion, you can check on this page https://jwt.io/libraries the library that best suits your stack.

Step 3 The Token

Once you have signed properly the JWT assertion token, you can request to authN an access token making a login request such as:

Name Description
grant_type parameter defines the OAuth2 flow that is going to be used; in this case urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion is the assertion created through the RSA keys provided by Authn.
content_copy
1
2
3
4
curl --location --request POST 'https://{{authn_host}}/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'assertion={{assertion_token}}' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer'

If the request is successful, you should get a response like the following:

Name Description
access_token is a signed JWT used by a user to authenticate himself against Istio’s service mesh.
expires_in is the time that the access_token will be valid. Once it expires, the access_token won’t be valid and the user won’t be able to authenticate with it.
token_type defines the type of the access_token that has been generated. This will normally be used in the Authorization header to indicate which kind of authentication has the request.
content_copy
1
2
3
4
5
{
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImY3ZWZiY2JkLTM5ZDAtNDhlYS04YzU3LTMyMzk5OTFjNjA2ZSIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ2b2RhZm9uZUBCTTVpY2hiZ0Q1Q3RUc0R0QXFuUi5hdXRoLm1hc21vdmlsLmNvbSIsImNpZCI6IkJNNWljaGJnRDVDdFRzRHRBcW5SIiwiZXhwIjoxNTc4NDA1MzAzLCJpYXQiOjE1NzgzOTgxMDMsImlzcyI6Imh0dHA6Ly9hcGk6ODA4MC9vYXV0aC90b2tlbiIsIm1vaSI6MSwic2NvcGUiOiJteXNpbS5lZGl0b3IuZnVsbGNvbnRyb2wiLCJzdWIiOiJ2b2RhZm9uZUBCTTVpY2hiZ0Q1Q3RUc0R0QXFuUi5hdXRoLm1hc21vdmlsLmNvbSIsInRpZCI6ImVlZjYyMzRjLTgyMTMtNGNjYi05YmJhLTNiM2RmZmNkMjc5YiJ9.W_AlzK9WQdibK-1ZO4N1_DubxvK-q0R0oLxXSuFhTLSSrdAALFLNkMozCQd-tEBA1JnxmC628j0VCJQ9zw6wxQ70ryN5293YrivNlREmZ4RbjrZMyGlY2vfd30lFWKR3xmlb7p24Sl5-0Fo9OpiWgTaStWVtvLVmadmGwDHx2LpKSqnA3nQgUYczuU50DadqLGRrBD5QvEzzCYlzwSDwtLN5h1bGRTVCIcyxpsnyLg7lW8NM5DFhkKRLr0b-o_01bsmM03aNmXzO3kLajf7L1eczUPi4iUkhRE1ETRdNVqKuOqfupEan405rM-P9LevYjJoOVZ420IAW9l_S78Fu8A",
  "expires_in": 3600,
  "token_type": "Bearer"
}

If the response includes an access token, you can use the access token to call a MasMovil API. (If the response does not include an access token, your JWT and token request might not be properly formed, or the service account might not have permission to access to MasMovil’s APIs)

When the access token expires, your application should generate another JWT, sign it, and request another access token.