About Service Accounts
Only an organization administrator can create or modify a service account.
Every service account has a specific purpose and the necessary permissions. The most common use cases are:
- A management account that can create, update, and delete other service accounts.
- A project management account that has the ability to create projects.
- A view-only account that can read reports and issue metrics.
A service account functions like other Coverity on Polaris user accounts in that both can:
- Be assigned a role (administrator or contributor) on an organization or project.
- Perform role-appropriate actions in Coverity on Polaris, using the API.
Service accounts cannot access the browser-based user interface.
Security Considerations
Service accounts can bypass single sign-on authentication services by using a registered email and password. However, they are restricted to automated interactions between the API and addresses in the IP whitelist.
Overview of the Process for Creating Service Accounts
This figure shows the steps for creating a new service account and assigning a role to it.
-
Retrieve the organization's details.
Request:
GET /api/auth/v1/organizationsResponse:
{ "data" : [ { "type" : "organizations", "id" : "02d7dnqcs52f7eiptpjinp8gis", "attributes" : { "organizationname" : "orgname", "description" : "orgdescription", "soft-deleted" : false, "password-authentication" : { "enabled" : false, "allowSelfSignup" : false }, "date-created" : "2019-07-03T18:36:24.126+0000" }, "relationships" : { "owners" : { "links" : { "self" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/relationships/owners", "related" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/owners" }, "data" : [ { "type" : "users", "id" : "prg6ncjib96shbvh25vdmqkhjc" } ] }, "licenses" : { "links" : { "self" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/relationships/licenses", "related" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/licenses" } }, "licenseViolations" : { "links" : { "self" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/relationships/licenseViolations", "related" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/licenseViolations" } }, "users" : { "links" : { "self" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/relationships/users", "related" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/users" } }, "activeLicense" : { "links" : { "self" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/relationships/activeLicense", "related" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/activeLicense" }, "data" : null }, "groups" : { "links" : { "self" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/relationships/groups", "related" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/groups" } }, "role-assignments" : { "links" : { "self" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/relationships/role-assignments", "related" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis/role-assignments" } } }, "links" : { "self" : { "href" : "https://subdomain.cop.blackduck.com/api/auth/latest/organizations/02d7dnqcs52f7eiptpjinp8gis", "meta" : { "durable" : "urn:x-swip:organizations:02d7dnqcs52f7eiptpjinp8gis" } } } } ], "included" : [ ], "meta" : { "limit" : 500, "offset" : 0, "total" : 1 } } -
Create the service account.
Request:
POST /api/auth/v1/users { "data": { "type": "users", "attributes": { "email": "example@example.com", "name": "CI Pipeline", "username": "ci_pipeline", "enabled": true, "password-login": { "password": "hunter2" }, "automated": true, "ip-whitelist": [ "0.0.0.0/0", "::/0" ] }, "relationships": { "organization": { "data": { "type": "organizations", "id": "02d7dnqcs52f7eiptpjinp8gis" } } } } }When you create the service account, always include the values for
data.attributes.email,data.attributes.password-login.password,data.automated, anddata.ip-whitelist. These are required.Every service account requires an associated email address, regardless of whether the inbox is used.
The IP whitelist describes the range of addresses from which the service account can call the API. The whitelist must use CIDR notation. It can include one IP address or all IP addresses.
-
Retrieve the roles.
Request:
GET /api/auth/v1/rolesResponse:
{ "data": [ { "type": "roles", "id": "ba47qfjl192or34fofmebc9ams", "attributes": { "permissions": { "ORGANIZATION": [ "users.read", "groups.read" ], "PROJECT": [ "projects.read" ] }, "rolename": "Contributor" }, "relationships": {}, "links": { "self": { "href": "https://subdomain.cop.blackduck.com/api /auth/latest/roles/ba47qfjl192or34fofmebc9ams" } } }, { "type": "roles", "id": "3iv42qg2u48uhek91ravh7rhhc", "attributes": { "permissions": { "ORGANIZATION": [ "administer", "users.read", "users.readPrivate", "users.write", "groups.read", "groups.write", "projects.create" ], "PROJECT": [ "administer", "projects.read", "projects.write" ] }, "rolename": "Administrator" }, "relationships": {}, "links": { "self": { "href": "https://subdomain.cop.blackduck.com/api /auth/latest/roles/3iv42qg2u48uhek91ravh7rhhc" } } }, { "type": "roles", "id": "61lbviubjl7un4pis7f0c62it8", "attributes": { "permissions": { "ORGANIZATION": [ "users.read", "groups.read", "projects.create" ], "PROJECT": [ "projects.read", "projects.write" ] }, "rolename": "Contributor" }, "relationships": {}, "links": { "self": { "href": "https://subdomain.cop.blackduck.com/api /auth/latest/roles/61lbviubjl7un4pis7f0c62it8" } } } ], "included": [] } -
Assign a role to the service account.
Request:
POST /api/auth/v1/role-assignments { "data": { "type": "role-assignments", "attributes": { "expires-by": null, "object": "urn:x-swip:organizations: 02d7dnqcs52f7eiptpjinp8gis" }, "relationships": { "role": { "data": { "type": "roles", "id": "3iv42qg2u48uhek91ravh7rhhc" } }, "user": { "data": { "type": "users", "id": "92h1av03nd27h5k5kskk8fq8og" } }, "group": { "data": { "type": "groups", "id": "02d7dnqcs52f7eiptpjinp8gis" } } } } } -
Use Coverity on Polaris credentials (email and password) created for the
service account to obtain an API token.
Authentication requires these steps:
- Obtain a short-term Java web token (JWT).
- Use the JWT to generate an API token.
- Use the token to obtain a long-lasting JWT.
Request: Acquire the short-term JWT
POST api/auth/v1/authenticate -H 'Accept: application/json' -H 'Content-Type: application/x-www-form-urlencoded' -d 'email=user@domain.com&password=hunter2'Note that you must insert the Coverity on Polaris sign-in credentials created for your service account. The result is a short-term JWT, contained in the last line of the response. The short-term JWT is good for one hour.
Response:
{ }# Netscape HTTP Cookie File # https://curl.haxx.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. #HttpOnly_domain.cop.blackduck.com TRUE / TRUE 1592509556 __cfduid9ec84851a2ddd8645ed219bee36016501589917556 #HttpOnly_domain.cop.blackduck.com FALSE / TRUE 1589921157 access_token {The JWT appears here.} domain.cop.blackduck.com FALSE / TRUE 1589921157 access_token_exp_sec 3600 #HttpOnly_domain.cop.blackduck.com FALSE / TRUE 1589921157 private_csrf_token e963d8f88b925cc06551d2c7c8872109507ffcf2 domain.cop.blackduck.com FALSE / TRUE 1589921157 csrf_token l746rsc68p0q90so5k92noilag domain.cop.blackduck.com FALSE / TRUE 1589921157 organizationname dittoThen use the short-term JWT to generate an API token.
Request: Generate API token
POST api/auth/v1/apitokens -H 'Accept: application/vnd.api+json' -H 'Authorization: Bearer {token} {"data":{"attributes":{"name":"test113"},"type":"apitokens"}}Complete the example request above by inserting your short-term JWT, as shown at the end of the second line.
Response:
{ "data" : { "type" : "apitokens", "id" : "nbkj06t21d61n6m3hduipobgc8", "attributes" : { "name" : "mynewtoken", "access-token" : "1cc40d7b95e65dbf9e6995215187c2283bdfb921", "revoked" : false, "date-created" : "2020-05-19T20:19:57.661+0000" }, "relationships" : { "owner" : { "links" : { "self" : "https://domain.cop.blackduck.com/api/auth/latest/apitokens/nbkj06t21d61n6m3hduipobgc8/relationships/owner", "related" : "https://domain.cop.blackduck.com/api/auth/latest/apitokens/nbkj06t21d61n6m3hduipobgc8/owner" }, "data" : { "type" : "users", "id" : "kkmnvsuqe50a57j5u9gj7un1ic" } } }, "links" : { "self" : { "href" : "https://domain.cop.blackduck.com/api/auth/latest/apitokens/nbkj06t21d61n6m3hduipobgc8" } } }, "included" : [ ]You can use the token for later access to the API. When you start a session, the first step is to use the API token to retrieve a long-lasting JWT
Request: Retrieve a long-lasting JWT
POST api/auth/v1/authenticate -H 'Accept: application/json' -H 'Content-Type: application/x-www-form-urlencoded' -d accesstoken={token}Append the long-lasting JWT to every API call during your session, as follows:
'Authorization: Bearer {token}'A long-lasting JWT is good for 12 hours.