Getting started with RHSM APIs in tech preview

Updated -

Using RHSM APIs in the tech preview

We are currently looking for feedback on the implementation of our new API offerings. At the end of this document, there are links for support and feedback. Please let us know if you need anything or have any requests!
Using APIs in RHSM can help you more effectively keep track of and automate how you manage your Red Hat subscriptions and entitlement usage. By using APIs in RHSM, you can:

  • Control which tooling you use for which products
  • Better manage your system inventory
  • Update and secure your systems more efficiently
  • Continue receiving official support for your Red Hat products

In order to transition to using APIs for Red Hat Subscription Management, Red Hat has created a tech preview program for early access and feedback. Red Hat is in the process of decommissioning Red Hat Network (RHN), including access to its APIs. As a part of this effort, Red Hat has been developing and documenting support for RHSM.

Prerequisites

Red Hat Subscription Management APIs use OAuth 2.0 for authorization. To obtain a token and access the APIs, you will need the following pieces of information:

  • Offline token generated on the RHSM API Tokens page
  • Client ID = rhsm-api
  • Token URL = https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token

Generating a new offline token

An offline token never expires as long as it is used at least once every 30 days and is used to create access tokens for the RHSM APIs. It works as a password and allows you to continue being able to authenticate your account without having to create new refresh tokens.

Warning: Please use password management that is consistent with networking best practices. It is never safe to store any passwords or credentials in plaintext. Treat your offline token with the same security measures that you would a password to protect it against unauthorized use.

To generate an offline token, visit the RHSM API Tokens page and click the Generate Token button.

Generating an access token

Once you have created the offline token, you can use that token to create a new refresh token, which includes an access token that is valid for five minutes. Access tokens are passed in the header to authenticate your Customer Portal user to the RHSM APIs.

Warning: Please use password management that is consistent with networking best practices. It is never safe to store any passwords or credentials in plaintext.

Set the offline token value (in this example, we set it in plaintext and shorten the token value for clarity)
# offline_token='eyJhbGciOiJSUzI1NiIsInR5cCIgOiA'

Create a function to easily filter out JSON values:
# function jsonValue() {
KEY=$1                                            
num=$2
awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'$KEY'\042/){print $(i+1)}}}' | tr -d '"' | sed -n ${num}p
}

# curl https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token -d grant_type=refresh_token -d client_id=rhsm-api -d refresh_token=$offline_token

You should see an output similar to the below where access_token is what will be used as authorization token:

