Authentication

Authentication with the Workday Credential's Issuance and Verification APIs is a two-step operation. These APIs require an access token obtained via a Token API using a JWT Bearer Grant flow. As such, any call to issue or verify credentials must be preceded by a call to obtain an access token. The token is cacheable and may continue to be used until it expires at which point a new one must be obtained.

Preparing the token request

The token API, itself, authenticates using a JWT token that you construct and sign, cryptographically, using values provided at configuration time. You'll need three pieces of information:

  1. Your org. This will be in your cred admin url. For example: https://credentials.workday.com/gms/applications. In this case, the organization is gms.
  2. A clientId - This is created when you create a new Application in Cred Admin. You can always go look this value up in Cred Admin.
  3. A privateKey - Also created when you create a new Application in Cred Admin. You must save this key immedately upon creation of an Application. Workday does not hold this key for you.

With these pieces of information in hand, the 1st thing to do is formulate the necessary JWT claims. The template below shows what these claims should look like with tokens for org and clientId. A token expiration two hours from now has been chosen.

{
	"tenant": [org],
	"scope":"Regular",
	"sub": [clientId],
	"iss": [clientId],
	"exp": Date.now() + 120 * 1000
}

Now that the claims are complete, we need only use our favorite JWT library and our private key to generate a signed token that we can send to the Token API in exchange for an access token we can use for Issuance & Verification API calls.

let jwtToken = jwt.sign(claims, privateKey, {algorithm: 'RS512'})

There is a fully working sample written in NodeJS on the Getting Started page.

The token produced needs to be added as the value of assertion in the following message:

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=[token]

That entire value, in turn, needs to be URL encoded and then used as the body of a POST request to the Token API with a Content-Type of x-www-form-urlencoded.

Sample Request:

POST https://accounts.workday.com/oauth2/v1/token
Headers:
	Content-Type: x-www-form-urlencoded
Body:
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnQiOiJzbWciLCJzY29wZSI6IlJlZ3VsYXIiLCJzdWIiOiJORGd4WldReU1HRXRObUUwT0MwMFlqSTRMV0l6TjJJdE5UWTJaamhoWlRsbE9EbG0iLCJpc3MiOiJORGd4WldReU1HRXRObUUwT0MwMFlqSTRMV0l6TjJJdE5UWTJaamhoWlRsbE9EbG0iLCJleHAiOjE1NTk4NzI3Nzk5OTgsImlhdCI6MTU1OTg3MjY1OX0.YU-gyzcbbQTQG1Z5_jeMEaPFewNjnnhYpeawsf_13MSAGynUubUieaia9gpkMHGfx1eQMkzbc2x_Q8sONdEM1jfVDTu8DCtZI9bOOPoUzYouobERsap0olomv26_sD36LsUmvdQ7Ete1jrPB4T962AhZDWiLvX7row6VpUhl2cF5c7JkPwJYI5GHr9SGmUb3W8BCkp6MZIHg-Sfwc8kdenU6cAKCLTj6v3gTaIs9MvkUjXh9dsXegbrXJyAL3CSjqp7O-k81Rl7EchpJUOr783otDei2RMvZVdtSRp_uY4OxyzuYbH9HnnPjtGKKBpRuvt4uPPjJecSVasaox3H5GQ

Sample Response:

{
    "access_token": "eyJraWQiOiIyM...",
    "id_token": "eyJraWQiOi...",
    "token_type": "Bearer",
    "expires_in": "3600"
}

The access_token in this response, can now be used as the Authorization header on a request to, for example, create an offer:

Sample Request

POST https://credentials.id.workday.com/v1/offers
Headers:
	Content-Type: application/json
	Authorization: Bearer eyJraWQiOiIyM...
Body:
{
    "recipient": {
        "email": "john.smith@trywayto.com"
    },
    "templateId": "did:work:AnpAoW1CuKdTYnGfhrg6RN",
    "data": {
        "firstName": "a string value",
        "lastName": "a string value",
        "middleName": "a string value",
        "suffix": "a string value",
        "title": "a string value"
    }
}

NOTE: It is important to note that issuing with a templateId requires a JWT token with an org, clientId and private key signature that matches an application associated with that templateId. Any other JWTs' access tokens will fail authorization.