Important Update Effective February 1, 2024!
Due to recent changes in Jira and Confluence, we've made the tough decision to discontinue the OpenID Connect (OIDC)/OAuth app and no longer provide new versions for the newest Jira/Confluence releases as of January 31, 2024.
This is due to some necessary components no longer shipping with Jira/Confluence, which would require some extensive rewrites of the OIDC App.
Important Update! This app will be discontinued soon!
Due to recent changes in Jira, which no longer ships with some components required for our Read Receipts app to run, we've made the tough decision to discontinue the app, as of Februar 5, 2025.
Important Update! This app will be discontinued soon!
We've made the tough business decision to discontinue the app, as of January 11, 2025.
REST API
The API Token Authentication app currently provides a few REST API endpoints. Please find below a summary of what can be done already.
Create a new token
Create a new token by providing its description as follows. The response will contain the token automatically generated.
curl -v -u user:password -d '{"tokenDescription":"<enter-your-token-description-here>"}' POST https://<your-jira-or-confluence>/rest/de.resolution.apitokenauth/latest/user/token --header "Content-Type: application/json"
You could also provide an expiration period in months, provided that it is smaller or equal to the one defined by the administrator in the system-wide settings.
In the below example, a token with an expiration time of just one month is created:
curl -v -u user:password -d '{"tokenDescription":"<enter-your-token-description-here>", "tokenValidityTimeInMonths" : 1}' POST https://<your-jira-or-confluence>/rest/de.resolution.apitokenauth/latest/user/token --header "Content-Type: application/json"
Creating tokens with a specific expiration date
Since version 1.5.0 you may also pass an ISO 8601 date-time string for the tokenExpirationDateTime field in the payload.
curl -v -u user:password -d '{"tokenDescription":"Custom expiration", "tokenExpirationDateTime" : "2020-10-19T10:29:00.000+02:00"}' POST https://<your-jira-or-confluence>/rest/de.resolution.apitokenauth/latest/user/token --header "Content-Type: application/json"
Please note that it must be below or equal to the maximum allowed value set by your administrator. If not, you'll get a 400 error with some details:
{
"errorMessage" : "The custom expiration you've provided is greater than the maximum defined by your administrator. You need to provide a date within the next 12 months."
}
Otherwise, it will return the token response. Please note that tokenValidityTimeInMonths is not important then, but tokenExpirationDateTime and tokenExpirationDateTimeMillis instead.
{
"id": 9,
"plainTextToken": "pltFERJm3XCjoRnG48wmIiEE3lJWCUD01tjdtv",
"tokenDescription": "Custom expiration",
"tokenForUserKey": "JIRAUSER10100",
"tokenValidityTimeInMonths": 12,
"tokenExpirationDateTime": "2020-10-19T10:29:00.000+02:00",
"tokenExpirationDateTimeMillis": 1603096140000,
"tokenScope": 0
"rateLimitBucketLifetime": 0,
"rateLimitBucketSize": 0,
"publicKey": "",
"allowedIpRanges": [],
"headerValueAccessRules": []
}
You need to include the offset to UTC in that string so that the expiration time works as expected in the user's time zone.
You could validate the expiration date time by reviewing it again in your token list:
Update a token description
This will only succeed for users in groups with the Create Token Permission or Create & Delete Token On Behalf Permission assigned to it. Updating the description of another user's token will only work for users in a group with the Create & Delete Token On Behalf Permission. Here's more on the topic of permissions.
curl -v -u user:password -d '{"tokenDescription":"Updated token description"}' -X PATCH https://<your-jira-or-confluence>/rest/de.resolution.apitokenauth/latest/user/token/<token-id> --header "Content-Type: application/json"
List all tokens
To get an overview of what tokens you've added for your user and to grab an ID of one to update or delete it, execute the request below.
You may omit the pipe symbol and python command at the end, it is just for beautifying the JSON response.
curl -v -u user:password GET https://<your-jira-or-confluence>/rest/de.resolution.apitokenauth/latest/user/token/ | python -mjson.tool
which produces output like:
[
{
"created": 1573814077364,
"description": "Automation token",
"id": 4,
"lastAccessed": 1573814464012
}
]
List all tokens (all users)
The REST endpoint to retrieve token details for all users is only accessible for users with the Create & Delete Token On Behalf Permission. Please read more about permissions here.
You can also use the filter parameters described here to filter for specific properties.
To get an overview of all tokens in the system (including the expired ones) and to grab an id of one to update or delete it, execute the request below. You may omit the pipe symbol and python command at the end, it is just for beautifying the JSON response.
curl -v -u admin:password GET https://<your-jira-or-confluence>/rest/de.resolution.apitokenauth/latest/user/tokensByFilter | python -mjson.tool
which produces output like:
[
{
"created": 1629212615280,
"description": "API Token from 2021-08-17",
"id": 1,
"lastAccessed": 0,
"tokenCreatedByUserKey": "admin",
"tokenForUserKey": "admin",
"tokenScope": 2,
"validUntil": 1631891015279
},
{
"created": 1629212647398,
"description": "API Token from 2021-08-17",
"id": 2,
"lastAccessed": 0,
"tokenCreatedByUserKey": "admin",
"tokenForUserKey": "JIRAUSER10329",
"tokenScope": 2,
"validUntil": 1634483047398
}
]
Delete a token
Grab a token ID retrieved with the previous call and put it to end of the call:
curl -v -u user:password -X DELETE https://<your-jira-or-confluence>/rest/de.resolution.apitokenauth/latest/user/token/<token-id>
Administrative REST API Methods
Since version 1.1.0, sys admins may use the endpoints below as well
Create Tokens for other Users
Admins may create tokens for other users by providing their user key in the request payload. If no token validity time is provided, the system default will be used. How to get a key for a user in Jira/ Confluence is explained in the previous chapter.
curl -v -u admin:passwordOrToken -d '{"tokenDescription":"token for another user", "tokenForUserKey":"JIRAUSER10105"}' POST https://your-jira-or-confluence/rest/de.resolution.apitokenauth/latest/user/token --header "Content-Type: application/json"
If a token validity time is provided, it will be validated and adjusted to the value set in the system-wide settings, if required. This prevents again trying to keep a token valid forever or for 12 months, where only 6 are allowed.
curl -v -u admin:passwordOrToken -d '{"tokenDescription":"token for another user", "tokenForUserKey":"JIRAUSER10105","tokenValidityTimeInMonths":12}' POST https://your-jira-or-confluence/rest/de.resolution.apitokenauth/latest/user/token --header "Content-Type: application/json"
Delete all tokens for a user
This call will work for sysadmins only and otherwise throw 403. Please note that the user key is passed, not the username *.
curl -v -u admin:password -X DELETE https://<your-jira-or-confluence>/rest/de.resolution.apitokenauth/latest/user/token/deleteAllFor/<user-key-not-user-name>
Get User Key for a User
* you can get a user's key by using the REST API as an admin
The result will contain a key or userKey field (Jira or Confluence)
Jira
curl -u admin:password GET https://<your-jira>/rest/api/2/user?username=some.username | python -mjson.tool
{
"active": true,
"applicationRoles": {
"items": [],
"size": 1
},
"avatarUrls": {
"16x16": "https://www.gravatar.com/avatar/9c7da4947106c84fe2c18c1a48747c54?d=mm&s=16",
"24x24": "https://www.gravatar.com/avatar/9c7da4947106c84fe2c18c1a48747c54?d=mm&s=24",
"32x32": "https://www.gravatar.com/avatar/9c7da4947106c84fe2c18c1a48747c54?d=mm&s=32",
"48x48": "https://www.gravatar.com/avatar/9c7da4947106c84fe2c18c1a48747c54?d=mm&s=48"
},
"displayName": "Some User",
"emailAddress": "some@user.com",
"expand": "groups,applicationRoles",
"groups": {
"items": [],
"size": 1
},
"key": "JIRAUSER10100",
"locale": "en_US",
"name": "Some User",
"self": "https://<your-jira>/rest/api/2/user?username=some.username",
"timeZone": "GMT"
}
Confluence
curl -v -u admin:password GET https://<your-confluence>/rest/api/user?username=some.username | python -mjson.tool
{
"_expandable": {
"status": ""
},
"_links": {
"base": "https://<your-confluence>",
"context": "",
"self": "https://<your-confluence>/rest/api/user?key=e4fc80a46ebbdf4c016fa42e69be01f8"
},
"displayName": "some.username",
"profilePicture": {
"height": 48,
"isDefault": true,
"path": "/images/icons/profilepics/default.svg",
"width": 48
},
"type": "known",
"userKey": "e4fc80a46ebbdf4c016fa42e69be01f8",
"username": "some.username"
}
Get User Key by E-Mail
Since version 1.5.0 users with the Create Token On Behalf Permission can use a REST endpoint which allows them to retrieve a user key by providing an e-mail address of a user.
If this address is valid and unique (only assigned to a single user), the endpoint will return the user key.
curl -u user-with-create-token-on-behalf-permission "https://jobo-jira-sd.klab.resolution.de/rest/de.resolution.apitokenauth/latest/user/userKeyByEmail?email=john.doe@deville.com"
JIRAUSER12800
Response if not a single user has the email address
{
"errorMessage" : "Could not retrieve a userkey for email 'unknown@deville.com', error was: NOT_FOUND"
}
Response if the email address has been assigned to more than one user:
{
"errorMessage": "Can't return a userkey since there is more than one user with the email 'john.doe@deville.com'"
}
Filter User Tokens
Since version 1.3.0, the Token Manager tab (read the Token Manager section here) provides an easy-to-use interface for almost all purposes.
There is also a REST endpoint to filter for tokens, i.e. to remind users about their tokens soon to expire, with a custom integration.
We are planning to integrate notifications for tokens to expire soon in a future release.
Filter parameters
Parameter | Value | Comment |
---|---|---|
userFilter | valid user key | read above how to get a user key for a name or by email address; if you want to filter for more than one user, repeat that parameter for as many users you want to filter for |
descriptionFilter | search term | string to search for in all token descriptions |
notValidAfter | epoch Unix timestamp | tokens not valid anymore after that date/ time in milliseconds |
tokenScope | integer | 0 = no scope (all pre 1.5.0 tokens), 1 = read-only, 2 = read/ write |
fromCreated | epoch Unix timestamp | |
untilCreated | epoch Unix timestamp | |
fromLastUsed | epoch Unix timestamp | |
untilLastUsed | epoch Unix timestamp | |
fromExpiresDuring | epoch Unix timestamp | |
untilExpiresDuring | epoch Unix timestamp |
Below is an example of all the above parameters but the notValidAfter parameter
curl -u admin:passwordOrToken "https://your-jira-or-confluence/rest/de.resolution.apitokenauth/latest/user/tokensByFilter?userFilter=JIRAUSER00007&userFilter=JIRAUSER13517&fromCreated=1601503200000&untilCreated=1604185199999&descriptionFilter=findme&tokenScope=1&fromLastUsed=1601503200000&untilLastUsed=1604185199999&fromExpiresDuring=1604185200000&untilExpiresDuring=1612133999999" | python -mjson.tool
Retrieve all tokens not valid after a certain time
The below examples show how to receive all tokens not valid anymore after a certain date/ time in milliseconds
Instead of passing a timestamp as parameter value for notValidAfter, you can also send -1 which will return all tokens
curl -u admin:passwordOrToken "https://your-jira-or-confluence/rest/de.resolution.apitokenauth/latest/user/tokensByFilter?notValidAfter=1688918956972" | python -mjson.tool
And returns
{
"content": [
{
"created": 1580832062985,
"description": "Shell Script",
"id": 64,
"lastAccessed": 0,
"tokenCreatedByUserKey": "admin",
"tokenForUserKey": "admin",
"validUntil": 1596556862985
},
{
"created": 1580832051168,
"description": "Automation Script",
"id": 63,
"lastAccessed": 0,
"tokenCreatedByUserKey": "admin",
"tokenForUserKey": "admin",
"validUntil": 1612454451168
},
{
"created": 1580892710444,
"description": "API Token from 2020-02-05",
"id": 65,
"lastAccessed": 1580892730216,
"tokenCreatedByUserKey": "admin",
"tokenForUserKey": "admin",
"validUntil": 1612515110443
},
{
"created": 1580893252170,
"description": "token for another user",
"id": 66,
"lastAccessed": 0,
"tokenCreatedByUserKey": "admin",
"tokenForUserKey": "JIRAUSER10105",
"validUntil": 1612515652170
}
],
"currentPage": 0,
"limit": 50,
"offset": 0,
"paginationLinks": {
"baseUrl": "https://your-jira-or-confluence",
"nextPage": "",
"previousPage": ""
},
"total": 4,
"totalPages": 1
}
The results are paged and you may only retrieve 50 results max per page. Below another example with paging:
curl -u admin:passwordOrToken "https://your-jira-or-confluence/rest/de.resolution.apitokenauth/latest/user/tokensByFilter?page=0&limit=1¬ValidAfter=1688918956972"
Don't forget to wrap the URL in double quotes, when doing that on the command line, as the & would be interpreted as sending the process into the background
The output would look like the below and contain links to the previous and next page, if available.
{
"content": [
{
"created": 1580832062985,
"description": "Shell Script",
"id": 64,
"lastAccessed": 0,
"tokenCreatedByUserKey": "admin",
"tokenForUserKey": "admin",
"validUntil": 1596556862985
}
],
"currentPage": 0,
"limit": 1,
"offset": 0,
"paginationLinks": {
"baseUrl": "https://your-jira-or-confluence",
"nextPage": "https://your-jira-or-confluence/rest/de.resolution.apitokenauth/latest/user/tokensByFilter?page=1&limit=1¬ValidAfter=1688918956972",
"previousPage": ""
},
"total": 4,
"totalPages": 4
}
Get Email Addresses For Users
The output contains the user key as a unique user identifier. If you need to retrieve the username or email for the user, you need to call the Atlassian REST API:
Jira
curl -u admin:passwordOrToken GET https://<your-jira>/rest/api/2/user?key=JIRAUSER10100| python -mjson.tool
{
"self": "https://<your-jira>/rest/api/2/user?username=user4",
"key": "JIRAUSER10100",
"name": "user4",
"emailAddress": "user4@nowhere.com",
"avatarUrls": {
"48x48": "https://www.gravatar.com/avatar/cdff8c40c13bc745cb3905efece28289?d=mm&s=48",
"24x24": "https://www.gravatar.com/avatar/cdff8c40c13bc745cb3905efece28289?d=mm&s=24",
"16x16": "https://www.gravatar.com/avatar/cdff8c40c13bc745cb3905efece28289?d=mm&s=16",
"32x32": "https://www.gravatar.com/avatar/cdff8c40c13bc745cb3905efece28289?d=mm&s=32"
},
"displayName": "John Doe",
"active": true,
"deleted": false,
"timeZone": "GMT",
"locale": "en_US",
"groups": {
"size": 8,
"items": []
},
"applicationRoles": {
"size": 0,
"items": []
},
"expand": "groups,applicationRoles"
}
Confluence
Unfortunately, the Confluence REST API doesn't return the email address for a user https://docs.atlassian.com/ConfluenceServer/rest/7.12.0/#api/user-getUser,
not even as a property which could be expanded.
REST API Error Response Codes
REST Endpoint | Action | HTTP Result Code |
---|---|---|
Regular REST endpoints with the API Token app enabled and Basic Auth with password still allowed | User accesses the endpoint with a token expired or wrong | 401 |
Regular REST endpoints with the API Token app enabled and Basic Auth with password disabled | User accesses the endpoint with a token expired or wrong | 401 |
Regular REST endpoints with the API Token app enabled and Basic Auth with password enabled | User accesses the endpoint with a regular password | 401 |
API Token REST endpoints (listed in the guide above) | Non sys-admin user is trying to access an API Token app endpoint only intend for sysadmins | 403 |
Please be aware that depending on the system settings, Jira & Confluence might increase the failed login counter up to a point where the user would need to enter a captcha to reset that
counter or let a sys admin do that for him/ her. Until then, every further attempt to access the REST API will result in a 403 Forbidden error.
Read more about the security configuration below:
Jira: https://your-jira/secure/admin/ViewApplicationProperties.jspa - Maximum Authentication Attempts Allowed
Confluence: Atlassian documentation https://confluence.atlassian.com/doc/configuring-captcha-for-failed-logins-216957808.html