{"access_token":"oiZjo1MjhkNzZmZi1mNzA4LTQzZWQtOGNkNS1mZTE2ZjRmZTBjZTY6cmhuLXN1cHBvcnQta3RvcmRldXIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJyaHNtLWFwaSIsImF1dGhfdGltZSI6MTU2NzQwODU5Nywic2Vzc2lvbl9zdGF0ZSI6ImYwZGJiOGQ0LTRlNGUtNDY1NC04NDRjLTZmMzcwNGM4NDQyMiIsImFjciI6IjAiLCJhbGxvd2VkLW9yaWdpbnMiOltdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsicG9ydGFsX21hbmFnZV9zdWJzY3JpcHRpb25zIiwib2ZmbGluZV9hY2Nlc3MiLCJjYW5kbGVwaW5fc3lzdGVtX2FjY2Vzc192aWV3X2VkaXRfYWxsIiwiYWRtaW46b3JnOmFsbCIsInBvcnRhbF9tYW5hZ2VfY2FzZXMiLCJwb3J0YWxfc3lzdGVtX21hbmFnZW1lbnQiLCJwb3J0YWxfZG93bmxvYWQiXX0sInJlc291cmNlX2FjY2VzcyI6e30sImFjY291bnRfaWQiOiIxOTc5NzEwIiwibmFtZSI6Iktlbm55IFRvcmRldXJzIiwicHJlZmVycmVkX3VzZXJuYW1lIjoicmhuLXN1cHBvcnQta3RvcmRldXIiLCJnaXZlbl9uYW1lIjoiS2VubnkiLCJmYW1pbHlfbmFtZSI6IlRvcmRldXJzIiwiZW1haWwiOiJrdG9yZGV1ckByZWRoYXQuY29tIn0.JfStOgLvgFUAlMb7aVfm-dWxd4wN5oqk377Q6oyDe55pM4zDiZ0f1yJfHsWL8RHeb3r0tj8DY_UAyAFkxAnjyWjq52d7h2EfJUPOs1p1P8Yeu5hDwOrA34Es2maN-ZbJCc4sOb7stGhxSCU15CfvPFIRR5tgSQ17-Mx-x4ZnK_fwpOK6DqQpNzZ0Krz3U1a-NH86XJ8dT8lC3o03YrdlcZx_-wv6-PehqNQa2Hb9vt1csX8QlL3PEyBVNPZXaaTHvyFYx0orGyjKA83Qq-LihbWBXzNjf_rIEfsPJYi-uQHIT_zjaOPYo2rXi7VTPJC2qRSxF2yaRGlihZHxkDzMOTITnaDeMhbx1zvRr-R9eXocEUzsU9j-Yx7h3WYCFjb8zdfXTBHV8SCaMdH1u9Eesa5gmHOoki8882RR85i1fjpBayFTS36y4S-yDebUYiukXOnw8mMMKy04NhVpFGfWtJ8--Jy4Ypndqqk_OS_PiWBsFFN6lMv5S6DZWVpjjE-CENHKn9ceA4MlerBBXLY02Xz9h0biiQUZrd-NLy11j4os124Mai1mmlNOLz993hw0gl-vKKno_bYOV8dEEmKtSLlSPVdW5X_0vBU0BtQuSEVctz_8zsRKHpT-YlDdmP0VDuzJjWM0YsGz2W0_tMuLG7NYS_Ia3vWAVuK--Uv5cAQ","expires_in":900,"refresh_expires_in":0,"refresh_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICItNGVsY19WZE5fV3NPVVlmMkc0UXhyOEdjd0l4X0t0WFVDaXRhdExLbEx3In0.eyJqdGkiOiJhODZlZDczZS00MmE1LTQzYjUtYjJkYS1iMWM5NzU3OWUyZWMiLCJleHAiOjAsIm5iZiI6MCwiaWF0IjoxNTY3NDEwMDIxLCJpc3MiOiJodHRwczovL3Nzby5yZWRoYXQuY29tL2F1dGgvcmVhbG1zL3JlZGhhdC1leHRlcm5hbCIsImF1ZCI6InJoc20tYXBpIiwic3ViIjoiZjo1MjhkNzZmZi1mNzA4LTQzZWQtOGNkNS1mZTE2ZjRmZTBjZTY6cmhuLXN1cHBvcnQta3RvcmRldXIiLCJ0eXAiOiJPZmZsaW5lIiwiYXpwIjoicmhzbS1hcGkiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiJmMGRiYjhkNC00ZTRlLTQ2NTQtODQ0Yy02ZjM3MDRjODQ0MjIiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsicG9ydGFsX21hbmFnZV9zdWJzY3JpcHRpb25zIiwib2ZmbGluZV9hY2Nlc3MiLCJjYW5kbGVwaW5fc3lzdGVtX2FjY2Vzc192aWV3X2VkaXRfYWxsIiwiYWRtaW46b3JnOmFsbCIsInBvcnRhbF9tYW5hZ2VfY2FzZXMiLCJwb3J0YWxfc3lzdGVtX21hbmFnZW1lbnQiLCJwb3J0YWxfZG93bmxvYWQiXX0sInJlc291cmNlX2FjY2VzcyI6e319.S_pmAWzQUc04f0uGHN9rRYd4sH1t4IPnEwCcOH1aBL9Qo4_EbXPWCrtnf84f1pfuKJTQwUS-DldY6eloyVEsGgnqkygBKh270bu_bNXCNAuLJigEMsYx_2VzdnwWLptWS2_FUaNwe7Tai8qXwd8F0ge0Zjoi3P15S_8z4Tp79uD-qKcvwz6NlPKCOZwEbwZqOkJDZ8JKTIK8O0jfqdtHMfaWwlXMXdvx3B70tTOtHjQGAsxZA2dPPvqVGuyMOMmC3bMaISReUbtDwsCV-eAZplDfDZthr4k4JbmG9Iwq1aATaF3aCwfpebcmoIZGHE4_RLZrXCZKapXVVvRxcOrJytxIZrbDHq6ozX7j-j1SE3kuexcSLvlodmfTlxwPX9g7aqJu2ZLno54NxQSgYO8lQqSvScFgLtbX5f_FUS0Iw6yRWWJy2o2fnvfGk83rt5UYTtIb8Xd1GXcpHf8Yl10nVy21BetSQY__VpahF_eZghBNxS689GJnwUqAwlu01pOlb26mmHaydHc3hqUsudZydRbaFfI7nR6gQP8lCtp6b0z5hgVHLG4ZJ7i4MmEL6C5G4xHUaUs6RZgJUSsc2DzLW0b7rSQj41JuvTmSgD8bMrnVokmkAbfvxjKGc7E8n2GyImO7JiKb3RA7_o0xOTRYDIa_Ns-lnigJkUlQZUzt7JI","token_type":"bearer","not-before-policy":0,"session_state":"f0dbb8d4-4e4e-4654-844c-6f3704c84422","scope":"offline_access"}%    

The access_token is what needs to be set/used as authorization token to perform the API call.

# token=`curl https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token -d grant_type=refresh_token -d client_id=rhsm-api -d refresh_token=$offline_token | jsonValue access_token`

Perform an API call with the token

Example API call to list 100 systems:

# curl -H "Authorization: Bearer $token"  "https://api.access.redhat.com/management/v1/systems?limit=100"

Optional CLI tooling support

Install a JSON formatting tool, such as jq or json_reformat to receive more structured returns of your API calls.

  • jq is a command-line JSON processor which can be installed using the yum command: sudo yum install jq
  • json_reformat is a command-line JSON formatter that comes standard on Red Hat Enterprise Linux.

Developers familiar with standard OIDC libraries that supports OAuth 2.0 can use those libraries to build authorization to the Red Hat Subscription Management APIs into scripts and applications.

An option for testing APIs, or for users who access APIs less frequently, is to use a REST client. As long as your REST client supports OAuth 2.0 or custom form submission, you can use that client to access the Red Hat Subscription Management APIs. Some examples of popular REST clients include Postman, Advanced REST Client, and Restlet.

While RHSM no longer officially supports the took application, you can still use it if you found it to be a helpful solution to your workflow.

Accessing available Red Hat Subscription Management APIs

Red Hat provides a Swagger file to describe the specifications of the Red Hat Subscription Management APIs. The Swagger specification includes information about the API endpoints available, input parameters, expected output, and possible error responses. The swagger file can be imported into REST clients like Postman or RESTlet to automatically build a library of API calls. The RHSM API Swagger documentation can be found on the RHSM API Tokens and Swagger documentation page linked at the bottom of this article.

Contact Red Hat

If you run into problems and require support, please open a support case.

We would love feedback on the API implementation we have so far. If you have any suggestions, please feel free to let us know in our survey.

Resources for downloads and Swagger documentation

Troubleshooting

0) Obtain offline_token from https://access.redhat.com/management/api

1) Set the offline token:

#offline_token='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

Verify it's set:

# echo $offline_token

2) Create a function to easily filter out JSON values:

# function jsonValue() {
KEY=$1                                            
num=$2
awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'$KEY'\042/){print $(i+1)}}}' | tr -d '"' | sed -n ${num}p
}

3) Get the access token

# curl https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token -d grant_type=refresh_token -d client_id=rhsm-api -d refresh_token=$offline_token

4) Grab the access token with the function we created before

# token=`curl https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token -d grant_type=refresh_token -d client_id=rhsm-api -d refresh_token=$offline_token | jsonValue access_token`

Verify the access_token is set

# echo $token

5) Perform an API call:

# curl -H "Authorization: Bearer $token"  "https://api.access.redhat.com/management/v1/systems?limit=100"

21 Comments

The API only appears to support GET requests at this point, is that correct? Are there plans to allow changes via the API?

Hi Erinn! Yes, throughout the Tech Preview, we will be publishing additional endpoints for actions like attaching or removing entitlements from Systems, creating and managing Subscriptions on Subscription Allocations and Activation Keys, and many of the other functions you are accustomed to.

The API shows there are POSTs and DELETEs - are these functional now? - I seem to get a 302 response (redirect) when doing DELETE /systems/{uuid}

Yes, the POSTs, PUTs, and DELETEs that are listed in the swagger spec are all functional. As before, if you could submit a support case with steps, that would be great. I will also follow-up for more information. Thanks!

this was my mistake. I had not correctly addressed the endpoint.

from the swagger json

  "host": "api.access.redhat.com",
  "basePath": "/management/v1",

So all urls are https://api.access.redhat.com/management/v1

and then tack on what ever you want to use in the swagger docs.

using python request module , it seems it is only returning response in html. Do you have example of what the request should look like ? This is what I have . r = requests.get(url, headers={"Content-Type": "application/json","Authorization":"Bearer %s " %(auth_token) })

Hi Mahesh.

The request should return JSON not the HTML. Try to load the json as below and check if you get any error.

json.loads(r.text)

Hello, When I request a list of systems by using the api, the list is limited to 100 even if I use the "?limit=500" parameter, did somebody notice the same ( or the syntax is not correct in the Swagger ) ? Exemple : curl -s -H "Authorization: Bearer $BEARER" -H "Content-Type: application/json" -X GET https://api.access.redhat.com/management/v1/systems?limit=500

The syntax is correct, though the description states, "The default and max number of results in a response are 100." We are always looking to tune the performance of these calls and may increase the max in the future.

Ok, Thanks.

We can obtain some information for a system ( Errata, Package, available pool ) but not the subscribed entitlement name, do you think it will be possible in the future ?

Regards,

Seeing -- {"error":"not_allowed","error_description":"Offline tokens not allowed for the user or client"}%

Getting the same error

This assumes that only a web interface will be used. I would like to link a C library into a compiled application for the purpose of verifying the platform is running on is licensed by Red Hat. Has a current subscription. The correct level of subscription. So the customer can be informed of there liability, non-compliance and security situation. C or C++ (gcc) would be great.

Can't authenticate at all.

< HTTP/1.1 401 Unauthorized
< Content-Type: text/plain; charset=utf-8
< X-Content-Type-Options: nosniff
< Content-Length: 24
< Date: Mon, 16 Sep 2019 15:45:31 GMT
< Connection: keep-alive
< Set-Cookie: ff5bc2a9348f7bd5a92b54af186b4a28=b305a95e900aac4ffc1758b7c58eb516; path=/; HttpOnly; Secure

Neither of these work

curl -v -H "Authorization: Bearer $TOKEN" \
    -X GET \
    https://api.access.redhat.com/management/v1/systems?limit=500
or
curl -v -X GET \
    -H "accept: application/json" \
    -H "Authorization: Bearer $TOKEN" \
    "https://api.access.redhat.com/management/v1/subscriptions/$SUB/systems" 

~~~

Could you please open a new support case describing the steps you did and at which point you have the failure.

Thanks

02472876

thanks

My bad on this.

  1. create offline token

  2. create online token from offline token in step #1

  3. authenticate with online token from step #2 and get API data

missed out step #2 doh!

Great thanks for the feedback, based on that I've added a new section "Troubleshooting" which contains the same steps as I provided in the case.

https://access.redhat.com/articles/3626371#btroubleshootingb-9

awesome, thanks again.

What if an advisory (example: RHBA-2019:2824) contains only container images and no RPM packages? How can I obtain the list of included container images? Obviously, https://api.access.redhat.com/management/v1/errata/RHBA-2019%3A2824/packages call returns an empty body.

The list of container images is currently included in the details of the advisory (https://api.access.redhat.com/management/v1/errata/RHBA-2019%3A2824), but not in an easily-readable format. Providing a proper list of container images for an advisory in both the Customer Portal and in the RHSM API is high on our roadmap for early-to-mid 2020. I will follow up with you, Dominik, for some additional information. Thank you!